@metorial-services/relay-client 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +21 -0
  2. package/dist/clients/typescript/src/index.d.ts +120 -0
  3. package/dist/clients/typescript/src/index.d.ts.map +1 -0
  4. package/dist/clients/typescript/src/templates/components/button.d.ts +6 -0
  5. package/dist/clients/typescript/src/templates/components/button.d.ts.map +1 -0
  6. package/dist/clients/typescript/src/templates/components/code.d.ts +4 -0
  7. package/dist/clients/typescript/src/templates/components/code.d.ts.map +1 -0
  8. package/dist/clients/typescript/src/templates/components/dataList.d.ts +7 -0
  9. package/dist/clients/typescript/src/templates/components/dataList.d.ts.map +1 -0
  10. package/dist/clients/typescript/src/templates/components/index.d.ts +7 -0
  11. package/dist/clients/typescript/src/templates/components/index.d.ts.map +1 -0
  12. package/dist/clients/typescript/src/templates/components/layout.d.ts +8 -0
  13. package/dist/clients/typescript/src/templates/components/layout.d.ts.map +1 -0
  14. package/dist/clients/typescript/src/templates/components/text.d.ts +6 -0
  15. package/dist/clients/typescript/src/templates/components/text.d.ts.map +1 -0
  16. package/dist/clients/typescript/src/templates/components/wrapper.d.ts +6 -0
  17. package/dist/clients/typescript/src/templates/components/wrapper.d.ts.map +1 -0
  18. package/dist/clients/typescript/src/templates/index.d.ts +4 -0
  19. package/dist/clients/typescript/src/templates/index.d.ts.map +1 -0
  20. package/dist/clients/typescript/src/templates/lib/email.d.ts +16 -0
  21. package/dist/clients/typescript/src/templates/lib/email.d.ts.map +1 -0
  22. package/dist/clients/typescript/src/templates/template.d.ts +6 -0
  23. package/dist/clients/typescript/src/templates/template.d.ts.map +1 -0
  24. package/dist/index.cjs +2 -0
  25. package/dist/index.cjs.map +1 -0
  26. package/dist/index.d.ts +404 -0
  27. package/dist/index.module.js +2 -0
  28. package/dist/index.module.js.map +1 -0
  29. package/dist/index.umd.js +2 -0
  30. package/dist/index.umd.js.map +1 -0
  31. package/package.json +45 -0
  32. package/src/index.ts +74 -0
  33. package/src/templates/components/button.tsx +28 -0
  34. package/src/templates/components/code.tsx +30 -0
  35. package/src/templates/components/dataList.tsx +23 -0
  36. package/src/templates/components/index.tsx +6 -0
  37. package/src/templates/components/layout.tsx +45 -0
  38. package/src/templates/components/text.tsx +22 -0
  39. package/src/templates/components/wrapper.tsx +86 -0
  40. package/src/templates/index.ts +3 -0
  41. package/src/templates/lib/email.tsx +30 -0
  42. package/src/templates/template.ts +7 -0
