@barefootjs/go-template 0.18.3 → 0.18.5

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.js CHANGED
@@ -42,10 +42,11 @@ import {
42
42
  collectModuleStringConsts as collectModuleStringConstsShared,
43
43
  prepareLoweringMatchers,
44
44
  envSignalReaderFor,
45
- computeSsrSeedPlan
45
+ computeSsrSeedPlan,
46
+ isStringConcatBinary
46
47
  } from "@barefootjs/jsx";
47
48
  import { findInterpolationEnd } from "@barefootjs/jsx/scanner";
48
- import { BF_REGION } from "@barefootjs/shared";
49
+ import { BF_REGION, escapeHtml } from "@barefootjs/shared";
49
50
 
50
51
  // src/adapter/lib/go-naming.ts
51
52
  var GO_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
@@ -332,6 +333,7 @@ var GO_TEMPLATE_PRIMITIVES = {
332
333
  "Math.floor": { arity: 1, emit: (args) => `bf_floor ${wrapGoArg(args[0])}` },
333
334
  "Math.ceil": { arity: 1, emit: (args) => `bf_ceil ${wrapGoArg(args[0])}` },
334
335
  "Math.round": { arity: 1, emit: (args) => `bf_round ${wrapGoArg(args[0])}` },
336
+ "Math.abs": { arity: 1, emit: (args) => `bf_abs ${wrapGoArg(args[0])}` },
335
337
  "Math.min": { arity: 2, emit: (args) => `bf_min ${wrapGoArg(args[0])} ${wrapGoArg(args[1])}` },
336
338
  "Math.max": { arity: 2, emit: (args) => `bf_max ${wrapGoArg(args[0])} ${wrapGoArg(args[1])}` }
337
339
  };
@@ -357,6 +359,7 @@ class CompileState {
357
359
  hoistedMemoLocals = new Map;
358
360
  loweringMatchers = [];
359
361
  nillablePropNames = new Set;
362
+ stringValueNames = new Set;
360
363
  rootScopeNodes = new Set;
361
364
  memoBackedLoopSlice = new Map;
362
365
  usesHtmlTemplate = false;
@@ -776,7 +779,7 @@ function typeInfoToGo(ctx, typeInfo, defaultValue) {
776
779
  case "string":
777
780
  return "string";
778
781
  case "number":
779
- return "int";
782
+ return defaultValue !== undefined ? numberPrimitiveGoType(defaultValue) : "int";
780
783
  case "boolean":
781
784
  return "bool";
782
785
  default:
@@ -827,6 +830,9 @@ function tsTypeStringToGo(ctx, tsType) {
827
830
  return t;
828
831
  return "interface{}";
829
832
  }
833
+ function numberPrimitiveGoType(value) {
834
+ return /^-?\d+\.\d+$/.test(value) ? "float64" : "int";
835
+ }
830
836
  function inferTypeFromValue(value) {
831
837
  if (value === "true" || value === "false")
832
838
  return "bool";
@@ -939,9 +945,9 @@ function convertInitialValue(ctx, value, typeInfo, propsParams, preParsed) {
939
945
  return value === "true" ? "true" : "false";
940
946
  }
941
947
  if (typeInfo.primitive === "number") {
942
- if (/^\d+$/.test(value))
948
+ if (/^-?\d+$/.test(value))
943
949
  return value;
944
- if (/^\d+\.\d+$/.test(value))
950
+ if (/^-?\d+\.\d+$/.test(value))
945
951
  return value;
946
952
  return "0";
947
953
  }
@@ -966,6 +972,12 @@ function convertInitialValue(ctx, value, typeInfo, propsParams, preParsed) {
966
972
  }
967
973
  return '""';
968
974
  }
975
+ if (ctx.state.localStructFields.has(typeInfo.raw)) {
976
+ const baked = jsLiteralToGo(ctx, typeInfo, preParsed);
977
+ if (baked !== null)
978
+ return baked;
979
+ return `${typeInfo.raw}{}`;
980
+ }
969
981
  }
970
982
  return "nil";
971
983
  }
