pte-interpolation-core 1.2.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -61,7 +61,10 @@ function interpolateToString(blocks, values, fallback = defaultFallback) {
61
61
  return children.map((child) => {
62
62
  if (child._type === VARIABLE_TYPE_PREFIX) {
63
63
  const variableKey = child.variableKey;
64
- return values[variableKey] !== void 0 ? values[variableKey] : fallback(variableKey);
64
+ if (typeof variableKey === "string") {
65
+ return values[variableKey] !== void 0 ? values[variableKey] : fallback(variableKey);
66
+ }
67
+ return "";
65
68
  }
66
69
  return typeof child.text === "string" ? child.text : "";
67
70
  }).join("");
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/extractVariableKeys.ts","../src/getMissingVariableKeys.ts","../src/interpolateToString.ts"],"sourcesContent":["export {VARIABLE_TYPE_PREFIX} from './constants'\nexport {extractVariableKeys} from './extractVariableKeys'\nexport {getMissingVariableKeys} from './getMissingVariableKeys'\nexport {interpolateToString} from './interpolateToString'\nexport type {\n InterpolationFallback,\n InterpolationValues,\n PortableTextBlockLike,\n PortableTextChild,\n PteInterpolationVariableBlock,\n} from './types'\n","/** @public */\nexport const VARIABLE_TYPE_PREFIX = 'pteInterpolationVariable'\n","import {VARIABLE_TYPE_PREFIX} from './constants'\nimport type {PortableTextBlockLike} from './types'\n\n/** @public */\nexport function extractVariableKeys(blocks: PortableTextBlockLike[]): string[] {\n const seen = new Set<string>()\n\n return blocks.reduce<string[]>((keys, block) => {\n const children = block.children ?? []\n\n return children.reduce((accumulated, child) => {\n if (child._type !== VARIABLE_TYPE_PREFIX) return accumulated\n\n const variableKey = child.variableKey\n if (typeof variableKey !== 'string') return accumulated\n if (seen.has(variableKey)) return accumulated\n\n seen.add(variableKey)\n return [...accumulated, variableKey]\n }, keys)\n }, [])\n}\n","import {extractVariableKeys} from './extractVariableKeys'\nimport type {InterpolationValues, PortableTextBlockLike} from './types'\n\n/** @public */\nexport function getMissingVariableKeys(\n blocks: PortableTextBlockLike[],\n values: InterpolationValues,\n): string[] {\n return extractVariableKeys(blocks).filter((key) => values[key] === undefined)\n}\n","import {VARIABLE_TYPE_PREFIX} from './constants'\nimport type {InterpolationFallback, InterpolationValues, PortableTextBlockLike} from './types'\n\nfunction defaultFallback(variableKey: string): string {\n return `{${variableKey}}`\n}\n\n/** @public */\nexport function interpolateToString(\n blocks: PortableTextBlockLike[],\n values: InterpolationValues,\n fallback: InterpolationFallback = defaultFallback,\n): string {\n return blocks\n .map((block) => {\n const children = block.children ?? []\n\n return children\n .map((child) => {\n if (child._type === VARIABLE_TYPE_PREFIX) {\n const variableKey = child.variableKey as string\n return values[variableKey] !== undefined ? values[variableKey] : fallback(variableKey)\n }\n\n return typeof child.text === 'string' ? child.text : ''\n })\n .join('')\n })\n .join('\\n')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCO,IAAM,uBAAuB;;;ACG7B,SAAS,oBAAoB,QAA2C;AAC7E,QAAM,OAAO,oBAAI,IAAY;AAE7B,SAAO,OAAO,OAAiB,CAAC,MAAM,UAAU;AAC9C,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO,SAAS,OAAO,CAAC,aAAa,UAAU;AAC7C,UAAI,MAAM,UAAU,qBAAsB,QAAO;AAEjD,YAAM,cAAc,MAAM;AAC1B,UAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,UAAI,KAAK,IAAI,WAAW,EAAG,QAAO;AAElC,WAAK,IAAI,WAAW;AACpB,aAAO,CAAC,GAAG,aAAa,WAAW;AAAA,IACrC,GAAG,IAAI;AAAA,EACT,GAAG,CAAC,CAAC;AACP;;;ACjBO,SAAS,uBACd,QACA,QACU;AACV,SAAO,oBAAoB,MAAM,EAAE,OAAO,CAAC,QAAQ,OAAO,GAAG,MAAM,MAAS;AAC9E;;;ACNA,SAAS,gBAAgB,aAA6B;AACpD,SAAO,IAAI,WAAW;AACxB;AAGO,SAAS,oBACd,QACA,QACA,WAAkC,iBAC1B;AACR,SAAO,OACJ,IAAI,CAAC,UAAU;AACd,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO,SACJ,IAAI,CAAC,UAAU;AACd,UAAI,MAAM,UAAU,sBAAsB;AACxC,cAAM,cAAc,MAAM;AAC1B,eAAO,OAAO,WAAW,MAAM,SAAY,OAAO,WAAW,IAAI,SAAS,WAAW;AAAA,MACvF;AAEA,aAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAAA,IACvD,CAAC,EACA,KAAK,EAAE;AAAA,EACZ,CAAC,EACA,KAAK,IAAI;AACd;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/extractVariableKeys.ts","../src/getMissingVariableKeys.ts","../src/interpolateToString.ts"],"sourcesContent":["export {VARIABLE_TYPE_PREFIX} from './constants'\nexport {extractVariableKeys} from './extractVariableKeys'\nexport {getMissingVariableKeys} from './getMissingVariableKeys'\nexport {interpolateToString} from './interpolateToString'\nexport type {\n InterpolationFallback,\n InterpolationValues,\n PortableTextBlockLike,\n PortableTextChild,\n PteInterpolationVariableBlock,\n} from './types'\n","/** @public */\nexport const VARIABLE_TYPE_PREFIX = 'pteInterpolationVariable'\n","import {VARIABLE_TYPE_PREFIX} from './constants'\nimport type {PortableTextBlockLike} from './types'\n\n/** @public */\nexport function extractVariableKeys(blocks: PortableTextBlockLike[]): string[] {\n const seen = new Set<string>()\n\n return blocks.reduce<string[]>((keys, block) => {\n const children = block.children ?? []\n\n return children.reduce((accumulated, child) => {\n if (child._type !== VARIABLE_TYPE_PREFIX) return accumulated\n\n const variableKey = child.variableKey\n if (typeof variableKey !== 'string') return accumulated\n if (seen.has(variableKey)) return accumulated\n\n seen.add(variableKey)\n return [...accumulated, variableKey]\n }, keys)\n }, [])\n}\n","import {extractVariableKeys} from './extractVariableKeys'\nimport type {InterpolationValues, PortableTextBlockLike} from './types'\n\n/** @public */\nexport function getMissingVariableKeys(\n blocks: PortableTextBlockLike[],\n values: InterpolationValues,\n): string[] {\n return extractVariableKeys(blocks).filter((key) => values[key] === undefined)\n}\n","import {VARIABLE_TYPE_PREFIX} from './constants'\nimport type {InterpolationFallback, InterpolationValues, PortableTextBlockLike} from './types'\n\nfunction defaultFallback(variableKey: string): string {\n return `{${variableKey}}`\n}\n\n/** @public */\nexport function interpolateToString(\n blocks: PortableTextBlockLike[],\n values: InterpolationValues,\n fallback: InterpolationFallback = defaultFallback,\n): string {\n return blocks\n .map((block) => {\n const children = block.children ?? []\n\n return children\n .map((child) => {\n if (child._type === VARIABLE_TYPE_PREFIX) {\n const variableKey = child.variableKey\n if (typeof variableKey === 'string') {\n return values[variableKey] !== undefined ? values[variableKey] : fallback(variableKey)\n }\n return ''\n }\n\n return typeof child.text === 'string' ? child.text : ''\n })\n .join('')\n })\n .join('\\n')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCO,IAAM,uBAAuB;;;ACG7B,SAAS,oBAAoB,QAA2C;AAC7E,QAAM,OAAO,oBAAI,IAAY;AAE7B,SAAO,OAAO,OAAiB,CAAC,MAAM,UAAU;AAC9C,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO,SAAS,OAAO,CAAC,aAAa,UAAU;AAC7C,UAAI,MAAM,UAAU,qBAAsB,QAAO;AAEjD,YAAM,cAAc,MAAM;AAC1B,UAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,UAAI,KAAK,IAAI,WAAW,EAAG,QAAO;AAElC,WAAK,IAAI,WAAW;AACpB,aAAO,CAAC,GAAG,aAAa,WAAW;AAAA,IACrC,GAAG,IAAI;AAAA,EACT,GAAG,CAAC,CAAC;AACP;;;ACjBO,SAAS,uBACd,QACA,QACU;AACV,SAAO,oBAAoB,MAAM,EAAE,OAAO,CAAC,QAAQ,OAAO,GAAG,MAAM,MAAS;AAC9E;;;ACNA,SAAS,gBAAgB,aAA6B;AACpD,SAAO,IAAI,WAAW;AACxB;AAGO,SAAS,oBACd,QACA,QACA,WAAkC,iBAC1B;AACR,SAAO,OACJ,IAAI,CAAC,UAAU;AACd,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO,SACJ,IAAI,CAAC,UAAU;AACd,UAAI,MAAM,UAAU,sBAAsB;AACxC,cAAM,cAAc,MAAM;AAC1B,YAAI,OAAO,gBAAgB,UAAU;AACnC,iBAAO,OAAO,WAAW,MAAM,SAAY,OAAO,WAAW,IAAI,SAAS,WAAW;AAAA,QACvF;AACA,eAAO;AAAA,MACT;AAEA,aAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAAA,IACvD,CAAC,EACA,KAAK,EAAE;AAAA,EACZ,CAAC,EACA,KAAK,IAAI;AACd;","names":[]}
package/dist/index.js CHANGED
@@ -32,7 +32,10 @@ function interpolateToString(blocks, values, fallback = defaultFallback) {
32
32
  return children.map((child) => {
33
33
  if (child._type === VARIABLE_TYPE_PREFIX) {
34
34
  const variableKey = child.variableKey;
35
- return values[variableKey] !== void 0 ? values[variableKey] : fallback(variableKey);
35
+ if (typeof variableKey === "string") {
36
+ return values[variableKey] !== void 0 ? values[variableKey] : fallback(variableKey);
37
+ }
38
+ return "";
36
39
  }
37
40
  return typeof child.text === "string" ? child.text : "";
38
41
  }).join("");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/extractVariableKeys.ts","../src/getMissingVariableKeys.ts","../src/interpolateToString.ts"],"sourcesContent":["/** @public */\nexport const VARIABLE_TYPE_PREFIX = 'pteInterpolationVariable'\n","import {VARIABLE_TYPE_PREFIX} from './constants'\nimport type {PortableTextBlockLike} from './types'\n\n/** @public */\nexport function extractVariableKeys(blocks: PortableTextBlockLike[]): string[] {\n const seen = new Set<string>()\n\n return blocks.reduce<string[]>((keys, block) => {\n const children = block.children ?? []\n\n return children.reduce((accumulated, child) => {\n if (child._type !== VARIABLE_TYPE_PREFIX) return accumulated\n\n const variableKey = child.variableKey\n if (typeof variableKey !== 'string') return accumulated\n if (seen.has(variableKey)) return accumulated\n\n seen.add(variableKey)\n return [...accumulated, variableKey]\n }, keys)\n }, [])\n}\n","import {extractVariableKeys} from './extractVariableKeys'\nimport type {InterpolationValues, PortableTextBlockLike} from './types'\n\n/** @public */\nexport function getMissingVariableKeys(\n blocks: PortableTextBlockLike[],\n values: InterpolationValues,\n): string[] {\n return extractVariableKeys(blocks).filter((key) => values[key] === undefined)\n}\n","import {VARIABLE_TYPE_PREFIX} from './constants'\nimport type {InterpolationFallback, InterpolationValues, PortableTextBlockLike} from './types'\n\nfunction defaultFallback(variableKey: string): string {\n return `{${variableKey}}`\n}\n\n/** @public */\nexport function interpolateToString(\n blocks: PortableTextBlockLike[],\n values: InterpolationValues,\n fallback: InterpolationFallback = defaultFallback,\n): string {\n return blocks\n .map((block) => {\n const children = block.children ?? []\n\n return children\n .map((child) => {\n if (child._type === VARIABLE_TYPE_PREFIX) {\n const variableKey = child.variableKey as string\n return values[variableKey] !== undefined ? values[variableKey] : fallback(variableKey)\n }\n\n return typeof child.text === 'string' ? child.text : ''\n })\n .join('')\n })\n .join('\\n')\n}\n"],"mappings":";AACO,IAAM,uBAAuB;;;ACG7B,SAAS,oBAAoB,QAA2C;AAC7E,QAAM,OAAO,oBAAI,IAAY;AAE7B,SAAO,OAAO,OAAiB,CAAC,MAAM,UAAU;AAC9C,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO,SAAS,OAAO,CAAC,aAAa,UAAU;AAC7C,UAAI,MAAM,UAAU,qBAAsB,QAAO;AAEjD,YAAM,cAAc,MAAM;AAC1B,UAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,UAAI,KAAK,IAAI,WAAW,EAAG,QAAO;AAElC,WAAK,IAAI,WAAW;AACpB,aAAO,CAAC,GAAG,aAAa,WAAW;AAAA,IACrC,GAAG,IAAI;AAAA,EACT,GAAG,CAAC,CAAC;AACP;;;ACjBO,SAAS,uBACd,QACA,QACU;AACV,SAAO,oBAAoB,MAAM,EAAE,OAAO,CAAC,QAAQ,OAAO,GAAG,MAAM,MAAS;AAC9E;;;ACNA,SAAS,gBAAgB,aAA6B;AACpD,SAAO,IAAI,WAAW;AACxB;AAGO,SAAS,oBACd,QACA,QACA,WAAkC,iBAC1B;AACR,SAAO,OACJ,IAAI,CAAC,UAAU;AACd,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO,SACJ,IAAI,CAAC,UAAU;AACd,UAAI,MAAM,UAAU,sBAAsB;AACxC,cAAM,cAAc,MAAM;AAC1B,eAAO,OAAO,WAAW,MAAM,SAAY,OAAO,WAAW,IAAI,SAAS,WAAW;AAAA,MACvF;AAEA,aAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAAA,IACvD,CAAC,EACA,KAAK,EAAE;AAAA,EACZ,CAAC,EACA,KAAK,IAAI;AACd;","names":[]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/extractVariableKeys.ts","../src/getMissingVariableKeys.ts","../src/interpolateToString.ts"],"sourcesContent":["/** @public */\nexport const VARIABLE_TYPE_PREFIX = 'pteInterpolationVariable'\n","import {VARIABLE_TYPE_PREFIX} from './constants'\nimport type {PortableTextBlockLike} from './types'\n\n/** @public */\nexport function extractVariableKeys(blocks: PortableTextBlockLike[]): string[] {\n const seen = new Set<string>()\n\n return blocks.reduce<string[]>((keys, block) => {\n const children = block.children ?? []\n\n return children.reduce((accumulated, child) => {\n if (child._type !== VARIABLE_TYPE_PREFIX) return accumulated\n\n const variableKey = child.variableKey\n if (typeof variableKey !== 'string') return accumulated\n if (seen.has(variableKey)) return accumulated\n\n seen.add(variableKey)\n return [...accumulated, variableKey]\n }, keys)\n }, [])\n}\n","import {extractVariableKeys} from './extractVariableKeys'\nimport type {InterpolationValues, PortableTextBlockLike} from './types'\n\n/** @public */\nexport function getMissingVariableKeys(\n blocks: PortableTextBlockLike[],\n values: InterpolationValues,\n): string[] {\n return extractVariableKeys(blocks).filter((key) => values[key] === undefined)\n}\n","import {VARIABLE_TYPE_PREFIX} from './constants'\nimport type {InterpolationFallback, InterpolationValues, PortableTextBlockLike} from './types'\n\nfunction defaultFallback(variableKey: string): string {\n return `{${variableKey}}`\n}\n\n/** @public */\nexport function interpolateToString(\n blocks: PortableTextBlockLike[],\n values: InterpolationValues,\n fallback: InterpolationFallback = defaultFallback,\n): string {\n return blocks\n .map((block) => {\n const children = block.children ?? []\n\n return children\n .map((child) => {\n if (child._type === VARIABLE_TYPE_PREFIX) {\n const variableKey = child.variableKey\n if (typeof variableKey === 'string') {\n return values[variableKey] !== undefined ? values[variableKey] : fallback(variableKey)\n }\n return ''\n }\n\n return typeof child.text === 'string' ? child.text : ''\n })\n .join('')\n })\n .join('\\n')\n}\n"],"mappings":";AACO,IAAM,uBAAuB;;;ACG7B,SAAS,oBAAoB,QAA2C;AAC7E,QAAM,OAAO,oBAAI,IAAY;AAE7B,SAAO,OAAO,OAAiB,CAAC,MAAM,UAAU;AAC9C,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO,SAAS,OAAO,CAAC,aAAa,UAAU;AAC7C,UAAI,MAAM,UAAU,qBAAsB,QAAO;AAEjD,YAAM,cAAc,MAAM;AAC1B,UAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,UAAI,KAAK,IAAI,WAAW,EAAG,QAAO;AAElC,WAAK,IAAI,WAAW;AACpB,aAAO,CAAC,GAAG,aAAa,WAAW;AAAA,IACrC,GAAG,IAAI;AAAA,EACT,GAAG,CAAC,CAAC;AACP;;;ACjBO,SAAS,uBACd,QACA,QACU;AACV,SAAO,oBAAoB,MAAM,EAAE,OAAO,CAAC,QAAQ,OAAO,GAAG,MAAM,MAAS;AAC9E;;;ACNA,SAAS,gBAAgB,aAA6B;AACpD,SAAO,IAAI,WAAW;AACxB;AAGO,SAAS,oBACd,QACA,QACA,WAAkC,iBAC1B;AACR,SAAO,OACJ,IAAI,CAAC,UAAU;AACd,UAAM,WAAW,MAAM,YAAY,CAAC;AAEpC,WAAO,SACJ,IAAI,CAAC,UAAU;AACd,UAAI,MAAM,UAAU,sBAAsB;AACxC,cAAM,cAAc,MAAM;AAC1B,YAAI,OAAO,gBAAgB,UAAU;AACnC,iBAAO,OAAO,WAAW,MAAM,SAAY,OAAO,WAAW,IAAI,SAAS,WAAW;AAAA,QACvF;AACA,eAAO;AAAA,MACT;AAEA,aAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAAA,IACvD,CAAC,EACA,KAAK,EAAE;AAAA,EACZ,CAAC,EACA,KAAK,IAAI;AACd;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pte-interpolation-core",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Framework-agnostic utilities for Portable Text variable interpolation",
@@ -81,6 +81,14 @@ export const duplicateVariableBlock: PortableTextBlockLike[] = [
81
81
 
82
82
  export const blockWithNoChildren: PortableTextBlockLike[] = [{_type: 'block', _key: 'block-1'}]
83
83
 
84
+ export const blockWithMissingVariableKey: PortableTextBlockLike[] = [
85
+ {
86
+ _type: 'block',
87
+ _key: 'block-1',
88
+ children: [{_type: 'pteInterpolationVariable', _key: 'var-1'}],
89
+ },
90
+ ]
91
+
84
92
  export const blockWithNonStringVariableKey: PortableTextBlockLike[] = [
85
93
  {
86
94
  _type: 'block',
@@ -22,14 +22,14 @@ describe('getMissingVariableKeys', () => {
22
22
  })
23
23
 
24
24
  it('returns empty array when all variables provided', () => {
25
- expect(getMissingVariableKeys(singleVariableBlock, {firstName: 'Alice'})).toEqual([])
25
+ expect(getMissingVariableKeys(singleVariableBlock, {firstName: 'Patrick'})).toEqual([])
26
26
  })
27
27
 
28
28
  it('returns empty array when all multiple variables provided', () => {
29
29
  expect(
30
30
  getMissingVariableKeys(multipleVariablesBlock, {
31
- firstName: 'Alice',
32
- lastName: 'Smith',
31
+ firstName: 'Patrick',
32
+ lastName: 'Pickles',
33
33
  email: 'a@b.com',
34
34
  }),
35
35
  ).toEqual([])
@@ -40,7 +40,7 @@ describe('getMissingVariableKeys', () => {
40
40
  })
41
41
 
42
42
  it('returns only missing keys when some values provided', () => {
43
- expect(getMissingVariableKeys(multipleVariablesBlock, {firstName: 'Alice'})).toEqual([
43
+ expect(getMissingVariableKeys(multipleVariablesBlock, {firstName: 'Patrick'})).toEqual([
44
44
  'lastName',
45
45
  'email',
46
46
  ])
@@ -51,7 +51,7 @@ describe('getMissingVariableKeys', () => {
51
51
  })
52
52
 
53
53
  it('returns missing keys across multiple blocks', () => {
54
- expect(getMissingVariableKeys(multiBlockContent, {firstName: 'Alice'})).toEqual(['email'])
54
+ expect(getMissingVariableKeys(multiBlockContent, {firstName: 'Patrick'})).toEqual(['email'])
55
55
  })
56
56
 
57
57
  it('deduplicates missing keys', () => {
@@ -67,14 +67,14 @@ describe('getMissingVariableKeys', () => {
67
67
  })
68
68
 
69
69
  it('returns missing keys for consecutive variables', () => {
70
- expect(getMissingVariableKeys(consecutiveVariablesBlock, {firstName: 'Alice'})).toEqual([
70
+ expect(getMissingVariableKeys(consecutiveVariablesBlock, {firstName: 'Patrick'})).toEqual([
71
71
  'lastName',
72
72
  ])
73
73
  })
74
74
 
75
75
  it('ignores extra values not in blocks', () => {
76
76
  expect(
77
- getMissingVariableKeys(singleVariableBlock, {firstName: 'Alice', extraKey: 'ignored'}),
77
+ getMissingVariableKeys(singleVariableBlock, {firstName: 'Patrick', extraKey: 'ignored'}),
78
78
  ).toEqual([])
79
79
  })
80
80
 
@@ -1,6 +1,8 @@
1
1
  import {describe, expect, it} from 'vitest'
2
2
  import {interpolateToString} from '../interpolateToString'
3
3
  import {
4
+ blockWithMissingVariableKey,
5
+ blockWithNonStringVariableKey,
4
6
  consecutiveVariablesBlock,
5
7
  emptyBlocksContent,
6
8
  multiBlockContent,
@@ -19,7 +21,7 @@ describe('interpolateToString', () => {
19
21
  })
20
22
 
21
23
  it('resolves a single variable from values', () => {
22
- expect(interpolateToString(singleVariableBlock, {firstName: 'Alice'})).toBe('Hello, Alice!')
24
+ expect(interpolateToString(singleVariableBlock, {firstName: 'Patrick'})).toBe('Hello, Patrick!')
23
25
  })
24
26
 
25
27
  it('uses default fallback for missing variables', () => {
@@ -37,23 +39,31 @@ describe('interpolateToString', () => {
37
39
 
38
40
  it('resolves consecutive variables', () => {
39
41
  expect(
40
- interpolateToString(consecutiveVariablesBlock, {firstName: 'Alice', lastName: 'Smith'}),
41
- ).toBe('AliceSmith')
42
+ interpolateToString(consecutiveVariablesBlock, {firstName: 'Patrick', lastName: 'Pickles'}),
43
+ ).toBe('PatrickPickles')
42
44
  })
43
45
 
44
46
  it('joins multiple blocks with newlines', () => {
45
47
  expect(
46
- interpolateToString(multiBlockContent, {firstName: 'Alice', email: 'alice@example.com'}),
47
- ).toBe('Dear Alice,\nYour email is alice@example.com.')
48
+ interpolateToString(multiBlockContent, {firstName: 'Patrick', email: 'patrick@example.com'}),
49
+ ).toBe('Dear Patrick,\nYour email is patrick@example.com.')
48
50
  })
49
51
 
50
52
  it('resolves multiple variables in one block', () => {
51
53
  expect(
52
54
  interpolateToString(multipleVariablesBlock, {
53
- firstName: 'Alice',
54
- lastName: 'Smith',
55
- email: 'alice@example.com',
55
+ firstName: 'Patrick',
56
+ lastName: 'Pickles',
57
+ email: 'patrick@example.com',
56
58
  }),
57
- ).toBe('Name: Alice Smith, Email: alice@example.com')
59
+ ).toBe('Name: Patrick Pickles, Email: patrick@example.com')
60
+ })
61
+
62
+ it('returns empty string for a variable block with a missing variableKey', () => {
63
+ expect(interpolateToString(blockWithMissingVariableKey, {})).toBe('')
64
+ })
65
+
66
+ it('returns empty string for a variable block with a non-string variableKey', () => {
67
+ expect(interpolateToString(blockWithNonStringVariableKey, {})).toBe('')
58
68
  })
59
69
  })
@@ -18,8 +18,11 @@ export function interpolateToString(
18
18
  return children
19
19
  .map((child) => {
20
20
  if (child._type === VARIABLE_TYPE_PREFIX) {
21
- const variableKey = child.variableKey as string
22
- return values[variableKey] !== undefined ? values[variableKey] : fallback(variableKey)
21
+ const variableKey = child.variableKey
22
+ if (typeof variableKey === 'string') {
23
+ return values[variableKey] !== undefined ? values[variableKey] : fallback(variableKey)
24
+ }
25
+ return ''
23
26
  }
24
27
 
25
28
  return typeof child.text === 'string' ? child.text : ''