package/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # Metorial Relay Client
2
+
3
+ A client library for interacting with the Metorial Relay platform using TypeScript.
4
+
5
+ ## Usage
6
+
7
+ ```ts
8
+ import { createRelayClient } from '@lowerdeck/forge-client';
9
+
10
+ let forge = createRelayClient({
11
+ endpoint: '...'
12
+ });
13
+ ```
14
+
15
+ ## License
16
+
17
+ This project is licensed under the Apache License 2.0.
18
+
19
+ <div align="center">
20
+ <sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
21
+ </div>
@@ -0,0 +1,120 @@
1
+ import { createClient } from '@lowerdeck/rpc-client';
2
+ import type { RelayClient } from '../../../service/src/controllers';
3
+ import { ITemplate } from './templates';
4
+ export * from './templates';
5
+ type ClientOpts = Parameters<typeof createClient>[0];
6
+ type EmailIdentity = Awaited<ReturnType<RelayClient['emailIdentity']['get']>>;
7
+ export declare let createRelayClient: (o: ClientOpts & {
8
+ sender: {
9
+ identifier: string;
10
+ name: string;
11
+ };
12
+ }) => {
13
+ sender: {
14
+ get: (arg0: Omit<import("@lowerdeck/validation/dist/validators").UndefinedIsOptional<{
15
+ senderId: string;
16
+ }>, "senderId">, opts?: {
17
+ headers?: Record<string, string>;
18
+ query?: Record<string, string>;
19
+ } | undefined) => Promise<{
20
+ object: string;
21
+ id: string;
22
+ identifier: string;
23
+ name: string;
24
+ createdAt: Date;
25
+ }>;
26
+ upsert: (arg0: Omit<import("@lowerdeck/validation/dist/validators").UndefinedIsOptional<{
27
+ name: string;
28
+ identifier: string;
29
+ }>, "senderId">, opts?: {
30
+ headers?: Record<string, string>;
31
+ query?: Record<string, string>;
32
+ } | undefined) => Promise<{
33
+ object: string;
34
+ id: string;
35
+ identifier: string;
36
+ name: string;
37
+ createdAt: Date;
38
+ }>;
39
+ };
40
+ emailIdentity: {
41
+ get: (arg0: Omit<import("@lowerdeck/validation/dist/validators").UndefinedIsOptional<{
42
+ senderId: string;
43
+ emailIdentityId: string;
44
+ }>, "senderId">, opts?: {
45
+ headers?: Record<string, string>;
46
+ query?: Record<string, string>;
47
+ } | undefined) => Promise<{
48
+ object: string;
49
+ id: string;
50
+ type: "email";
51
+ slug: string;
52
+ fromName: string;
53
+ fromEmail: string;
54
+ senderOid: number;
55
+ createdAt: Date;
56
+ }>;
57
+ upsert: (arg0: Omit<import("@lowerdeck/validation/dist/validators").UndefinedIsOptional<{
58
+ senderId: string;
59
+ name: string;
60
+ email: string;
61
+ }>, "senderId">, opts?: {
62
+ headers?: Record<string, string>;
63
+ query?: Record<string, string>;
64
+ } | undefined) => Promise<{
65
+ object: string;
66
+ id: string;
67
+ type: "email";
68
+ slug: string;
69
+ fromName: string;
70
+ fromEmail: string;
71
+ senderOid: number;
72
+ createdAt: Date;
73
+ }>;
74
+ };
75
+ email: {
76
+ send: (arg0: Omit<import("@lowerdeck/validation/dist/validators").UndefinedIsOptional<{
77
+ senderId: string;
78
+ emailIdentityId: string;
79
+ type: "email" | undefined;
80
+ to: string[];
81
+ template: Record<string, any>;
82
+ content: import("@lowerdeck/validation/dist/validators").UndefinedIsOptional<{
83
+ subject: string;
84
+ html: string;
85
+ text: string;
86
+ }>;
87
+ }>, "senderId">, opts?: {
88
+ headers?: Record<string, string>;
89
+ query?: Record<string, string>;
90
+ } | undefined) => Promise<{
91
+ id: string;
92
+ }>;
93
+ };
94
+ send: (arg0: Omit<import("@lowerdeck/validation/dist/validators").UndefinedIsOptional<{
95
+ senderId: string;
96
+ emailIdentityId: string;
97
+ type: "email" | undefined;
98
+ to: string[];
99
+ template: Record<string, any>;
100
+ content: import("@lowerdeck/validation/dist/validators").UndefinedIsOptional<{
101
+ subject: string;
102
+ html: string;
103
+ text: string;
104
+ }>;
105
+ }>, "senderId">, opts?: {
106
+ headers?: Record<string, string>;
107
+ query?: Record<string, string>;
108
+ } | undefined) => Promise<{
109
+ id: string;
110
+ }>;
111
+ createTemplate<Data>(template: ITemplate<Data>, identity: EmailIdentity | Promise<EmailIdentity>): {
112
+ send: (i: {
113
+ data: Data;
114
+ to: string[];
115
+ }) => Promise<{
116
+ id: string;
117
+ }>;
118
+ };
119
+ };
120
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,cAAc,aAAa,CAAC;AAE5B,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAErD,KAAK,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAE9E,eAAO,IAAI,iBAAiB,GAC1B,GAAG,UAAU,GAAG;IACd,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA8BgB,IAAI,YACP,SAAS,CAAC,IAAI,CAAC,YACf,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;kBAG9B;YAAE,IAAI,EAAE,IAAI,CAAC;YAAC,EAAE,EAAE,MAAM,EAAE,CAAA;SAAE;;;;CAsBnD,CAAC"}
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare let Button: ({ href, children }: {
3
+ href: string;
4
+ children: React.ReactNode;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../../../src/templates/components/button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkB1B,eAAO,IAAI,MAAM,GAAI,oBAAoB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,4CAQnF,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare let Code: ({ code }: {
2
+ code: string;
3
+ }) => import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../../../../../src/templates/components/code.tsx"],"names":[],"mappings":"AAEA,eAAO,IAAI,IAAI,GAAI,UAAU;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,4CA2B5C,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare let DataList: ({ items }: {
2
+ items: {
3
+ label: string;
4
+ value: string;
5
+ }[];
6
+ }) => import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=dataList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataList.d.ts","sourceRoot":"","sources":["../../../../../../src/templates/components/dataList.tsx"],"names":[],"mappings":"AAOA,eAAO,IAAI,QAAQ,GAAI,WAAW;IAAE,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,4CAe9E,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './button';
2
+ export * from './code';
3
+ export * from './dataList';
4
+ export * from './layout';
5
+ export * from './text';
6
+ export * from './wrapper';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/templates/components/index.tsx"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC"}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export declare let Layout: ({ title, description, children, style }: {
3
+ title: React.ReactNode;
4
+ description?: React.ReactNode;
5
+ children: React.ReactNode;
6
+ style?: React.CSSProperties;
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/templates/components/layout.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,IAAI,MAAM,GAAI,yCAKlB;IACD,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,4CA+BA,CAAC"}
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare let Text: ({ children, style }: {
3
+ children: React.ReactNode;
4
+ style?: React.CSSProperties;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../../../../src/templates/components/text.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,IAAI,IAAI,GAAI,qBAGhB;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,4CAYA,CAAC"}
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare let Wrapper: ({ children, preview }: {
3
+ children?: React.ReactNode;
4
+ preview?: string;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../../../../../../src/templates/components/wrapper.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,MAAM,OAAO,CAAC;AA8B1B,eAAO,IAAI,OAAO,GAAI,uBAGnB;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,4CAsCA,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './components';
2
+ export * from './lib/email';
3
+ export * from './template';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/templates/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ export interface IEmail {
3
+ subject: string;
4
+ html: string | Promise<string>;
5
+ text: string | Promise<string>;
6
+ }
7
+ export declare let createEmail: ({ content, preview, subject }: {
8
+ content: React.ReactElement;
9
+ preview?: string;
10
+ subject: string;
11
+ }) => {
12
+ subject: string;
13
+ html: Promise<string>;
14
+ text: Promise<string>;
15
+ };
16
+ //# sourceMappingURL=email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../../../../../src/templates/lib/email.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAChC;AAED,eAAO,IAAI,WAAW,GAAI,+BAIvB;IACD,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;;;;CAWA,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { IEmail } from './lib/email';
2
+ export interface ITemplate<Data> {
3
+ render: (data: Data) => IEmail | Promise<IEmail>;
4
+ }
5
+ export declare let createTemplate: <Data>(template: ITemplate<Data>) => ITemplate<Data>;
6
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../../../src/templates/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,WAAW,SAAS,CAAC,IAAI;IAC7B,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD;AAED,eAAO,IAAI,cAAc,GAAI,IAAI,EAAE,UAAU,SAAS,CAAC,IAAI,CAAC,oBAAa,CAAC"}
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ var e=require("@lowerdeck/rpc-client"),t=require("react/jsx-runtime"),n=require("@react-email/components");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var i=/*#__PURE__*/r(require("react"));function s(){return s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(null,arguments)}var o={padding:"27px 0 27px",textAlign:"center"},a={backgroundColor:"#000000",borderRadius:"7px",fontWeight:"600",color:"#fff",fontSize:"15px",textDecoration:"none",textAlign:"center",display:"block"},l={},c={backgroundColor:"#ffffff",margin:"0 auto",fontFamily:"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif"},d={maxWidth:"600px",margin:"0 auto"},u={marginTop:"25px"},x={fontSize:"12px",color:"#777"},p={margin:"20px 0px",border:"none",borderBottom:"1px solid #ddd",background:"none"},f=function(e){var r=e.children,i=e.preview;return t.jsxs(n.Html,{children:[t.jsx(n.Head,{}),i&&t.jsx(n.Preview,{children:i}),t.jsx(n.Body,{style:c,children:t.jsxs(n.Container,{style:d,children:[t.jsx(n.Section,{style:u,children:t.jsx(n.Img,{src:"https://cdn.metorial.com/2025-06-13--14-59-55/logos/metorial/primary_logo_text/resized-100-w881-h256.png",height:"30",alt:"Metorial"})}),r,t.jsx(n.Hr,{style:p}),t.jsx(n.Section,{children:"enterprise"==process.env.METORIAL_SOURCE?t.jsx(n.Text,{style:x,children:"Sent by Metorial 💌. If you have any questions, feel free to contact us. If you need to reference this message use this ID: EMAIL_ID."}):t.jsxs(n.Text,{style:x,children:["Sent by a self hosted instance of ",t.jsx("a",{href:"https://metorial.com",children:"Metorial"}),". Contact the administrator of this instance if you have any questions."]})})]})})]})};exports.Button=function(e){var r=e.href,i=e.children;return t.jsx(n.Section,{style:o,children:t.jsx(n.Button,{style:s({},a,{padding:"12px 18px"}),href:r,children:i})})},exports.Code=function(e){var r=e.code,i=r.slice(0,3),s=r.slice(3,6);return t.jsx(n.Section,{style:{background:"#fff",border:"1px solid #ddd",borderRadius:"8px",margin:"20px 0px",padding:"6px 15px"},children:t.jsxs(n.Text,{style:{fontSize:"20px",textAlign:"center",verticalAlign:"middle"},children:[t.jsx("span",{children:i}),t.jsx("span",{style:{margin:"0 5px",color:"#aaa"},children:"-"}),t.jsx("span",{children:s})]})})},exports.DataList=function(e){return t.jsx(n.Section,{style:l,children:e.items.map(function(e,r){var i=e.value;return t.jsx(n.Row,{children:t.jsxs(n.Column,{style:{padding:"10px 0px"},children:[t.jsxs(n.Text,{style:{fontSize:14,fontWeight:"bold",padding:"3px 0px",margin:0},children:[e.label,":"," "]}),t.jsx(n.Text,{style:{fontSize:14,padding:"3px 0px",margin:0},children:i})]})},r)})})},exports.Layout=function(e){var r=e.title,o=e.description,a=e.children,l=e.style;return t.jsxs(i.default.Fragment,{children:[t.jsx(n.Text,{style:s({fontFamily:"sans-serif",fontSize:20,fontWeight:"bold",marginBottom:10},l),children:r}),o&&t.jsx(n.Text,{style:s({fontFamily:"sans-serif",fontSize:16,marginBottom:20},l),children:o}),a]})},exports.Text=function(e){var r=e.children;return t.jsx(n.Text,{style:s({fontFamily:"sans-serif",fontSize:14},e.style),children:r})},exports.Wrapper=f,exports.createEmail=function(e){var r=e.subject,i=t.jsx(f,{preview:e.preview,children:e.content});return{subject:r,html:n.render(i,{plainText:!1}),text:n.render(i,{plainText:!0})}},exports.createRelayClient=function(t){var n=e.createClient(t),r=n.sender.upsert({identifier:t.sender.identifier,name:t.sender.name}),i=function(e){return function(t){try{var n=arguments;return Promise.resolve(r).then(function(r){return Promise.resolve(e.apply(void 0,[s({},t,{senderId:r.id})].concat([].slice.call(n,1))))})}catch(e){return Promise.reject(e)}}};return{sender:{get:i(n.sender.get),upsert:i(n.sender.upsert)},emailIdentity:{get:i(n.emailIdentity.get),upsert:i(n.emailIdentity.upsert)},email:{send:i(n.email.send)},send:i(n.email.send),createTemplate:function(e,t){return{send:function(i){try{return Promise.resolve(e.render(i.data)).then(function(e){return Promise.resolve(r).then(function(r){var s=n.email,o=s.send,a=i.data,l=i.to;return Promise.resolve(t).then(function(t){var n=r.id,i=t.id,c=e.subject;return Promise.resolve(e.html).then(function(t){return Promise.resolve(e.text).then(function(e){return Promise.resolve(o.call(s,{type:"email",to:l,template:a,emailIdentityId:i,senderId:n,content:{subject:c,html:t,text:e}}))})})})})})}catch(e){return Promise.reject(e)}}}}}},exports.createTemplate=function(e){return e};
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/templates/components/button.tsx","../src/templates/components/dataList.tsx","../src/templates/components/wrapper.tsx","../src/templates/components/code.tsx","../src/templates/components/layout.tsx","../src/templates/components/text.tsx","../src/templates/lib/email.tsx","../src/index.ts","../src/templates/template.ts"],"sourcesContent":["import { Button as EmailButton, Section } from '@react-email/components';\nimport React from 'react';\n\nlet buttonContainer = {\n padding: '27px 0 27px',\n textAlign: 'center' as const\n};\n\nlet button = {\n backgroundColor: '#000000',\n borderRadius: '7px',\n fontWeight: '600',\n color: '#fff',\n fontSize: '15px',\n textDecoration: 'none',\n textAlign: 'center' as const,\n display: 'block'\n};\n\nexport let Button = ({ href, children }: { href: string; children: React.ReactNode }) => {\n return (\n <Section style={buttonContainer}>\n <EmailButton style={{ ...button, padding: '12px 18px' }} href={href}>\n {children as any}\n </EmailButton>\n </Section>\n );\n};\n","import { Column, Row, Section, Text } from '@react-email/components';\n\nlet container = {\n // background: '#efefef',\n // border: '1px solid #ccc'\n};\n\nexport let DataList = ({ items }: { items: { label: string; value: string }[] }) => {\n return (\n <Section style={container}>\n {items.map(({ label, value }, i) => (\n <Row key={i}>\n <Column style={{ padding: '10px 0px' }}>\n <Text style={{ fontSize: 14, fontWeight: 'bold', padding: '3px 0px', margin: 0 }}>\n {label}:{' '}\n </Text>\n <Text style={{ fontSize: 14, padding: '3px 0px', margin: 0 }}>{value}</Text>\n </Column>\n </Row>\n ))}\n </Section>\n );\n};\n","import {\n Body,\n Container,\n Head,\n Hr,\n Html,\n Img,\n Preview,\n Section,\n Text\n} from '@react-email/components';\nimport React from 'react';\n\nlet main = {\n backgroundColor: '#ffffff',\n margin: '0 auto',\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif\"\n};\n\nlet container = {\n maxWidth: '600px',\n margin: '0 auto'\n};\n\nlet logoContainer = {\n marginTop: '25px'\n};\n\nlet footerText = {\n fontSize: '12px',\n color: '#777'\n};\n\nlet hr = {\n margin: '20px 0px',\n border: 'none',\n borderBottom: '1px solid #ddd',\n background: 'none'\n};\n\nexport let Wrapper = ({\n children,\n preview\n}: {\n children?: React.ReactNode;\n preview?: string;\n}) => {\n return (\n <Html>\n <Head />\n\n {preview && <Preview>{preview}</Preview>}\n\n <Body style={main}>\n <Container style={container}>\n <Section style={logoContainer}>\n <Img\n src=\"https://cdn.metorial.com/2025-06-13--14-59-55/logos/metorial/primary_logo_text/resized-100-w881-h256.png\"\n height=\"30\"\n alt=\"Metorial\"\n />\n </Section>\n\n {children}\n\n <Hr style={hr} />\n\n <Section>\n {process.env.METORIAL_SOURCE == 'enterprise' ? (\n <Text style={footerText}>\n Sent by Metorial 💌. If you have any questions, feel free to contact us. If you\n need to reference this message use this ID: EMAIL_ID.\n </Text>\n ) : (\n <Text style={footerText}>\n Sent by a self hosted instance of <a href=\"https://metorial.com\">Metorial</a>.\n Contact the administrator of this instance if you have any questions.\n </Text>\n )}\n </Section>\n </Container>\n </Body>\n </Html>\n );\n};\n","import { Section, Text } from '@react-email/components';\n\nexport let Code = ({ code }: { code: string }) => {\n let first3 = code.slice(0, 3);\n let last3 = code.slice(3, 6);\n\n return (\n <Section\n style={{\n background: '#fff',\n border: '1px solid #ddd',\n borderRadius: '8px',\n margin: '20px 0px',\n padding: '6px 15px'\n }}\n >\n <Text\n style={{\n fontSize: '20px',\n textAlign: 'center',\n verticalAlign: 'middle'\n }}\n >\n <span>{first3}</span>\n <span style={{ margin: '0 5px', color: '#aaa' }}>-</span>\n <span>{last3}</span>\n </Text>\n </Section>\n );\n};\n","import { Text as EmailText } from '@react-email/components';\nimport React from 'react';\n\nexport let Layout = ({\n title,\n description,\n children,\n style\n}: {\n title: React.ReactNode;\n description?: React.ReactNode;\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) => {\n return (\n <React.Fragment>\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 20,\n fontWeight: 'bold',\n marginBottom: 10,\n ...style\n }}\n >\n {title}\n </EmailText>\n\n {description && (\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 16,\n marginBottom: 20,\n ...style\n }}\n >\n {description}\n </EmailText>\n )}\n\n {children}\n </React.Fragment>\n );\n};\n","import { Text as EmailText } from '@react-email/components';\nimport React from 'react';\n\nexport let Text = ({\n children,\n style\n}: {\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) => {\n return (\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 14,\n ...style\n }}\n >\n {children}\n </EmailText>\n );\n};\n","import { render } from '@react-email/components';\nimport React from 'react';\nimport { Wrapper } from '../components/wrapper';\n\nexport interface IEmail {\n subject: string;\n html: string | Promise<string>;\n text: string | Promise<string>;\n}\n\nexport let createEmail = ({\n content,\n preview,\n subject\n}: {\n content: React.ReactElement;\n preview?: string;\n subject: string;\n}) => {\n let inner = <Wrapper preview={preview}>{content}</Wrapper>;\n\n let html = render(inner, { plainText: false });\n let text = render(inner, { plainText: true });\n\n return {\n subject,\n html,\n text\n };\n};\n","import { createClient } from '@lowerdeck/rpc-client';\nimport type { RelayClient } from '../../../service/src/controllers';\nimport { ITemplate } from './templates';\n\nexport * from './templates';\n\ntype ClientOpts = Parameters<typeof createClient>[0];\n\ntype EmailIdentity = Awaited<ReturnType<RelayClient['emailIdentity']['get']>>;\n\nexport let createRelayClient = (\n o: ClientOpts & {\n sender: {\n identifier: string;\n name: string;\n };\n }\n) => {\n let inner = createClient<RelayClient>(o);\n\n let sender = inner.sender.upsert({\n identifier: o.sender.identifier,\n name: o.sender.name\n });\n\n let wrap =\n <Arg0, Args extends any[], R>(fn: (arg0: Arg0, ...args: Args) => Promise<R>) =>\n async (arg0: Omit<Arg0, 'senderId'>, ...args: Args) => {\n let s = await sender;\n return await fn({ ...arg0, senderId: s.id } as any, ...args);\n };\n\n return {\n sender: {\n get: wrap(inner.sender.get),\n upsert: wrap(inner.sender.upsert)\n },\n emailIdentity: {\n get: wrap(inner.emailIdentity.get),\n upsert: wrap(inner.emailIdentity.upsert)\n },\n email: {\n send: wrap(inner.email.send)\n },\n send: wrap(inner.email.send),\n\n createTemplate<Data>(\n template: ITemplate<Data>,\n identity: EmailIdentity | Promise<EmailIdentity>\n ) {\n return {\n send: async (i: { data: Data; to: string[] }) => {\n let rendered = await template.render(i.data);\n let s = await sender;\n\n return await inner.email.send({\n type: 'email',\n to: i.to,\n template: i.data as any,\n\n emailIdentityId: (await identity).id,\n senderId: s.id,\n\n content: {\n subject: rendered.subject,\n html: await rendered.html,\n text: await rendered.text\n }\n });\n }\n };\n }\n };\n};\n","import { IEmail } from './lib/email';\n\nexport interface ITemplate<Data> {\n render: (data: Data) => IEmail | Promise<IEmail>;\n}\n\nexport let createTemplate = <Data>(template: ITemplate<Data>) => template;\n"],"names":["buttonContainer","padding","textAlign","button","backgroundColor","borderRadius","fontWeight","color","fontSize","textDecoration","display","container","main","margin","fontFamily","maxWidth","logoContainer","marginTop","footerText","hr","border","borderBottom","background","Wrapper","_ref","children","preview","_jsxs","Html","_jsx","Head","Preview","jsx","Body","style","jsxs","Container","Section","Img","src","height","alt","Hr","process","env","METORIAL_SOURCE","Text","href","EmailButton","_extends","code","first3","slice","last3","verticalAlign","items","map","_ref2","i","value","Row","Column","label","title","description","React","Fragment","EmailText","marginBottom","subject","inner","content","html","render","plainText","text","o","createClient","sender","upsert","identifier","name","wrap","fn","arg0","_arguments","arguments","Promise","resolve","then","s","apply","senderId","id","concat","call","e","reject","get","emailIdentity","email","send","createTemplate","template","identity","data","rendered","_inner$email","_send","_i$data","_i$to","to","_identity","_s$id","_identity$id","_rendered$subject","_rendered$html","_rendered$text","type","emailIdentityId"],"mappings":"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"}
@@ -0,0 +1,404 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ import * as Cookie from 'cookie';
4
+ import React$1 from 'react';
5
+
6
+ export interface ClientOpts {
7
+ endpoint: string;
8
+ headers?: Record<string, string | undefined>;
9
+ getHeaders?: () => Promise<Record<string, string>> | Record<string, string>;
10
+ onRequest?: (d: {
11
+ endpoint: string;
12
+ name: string;
13
+ payload: any;
14
+ headers: Record<string, string | undefined>;
15
+ query?: Record<string, string | undefined>;
16
+ }) => any;
17
+ }
18
+ declare let createClient: <T extends object>(clientOpts: ClientOpts) => T;
19
+ export interface ValidationError {
20
+ code: string;
21
+ message: string;
22
+ expected?: any;
23
+ received?: any;
24
+ path?: string[];
25
+ min?: number;
26
+ max?: number;
27
+ positive?: boolean;
28
+ negative?: boolean;
29
+ }
30
+ export type ValidationResult<T> = {
31
+ success: true;
32
+ value: T;
33
+ } | {
34
+ success: false;
35
+ errors: ValidationError[];
36
+ };
37
+ export type ValidationType<T> = {
38
+ validate: (value: any) => ValidationResult<T>;
39
+ examples?: T[];
40
+ items?: ValidationType<any> | ValidationType<any>[];
41
+ properties?: {
42
+ [key: string]: ValidationType<any>;
43
+ };
44
+ type: string;
45
+ name?: string;
46
+ description?: string;
47
+ optional?: boolean;
48
+ nullable?: boolean;
49
+ hidden?: boolean;
50
+ };
51
+ export type KeysWhichExtend<T, SelectedType> = {
52
+ [key in keyof T]: SelectedType extends T[key] ? key : never;
53
+ }[keyof T];
54
+ export type Optional<T> = Partial<Pick<T, KeysWhichExtend<T, undefined>>>;
55
+ type Required$1<T> = Omit<T, KeysWhichExtend<T, undefined>>;
56
+ export type UndefinedIsOptional<T> = Optional<T> & Required$1<T>;
57
+ export interface ServiceRequest {
58
+ query: URLSearchParams;
59
+ headers: Headers;
60
+ url: string;
61
+ ip?: string;
62
+ body: any;
63
+ rawBody: any;
64
+ requestId: string;
65
+ getCookies: () => Record<string, string | undefined>;
66
+ getCookie: (name: string) => string | undefined;
67
+ setCookie: (name: string, value: string, opts?: Cookie.SerializeOptions) => void;
68
+ sharedMiddlewareMemo: Map<string, Promise<any>>;
69
+ beforeSend: (handler: () => Promise<any>) => void;
70
+ appendHeaders: (headers: Record<string, string | string[]>) => void;
71
+ }
72
+ export type Simplify<T> = {
73
+ [KeyType in keyof T]: T[KeyType];
74
+ } & {};
75
+ export type ExtendContext<C extends object, E> = E extends object ? Simplify<C & E> : C;
76
+ export type Controller<HandlersAndSubControllers extends {
77
+ [key: string]: Handler<any, any, any> | Controller<any>;
78
+ }> = HandlersAndSubControllers;
79
+ export type InferClient<HandlersAndSubControllers extends {
80
+ [key: string]: Handler<any, any, any> | Controller<any>;
81
+ }> = {
82
+ [K in keyof HandlersAndSubControllers]: HandlersAndSubControllers[K] extends Handler<infer I, infer O, infer C> ? ((input: I, opts?: {
83
+ headers?: Record<string, string>;
84
+ query?: Record<string, string>;
85
+ }) => Promise<O>) & {
86
+ getFull: (input: I, opts?: {
87
+ headers?: Record<string, string>;
88
+ query?: Record<string, string>;
89
+ }) => Promise<{
90
+ data: O;
91
+ status: number;
92
+ headers: Record<string, string>;
93
+ }>;
94
+ } : HandlersAndSubControllers[K] extends Controller<infer U> ? InferClient<U> : never;
95
+ };
96
+ declare class Handler<Input, Output, Context extends {
97
+ [key: string]: any;
98
+ } = {}> {
99
+ private _middleware;
100
+ private _handler;
101
+ private _validation;
102
+ constructor(_middleware?: Array<(ctx: Context & ServiceRequest) => Promise<any>>);
103
+ do<HandlerOutput>(handler: (ctx: Context & Omit<ServiceRequest, "body"> & {
104
+ input: Input;
105
+ }) => Promise<HandlerOutput>): Handler<Input, HandlerOutput, Context>;
106
+ use<T extends {
107
+ [key: string]: any;
108
+ } = {}>(handler: (ctx: Context & ServiceRequest) => Promise<T | undefined | void>): Handler<Input, Output, ExtendContext<Context, T>>;
109
+ input<HandlerInput>(validation: ValidationType<HandlerInput>): Handler<HandlerInput, Output, Context>;
110
+ run(req: ServiceRequest, initialContext: any): Promise<{
111
+ response: Output;
112
+ }>;
113
+ }
114
+ declare const EmailIdentityType: {
115
+ readonly email: "email";
116
+ };
117
+ export type EmailIdentityType = (typeof EmailIdentityType)[keyof typeof EmailIdentityType];
118
+ declare let rootController: {
119
+ emailIdentity: {
120
+ upsert: Handler<UndefinedIsOptional<{
121
+ senderId: string;
122
+ name: string;
123
+ email: string;
124
+ }>, {
125
+ object: string;
126
+ id: string;
127
+ type: "email";
128
+ slug: string;
129
+ fromName: string;
130
+ fromEmail: string;
131
+ senderOid: number;
132
+ createdAt: Date;
133
+ }, {
134
+ sender: {} & {
135
+ name: string;
136
+ oid: number;
137
+ id: string;
138
+ createdAt: Date;
139
+ identifier: string;
140
+ };
141
+ }>;
142
+ get: Handler<UndefinedIsOptional<{
143
+ senderId: string;
144
+ emailIdentityId: string;
145
+ }>, {
146
+ object: string;
147
+ id: string;
148
+ type: "email";
149
+ slug: string;
150
+ fromName: string;
151
+ fromEmail: string;
152
+ senderOid: number;
153
+ createdAt: Date;
154
+ }, {
155
+ sender: {} & {
156
+ name: string;
157
+ oid: number;
158
+ id: string;
159
+ createdAt: Date;
160
+ identifier: string;
161
+ };
162
+ emailIdentity: {
163
+ sender: {
164
+ name: string;
165
+ oid: number;
166
+ id: string;
167
+ createdAt: Date;
168
+ identifier: string;
169
+ };
170
+ } & {
171
+ oid: number;
172
+ id: string;
173
+ type: EmailIdentityType;
174
+ slug: string;
175
+ fromName: string;
176
+ fromEmail: string;
177
+ subjectMarker: string | null;
178
+ senderOid: number;
179
+ createdAt: Date;
180
+ updatedAt: Date;
181
+ };
182
+ }>;
183
+ };
184
+ sender: {
185
+ upsert: Handler<UndefinedIsOptional<{
186
+ name: string;
187
+ identifier: string;
188
+ }>, {
189
+ object: string;
190
+ id: string;
191
+ identifier: string;
192
+ name: string;
193
+ createdAt: Date;
194
+ }, {}>;
195
+ get: Handler<UndefinedIsOptional<{
196
+ senderId: string;
197
+ }>, {
198
+ object: string;
199
+ id: string;
200
+ identifier: string;
201
+ name: string;
202
+ createdAt: Date;
203
+ }, {
204
+ sender: {} & {
205
+ name: string;
206
+ oid: number;
207
+ id: string;
208
+ createdAt: Date;
209
+ identifier: string;
210
+ };
211
+ }>;
212
+ };
213
+ email: {
214
+ send: Handler<UndefinedIsOptional<{
215
+ senderId: string;
216
+ emailIdentityId: string;
217
+ type: "email" | undefined;
218
+ to: string[];
219
+ template: Record<string, any>;
220
+ content: UndefinedIsOptional<{
221
+ subject: string;
222
+ html: string;
223
+ text: string;
224
+ }>;
225
+ }>, {
226
+ id: string;
227
+ }, {
228
+ sender: {} & {
229
+ name: string;
230
+ oid: number;
231
+ id: string;
232
+ createdAt: Date;
233
+ identifier: string;
234
+ };
235
+ }>;
236
+ };
237
+ };
238
+ export type RelayClient = InferClient<typeof rootController>;
239
+ export declare let Button: ({ href, children }: {
240
+ href: string;
241
+ children: React$1.ReactNode;
242
+ }) => import("react/jsx-runtime").JSX.Element;
243
+ export declare let Code: ({ code }: {
244
+ code: string;
245
+ }) => import("react/jsx-runtime").JSX.Element;
246
+ export declare let DataList: ({ items }: {
247
+ items: {
248
+ label: string;
249
+ value: string;
250
+ }[];
251
+ }) => import("react/jsx-runtime").JSX.Element;
252
+ export declare let Layout: ({ title, description, children, style }: {
253
+ title: React$1.ReactNode;
254
+ description?: React$1.ReactNode;
255
+ children: React$1.ReactNode;
256
+ style?: React$1.CSSProperties;
257
+ }) => import("react/jsx-runtime").JSX.Element;
258
+ declare let Text$1: ({ children, style }: {
259
+ children: React$1.ReactNode;
260
+ style?: React$1.CSSProperties;
261
+ }) => import("react/jsx-runtime").JSX.Element;
262
+ export declare let Wrapper: ({ children, preview }: {
263
+ children?: React$1.ReactNode;
264
+ preview?: string;
265
+ }) => import("react/jsx-runtime").JSX.Element;
266
+ export interface IEmail {
267
+ subject: string;
268
+ html: string | Promise<string>;
269
+ text: string | Promise<string>;
270
+ }
271
+ export declare let createEmail: ({ content, preview, subject }: {
272
+ content: React$1.ReactElement;
273
+ preview?: string;
274
+ subject: string;
275
+ }) => {
276
+ subject: string;
277
+ html: Promise<string>;
278
+ text: Promise<string>;
279
+ };
280
+ export interface ITemplate<Data> {
281
+ render: (data: Data) => IEmail | Promise<IEmail>;
282
+ }
283
+ export declare let createTemplate: <Data>(template: ITemplate<Data>) => ITemplate<Data>;
284
+ type ClientOpts$1 = Parameters<typeof createClient>[0];
285
+ export type EmailIdentity = Awaited<ReturnType<RelayClient["emailIdentity"]["get"]>>;
286
+ export declare let createRelayClient: (o: ClientOpts$1 & {
287
+ sender: {
288
+ identifier: string;
289
+ name: string;
290
+ };
291
+ }) => {
292
+ sender: {
293
+ get: (arg0: Omit<UndefinedIsOptional<{
294
+ senderId: string;
295
+ }>, "senderId">, opts?: {
296
+ headers?: Record<string, string>;
297
+ query?: Record<string, string>;
298
+ } | undefined) => Promise<{
299
+ object: string;
300
+ id: string;
301
+ identifier: string;
302
+ name: string;
303
+ createdAt: Date;
304
+ }>;
305
+ upsert: (arg0: Omit<UndefinedIsOptional<{
306
+ name: string;
307
+ identifier: string;
308
+ }>, "senderId">, opts?: {
309
+ headers?: Record<string, string>;
310
+ query?: Record<string, string>;
311
+ } | undefined) => Promise<{
312
+ object: string;
313
+ id: string;
314
+ identifier: string;
315
+ name: string;
316
+ createdAt: Date;
317
+ }>;
318
+ };
319
+ emailIdentity: {
320
+ get: (arg0: Omit<UndefinedIsOptional<{
321
+ senderId: string;
322
+ emailIdentityId: string;
323
+ }>, "senderId">, opts?: {
324
+ headers?: Record<string, string>;
325
+ query?: Record<string, string>;
326
+ } | undefined) => Promise<{
327
+ object: string;
328
+ id: string;
329
+ type: "email";
330
+ slug: string;
331
+ fromName: string;
332
+ fromEmail: string;
333
+ senderOid: number;
334
+ createdAt: Date;
335
+ }>;
336
+ upsert: (arg0: Omit<UndefinedIsOptional<{
337
+ senderId: string;
338
+ name: string;
339
+ email: string;
340
+ }>, "senderId">, opts?: {
341
+ headers?: Record<string, string>;
342
+ query?: Record<string, string>;
343
+ } | undefined) => Promise<{
344
+ object: string;
345
+ id: string;
346
+ type: "email";
347
+ slug: string;
348
+ fromName: string;
349
+ fromEmail: string;
350
+ senderOid: number;
351
+ createdAt: Date;
352
+ }>;
353
+ };
354
+ email: {
355
+ send: (arg0: Omit<UndefinedIsOptional<{
356
+ senderId: string;
357
+ emailIdentityId: string;
358
+ type: "email" | undefined;
359
+ to: string[];
360
+ template: Record<string, any>;
361
+ content: UndefinedIsOptional<{
362
+ subject: string;
363
+ html: string;
364
+ text: string;
365
+ }>;
366
+ }>, "senderId">, opts?: {
367
+ headers?: Record<string, string>;
368
+ query?: Record<string, string>;
369
+ } | undefined) => Promise<{
370
+ id: string;
371
+ }>;
372
+ };
373
+ send: (arg0: Omit<UndefinedIsOptional<{
374
+ senderId: string;
375
+ emailIdentityId: string;
376
+ type: "email" | undefined;
377
+ to: string[];
378
+ template: Record<string, any>;
379
+ content: UndefinedIsOptional<{
380
+ subject: string;
381
+ html: string;
382
+ text: string;
383
+ }>;
384
+ }>, "senderId">, opts?: {
385
+ headers?: Record<string, string>;
386
+ query?: Record<string, string>;
387
+ } | undefined) => Promise<{
388
+ id: string;
389
+ }>;
390
+ createTemplate<Data>(template: ITemplate<Data>, identity: EmailIdentity | Promise<EmailIdentity>): {
391
+ send: (i: {
392
+ data: Data;
393
+ to: string[];
394
+ }) => Promise<{
395
+ id: string;
396
+ }>;
397
+ };
398
+ };
399
+
400
+ export {
401
+ Text$1 as Text,
402
+ };
403
+
404
+ export {};
@@ -0,0 +1,2 @@
1
+ import{createClient as e}from"@lowerdeck/rpc-client";import{jsx as n,jsxs as t}from"react/jsx-runtime";import{Section as r,Button as i,Text as o,Row as l,Column as a,Html as s,Head as c,Preview as d,Body as u,Container as f,Img as p,Hr as m,render as h}from"@react-email/components";import y from"react";function g(){return g=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},g.apply(null,arguments)}var x={padding:"27px 0 27px",textAlign:"center"},v={backgroundColor:"#000000",borderRadius:"7px",fontWeight:"600",color:"#fff",fontSize:"15px",textDecoration:"none",textAlign:"center",display:"block"},b=function(e){var t=e.href,o=e.children;return n(r,{style:x,children:n(i,{style:g({},v,{padding:"12px 18px"}),href:t,children:o})})},S=function(e){var i=e.code,l=i.slice(0,3),a=i.slice(3,6);return n(r,{style:{background:"#fff",border:"1px solid #ddd",borderRadius:"8px",margin:"20px 0px",padding:"6px 15px"},children:t(o,{style:{fontSize:"20px",textAlign:"center",verticalAlign:"middle"},children:[n("span",{children:l}),n("span",{style:{margin:"0 5px",color:"#aaa"},children:"-"}),n("span",{children:a})]})})},I={},P=function(e){return n(r,{style:I,children:e.items.map(function(e,r){var i=e.value;return n(l,{children:t(a,{style:{padding:"10px 0px"},children:[t(o,{style:{fontSize:14,fontWeight:"bold",padding:"3px 0px",margin:0},children:[e.label,":"," "]}),n(o,{style:{fontSize:14,padding:"3px 0px",margin:0},children:i})]})},r)})})},j=function(e){var r=e.title,i=e.description,l=e.children,a=e.style;return t(y.Fragment,{children:[n(o,{style:g({fontFamily:"sans-serif",fontSize:20,fontWeight:"bold",marginBottom:10},a),children:r}),i&&n(o,{style:g({fontFamily:"sans-serif",fontSize:16,marginBottom:20},a),children:i}),l]})},z=function(e){var t=e.children;return n(o,{style:g({fontFamily:"sans-serif",fontSize:14},e.style),children:t})},k={backgroundColor:"#ffffff",margin:"0 auto",fontFamily:"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif"},F={maxWidth:"600px",margin:"0 auto"},w={marginTop:"25px"},A={fontSize:"12px",color:"#777"},M={margin:"20px 0px",border:"none",borderBottom:"1px solid #ddd",background:"none"},O=function(e){var i=e.children,l=e.preview;return t(s,{children:[n(c,{}),l&&n(d,{children:l}),n(u,{style:k,children:t(f,{style:F,children:[n(r,{style:w,children:n(p,{src:"https://cdn.metorial.com/2025-06-13--14-59-55/logos/metorial/primary_logo_text/resized-100-w881-h256.png",height:"30",alt:"Metorial"})}),i,n(m,{style:M}),n(r,{children:"enterprise"==process.env.METORIAL_SOURCE?n(o,{style:A,children:"Sent by Metorial 💌. If you have any questions, feel free to contact us. If you need to reference this message use this ID: EMAIL_ID."}):t(o,{style:A,children:["Sent by a self hosted instance of ",n("a",{href:"https://metorial.com",children:"Metorial"}),". Contact the administrator of this instance if you have any questions."]})})]})})]})},T=function(e){var t=e.subject,r=n(O,{preview:e.preview,children:e.content});return{subject:t,html:h(r,{plainText:!1}),text:h(r,{plainText:!0})}},B=function(e){return e},C=function(n){var t=e(n),r=t.sender.upsert({identifier:n.sender.identifier,name:n.sender.name}),i=function(e){return function(n){try{var t=arguments;return Promise.resolve(r).then(function(r){return Promise.resolve(e.apply(void 0,[g({},n,{senderId:r.id})].concat([].slice.call(t,1))))})}catch(e){return Promise.reject(e)}}};return{sender:{get:i(t.sender.get),upsert:i(t.sender.upsert)},emailIdentity:{get:i(t.emailIdentity.get),upsert:i(t.emailIdentity.upsert)},email:{send:i(t.email.send)},send:i(t.email.send),createTemplate:function(e,n){return{send:function(i){try{return Promise.resolve(e.render(i.data)).then(function(e){return Promise.resolve(r).then(function(r){var o=t.email,l=o.send,a=i.data,s=i.to;return Promise.resolve(n).then(function(n){var t=r.id,i=n.id,c=e.subject;return Promise.resolve(e.html).then(function(n){return Promise.resolve(e.text).then(function(e){return Promise.resolve(l.call(o,{type:"email",to:s,template:a,emailIdentityId:i,senderId:t,content:{subject:c,html:n,text:e}}))})})})})})}catch(e){return Promise.reject(e)}}}}}};export{b as Button,S as Code,P as DataList,j as Layout,z as Text,O as Wrapper,T as createEmail,C as createRelayClient,B as createTemplate};
2
+ //# sourceMappingURL=index.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.module.js","sources":["../src/templates/components/button.tsx","../src/templates/components/code.tsx","../src/templates/components/dataList.tsx","../src/templates/components/layout.tsx","../src/templates/components/text.tsx","../src/templates/components/wrapper.tsx","../src/templates/lib/email.tsx","../src/templates/template.ts","../src/index.ts"],"sourcesContent":["import { Button as EmailButton, Section } from '@react-email/components';\nimport React from 'react';\n\nlet buttonContainer = {\n padding: '27px 0 27px',\n textAlign: 'center' as const\n};\n\nlet button = {\n backgroundColor: '#000000',\n borderRadius: '7px',\n fontWeight: '600',\n color: '#fff',\n fontSize: '15px',\n textDecoration: 'none',\n textAlign: 'center' as const,\n display: 'block'\n};\n\nexport let Button = ({ href, children }: { href: string; children: React.ReactNode }) => {\n return (\n <Section style={buttonContainer}>\n <EmailButton style={{ ...button, padding: '12px 18px' }} href={href}>\n {children as any}\n </EmailButton>\n </Section>\n );\n};\n","import { Section, Text } from '@react-email/components';\n\nexport let Code = ({ code }: { code: string }) => {\n let first3 = code.slice(0, 3);\n let last3 = code.slice(3, 6);\n\n return (\n <Section\n style={{\n background: '#fff',\n border: '1px solid #ddd',\n borderRadius: '8px',\n margin: '20px 0px',\n padding: '6px 15px'\n }}\n >\n <Text\n style={{\n fontSize: '20px',\n textAlign: 'center',\n verticalAlign: 'middle'\n }}\n >\n <span>{first3}</span>\n <span style={{ margin: '0 5px', color: '#aaa' }}>-</span>\n <span>{last3}</span>\n </Text>\n </Section>\n );\n};\n","import { Column, Row, Section, Text } from '@react-email/components';\n\nlet container = {\n // background: '#efefef',\n // border: '1px solid #ccc'\n};\n\nexport let DataList = ({ items }: { items: { label: string; value: string }[] }) => {\n return (\n <Section style={container}>\n {items.map(({ label, value }, i) => (\n <Row key={i}>\n <Column style={{ padding: '10px 0px' }}>\n <Text style={{ fontSize: 14, fontWeight: 'bold', padding: '3px 0px', margin: 0 }}>\n {label}:{' '}\n </Text>\n <Text style={{ fontSize: 14, padding: '3px 0px', margin: 0 }}>{value}</Text>\n </Column>\n </Row>\n ))}\n </Section>\n );\n};\n","import { Text as EmailText } from '@react-email/components';\nimport React from 'react';\n\nexport let Layout = ({\n title,\n description,\n children,\n style\n}: {\n title: React.ReactNode;\n description?: React.ReactNode;\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) => {\n return (\n <React.Fragment>\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 20,\n fontWeight: 'bold',\n marginBottom: 10,\n ...style\n }}\n >\n {title}\n </EmailText>\n\n {description && (\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 16,\n marginBottom: 20,\n ...style\n }}\n >\n {description}\n </EmailText>\n )}\n\n {children}\n </React.Fragment>\n );\n};\n","import { Text as EmailText } from '@react-email/components';\nimport React from 'react';\n\nexport let Text = ({\n children,\n style\n}: {\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) => {\n return (\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 14,\n ...style\n }}\n >\n {children}\n </EmailText>\n );\n};\n","import {\n Body,\n Container,\n Head,\n Hr,\n Html,\n Img,\n Preview,\n Section,\n Text\n} from '@react-email/components';\nimport React from 'react';\n\nlet main = {\n backgroundColor: '#ffffff',\n margin: '0 auto',\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif\"\n};\n\nlet container = {\n maxWidth: '600px',\n margin: '0 auto'\n};\n\nlet logoContainer = {\n marginTop: '25px'\n};\n\nlet footerText = {\n fontSize: '12px',\n color: '#777'\n};\n\nlet hr = {\n margin: '20px 0px',\n border: 'none',\n borderBottom: '1px solid #ddd',\n background: 'none'\n};\n\nexport let Wrapper = ({\n children,\n preview\n}: {\n children?: React.ReactNode;\n preview?: string;\n}) => {\n return (\n <Html>\n <Head />\n\n {preview && <Preview>{preview}</Preview>}\n\n <Body style={main}>\n <Container style={container}>\n <Section style={logoContainer}>\n <Img\n src=\"https://cdn.metorial.com/2025-06-13--14-59-55/logos/metorial/primary_logo_text/resized-100-w881-h256.png\"\n height=\"30\"\n alt=\"Metorial\"\n />\n </Section>\n\n {children}\n\n <Hr style={hr} />\n\n <Section>\n {process.env.METORIAL_SOURCE == 'enterprise' ? (\n <Text style={footerText}>\n Sent by Metorial 💌. If you have any questions, feel free to contact us. If you\n need to reference this message use this ID: EMAIL_ID.\n </Text>\n ) : (\n <Text style={footerText}>\n Sent by a self hosted instance of <a href=\"https://metorial.com\">Metorial</a>.\n Contact the administrator of this instance if you have any questions.\n </Text>\n )}\n </Section>\n </Container>\n </Body>\n </Html>\n );\n};\n","import { render } from '@react-email/components';\nimport React from 'react';\nimport { Wrapper } from '../components/wrapper';\n\nexport interface IEmail {\n subject: string;\n html: string | Promise<string>;\n text: string | Promise<string>;\n}\n\nexport let createEmail = ({\n content,\n preview,\n subject\n}: {\n content: React.ReactElement;\n preview?: string;\n subject: string;\n}) => {\n let inner = <Wrapper preview={preview}>{content}</Wrapper>;\n\n let html = render(inner, { plainText: false });\n let text = render(inner, { plainText: true });\n\n return {\n subject,\n html,\n text\n };\n};\n","import { IEmail } from './lib/email';\n\nexport interface ITemplate<Data> {\n render: (data: Data) => IEmail | Promise<IEmail>;\n}\n\nexport let createTemplate = <Data>(template: ITemplate<Data>) => template;\n","import { createClient } from '@lowerdeck/rpc-client';\nimport type { RelayClient } from '../../../service/src/controllers';\nimport { ITemplate } from './templates';\n\nexport * from './templates';\n\ntype ClientOpts = Parameters<typeof createClient>[0];\n\ntype EmailIdentity = Awaited<ReturnType<RelayClient['emailIdentity']['get']>>;\n\nexport let createRelayClient = (\n o: ClientOpts & {\n sender: {\n identifier: string;\n name: string;\n };\n }\n) => {\n let inner = createClient<RelayClient>(o);\n\n let sender = inner.sender.upsert({\n identifier: o.sender.identifier,\n name: o.sender.name\n });\n\n let wrap =\n <Arg0, Args extends any[], R>(fn: (arg0: Arg0, ...args: Args) => Promise<R>) =>\n async (arg0: Omit<Arg0, 'senderId'>, ...args: Args) => {\n let s = await sender;\n return await fn({ ...arg0, senderId: s.id } as any, ...args);\n };\n\n return {\n sender: {\n get: wrap(inner.sender.get),\n upsert: wrap(inner.sender.upsert)\n },\n emailIdentity: {\n get: wrap(inner.emailIdentity.get),\n upsert: wrap(inner.emailIdentity.upsert)\n },\n email: {\n send: wrap(inner.email.send)\n },\n send: wrap(inner.email.send),\n\n createTemplate<Data>(\n template: ITemplate<Data>,\n identity: EmailIdentity | Promise<EmailIdentity>\n ) {\n return {\n send: async (i: { data: Data; to: string[] }) => {\n let rendered = await template.render(i.data);\n let s = await sender;\n\n return await inner.email.send({\n type: 'email',\n to: i.to,\n template: i.data as any,\n\n emailIdentityId: (await identity).id,\n senderId: s.id,\n\n content: {\n subject: rendered.subject,\n html: await rendered.html,\n text: await rendered.text\n }\n });\n }\n };\n }\n };\n};\n"],"names":["buttonContainer","padding","textAlign","button","backgroundColor","borderRadius","fontWeight","color","fontSize","textDecoration","display","Button","_ref","href","children","_jsx","Section","style","EmailButton","_extends","Code","code","first3","slice","last3","background","border","margin","_jsxs","Text","verticalAlign","container","DataList","items","map","_ref2","i","value","Row","Column","label","Layout","title","description","React","Fragment","EmailText","fontFamily","marginBottom","main","maxWidth","logoContainer","marginTop","footerText","hr","borderBottom","Wrapper","preview","Html","Head","Preview","Body","Container","Img","src","height","alt","Hr","process","env","METORIAL_SOURCE","createEmail","subject","inner","content","html","render","plainText","text","createTemplate","template","createRelayClient","o","createClient","sender","upsert","identifier","name","wrap","fn","arg0","_arguments","arguments","Promise","resolve","then","s","apply","senderId","id","concat","call","e","reject","get","emailIdentity","email","send","identity","data","rendered","_inner$email","_send","_i$data","_i$to","to","_identity","_s$id","_identity$id","_rendered$subject","_rendered$html","_rendered$text","type","emailIdentityId"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@lowerdeck/rpc-client"),require("react/jsx-runtime"),require("@react-email/components"),require("react")):"function"==typeof define&&define.amd?define(["exports","@lowerdeck/rpc-client","react/jsx-runtime","@react-email/components","react"],t):t((e||self).relayClient={},e.rpcClient,e.jsxRuntime,e.components,e.react)}(this,function(e,t,n,r,i){function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=/*#__PURE__*/o(i);function l(){return l=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},l.apply(null,arguments)}var a={padding:"27px 0 27px",textAlign:"center"},c={backgroundColor:"#000000",borderRadius:"7px",fontWeight:"600",color:"#fff",fontSize:"15px",textDecoration:"none",textAlign:"center",display:"block"},d={},u={backgroundColor:"#ffffff",margin:"0 auto",fontFamily:"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif"},f={maxWidth:"600px",margin:"0 auto"},p={marginTop:"25px"},x={fontSize:"12px",color:"#777"},m={margin:"20px 0px",border:"none",borderBottom:"1px solid #ddd",background:"none"},h=function(e){var t=e.children,i=e.preview;return n.jsxs(r.Html,{children:[n.jsx(r.Head,{}),i&&n.jsx(r.Preview,{children:i}),n.jsx(r.Body,{style:u,children:n.jsxs(r.Container,{style:f,children:[n.jsx(r.Section,{style:p,children:n.jsx(r.Img,{src:"https://cdn.metorial.com/2025-06-13--14-59-55/logos/metorial/primary_logo_text/resized-100-w881-h256.png",height:"30",alt:"Metorial"})}),t,n.jsx(r.Hr,{style:m}),n.jsx(r.Section,{children:"enterprise"==process.env.METORIAL_SOURCE?n.jsx(r.Text,{style:x,children:"Sent by Metorial 💌. If you have any questions, feel free to contact us. If you need to reference this message use this ID: EMAIL_ID."}):n.jsxs(r.Text,{style:x,children:["Sent by a self hosted instance of ",n.jsx("a",{href:"https://metorial.com",children:"Metorial"}),". Contact the administrator of this instance if you have any questions."]})})]})})]})};e.Button=function(e){var t=e.href,i=e.children;return n.jsx(r.Section,{style:a,children:n.jsx(r.Button,{style:l({},c,{padding:"12px 18px"}),href:t,children:i})})},e.Code=function(e){var t=e.code,i=t.slice(0,3),o=t.slice(3,6);return n.jsx(r.Section,{style:{background:"#fff",border:"1px solid #ddd",borderRadius:"8px",margin:"20px 0px",padding:"6px 15px"},children:n.jsxs(r.Text,{style:{fontSize:"20px",textAlign:"center",verticalAlign:"middle"},children:[n.jsx("span",{children:i}),n.jsx("span",{style:{margin:"0 5px",color:"#aaa"},children:"-"}),n.jsx("span",{children:o})]})})},e.DataList=function(e){return n.jsx(r.Section,{style:d,children:e.items.map(function(e,t){var i=e.value;return n.jsx(r.Row,{children:n.jsxs(r.Column,{style:{padding:"10px 0px"},children:[n.jsxs(r.Text,{style:{fontSize:14,fontWeight:"bold",padding:"3px 0px",margin:0},children:[e.label,":"," "]}),n.jsx(r.Text,{style:{fontSize:14,padding:"3px 0px",margin:0},children:i})]})},t)})})},e.Layout=function(e){var t=e.title,i=e.description,o=e.children,a=e.style;return n.jsxs(s.default.Fragment,{children:[n.jsx(r.Text,{style:l({fontFamily:"sans-serif",fontSize:20,fontWeight:"bold",marginBottom:10},a),children:t}),i&&n.jsx(r.Text,{style:l({fontFamily:"sans-serif",fontSize:16,marginBottom:20},a),children:i}),o]})},e.Text=function(e){var t=e.children;return n.jsx(r.Text,{style:l({fontFamily:"sans-serif",fontSize:14},e.style),children:t})},e.Wrapper=h,e.createEmail=function(e){var t=e.subject,i=n.jsx(h,{preview:e.preview,children:e.content});return{subject:t,html:r.render(i,{plainText:!1}),text:r.render(i,{plainText:!0})}},e.createRelayClient=function(e){var n=t.createClient(e),r=n.sender.upsert({identifier:e.sender.identifier,name:e.sender.name}),i=function(e){return function(t){try{var n=arguments;return Promise.resolve(r).then(function(r){return Promise.resolve(e.apply(void 0,[l({},t,{senderId:r.id})].concat([].slice.call(n,1))))})}catch(e){return Promise.reject(e)}}};return{sender:{get:i(n.sender.get),upsert:i(n.sender.upsert)},emailIdentity:{get:i(n.emailIdentity.get),upsert:i(n.emailIdentity.upsert)},email:{send:i(n.email.send)},send:i(n.email.send),createTemplate:function(e,t){return{send:function(i){try{return Promise.resolve(e.render(i.data)).then(function(e){return Promise.resolve(r).then(function(r){var o=n.email,s=o.send,l=i.data,a=i.to;return Promise.resolve(t).then(function(t){var n=r.id,i=t.id,c=e.subject;return Promise.resolve(e.html).then(function(t){return Promise.resolve(e.text).then(function(e){return Promise.resolve(s.call(o,{type:"email",to:a,template:l,emailIdentityId:i,senderId:n,content:{subject:c,html:t,text:e}}))})})})})})}catch(e){return Promise.reject(e)}}}}}},e.createTemplate=function(e){return e}});
2
+ //# sourceMappingURL=index.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.umd.js","sources":["../src/templates/components/button.tsx","../src/templates/components/dataList.tsx","../src/templates/components/wrapper.tsx","../src/templates/components/code.tsx","../src/templates/components/layout.tsx","../src/templates/components/text.tsx","../src/templates/lib/email.tsx","../src/index.ts","../src/templates/template.ts"],"sourcesContent":["import { Button as EmailButton, Section } from '@react-email/components';\nimport React from 'react';\n\nlet buttonContainer = {\n padding: '27px 0 27px',\n textAlign: 'center' as const\n};\n\nlet button = {\n backgroundColor: '#000000',\n borderRadius: '7px',\n fontWeight: '600',\n color: '#fff',\n fontSize: '15px',\n textDecoration: 'none',\n textAlign: 'center' as const,\n display: 'block'\n};\n\nexport let Button = ({ href, children }: { href: string; children: React.ReactNode }) => {\n return (\n <Section style={buttonContainer}>\n <EmailButton style={{ ...button, padding: '12px 18px' }} href={href}>\n {children as any}\n </EmailButton>\n </Section>\n );\n};\n","import { Column, Row, Section, Text } from '@react-email/components';\n\nlet container = {\n // background: '#efefef',\n // border: '1px solid #ccc'\n};\n\nexport let DataList = ({ items }: { items: { label: string; value: string }[] }) => {\n return (\n <Section style={container}>\n {items.map(({ label, value }, i) => (\n <Row key={i}>\n <Column style={{ padding: '10px 0px' }}>\n <Text style={{ fontSize: 14, fontWeight: 'bold', padding: '3px 0px', margin: 0 }}>\n {label}:{' '}\n </Text>\n <Text style={{ fontSize: 14, padding: '3px 0px', margin: 0 }}>{value}</Text>\n </Column>\n </Row>\n ))}\n </Section>\n );\n};\n","import {\n Body,\n Container,\n Head,\n Hr,\n Html,\n Img,\n Preview,\n Section,\n Text\n} from '@react-email/components';\nimport React from 'react';\n\nlet main = {\n backgroundColor: '#ffffff',\n margin: '0 auto',\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif\"\n};\n\nlet container = {\n maxWidth: '600px',\n margin: '0 auto'\n};\n\nlet logoContainer = {\n marginTop: '25px'\n};\n\nlet footerText = {\n fontSize: '12px',\n color: '#777'\n};\n\nlet hr = {\n margin: '20px 0px',\n border: 'none',\n borderBottom: '1px solid #ddd',\n background: 'none'\n};\n\nexport let Wrapper = ({\n children,\n preview\n}: {\n children?: React.ReactNode;\n preview?: string;\n}) => {\n return (\n <Html>\n <Head />\n\n {preview && <Preview>{preview}</Preview>}\n\n <Body style={main}>\n <Container style={container}>\n <Section style={logoContainer}>\n <Img\n src=\"https://cdn.metorial.com/2025-06-13--14-59-55/logos/metorial/primary_logo_text/resized-100-w881-h256.png\"\n height=\"30\"\n alt=\"Metorial\"\n />\n </Section>\n\n {children}\n\n <Hr style={hr} />\n\n <Section>\n {process.env.METORIAL_SOURCE == 'enterprise' ? (\n <Text style={footerText}>\n Sent by Metorial 💌. If you have any questions, feel free to contact us. If you\n need to reference this message use this ID: EMAIL_ID.\n </Text>\n ) : (\n <Text style={footerText}>\n Sent by a self hosted instance of <a href=\"https://metorial.com\">Metorial</a>.\n Contact the administrator of this instance if you have any questions.\n </Text>\n )}\n </Section>\n </Container>\n </Body>\n </Html>\n );\n};\n","import { Section, Text } from '@react-email/components';\n\nexport let Code = ({ code }: { code: string }) => {\n let first3 = code.slice(0, 3);\n let last3 = code.slice(3, 6);\n\n return (\n <Section\n style={{\n background: '#fff',\n border: '1px solid #ddd',\n borderRadius: '8px',\n margin: '20px 0px',\n padding: '6px 15px'\n }}\n >\n <Text\n style={{\n fontSize: '20px',\n textAlign: 'center',\n verticalAlign: 'middle'\n }}\n >\n <span>{first3}</span>\n <span style={{ margin: '0 5px', color: '#aaa' }}>-</span>\n <span>{last3}</span>\n </Text>\n </Section>\n );\n};\n","import { Text as EmailText } from '@react-email/components';\nimport React from 'react';\n\nexport let Layout = ({\n title,\n description,\n children,\n style\n}: {\n title: React.ReactNode;\n description?: React.ReactNode;\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) => {\n return (\n <React.Fragment>\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 20,\n fontWeight: 'bold',\n marginBottom: 10,\n ...style\n }}\n >\n {title}\n </EmailText>\n\n {description && (\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 16,\n marginBottom: 20,\n ...style\n }}\n >\n {description}\n </EmailText>\n )}\n\n {children}\n </React.Fragment>\n );\n};\n","import { Text as EmailText } from '@react-email/components';\nimport React from 'react';\n\nexport let Text = ({\n children,\n style\n}: {\n children: React.ReactNode;\n style?: React.CSSProperties;\n}) => {\n return (\n <EmailText\n style={{\n fontFamily: 'sans-serif',\n fontSize: 14,\n ...style\n }}\n >\n {children}\n </EmailText>\n );\n};\n","import { render } from '@react-email/components';\nimport React from 'react';\nimport { Wrapper } from '../components/wrapper';\n\nexport interface IEmail {\n subject: string;\n html: string | Promise<string>;\n text: string | Promise<string>;\n}\n\nexport let createEmail = ({\n content,\n preview,\n subject\n}: {\n content: React.ReactElement;\n preview?: string;\n subject: string;\n}) => {\n let inner = <Wrapper preview={preview}>{content}</Wrapper>;\n\n let html = render(inner, { plainText: false });\n let text = render(inner, { plainText: true });\n\n return {\n subject,\n html,\n text\n };\n};\n","import { createClient } from '@lowerdeck/rpc-client';\nimport type { RelayClient } from '../../../service/src/controllers';\nimport { ITemplate } from './templates';\n\nexport * from './templates';\n\ntype ClientOpts = Parameters<typeof createClient>[0];\n\ntype EmailIdentity = Awaited<ReturnType<RelayClient['emailIdentity']['get']>>;\n\nexport let createRelayClient = (\n o: ClientOpts & {\n sender: {\n identifier: string;\n name: string;\n };\n }\n) => {\n let inner = createClient<RelayClient>(o);\n\n let sender = inner.sender.upsert({\n identifier: o.sender.identifier,\n name: o.sender.name\n });\n\n let wrap =\n <Arg0, Args extends any[], R>(fn: (arg0: Arg0, ...args: Args) => Promise<R>) =>\n async (arg0: Omit<Arg0, 'senderId'>, ...args: Args) => {\n let s = await sender;\n return await fn({ ...arg0, senderId: s.id } as any, ...args);\n };\n\n return {\n sender: {\n get: wrap(inner.sender.get),\n upsert: wrap(inner.sender.upsert)\n },\n emailIdentity: {\n get: wrap(inner.emailIdentity.get),\n upsert: wrap(inner.emailIdentity.upsert)\n },\n email: {\n send: wrap(inner.email.send)\n },\n send: wrap(inner.email.send),\n\n createTemplate<Data>(\n template: ITemplate<Data>,\n identity: EmailIdentity | Promise<EmailIdentity>\n ) {\n return {\n send: async (i: { data: Data; to: string[] }) => {\n let rendered = await template.render(i.data);\n let s = await sender;\n\n return await inner.email.send({\n type: 'email',\n to: i.to,\n template: i.data as any,\n\n emailIdentityId: (await identity).id,\n senderId: s.id,\n\n content: {\n subject: rendered.subject,\n html: await rendered.html,\n text: await rendered.text\n }\n });\n }\n };\n }\n };\n};\n","import { IEmail } from './lib/email';\n\nexport interface ITemplate<Data> {\n render: (data: Data) => IEmail | Promise<IEmail>;\n}\n\nexport let createTemplate = <Data>(template: ITemplate<Data>) => template;\n"],"names":["buttonContainer","padding","textAlign","button","backgroundColor","borderRadius","fontWeight","color","fontSize","textDecoration","display","container","main","margin","fontFamily","maxWidth","logoContainer","marginTop","footerText","hr","border","borderBottom","background","Wrapper","_ref","children","preview","_jsxs","Html","_jsx","Head","Preview","jsx","Body","style","jsxs","Container","Section","Img","src","height","alt","Hr","process","env","METORIAL_SOURCE","Text","href","EmailButton","_extends","code","first3","slice","last3","verticalAlign","items","map","_ref2","i","value","Row","Column","label","title","description","React","Fragment","EmailText","marginBottom","subject","inner","content","html","render","plainText","text","o","createClient","sender","upsert","identifier","name","wrap","fn","arg0","_arguments","arguments","Promise","resolve","then","s","apply","senderId","id","concat","call","e","reject","get","emailIdentity","email","send","createTemplate","template","identity","data","rendered","_inner$email","_send","_i$data","_i$to","to","_identity","_s$id","_identity$id","_rendered$subject","_rendered$html","_rendered$text","type","emailIdentityId"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@metorial-services/relay-client",
3
+ "version": "1.0.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "files": [
8
+ "src/**",
9
+ "dist/**",
10
+ "README.md",
11
+ "package.json"
12
+ ],
13
+ "author": "Tobias Herber",
14
+ "license": "Apache 2",
15
+ "type": "module",
16
+ "source": "src/index.ts",
17
+ "exports": {
18
+ "types": "./dist/index.d.ts",
19
+ "require": "./dist/index.cjs",
20
+ "import": "./dist/index.module.js",
21
+ "default": "./dist/index.module.js"
22
+ },
23
+ "main": "./dist/index.cjs",
24
+ "module": "./dist/index.module.js",
25
+ "types": "dist/index.d.ts",
26
+ "unpkg": "./dist/index.umd.js",
27
+ "scripts": {
28
+ "test": "vitest run --passWithNoTests",
29
+ "lint": "prettier src/**/*.ts --check",
30
+ "build": "rm -rf ./dist && microbundle && dts-bundle-generator --config dts-bundle-generator.config.json",
31
+ "prepublish": "bun run build"
32
+ },
33
+ "dependencies": {
34
+ "@lowerdeck/rpc-client": "^1.0.2",
35
+ "@react-email/components": "^1.0.7",
36
+ "react": "^19.2.4"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^25.0.3",
40
+ "dts-bundle-generator": "^9.5.1",
41
+ "microbundle": "^0.15.1",
42
+ "typescript": "^5.8.3",
43
+ "vitest": "^3.1.2"
44
+ }
45
+ }
package/src/index.ts ADDED
@@ -0,0 +1,74 @@
1
+ import { createClient } from '@lowerdeck/rpc-client';
2
+ import type { RelayClient } from '../../../service/src/controllers';
3
+ import { ITemplate } from './templates';
4
+
5
+ export * from './templates';
6
+
7
+ type ClientOpts = Parameters<typeof createClient>[0];
8
+
9
+ type EmailIdentity = Awaited<ReturnType<RelayClient['emailIdentity']['get']>>;
10
+
11
+ export let createRelayClient = (
12
+ o: ClientOpts & {
13
+ sender: {
14
+ identifier: string;
15
+ name: string;
16
+ };
17
+ }
18
+ ) => {
19
+ let inner = createClient<RelayClient>(o);
20
+
21
+ let sender = inner.sender.upsert({
22
+ identifier: o.sender.identifier,
23
+ name: o.sender.name
24
+ });
25
+
26
+ let wrap =
27
+ <Arg0, Args extends any[], R>(fn: (arg0: Arg0, ...args: Args) => Promise<R>) =>
28
+ async (arg0: Omit<Arg0, 'senderId'>, ...args: Args) => {
29
+ let s = await sender;
30
+ return await fn({ ...arg0, senderId: s.id } as any, ...args);
31
+ };
32
+
33
+ return {
34
+ sender: {
35
+ get: wrap(inner.sender.get),
36
+ upsert: wrap(inner.sender.upsert)
37
+ },
38
+ emailIdentity: {
39
+ get: wrap(inner.emailIdentity.get),
40
+ upsert: wrap(inner.emailIdentity.upsert)
41
+ },
42
+ email: {
43
+ send: wrap(inner.email.send)
44
+ },
45
+ send: wrap(inner.email.send),
46
+
47
+ createTemplate<Data>(
48
+ template: ITemplate<Data>,
49
+ identity: EmailIdentity | Promise<EmailIdentity>
50
+ ) {
51
+ return {
52
+ send: async (i: { data: Data; to: string[] }) => {
53
+ let rendered = await template.render(i.data);
54
+ let s = await sender;
55
+
56
+ return await inner.email.send({
57
+ type: 'email',
58
+ to: i.to,
59
+ template: i.data as any,
60
+
61
+ emailIdentityId: (await identity).id,
62
+ senderId: s.id,
63
+
64
+ content: {
65
+ subject: rendered.subject,
66
+ html: await rendered.html,
67
+ text: await rendered.text
68
+ }
69
+ });
70
+ }
71
+ };
72
+ }
73
+ };
74
+ };
@@ -0,0 +1,28 @@
1
+ import { Button as EmailButton, Section } from '@react-email/components';
2
+ import React from 'react';
3
+
4
+ let buttonContainer = {
5
+ padding: '27px 0 27px',
6
+ textAlign: 'center' as const
7
+ };
8
+
9
+ let button = {
10
+ backgroundColor: '#000000',
11
+ borderRadius: '7px',
12
+ fontWeight: '600',
13
+ color: '#fff',
14
+ fontSize: '15px',
15
+ textDecoration: 'none',
16
+ textAlign: 'center' as const,
17
+ display: 'block'
18
+ };
19
+
20
+ export let Button = ({ href, children }: { href: string; children: React.ReactNode }) => {
21
+ return (
22
+ <Section style={buttonContainer}>
23
+ <EmailButton style={{ ...button, padding: '12px 18px' }} href={href}>
24
+ {children as any}
25
+ </EmailButton>
26
+ </Section>
27
+ );
28
+ };
@@ -0,0 +1,30 @@
1
+ import { Section, Text } from '@react-email/components';
2
+
3
+ export let Code = ({ code }: { code: string }) => {
4
+ let first3 = code.slice(0, 3);
5
+ let last3 = code.slice(3, 6);
6
+
7
+ return (
8
+ <Section
9
+ style={{
10
+ background: '#fff',
11
+ border: '1px solid #ddd',
12
+ borderRadius: '8px',
13
+ margin: '20px 0px',
14
+ padding: '6px 15px'
15
+ }}
16
+ >
17
+ <Text
18
+ style={{
19
+ fontSize: '20px',
20
+ textAlign: 'center',
21
+ verticalAlign: 'middle'
22
+ }}
23
+ >
24
+ <span>{first3}</span>
25
+ <span style={{ margin: '0 5px', color: '#aaa' }}>-</span>
26
+ <span>{last3}</span>
27
+ </Text>
28
+ </Section>
29
+ );
30
+ };
@@ -0,0 +1,23 @@
1
+ import { Column, Row, Section, Text } from '@react-email/components';
2
+
3
+ let container = {
4
+ // background: '#efefef',
5
+ // border: '1px solid #ccc'
6
+ };
7
+
8
+ export let DataList = ({ items }: { items: { label: string; value: string }[] }) => {
9
+ return (
10
+ <Section style={container}>
11
+ {items.map(({ label, value }, i) => (
12
+ <Row key={i}>
13
+ <Column style={{ padding: '10px 0px' }}>
14
+ <Text style={{ fontSize: 14, fontWeight: 'bold', padding: '3px 0px', margin: 0 }}>
15
+ {label}:{' '}
16
+ </Text>
17
+ <Text style={{ fontSize: 14, padding: '3px 0px', margin: 0 }}>{value}</Text>
18
+ </Column>
19
+ </Row>
20
+ ))}
21
+ </Section>
22
+ );
23
+ };
@@ -0,0 +1,6 @@
1
+ export * from './button';
2
+ export * from './code';
3
+ export * from './dataList';
4
+ export * from './layout';
5
+ export * from './text';
6
+ export * from './wrapper';
@@ -0,0 +1,45 @@
1
+ import { Text as EmailText } from '@react-email/components';
2
+ import React from 'react';
3
+
4
+ export let Layout = ({
5
+ title,
6
+ description,
7
+ children,
8
+ style
9
+ }: {
10
+ title: React.ReactNode;
11
+ description?: React.ReactNode;
12
+ children: React.ReactNode;
13
+ style?: React.CSSProperties;
14
+ }) => {
15
+ return (
16
+ <React.Fragment>
17
+ <EmailText
18
+ style={{
19
+ fontFamily: 'sans-serif',
20
+ fontSize: 20,
21
+ fontWeight: 'bold',
22
+ marginBottom: 10,
23
+ ...style
24
+ }}
25
+ >
26
+ {title}
27
+ </EmailText>
28
+
29
+ {description && (
30
+ <EmailText
31
+ style={{
32
+ fontFamily: 'sans-serif',
33
+ fontSize: 16,
34
+ marginBottom: 20,
35
+ ...style
36
+ }}
37
+ >
38
+ {description}
39
+ </EmailText>
40
+ )}
41
+
42
+ {children}
43
+ </React.Fragment>
44
+ );
45
+ };
@@ -0,0 +1,22 @@
1
+ import { Text as EmailText } from '@react-email/components';
2
+ import React from 'react';
3
+
4
+ export let Text = ({
5
+ children,
6
+ style
7
+ }: {
8
+ children: React.ReactNode;
9
+ style?: React.CSSProperties;
10
+ }) => {
11
+ return (
12
+ <EmailText
13
+ style={{
14
+ fontFamily: 'sans-serif',
15
+ fontSize: 14,
16
+ ...style
17
+ }}
18
+ >
19
+ {children}
20
+ </EmailText>
21
+ );
22
+ };
@@ -0,0 +1,86 @@
1
+ import {
2
+ Body,
3
+ Container,
4
+ Head,
5
+ Hr,
6
+ Html,
7
+ Img,
8
+ Preview,
9
+ Section,
10
+ Text
11
+ } from '@react-email/components';
12
+ import React from 'react';
13
+
14
+ let main = {
15
+ backgroundColor: '#ffffff',
16
+ margin: '0 auto',
17
+ fontFamily:
18
+ "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif"
19
+ };
20
+
21
+ let container = {
22
+ maxWidth: '600px',
23
+ margin: '0 auto'
24
+ };
25
+
26
+ let logoContainer = {
27
+ marginTop: '25px'
28
+ };
29
+
30
+ let footerText = {
31
+ fontSize: '12px',
32
+ color: '#777'
33
+ };
34
+
35
+ let hr = {
36
+ margin: '20px 0px',
37
+ border: 'none',
38
+ borderBottom: '1px solid #ddd',
39
+ background: 'none'
40
+ };
41
+
42
+ export let Wrapper = ({
43
+ children,
44
+ preview
45
+ }: {
46
+ children?: React.ReactNode;
47
+ preview?: string;
48
+ }) => {
49
+ return (
50
+ <Html>
51
+ <Head />
52
+
53
+ {preview && <Preview>{preview}</Preview>}
54
+
55
+ <Body style={main}>
56
+ <Container style={container}>
57
+ <Section style={logoContainer}>
58
+ <Img
59
+ src="https://cdn.metorial.com/2025-06-13--14-59-55/logos/metorial/primary_logo_text/resized-100-w881-h256.png"
60
+ height="30"
61
+ alt="Metorial"
62
+ />
63
+ </Section>
64
+
65
+ {children}
66
+
67
+ <Hr style={hr} />
68
+
69
+ <Section>
70
+ {process.env.METORIAL_SOURCE == 'enterprise' ? (
71
+ <Text style={footerText}>
72
+ Sent by Metorial 💌. If you have any questions, feel free to contact us. If you
73
+ need to reference this message use this ID: EMAIL_ID.
74
+ </Text>
75
+ ) : (
76
+ <Text style={footerText}>
77
+ Sent by a self hosted instance of <a href="https://metorial.com">Metorial</a>.
78
+ Contact the administrator of this instance if you have any questions.
79
+ </Text>
80
+ )}
81
+ </Section>
82
+ </Container>
83
+ </Body>
84
+ </Html>
85
+ );
86
+ };
@@ -0,0 +1,3 @@
1
+ export * from './components';
2
+ export * from './lib/email';
3
+ export * from './template';
@@ -0,0 +1,30 @@
1
+ import { render } from '@react-email/components';
2
+ import React from 'react';
3
+ import { Wrapper } from '../components/wrapper';
4
+
5
+ export interface IEmail {
6
+ subject: string;
7
+ html: string | Promise<string>;
8
+ text: string | Promise<string>;
9
+ }
10
+
11
+ export let createEmail = ({
12
+ content,
13
+ preview,
14
+ subject
15
+ }: {
16
+ content: React.ReactElement;
17
+ preview?: string;
18
+ subject: string;
19
+ }) => {
20
+ let inner = <Wrapper preview={preview}>{content}</Wrapper>;
21
+
22
+ let html = render(inner, { plainText: false });
23
+ let text = render(inner, { plainText: true });
24
+
25
+ return {
26
+ subject,
27
+ html,
28
+ text
29
+ };
30
+ };
@@ -0,0 +1,7 @@
1
+ import { IEmail } from './lib/email';
2
+
3
+ export interface ITemplate<Data> {
4
+ render: (data: Data) => IEmail | Promise<IEmail>;
5
+ }
6
+
7
+ export let createTemplate = <Data>(template: ITemplate<Data>) => template;