@@ -1656,10 +1668,11 @@ function memoInitialFromParsedBody(ctx, body, signals, propsParams, propFallback
1656
1668
  const operand = String(body.right.value);
1657
1669
  const depName = getterCallName(body.left);
1658
1670
  if (depName) {
1659
- const signal = signals.find((s) => s.getter === depName);
1660
- if (signal) {
1661
- const signalInitial = getSignalInitialValueAsGo(ctx, signal.initialValue, propsParams, propFallbackVars);
1662
- return `${signalInitial} ${operator} ${operand}`;
1671
+ const depInitial = resolveGetterValueAsGo(ctx, depName, signals, propsParams, propFallbackVars, resolving);
1672
+ const isArithmeticSafe = depInitial !== null && !depInitial.startsWith("func(");
1673
+ if (isArithmeticSafe) {
1674
+ const wrapped = /\s/.test(depInitial) ? `(${depInitial})` : depInitial;
1675
+ return `${wrapped} ${operator} ${operand}`;
1663
1676
  }
1664
1677
  }
1665
1678
  const propName = propsMemberName(body.left);
@@ -1694,9 +1707,9 @@ function memoInitialFromParsedBody(ctx, body, signals, propsParams, propFallback
1694
1707
  }
1695
1708
  const simpleDep = getterCallName(body);
1696
1709
  if (simpleDep) {
1697
- const signal = signals.find((s) => s.getter === simpleDep);
1698
- if (signal) {
1699
- return getSignalInitialValueAsGo(ctx, signal.initialValue, propsParams, propFallbackVars);
1710
+ const depInitial = resolveGetterValueAsGo(ctx, simpleDep, signals, propsParams, propFallbackVars, resolving);
1711
+ if (depInitial !== null) {
1712
+ return depInitial;
1700
1713
  }
1701
1714
  }
1702
1715
  const simpleProp = propsMemberName(body);
@@ -2087,8 +2100,47 @@ function buildPropTypeOverrides(ctx, ir) {
2087
2100
  }
2088
2101
  }
2089
2102
  }
2103
+ for (const propName of collectToFixedPropNames(ir.root)) {
2104
+ const param = ir.metadata.propsParams.find((p) => p.name === propName);
2105
+ if (!param)
2106
+ continue;
2107
+ const resolved = overrides.get(propName) ?? typeInfoToGo(ctx, param.type, param.defaultValue);
2108
+ if (resolved === "int") {
2109
+ overrides.set(propName, "float64");
2110
+ }
2111
+ }
2090
2112
  return overrides;
2091
2113
  }
