@travetto/email-inky 7.0.0-rc.1 → 7.0.0-rc.2

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
@@ -41,15 +41,15 @@ export function createElement<T extends string | Class | JSXComponentFunction<P>
41
41
  export function createRootElement<T extends string | Class | JSXComponentFunction<P>, P extends {}>(
42
42
  type: T, props: P & JSXProps
43
43
  ): JSXElement<T, P> {
44
- const res = createElement(type, props);
44
+ const node = createElement(type, props);
45
45
 
46
- Object.assign(res, {
47
- prepare(loc: EmailTemplateLocation): Promise<EmailTemplateModule> {
48
- return import('@travetto/email-inky').then(v => v.prepare(castTo(res), loc));
46
+ Object.assign(node, {
47
+ prepare(location: EmailTemplateLocation): Promise<EmailTemplateModule> {
48
+ return import('@travetto/email-inky').then(value => value.prepare(castTo(node), location));
49
49
  }
50
50
  });
51
51
 
52
- return res;
52
+ return node;
53
53
  }
54
54
 
55
55
  export function createFragment<P extends {}>(props: P & JSXProps): JSXElement<typeof JSXFragmentType, P> {
@@ -59,8 +59,8 @@ export function createFragment<P extends {}>(props: P & JSXProps): JSXElement<ty
59
59
  export const jsx = createElement;
60
60
  export const jsxs = createRootElement;
61
61
  export const Fragment = createFragment;
62
- export function isJSXElement(el: unknown): el is JSXElement {
63
- return el !== undefined && el !== null && typeof el === 'object' && JSXRuntimeTag in el;
62
+ export function isJSXElement(value: unknown): value is JSXElement {
63
+ return value !== undefined && value !== null && typeof value === 'object' && JSXRuntimeTag in value;
64
64
  }
65
65
 
66
66
  createFrag = Fragment;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/email-inky",
3
- "version": "7.0.0-rc.1",
3
+ "version": "7.0.0-rc.2",
4
4
  "description": "Email Inky templating module",
5
5
  "keywords": [
6
6
  "email",
@@ -27,14 +27,14 @@
27
27
  "directory": "module/email-inky"
28
28
  },
29
29
  "dependencies": {
30
- "@travetto/config": "^7.0.0-rc.1",
31
- "@travetto/di": "^7.0.0-rc.1",
32
- "@travetto/email": "^7.0.0-rc.1",
33
- "@travetto/runtime": "^7.0.0-rc.1",
30
+ "@travetto/config": "^7.0.0-rc.2",
31
+ "@travetto/di": "^7.0.0-rc.2",
32
+ "@travetto/email": "^7.0.0-rc.2",
33
+ "@travetto/runtime": "^7.0.0-rc.2",
34
34
  "foundation-emails": "^2.4.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@travetto/email-compiler": "^7.0.0-rc.1"
37
+ "@travetto/email-compiler": "^7.0.0-rc.2"
38
38
  },
39
39
  "peerDependenciesMeta": {
40
40
  "@travetto/cli": {
package/src/components.ts CHANGED
@@ -49,7 +49,7 @@ export type JSXElements = { [K in keyof C]: JSXElementByFn<K>; };
49
49
 
50
50
  export const EMPTY_ELEMENT = EMPTY;
51
51
 
52
- const invertedC = new Map<Function, string>(TypedObject.entries(c).map(p => [p[1], p[0]] as const));
52
+ const invertedC = new Map<Function, string>(TypedObject.entries(c).map(([name, cls]) => [cls, name] as const));
53
53
 
54
54
  export function getComponentName(fn: Function | string): string {
55
55
  if (typeof fn === 'string') {
@@ -1,7 +1,7 @@
1
1
  import { JSXElement, isJSXElement } from '@travetto/email-inky/jsx-runtime';
2
2
 
3
- export const getKids = (el: JSXElement): JSXElement[] => {
4
- const kids = el?.props?.children;
3
+ export const getChildren = (node: JSXElement): JSXElement[] => {
4
+ const kids = node?.props?.children;
5
5
  let result: unknown[] = [];
6
6
  if (kids) {
7
7
  result = !Array.isArray(kids) ? [kids] : kids;
@@ -9,22 +9,22 @@ export const getKids = (el: JSXElement): JSXElement[] => {
9
9
  return result.filter(isJSXElement);
10
10
  };
11
11
 
12
- export const visit = (el: JSXElement, onVisit: (fn: JSXElement) => boolean | undefined | void, depth = 0): boolean | undefined => {
12
+ export const visit = (node: JSXElement, onVisit: (fn: JSXElement) => boolean | undefined | void, depth = 0): boolean | undefined => {
13
13
  if (depth > 0) {
14
- const res = onVisit(el);
15
- if (res === true) {
14
+ const result = onVisit(node);
15
+ if (result === true) {
16
16
  return true;
17
17
  }
18
18
  }
19
- for (const item of getKids(el)) {
20
- const res = visit(item, onVisit, depth + 1);
21
- if (res) {
19
+ for (const item of getChildren(node)) {
20
+ const result = visit(item, onVisit, depth + 1);
21
+ if (result) {
22
22
  return;
23
23
  }
24
24
  }
25
25
  };
26
26
 
27
- export const classStr = (existing: string | undefined, ...toAdd: string[]): string => {
27
+ export const classString = (existing: string | undefined, ...toAdd: string[]): string => {
28
28
  const out = [];
29
29
  const seen = new Set<string>();
30
30
  for (const item of existing?.split(/\s+/) ?? []) {
@@ -42,12 +42,12 @@ export const classStr = (existing: string | undefined, ...toAdd: string[]): stri
42
42
  return out.join(' ');
43
43
  };
44
44
 
45
- export const combinePropsToStr = (allowedProps: Set<string>, props: { className?: string } & Record<string, unknown>, addClasses: string[] = []): string => {
46
- const out = { ...props, className: classStr(props.className, ...addClasses) };
45
+ export const combinePropsToString = (allowedProps: Set<string>, props: { className?: string } & Record<string, unknown>, addClasses: string[] = []): string => {
46
+ const out = { ...props, className: classString(props.className, ...addClasses) };
47
47
  return Object.entries(out)
48
- .filter(([k, v]) => allowedProps.has(k) && v !== undefined && v !== null && v !== '')
49
- .map(([k, v]) => [k === 'className' ? 'class' : k, v])
50
- .map(([k, v]) => `${k}="${v}"`).join(' ');
48
+ .filter(([key, value]) => allowedProps.has(key) && value !== undefined && value !== null && value !== '')
49
+ .map(([key, value]) => [key === 'className' ? 'class' : key, value])
50
+ .map(([key, value]) => `${key}="${value}"`).join(' ');
51
51
  };
52
52
 
53
- export const isOfType = (el: JSXElement, type: string): boolean => typeof el.type === 'function' && el.type.name === type;
53
+ export const isOfType = (node: JSXElement, type: string): boolean => typeof node.type === 'function' && node.type.name === type;
@@ -2,7 +2,7 @@ import { JSXElement } from '@travetto/email-inky/jsx-runtime';
2
2
 
3
3
  import { RenderProvider, RenderState } from '../types.ts';
4
4
  import { RenderContext } from './context.ts';
5
- import { classStr, combinePropsToStr, getKids, isOfType, visit } from './common.ts';
5
+ import { classString, combinePropsToString, getChildren, isOfType, visit } from './common.ts';
6
6
 
7
7
  export const SUMMARY_STYLE = Object.entries({
8
8
  display: 'none',
@@ -13,7 +13,7 @@ export const SUMMARY_STYLE = Object.entries({
13
13
  'max-width': '0px',
14
14
  opacity: '0',
15
15
  overflow: 'hidden'
16
- }).map(([k, v]) => `${k}: ${v}`).join('; ');
16
+ }).map(([key, value]) => `${key}: ${value}`).join('; ');
17
17
 
18
18
  const allowedProps = new Set([
19
19
  'className', 'id', 'dir', 'name', 'src',
@@ -21,18 +21,18 @@ const allowedProps = new Set([
21
21
  'width', 'style', 'align', 'valign'
22
22
  ]);
23
23
 
24
- const propsToStr = combinePropsToStr.bind(null, allowedProps);
24
+ const propsToString = combinePropsToString.bind(null, allowedProps);
25
25
 
26
- const stdInline = async ({ recurse, el }: RenderState<JSXElement, RenderContext>): Promise<string> =>
27
- `<${el.type} ${propsToStr(el.props)}>${await recurse()}</${el.type}>`;
26
+ const standardInline = async ({ recurse, node }: RenderState<JSXElement, RenderContext>): Promise<string> =>
27
+ `<${node.type} ${propsToString(node.props)}>${await recurse()}</${node.type}>`;
28
28
 
29
- const std = async (state: RenderState<JSXElement, RenderContext>): Promise<string> => `${await stdInline(state)}\n`;
30
- const stdFull = async (state: RenderState<JSXElement, RenderContext>): Promise<string> => `\n${await stdInline(state)}\n`;
29
+ const standard = async (state: RenderState<JSXElement, RenderContext>): Promise<string> => `${await standardInline(state)}\n`;
30
+ const standardFull = async (state: RenderState<JSXElement, RenderContext>): Promise<string> => `\n${await standardInline(state)}\n`;
31
31
 
32
32
  export const Html: RenderProvider<RenderContext> = {
33
33
  finalize: async (html, context, isRoot = false) => {
34
34
  html = html
35
- .replace(/(<[/](?:a)>)([A-Za-z0-9$])/g, (_, tag, v) => `${tag} ${v}`)
35
+ .replace(/(<[/](?:a)>)([A-Za-z0-9$])/g, (_, tag, value) => `${tag} ${value}`)
36
36
  .replace(/(<[uo]l>)(<li>)/g, (_, a, b) => `${a} ${b}`);
37
37
 
38
38
  if (isRoot) {
@@ -47,13 +47,13 @@ export const Html: RenderProvider<RenderContext> = {
47
47
  .replace('<!-- BODY -->', html)
48
48
  .replace(/<title>.*?<\/title>/, a => { headerTop.push(a); return ''; })
49
49
  .replace(/<span[^>]+id="summary"[^>]*>(.*?)<\/span>/sm, a => { bodyTop.push(a); return ''; })
50
- .replace(/<head( [^>]*)?>/, t => `${t}\n${headerTop.join('\n')}`)
51
- .replace(/<body[^>]*>/, t => `${t}\n${bodyTop.join('\n')}`);
50
+ .replace(/<head( [^>]*)?>/, tag => `${tag}\n${headerTop.join('\n')}`)
51
+ .replace(/<body[^>]*>/, tag => `${tag}\n${bodyTop.join('\n')}`);
52
52
 
53
53
  // Allow tag suffixes/prefixes via comments
54
54
  html = final
55
- .replace(/\s*<!--\s*[$]:([^ -]+)\s*-->\s*(<\/[^>]+>)/g, (_, suf, tag) => `${tag}${suf}`)
56
- .replace(/(<[^\/][^>]+>)\s*<!--\s*[#]:([^ ]+)\s*-->\s*/g, (_, tag, pre) => `${pre}${tag}`);
55
+ .replace(/\s*<!--\s*[$]:([^ -]+)\s*-->\s*(<\/[^>]+>)/g, (_, suffix, tag) => `${tag}${suffix}`)
56
+ .replace(/(<[^\/][^>]+>)\s*<!--\s*[#]:([^ ]+)\s*-->\s*/g, (_, tag, prefix) => `${prefix}${tag}`);
57
57
  }
58
58
 
59
59
  return html;
@@ -65,51 +65,51 @@ export const Html: RenderProvider<RenderContext> = {
65
65
  Value: async ({ props }) => props.raw ? `{{{${props.attr}}}}` : `{{${props.attr}}}`,
66
66
 
67
67
  br: async () => '<br>\n',
68
- hr: async (el) => `<table ${propsToStr(el.props)}><th></th></table>`,
69
- strong: stdInline, em: stdInline, p: stdFull,
70
- h1: stdFull, h2: stdFull, h3: stdFull, h4: stdFull,
71
- li: std, ol: stdFull, ul: stdFull,
72
- table: stdFull, thead: std, tr: std, td: std, th: std, tbody: std, center: std, img: stdInline,
73
- title: std,
74
- div: std, span: stdInline, small: stdInline,
75
- a: async ({ recurse, props }) => `<a ${propsToStr(props)}>${await recurse()}</a>`,
76
-
77
- InkyTemplate: c => c.recurse(),
68
+ hr: async (node) => `<table ${propsToString(node.props)}><th></th></table>`,
69
+ strong: standardInline, em: standardInline, p: standardFull,
70
+ h1: standardFull, h2: standardFull, h3: standardFull, h4: standardFull,
71
+ li: standard, ol: standardFull, ul: standardFull,
72
+ table: standardFull, thead: standard, tr: standard, td: standard, th: standard, tbody: standard, center: standard, img: standardInline,
73
+ title: standard,
74
+ div: standard, span: standardInline, small: standardInline,
75
+ a: async ({ recurse, props }) => `<a ${propsToString(props)}>${await recurse()}</a>`,
76
+
77
+ InkyTemplate: ctx => ctx.recurse(),
78
78
  Title: async ({ recurse }) => `<title>${await recurse()}</title>`,
79
79
  Summary: async ({ recurse }) => `<span id="summary" style="${SUMMARY_STYLE}">${await recurse()}</span>`,
80
80
 
81
- Column: async ({ props, recurse, stack, el, context }): Promise<string> => {
81
+ Column: async ({ props, recurse, stack, node, context }): Promise<string> => {
82
82
 
83
83
  recurse();
84
84
 
85
85
  let expander = '';
86
86
 
87
87
  const parent = stack.at(-1)!;
88
- const sibs = getKids(parent).filter(x => isOfType(x, 'Column'));
89
- const colCount = sibs.length || 1;
88
+ const siblings = getChildren(parent).filter(child => isOfType(child, 'Column'));
89
+ const colCount = siblings.length || 1;
90
90
 
91
91
  if (parent) {
92
- const elParent: (typeof parent) & { columnVisited?: boolean } = parent;
93
- if (!elParent.columnVisited) {
94
- elParent.columnVisited = true;
95
- if (sibs.length) {
96
- sibs[0].props.className = classStr(sibs[0].props.className ?? '', 'first');
97
- sibs.at(-1)!.props.className = classStr(sibs.at(-1)!.props.className ?? '', 'last');
92
+ const parentNode: (typeof parent) & { columnVisited?: boolean } = parent;
93
+ if (!parentNode.columnVisited) {
94
+ parentNode.columnVisited = true;
95
+ if (siblings.length) {
96
+ siblings[0].props.className = classString(siblings[0].props.className ?? '', 'first');
97
+ siblings.at(-1)!.props.className = classString(siblings.at(-1)!.props.className ?? '', 'last');
98
98
  }
99
99
  }
100
100
  } else {
101
- props.className = classStr(props.className ?? '', 'first', 'last');
101
+ props.className = classString(props.className ?? '', 'first', 'last');
102
102
  }
103
103
 
104
104
  // Check for sizes. If no attribute is provided, default to small-12. Divide evenly for large columns
105
- const smallSize = el.props.small ?? context.columnCount;
106
- const largeSize = el.props.large ?? el.props.small ?? Math.trunc(context.columnCount / colCount);
105
+ const smallSize = node.props.small ?? context.columnCount;
106
+ const largeSize = node.props.large ?? node.props.small ?? Math.trunc(context.columnCount / colCount);
107
107
 
108
108
  // If the column contains a nested row, the .expander class should not be used
109
109
  if (largeSize === context.columnCount && !props.noExpander) {
110
110
  let hasRow = false;
111
- visit(el, (node) => {
112
- if (isOfType(node, 'Row')) {
111
+ visit(node, (child) => {
112
+ if (isOfType(child, 'Row')) {
113
113
  return hasRow = true;
114
114
  }
115
115
  });
@@ -134,7 +134,7 @@ export const Html: RenderProvider<RenderContext> = {
134
134
 
135
135
  // Final HTML output
136
136
  return `
137
- <th ${propsToStr(el.props, classes)}>
137
+ <th ${propsToString(node.props, classes)}>
138
138
  <table>
139
139
  <tbody>
140
140
  <tr>
@@ -146,14 +146,14 @@ export const Html: RenderProvider<RenderContext> = {
146
146
  },
147
147
 
148
148
  HLine: async ({ props }) => `
149
- <table ${propsToStr(props, ['h-line'])}>
149
+ <table ${propsToString(props, ['h-line'])}>
150
150
  <tbody>
151
151
  <tr><th>&nbsp;</th></tr>
152
152
  </tbody>
153
153
  </table>`,
154
154
 
155
- Row: async ({ recurse, el }): Promise<string> => `
156
- <table ${propsToStr(el.props, ['row'])}>
155
+ Row: async ({ recurse, node }): Promise<string> => `
156
+ <table ${propsToString(node.props, ['row'])}>
157
157
  <tbody>
158
158
  <tr>${await recurse()}</tr>
159
159
  </tbody>
@@ -170,19 +170,19 @@ export const Html: RenderProvider<RenderContext> = {
170
170
  if (props.expanded) {
171
171
  Object.assign(linkProps, { align: 'center', className: 'float-center' });
172
172
  }
173
- inner = `<a ${propsToStr(linkProps)}>${inner}</a>`;
173
+ inner = `<a ${propsToString(linkProps)}>${inner}</a>`;
174
174
  }
175
175
 
176
176
  // If the button is expanded, it needs a <center> tag around the content
177
177
  if (props.expanded) {
178
178
  inner = await Html.Center(createState('Center', { children: [inner] }));
179
- rest.className = classStr(rest.className ?? '', 'expand');
179
+ rest.className = classString(rest.className ?? '', 'expand');
180
180
  expander = '\n<td class="expander"></td>';
181
181
  }
182
182
 
183
183
  // The .button class is always there, along with any others on the <button> element
184
184
  return `
185
- <table ${propsToStr(rest, ['button'])}>
185
+ <table ${propsToString(rest, ['button'])}>
186
186
  <tbody>
187
187
  <tr>
188
188
  <td>
@@ -203,22 +203,22 @@ export const Html: RenderProvider<RenderContext> = {
203
203
  },
204
204
 
205
205
  Container: async ({ recurse, props }): Promise<string> => `
206
- <table align="center" ${propsToStr(props, ['container'])}>
206
+ <table align="center" ${propsToString(props, ['container'])}>
207
207
  <tbody>
208
208
  <tr><td>${await recurse()}</td></tr>
209
209
  </tbody>
210
210
  </table>`,
211
211
 
212
212
  BlockGrid: async ({ recurse, props }): Promise<string> => `
213
- <table ${propsToStr(props, ['block-grid', props.up ? `up-${props.up}` : ''])}>
213
+ <table ${propsToString(props, ['block-grid', props.up ? `up-${props.up}` : ''])}>
214
214
  <tbody>
215
215
  <tr>${await recurse()}</tr>
216
216
  </tbody>
217
217
  </table>`,
218
218
 
219
- Menu: async ({ recurse, el, props }): Promise<string> => {
219
+ Menu: async ({ recurse, node, props }): Promise<string> => {
220
220
  let hasItem = false;
221
- visit(el, (child) => {
221
+ visit(node, (child) => {
222
222
  if (isOfType(child, 'Item')) {
223
223
  return hasItem = true;
224
224
  } else if ((child.type === 'td' || child.type === 'th') && child.props.className?.includes('menu-item')) {
@@ -233,7 +233,7 @@ export const Html: RenderProvider<RenderContext> = {
233
233
  }
234
234
 
235
235
  return `
236
- <table ${propsToStr(props, ['menu'])}>
236
+ <table ${propsToString(props, ['menu'])}>
237
237
  <tbody>
238
238
  <tr>
239
239
  <td>
@@ -253,28 +253,28 @@ export const Html: RenderProvider<RenderContext> = {
253
253
  Item: async ({ recurse, props }): Promise<string> => {
254
254
  const { href, target, ...parentAttrs } = props;
255
255
  return `
256
- <th ${propsToStr(parentAttrs, ['menu-item'])}>
257
- <a ${propsToStr({ href, target })}>${await recurse()}</a>
256
+ <th ${propsToString(parentAttrs, ['menu-item'])}>
257
+ <a ${propsToString({ href, target })}>${await recurse()}</a>
258
258
  </th>`;
259
259
  },
260
260
 
261
- Center: async ({ props, recurse, el }): Promise<string> => {
262
- for (const kid of getKids(el)) {
263
- Object.assign(kid.props, {
261
+ Center: async ({ props, recurse, node }): Promise<string> => {
262
+ for (const child of getChildren(node)) {
263
+ Object.assign(child.props, {
264
264
  align: 'center',
265
- className: classStr(kid.props.className, 'float-center')
265
+ className: classString(child.props.className, 'float-center')
266
266
  });
267
267
  }
268
268
 
269
- visit(el, child => {
269
+ visit(node, child => {
270
270
  if (isOfType(child, 'Item')) {
271
- child.props.className = classStr(child.props.className, 'float-center');
271
+ child.props.className = classString(child.props.className, 'float-center');
272
272
  }
273
273
  return;
274
274
  });
275
275
 
276
276
  return `
277
- <center ${propsToStr(props)}>
277
+ <center ${propsToString(props)}>
278
278
  ${await recurse()}
279
279
  </center>
280
280
  `;
@@ -286,10 +286,10 @@ export const Html: RenderProvider<RenderContext> = {
286
286
  delete props.className;
287
287
 
288
288
  return `
289
- <table ${propsToStr(props, ['callout'])}>
289
+ <table ${propsToString(props, ['callout'])}>
290
290
  <tbody>
291
291
  <tr>
292
- <th ${propsToStr(innerProps, ['callout-inner'])}>
292
+ <th ${propsToString(innerProps, ['callout-inner'])}>
293
293
  ${await recurse()}
294
294
  </th>
295
295
  <th class="expander"></th>
@@ -302,7 +302,7 @@ export const Html: RenderProvider<RenderContext> = {
302
302
  const html: string[] = [];
303
303
  const buildSpacer = (size: number | string, extraClass: string = ''): string =>
304
304
  `
305
- <table ${propsToStr(props, ['spacer', extraClass])}>
305
+ <table ${propsToString(props, ['spacer', extraClass])}>
306
306
  <tbody>
307
307
  <tr>
308
308
  <td height="${size}px" style="font-size:${size}px;line-height:${size}px;">&nbsp;</td>
@@ -311,15 +311,15 @@ export const Html: RenderProvider<RenderContext> = {
311
311
  </table>
312
312
  `;
313
313
 
314
- const sm = props.small ?? undefined;
315
- const lg = props.large ?? undefined;
314
+ const small = props.small ?? undefined;
315
+ const large = props.large ?? undefined;
316
316
 
317
- if (sm || lg) {
318
- if (sm) {
319
- html.push(buildSpacer(sm, 'hide-for-large'));
317
+ if (small || large) {
318
+ if (small) {
319
+ html.push(buildSpacer(small, 'hide-for-large'));
320
320
  }
321
- if (lg) {
322
- html.push(buildSpacer(lg, 'show-for-large'));
321
+ if (large) {
322
+ html.push(buildSpacer(large, 'show-for-large'));
323
323
  }
324
324
  } else {
325
325
  html.push(buildSpacer(props.size || 16));
@@ -328,8 +328,8 @@ export const Html: RenderProvider<RenderContext> = {
328
328
  return html.join('\n');
329
329
  },
330
330
 
331
- Wrapper: async ({ recurse, el }) => `
332
- <table align="center" ${propsToStr(el.props, ['wrapper'])}>
331
+ Wrapper: async ({ recurse, node }) => `
332
+ <table align="center" ${propsToString(node.props, ['wrapper'])}>
333
333
  <tbody>
334
334
  <tr>
335
335
  <td class="wrapper-inner">
@@ -10,8 +10,8 @@ const ignore = async (_: RenderState<JSXElement, RenderContext>): Promise<string
10
10
  export const Markdown: RenderProvider<RenderContext> = {
11
11
  finalize: (text) => {
12
12
  text = text
13
- .replace(/(\[[^\]]{1,100}\]\([^)]{1,1000}\))([A-Za-z0-9$]{1,100})/g, (all, link, v) => v === 's' ? all : `${link} ${v}`)
14
- .replace(/(\S)\n(#)/g, (_, l, r) => `${l}\n\n${r}`);
13
+ .replace(/(\[[^\]]{1,100}\]\([^)]{1,1000}\))([A-Za-z0-9$]{1,100})/g, (all, link, value) => value === 's' ? all : `${link} ${value}`)
14
+ .replace(/(\S)\n(#)/g, (_, left, right) => `${left}\n\n${right}`);
15
15
  return text;
16
16
  },
17
17
 
@@ -29,8 +29,8 @@ export const Markdown: RenderProvider<RenderContext> = {
29
29
  ul: async ({ recurse }) => `\n${await recurse()}`,
30
30
  ol: async ({ recurse }) => `\n${await recurse()}`,
31
31
  li: async ({ recurse, stack }) => {
32
- const parent = stack.toReversed().find(x => x.type === 'ol' || x.type === 'ul');
33
- const depth = stack.filter(x => x.type === 'ol' || x.type === 'ul').length;
32
+ const parent = stack.toReversed().find(node => node.type === 'ol' || node.type === 'ul');
33
+ const depth = stack.filter(node => node.type === 'ol' || node.type === 'ul').length;
34
34
  return `${' '.repeat(depth)}${(parent && parent.type === 'ol') ? '1.' : '* '} ${await recurse()}\n`;
35
35
  },
36
36
  th: async ({ recurse }) => `|${await recurse()}`,
@@ -53,7 +53,7 @@ export const Markdown: RenderProvider<RenderContext> = {
53
53
 
54
54
  Menu: async ({ recurse }) => `\n${await recurse()}`,
55
55
  Item: async ({ recurse, stack, props }) => {
56
- const depth = stack.filter(x => x.type === 'Menu').length;
56
+ const depth = stack.filter(node => node.type === 'Menu').length;
57
57
  return `${' '.repeat(depth)}* [${await recurse()}](${props.href})\n`;
58
58
  },
59
59
  Spacer: async () => '\n\n',
@@ -13,23 +13,23 @@ export class InkyRenderer {
13
13
  static async #render(
14
14
  ctx: RenderContext,
15
15
  renderer: RenderProvider<RenderContext>,
16
- node: JSXChild[] | JSXChild | null | undefined,
16
+ input: JSXChild[] | JSXChild | null | undefined,
17
17
  stack: JSXElement[] = []
18
18
  ): Promise<string> {
19
- if (node === null || node === undefined) {
19
+ if (input === null || input === undefined) {
20
20
  return '';
21
- } else if (Array.isArray(node)) {
21
+ } else if (Array.isArray(input)) {
22
22
  const out: string[] = [];
23
- const nextStack = [...stack, { key: '', props: { children: node }, type: JSXFragmentType }];
24
- for (const el of node) {
25
- out.push(await this.#render(ctx, renderer, el, nextStack));
23
+ const nextStack = [...stack, { key: '', props: { children: input }, type: JSXFragmentType }];
24
+ for (const node of input) {
25
+ out.push(await this.#render(ctx, renderer, node, nextStack));
26
26
  }
27
27
  return out.join('');
28
- } else if (isJSXElement(node)) {
29
- let final: JSXElement = node;
28
+ } else if (isJSXElement(input)) {
29
+ let final: JSXElement = input;
30
30
  // Render simple element if needed
31
- if (typeof node.type === 'function' && node.type !== JSXFragmentType) {
32
- const out = castTo<Function>(node.type)(node.props);
31
+ if (typeof input.type === 'function' && input.type !== JSXFragmentType) {
32
+ const out = castTo<Function>(input.type)(input.props);
33
33
  final = out !== EMPTY_ELEMENT ? out : final;
34
34
  }
35
35
 
@@ -46,7 +46,7 @@ export class InkyRenderer {
46
46
  const recurse = (): Promise<string> => this.#render(ctx, renderer, final.props.children ?? [], [...stack, final]);
47
47
  // @ts-expect-error
48
48
  const state: RenderState<JSXElement, RenderContext> = {
49
- el: final, props: final.props, recurse, stack, context: ctx
49
+ node: final, props: final.props, recurse, stack, context: ctx
50
50
  };
51
51
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
52
52
  state.createState = (key, props) => this.createState(ctx, renderer, state, key, props);
@@ -57,7 +57,7 @@ export class InkyRenderer {
57
57
  throw new Error(`Unknown element: ${final.type}`);
58
58
  }
59
59
  } else {
60
- return `${node}`;
60
+ return `${input}`;
61
61
  }
62
62
  }
63
63
 
@@ -69,9 +69,9 @@ export class InkyRenderer {
69
69
  props: JSXElementByFn<K>['props'],
70
70
  // @ts-expect-error
71
71
  ): RenderState<JSXElementByFn<K>, RenderContext> {
72
- const el = ctx.createElement(key, props);
73
- const newStack: JSXElement[] = castTo([...state.stack, el]);
74
- return { ...state, el, props: el.props, recurse: () => this.#render(ctx, renderer, el.props.children ?? [], newStack) };
72
+ const node = ctx.createElement(key, props);
73
+ const newStack: JSXElement[] = castTo([...state.stack, node]);
74
+ return { ...state, node, props: node.props, recurse: () => this.#render(ctx, renderer, node.props.children ?? [], newStack) };
75
75
  }
76
76
 
77
77
  /**
package/src/types.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { JSXElement, ValidHtmlTags } from '../jsx-runtime.ts';
2
2
  import { JSXElementByFn, c } from './components.ts';
3
3
 
4
- export type Wrapper = Record<string, (cnt: string) => string>;
4
+ export type Wrapper = Record<string, (count: string) => string>;
5
5
 
6
6
  export type RenderState<T extends JSXElement, C> = {
7
- el: T;
7
+ node: T;
8
8
  props: T['props'];
9
9
  recurse: () => Promise<string>;
10
10
  stack: JSXElement[];
package/src/wrapper.ts CHANGED
@@ -9,10 +9,10 @@ import { Html } from './render/html.ts';
9
9
  import { Markdown } from './render/markdown.ts';
10
10
  import { Subject } from './render/subject.ts';
11
11
 
12
- export async function prepare(node: JSXElement, loc: EmailTemplateLocation): Promise<EmailTemplateModule> {
12
+ export async function prepare(node: JSXElement, location: EmailTemplateLocation): Promise<EmailTemplateModule> {
13
13
  const ctx = {
14
- ...loc,
15
- loader: new EmailResourceLoader(loc.module, [path.dirname(PackageUtil.resolveImport('foundation-emails/scss/_global.scss'))])
14
+ ...location,
15
+ loader: new EmailResourceLoader(location.module, [path.dirname(PackageUtil.resolveImport('foundation-emails/scss/_global.scss'))])
16
16
  };
17
17
  return {
18
18
  loader: ctx.loader,