@travetto/email-inky 3.4.4 → 4.0.0-rc.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.
package/jsx-runtime.ts CHANGED
@@ -53,22 +53,22 @@ declare global {
53
53
  }
54
54
  }
55
55
 
56
+ let createFrag: Function | undefined = undefined;
57
+
56
58
  export function createElement<T extends string | ConcreteClass | JSXComponentFunction<P>, P extends {}>(
57
59
  type: T, props: P & JSXProps
58
60
  ): JSXElement<T, P> {
61
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62
+ type = (type === createFrag ? JSXFragmentType : type) as T;
59
63
  return { [JSXRuntimeTag]: { id: (id += 1) }, type, key: '', props };
60
64
  }
61
65
 
62
66
  export function createRootElement<T extends string | ConcreteClass | JSXComponentFunction<P>, P extends {}>(
63
67
  type: T, props: P & JSXProps
64
68
  ): JSXElement<T, P> {
65
- const res: JSXElement<T, P> = { [JSXRuntimeTag]: { id: (id += 1) }, key: '', type, props };
66
- // @ts-expect-error
67
- res.wrap = async (): Promise<unknown> => {
68
- const { wrap } = await import('@travetto/email-inky');
69
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
70
- return wrap(res as JSXElement);
71
- };
69
+ const res: JSXElement<T, P> & { wrap?: Function } = createElement(type, props);
70
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
71
+ res.wrap = (): Promise<unknown> => import('@travetto/email-inky/src/wrapper.js').then(v => v.wrap(res as JSXElement));
72
72
  return res;
73
73
  }
74
74
 
@@ -81,4 +81,6 @@ export const jsxs = createRootElement;
81
81
  export const Fragment = createFragment;
82
82
  export function isJSXElement(el: unknown): el is JSXElement {
83
83
  return el !== undefined && el !== null && typeof el === 'object' && JSXRuntimeTag in el;
84
- }
84
+ }
85
+
86
+ createFrag = Fragment;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/email-inky",
3
- "version": "3.4.4",
3
+ "version": "4.0.0-rc.0",
4
4
  "description": "Email Inky templating module",
5
5
  "keywords": [
6
6
  "email",
@@ -27,17 +27,14 @@
27
27
  "directory": "module/email-inky"
28
28
  },
29
29
  "dependencies": {
30
- "@travetto/base": "^3.4.1",
31
- "@travetto/config": "^3.4.3",
32
- "@travetto/di": "^3.4.1",
33
- "@travetto/email": "^3.4.3",
30
+ "@travetto/base": "^4.0.0-rc.0",
31
+ "@travetto/config": "^4.0.0-rc.0",
32
+ "@travetto/di": "^4.0.0-rc.0",
33
+ "@travetto/email": "^4.0.0-rc.0",
34
34
  "foundation-emails": "^2.4.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@travetto/email-compiler": "^3.4.4"
38
- },
39
- "peerDependencies": {
40
- "@travetto/cli": "^3.4.6"
37
+ "@travetto/email-compiler": "^4.0.0-rc.0"
41
38
  },