2114
+ function collectToFixedPropNames(root) {
2115
+ const names = new Set;
2116
+ const checkExpr = (expr) => {
2117
+ if (expr?.kind === "array-method" && expr.method === "toFixed" && expr.object.kind === "identifier") {
2118
+ names.add(expr.object.name);
2119
+ }
2120
+ };
2121
+ const walk = (node) => {
2122
+ if (!node)
2123
+ return;
2124
+ if (node.type === "expression")
2125
+ checkExpr(node.parsed);
2126
+ if (node.type === "conditional") {
2127
+ checkExpr(node.parsedCondition);
2128
+ walk(node.whenTrue);
2129
+ walk(node.whenFalse);
2130
+ }
2131
+ if (node.type === "element") {
2132
+ for (const attr of node.attrs) {
2133
+ if (attr.value.kind === "expression")
2134
+ checkExpr(attr.value.parsed);
2135
+ }
2136
+ }
2137
+ if ("children" in node && Array.isArray(node.children)) {
2138
+ node.children.forEach(walk);
2139
+ }
2140
+ };
2141
+ walk(root);
2142
+ return names;
2143
+ }
2092
2144
  function resolvePropGoType(ctx, param, propTypeOverrides) {
2093
2145
  const base = propTypeOverrides.get(param.name) ?? typeInfoToGo(ctx, param.type, param.defaultValue);
2094
2146
  if (param.optional && ctx.state.localStructFields.has(base)) {
@@ -2107,6 +2159,30 @@ function collectNillablePropNames(ctx, ir) {
2107
2159
  return nillable;
2108
2160
  }
2109
2161
 
2162
+ // src/adapter/props/prop-classes.ts
2163
+ function isStringTypeInfo(type) {
2164
+ return type.kind === "primitive" && type.primitive === "string";
2165
+ }
2166
+ function isBareStringLiteral(initialValue) {
2167
+ if (!initialValue)
2168
+ return false;
2169
+ const v = initialValue.trim();
2170
+ return v.startsWith("'") && v.endsWith("'") || v.startsWith('"') && v.endsWith('"');
2171
+ }
2172
+ function collectStringValueNames(ir) {
2173
+ const names = new Set;
2174
+ for (const s of ir.metadata.signals) {
2175
+ if (isStringTypeInfo(s.type) || isBareStringLiteral(s.initialValue)) {
2176
+ names.add(s.getter);
2177
+ }
2178
+ }
2179
+ for (const p of ir.metadata.propsParams) {
2180
+ if (isStringTypeInfo(p.type))
2181
+ names.add(p.name);
2182
+ }
2183
+ return names;
2184
+ }
2185
+
2110
2186
  // src/adapter/go-template-adapter.ts
2111
2187
  var STRING_METHODS = new Set([
2112
2188
  "replace",
@@ -2149,6 +2225,7 @@ class GoTemplateAdapter extends BaseAdapter {
2149
2225
  }
2150
2226
  inLoop = false;
2151
2227
  loopParamStack = [];
2228
+ loopKeyDepthStack = [];
2152
2229
  loopScalarItemStack = [];
2153
2230
  loopWrapperStack = [];
2154
2231
  loopVarRefCount = new Map;
@@ -2196,6 +2273,7 @@ class GoTemplateAdapter extends BaseAdapter {
2196
2273
  this.state.pendingChildrenDefines = [];
2197
2274
  this.primeCompileState(ir);
2198
2275
  this.state.nillablePropNames = collectNillablePropNames(this.emitCtx, ir);
2276
+ this.state.stringValueNames = collectStringValueNames(ir);
2199
2277
  if (!options?.siblingTemplatesRegistered) {
2200
2278
  this.checkImportedLoopChildComponents(ir);
2201
2279
  }
@@ -2893,6 +2971,13 @@ ${goFields.join(`
2893
2971
  break;
2894
2972
  }
2895
2973
  }
2974
+ if (parsedValue) {
2975
+ const goVal = parsedLiteralToGo(this.emitCtx, parsedValue);
2976
+ if (goVal !== null) {
2977
+ emitChildField(prop.name, goVal);
2978
+ break;
2979
+ }
2980
+ }
2896
2981
  const resolvedValue = this.resolveDynamicPropValue(exprText, ir.metadata.signals, ir.metadata.memos, ir.metadata.propsParams);
2897
2982
  if (resolvedValue !== null) {
2898
2983
  emitChildField(prop.name, resolvedValue);
@@ -2900,6 +2985,24 @@ ${goFields.join(`
2900
2985
  break;
2901
2986
  }
2902
2987
  case "jsx-children":
2988
+ if (prop.name !== "children") {
2989
+ const text = this.extractTextChildren(prop.value.children);
2990
+ if (text !== null) {
2991
+ emitChildField(prop.name, JSON.stringify(text));
2992
+ } else {
2993
+ const html = this.extractHtmlChildren(prop.value.children);
2994
+ if (html !== null) {
2995
+ this.state.usesHtmlTemplate = true;
2996
+ emitChildField(prop.name, `template.HTML(${JSON.stringify(html)})`);
2997
+ } else {
2998
+ const scopedHtml = this.extractScopedHtmlChildren(prop.value.children);
2999
+ if (scopedHtml !== null) {
3000
+ this.state.usesHtmlTemplate = true;
3001
+ emitChildField(prop.name, `template.HTML(${scopedHtml})`);
3002
+ }
3003
+ }
3004
+ }
3005
+ }
2903
3006
  break;
2904
3007
  }
2905
3008
  }
@@ -3541,6 +3644,17 @@ ${goFields.join(`
3541
3644
  return computeMemoInitialValueOrNull(this.emitCtx, memo, signals, propsParams, undefined, new Set([memo.name]));
3542
3645
  }
3543
3646
  }
3647
+ const propsObjectName = this.state.propsObjectName;
3648
+ const identifierPattern = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
3649
+ const bareIdentifier = identifierPattern.test(expr) ? expr : null;
3650
+ const barePropAccess = propsObjectName && expr.startsWith(`${propsObjectName}.`) && identifierPattern.test(expr.slice(propsObjectName.length + 1)) ? expr.slice(propsObjectName.length + 1) : null;
3651
+ const passthroughName = bareIdentifier ?? barePropAccess;
3652
+ const localConst = this.state.localConstants.find((c) => c.name === passthroughName);
3653
+ const isPropsDestructureAlias = localConst !== undefined && propsObjectName !== null && localConst.value === `${propsObjectName}.${passthroughName}`;
3654
+ const shadowedByLocal = passthroughName !== null && (localConst !== undefined && !isPropsDestructureAlias || this.state.localHelperNames.has(passthroughName));
3655
+ if (passthroughName && !shadowedByLocal && propsParams.some((p) => p.name === passthroughName)) {
3656
+ return `in.${capitalizeFieldName(passthroughName)}`;
3657
+ }
3544
3658
  return null;
3545
3659
  }
3546
3660
  inferMemoType(memo, signals, propsParamMap) {
@@ -3665,7 +3779,7 @@ ${goFields.join(`
3665
3779
  return this.renderElement(node);
3666
3780
  }
3667
3781
  emitText(node) {
3668
- return node.value;
3782
+ return escapeHtml(node.value);
3669
3783
  }
3670
3784
  emitExpression(node) {
3671
3785
  return this.renderExpression(node);
@@ -3925,7 +4039,7 @@ ${goFields.join(`
3925
4039
  const argsStr = args.map(emit).join(" ");
3926
4040
  return `${calleeStr} ${argsStr}`;
3927
4041
  }
3928
- member(object, property, _computed, emit) {
4042
+ member(object, property, _computed, optional, emit) {
3929
4043
  const objHO = this.higherOrderShapeOf(object);
3930
4044
  if (property === "length" && objHO) {
3931
4045
  const result = this.renderFilterLengthExpr(objHO, emit);
@@ -3967,6 +4081,9 @@ ${goFields.join(`
3967
4081
  const obj = emit(object);
3968
4082
  if (property === "length")
3969
4083
  return `len ${obj}`;
4084
+ if (optional) {
4085
+ return `bf_get ${wrapIfMultiToken(obj)} ${JSON.stringify(goFieldNameForKey(property))}`;
4086
+ }
3970
4087
  return `${obj}.${goFieldNameForKey(property)}`;
3971
4088
  }
3972
4089
  indexAccess(object, index, emit) {
@@ -3997,7 +4114,7 @@ ${goFields.join(`
3997
4114
  case "<=":
3998
4115
  return `le ${wl} ${wr}`;
3999
4116
  case "+":
4000
- return `bf_add ${wl} ${wr}`;
4117
+ return this._emitPlus(left, right, wl, wr);
4001
4118
  case "-":
4002
4119
  return `bf_sub ${wl} ${wr}`;
4003
4120
  case "*":
@@ -4010,6 +4127,15 @@ ${goFields.join(`
4010
4127
  return `${l} ${op} ${r}`;
4011
4128
  }
4012
4129
  }
4130
+ _emitPlus(leftExpr, rightExpr, leftRendered, rightRendered) {
4131
+ if (isStringConcatBinary("+", leftExpr, rightExpr, (n) => this._isStringValueName(n))) {
4132
+ return `bf_concat_str ${leftRendered} ${rightRendered}`;
4133
+ }
4134
+ return `bf_add ${leftRendered} ${rightRendered}`;
4135
+ }
4136
+ _isStringValueName(name) {
4137
+ return this.state.stringValueNames.has(name);
4138
+ }
4013
4139
  unary(op, argument, emit) {
4014
4140
  const arg = emit(argument);
4015
4141
  if (op === "!")
@@ -4221,6 +4347,12 @@ ${goFields.join(`
4221
4347
  const recv = emit(object);
4222
4348
  return `bf_trim ${wrapIfMultiToken(recv)}`;
4223
4349
  }
4350
+ case "trimStart":
4351
+ case "trimEnd": {
4352
+ const fn = method === "trimStart" ? "bf_trim_start" : "bf_trim_end";
4353
+ const recv = emit(object);
4354
+ return `${fn} ${wrapIfMultiToken(recv)}`;
4355
+ }
4224
4356
  case "toFixed": {
4225
4357
  const recv = emit(object);
4226
4358
  const digits = args.length >= 1 ? emit(args[0]) : "0";
@@ -4255,6 +4387,12 @@ ${goFields.join(`
4255
4387
  const newS = emit(args[1]);
4256
4388
  return `bf_replace ${wrapIfMultiToken(recv)} ${wrapIfMultiToken(oldS)} ${wrapIfMultiToken(newS)}`;
4257
4389
  }
4390
+ case "replaceAll": {
4391
+ const recv = emit(object);
4392
+ const oldS = emit(args[0]);
4393
+ const newS = emit(args[1]);
4394
+ return `bf_replace_all ${wrapIfMultiToken(recv)} ${wrapIfMultiToken(oldS)} ${wrapIfMultiToken(newS)}`;
4395
+ }
4258
4396
  case "repeat": {
4259
4397
  const recv = emit(object);
4260
4398
  const count = args.length === 0 ? "0" : emit(args[0]);
@@ -4561,7 +4699,7 @@ ${goFields.join(`
4561
4699
  case "<=":
4562
4700
  return `le ${left} ${right}`;
4563
4701
  case "+":
4564
- return `bf_add ${left} ${right}`;
4702
+ return this._emitPlus(expr.left, expr.right, left, right);
4565
4703
  case "-":
4566
4704
  return `bf_sub ${left} ${right}`;
4567
4705
  case "*":
@@ -4930,7 +5068,7 @@ ${goFields.join(`
4930
5068
  result = `le ${left} ${right}`;
4931
5069
  break;
4932
5070
  case "+":
4933
- result = `bf_add ${left} ${right}`;
5071
+ result = this._emitPlus(expr.left, expr.right, left, right);
4934
5072
  break;
4935
5073
  case "-":
4936
5074
  result = `bf_sub ${left} ${right}`;
@@ -5087,7 +5225,9 @@ ${goFields.join(`
5087
5225
  }
5088
5226
  this.loopScalarItemStack.push(this.scalarLiteralLoopGoType(loop.arrayParsed, loop.itemType) !== null);
5089
5227
  this.loopWrapperStack.push(!!loop.childComponent);
5228
+ this.loopKeyDepthStack.push(loop.depth);
5090
5229
  const children = this.renderChildren(loop.children);
5230
+ this.loopKeyDepthStack.pop();
5091
5231
  this.loopWrapperStack.pop();
5092
5232
  this.loopScalarItemStack.pop();
5093
5233
  const itemMarker = this.loopItemMarker(loop);
@@ -5230,7 +5370,7 @@ ${goFields.join(`
5230
5370
  ${children}`;
5231
5371
  }
5232
5372
  elementAttrEmitter = {
5233
- emitLiteral: (value, name) => `${name}="${value.value}"`,
5373
+ emitLiteral: (value, name) => `${name}="${escapeHtml(value.value)}"`,
5234
5374
  emitExpression: (value, name) => {
5235
5375
  if (name === "style") {
5236
5376
  const css = this.tryLowerStyleObject(value.expr);
@@ -5320,9 +5460,10 @@ ${children}`;
5320
5460
  let attrName;
5321
5461
  if (attr.name === "className")
5322
5462
  attrName = "class";
5323
- else if (attr.name === "key")
5324
- attrName = "data-key";
5325
- else
5463
+ else if (attr.name === "key") {
5464
+ const depth = this.loopKeyDepthStack.at(-1) ?? 0;
5465
+ attrName = depth > 0 ? `data-key-${depth}` : "data-key";
5466
+ } else
5326
5467
  attrName = attr.name;
5327
5468
  const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName);
5328
5469
  if (lowered)
@@ -5437,30 +5578,10 @@ var conformancePins = {
5437
5578
  { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2038" }
5438
5579
  ],
5439
5580
  "array-map-function-reference": [{ code: "BF101", severity: "error" }],
5440
- "dangerous-inner-html": [{ code: "BF101", severity: "error" }],
5441
- "string-replaceall": [{ code: "BF101", severity: "error" }]
5581
+ "dangerous-inner-html": [{ code: "BF101", severity: "error" }]
5442
5582
  };
5443
5583
  // src/render-divergences.ts
5444
- var renderDivergences = {
5445
- "html-entity-text": "`&copy;` in JSX literal text: Hono decodes to `©`, this adapter re-emits the raw entity — same DOM, different bytes",
5446
- "string-concat-plus": "`'Hello, ' + name` renders \"0\" — JS string-concat `+` lowered through numeric addition",
5447
- "optional-chaining-prop": "`user?.name ?? …` on an object prop: generated Go fails to run (exit 1) — optional chaining into a struct/map prop has no lowering",
5448
- "number-tofixed": "`.toFixed(2)` on a number PROP: generated Go fails to run (exit 1)",
5449
- "math-methods": "Math.min/max/abs over a signal: generated Go fails to run (exit 1) — only Math.floor is registered",
5450
- "boolean-attr-literals": 'camelCase boolean alias `readOnly`: Hono SSRs `readOnly="true"`, this adapter emits bare presence',
5451
- "camelcase-attributes": "`htmlFor` is not lowered to `for` (Hono maps it)",
5452
- "static-attr-escape": 'static attribute values are not HTML-escaped (`title="Fish & Chips"` emitted raw; Hono escapes)',
5453
- "svg-icon": "SVG camelCase presentation attrs (`strokeWidth`, `strokeLinecap`) pass through unmapped; Hono lowers to kebab-case",
5454
- "object-entries-map": "`Object.entries(prop).map(([k, v]) => …)`: generated Go fails to run (exit 1) — no object-iteration loop lowering",
5455
- "nested-loop-outer-binding": "nested-loop inner items carry `data-key` where the reference emits the depth-suffixed `data-key-1`",
5456
- "jsx-element-prop": "a JSX element passed as a NON-children prop renders an empty slot — the element value is silently dropped",
5457
- "grandchild-composition": "three-level composition: the grandchild's threaded prop renders EMPTY — prop forwarding through two template-render layers loses the value",
5458
- "child-primitive-props": "numeric/boolean LITERAL props on a child (`count={5}` `active={true}`) render as Go zero values (0 / false)",
5459
- "memo-chain": "a memo derived from another memo renders EMPTY for the second layer — the constructor folds only one derivation level",
5460
- "signal-object-field": "object-valued signal (`user().name`): generated Go fails to run (exit 1) — no struct synthesis outside loops",
5461
- "string-slice": '`.slice()` on a STRING routes through the array `bf_slice` helper and renders "[]" instead of the substring',
5462
- "string-trim-sided": "`.trimStart()` / `.trimEnd()`: generated Go fails to run (exit 1) — only both-sides `bf_trim` exists"
5463
- };
5584
+ var renderDivergences = {};
5464
5585
  export {
5465
5586
  renderDivergences,
5466
5587
  goTemplateAdapter,
@@ -1 +1 @@
1
- {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAqC/B,CAAA"}
1
+ {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAC/B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/go-template",
3
- "version": "0.18.3",
3
+ "version": "0.18.5",
4
4
  "description": "Go html/template adapter for BarefootJS - generates Go template files from IR",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -49,7 +49,7 @@
49
49
  "directory": "packages/adapter-go-template"
50
50
  },
51
51
  "dependencies": {
52
- "@barefootjs/shared": "0.18.3"
52
+ "@barefootjs/shared": "0.18.5"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@barefootjs/jsx": ">=0.2.0",
@@ -57,6 +57,6 @@
57
57
  },
58
58
  "devDependencies": {
59
59
  "@barefootjs/adapter-tests": "0.1.0",
60
- "@barefootjs/jsx": "0.18.3"
60
+ "@barefootjs/jsx": "0.18.5"
61
61
  }
62
62
  }
@@ -2286,7 +2286,7 @@ export function Tagged(props: { className?: string }) {
2286
2286
  // list rather than replace.
2287
2287
  const a = new GoTemplateAdapter()
2288
2288
  const keys = Object.keys(a.templatePrimitives ?? {}).sort()
2289
- expect(keys).toEqual(['JSON.stringify', 'Math.ceil', 'Math.floor', 'Math.max', 'Math.min', 'Math.round', 'Number', 'String'])
2289
+ expect(keys).toEqual(['JSON.stringify', 'Math.abs', 'Math.ceil', 'Math.floor', 'Math.max', 'Math.min', 'Math.round', 'Number', 'String'])
2290
2290
  })
2291
2291
 
2292
2292
  test('unregistered identifier-path callee is NOT accepted by the registry', () => {