42
39
  "peerDependenciesMeta": {
43
40
  "@travetto/cli": {
package/src/components.ts CHANGED
@@ -28,9 +28,10 @@ export const If: CompFn<{ attr: string }> = () => EMPTY;
28
28
  export const Value: CompFn<{ attr: string, raw?: boolean }> = () => EMPTY;
29
29
  export const Unless: CompFn<{ attr: string }> = () => EMPTY;
30
30
  export const For: CompFn<{ attr: string }> = () => EMPTY;
31
+ export const InkyTemplate: CompFn<{}> = () => EMPTY;
31
32
 
32
33
  export const c = {
33
- Wrapper, Container,
34
+ Wrapper, Container, InkyTemplate,
34
35
  Column, Title, Summary, HLine, Row, Button,
35
36
  BlockGrid, Menu, Item, Center, Callout, Spacer,
36
37
  If, Unless, For, Value
@@ -1,5 +1,5 @@
1
1
  import { JSXElement } from '@travetto/email-inky/jsx-runtime';
2
- import { EmailResource } from '@travetto/email';
2
+ import { ResourceLoader } from '@travetto/base';
3
3
 
4
4
  import { RenderProvider, RenderState } from '../types';
5
5
  import { RenderContext } from './context';
@@ -37,7 +37,7 @@ export const Html: RenderProvider<RenderContext> = {
37
37
  .replace(/(<[uo]l>)(<li>)/g, (_, a, b) => `${a} ${b}`);
38
38
 
39
39
  if (isRoot) {
40
- const wrapper = await new EmailResource([`${context.module}#resources`, '@travetto/email-inky#resources'])
40
+ const wrapper = await new ResourceLoader([`${context.module}#resources`, '@travetto/email-inky#resources'])
41
41
  .read('/email/inky.wrapper.html');
42
42
 
43
43
  // Get Subject
@@ -76,6 +76,7 @@ export const Html: RenderProvider<RenderContext> = {
76
76
  div: std, span: stdInline, small: stdInline,
77
77
  a: async ({ recurse, props }) => `<a ${propsToStr(props)}>${await recurse()}</a>`,
78
78
 
79
+ InkyTemplate: c => c.recurse(),
79
80
  Title: async ({ recurse, el }) => `<title>${await recurse()}</title>`,
80
81
  Summary: async ({ recurse, el }) => `<span id="summary" style="${SUMMARY_STYLE}">${await recurse()}</span>`,
81
82
 
@@ -89,14 +90,18 @@ export const Html: RenderProvider<RenderContext> = {
89
90
  const sibs = getKids(parent).filter(x => isOfType(x, 'Column'));
90
91
  const colCount = sibs.length || 1;
91
92
 
92
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
93
- const pProps = parent.props as { columnVisited: boolean };
94
- if (!pProps.columnVisited) {
95
- pProps.columnVisited = true;
96
- if (sibs.length) {
97
- sibs[0].props.className = classStr(sibs[0].props.className ?? '', 'first');
98
- sibs[sibs.length - 1].props.className = classStr(sibs[sibs.length - 1].props.className ?? '', 'last');
93
+ if (parent) {
94
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
95
+ const pProps = parent?.props as { columnVisited: boolean };
96
+ if (!pProps.columnVisited) {
97
+ pProps.columnVisited = true;
98
+ if (sibs.length) {
99
+ sibs[0].props.className = classStr(sibs[0].props.className ?? '', 'first');
100
+ sibs[sibs.length - 1].props.className = classStr(sibs[sibs.length - 1].props.className ?? '', 'last');
101
+ }
99
102
  }
103
+ } else {
104
+ props.className = classStr(props.className ?? '', 'first', 'last');
100
105
  }
101
106
 
102
107
  // Check for sizes. If no attribute is provided, default to small-12. Divide evenly for large columns
@@ -46,6 +46,7 @@ export const Markdown: RenderProvider<RenderContext> = {
46
46
  a: async ({ recurse, props }) => `\n[${await recurse()}](${(props as { href: string }).href})\n`,
47
47
  Button: async ({ recurse, props }) => `\n[${await recurse()}](${props.href})\n`,
48
48
 
49
+ InkyTemplate: visit,
49
50
  Callout: visit, Center: visit, Container: visit,
50
51
  Column: visit, Wrapper: visit, Row: visit, BlockGrid: visit,
51
52
 
@@ -34,7 +34,7 @@ export class InkyRenderer {
34
34
  final = out !== EMPTY_ELEMENT ? out : final;
35
35
  }
36
36
 
37
- if (final.type === createFragment || final.type === JSXFragmentType) {
37
+ if (final.type === JSXFragmentType) {
38
38
  return this.#render(ctx, renderer, final.props.children ?? [], stack);
39
39
  }
40
40
 
@@ -87,7 +87,7 @@ export class InkyRenderer {
87
87
  isRoot = true
88
88
  ): Promise<string> {
89
89
  const ctx = new RenderContext(sourceLoc.file, sourceLoc.module);
90
- const par: JSXElement = root.type === JSXFragmentType ? root : { props: { children: [root] }, type: JSXFragmentType, key: '' };
90
+ const par: JSXElement = root.type === JSXFragmentType ? root : createFragment({ children: [root] });
91
91
  const text = await this.#render(ctx, provider, par, []);
92
92
  return provider.finalize(text, ctx, isRoot);
93
93
  }
package/src/wrapper.ts CHANGED
@@ -1,35 +1,22 @@
1
- import { createRequire } from 'module';
2
-
3
1
  import { EmailCompileSource } from '@travetto/email';
4
- import { JSXComponentFunction, JSXElement, JSXFragmentType } from '@travetto/email-inky/jsx-runtime';
5
- import { RootIndex, path } from '@travetto/manifest';
2
+ import { JSXElement } from '@travetto/email-inky/jsx-runtime';
3
+ import { PackageUtil, path } from '@travetto/manifest';
6
4
 
7
5
  import { InkyRenderer } from './render/renderer';
8
6
  import { Html } from './render/html';
9
7
  import { Markdown } from './render/markdown';
10
8
  import { Subject } from './render/subject';
11
9
 
12
- export const wrap = (content: JSXElement): EmailCompileSource => {
13
- const req = createRequire(`${RootIndex.manifest.workspacePath}/node_modules`);
14
- const finalContent = { ...content, key: '', type: JSXFragmentType };
15
-
16
- return {
17
- styles: {
18
- search: [path.dirname(req.resolve('foundation-emails/scss/_global.scss'))],
19
- global: `
10
+ export const wrap = (content: JSXElement): EmailCompileSource => ({
11
+ styles: {
12
+ search: [path.dirname(PackageUtil.resolveImport('foundation-emails/scss/_global.scss'))],
13
+ global: `
20
14
  @import 'email/inky.variables';
21
15
  @import '_global';
22
16
  @import 'foundation-emails';
23
17
  `
24
- },
25
- html: InkyRenderer.render.bind(InkyRenderer, finalContent, Html),
26
- text: InkyRenderer.render.bind(InkyRenderer, finalContent, Markdown),
27
- subject: InkyRenderer.render.bind(InkyRenderer, finalContent, Subject),
28
- };
29
- };
30
-
31
- export const InkyTemplate: JSXComponentFunction<{}> = (): JSXElement => ({ type: '', key: '', props: {} });
32
-
33
- export const unwrap = (element: JSXElement): Promise<EmailCompileSource | undefined> =>
34
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
35
- (element as unknown as { wrap: (el: JSXElement) => Promise<EmailCompileSource> }).wrap(element);
18
+ },
19
+ html: InkyRenderer.render.bind(InkyRenderer, content, Html),
20
+ text: InkyRenderer.render.bind(InkyRenderer, content, Markdown),
21
+ subject: InkyRenderer.render.bind(InkyRenderer, content, Subject),
22
+ });