@barefootjs/go-template 0.33.6 → 0.34.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.
@@ -6,7 +6,7 @@
6
6
  * `renderLoweringNode`, which maps a logical helper id to its Go helper; the
7
7
  * adapter carries no per-API recognition branch of its own.
8
8
  */
9
- import { type ParsedExpr } from '@barefootjs/jsx';
9
+ import { type LoweringNode, type ParsedExpr } from '@barefootjs/jsx';
10
10
  import type { GoEmitContext } from '../emit-context.ts';
11
11
  /**
12
12
  * Lower a `conditional` (ternary) ParsedExpr to the pipeline-position
@@ -28,6 +28,24 @@ import type { GoEmitContext } from '../emit-context.ts';
28
28
  * branches are arbitrary markup, not values.
29
29
  */
30
30
  export declare function lowerTernary(ctx: GoEmitContext, test: ParsedExpr, consequent: ParsedExpr, alternate: ParsedExpr): string;
31
+ /**
32
+ * First registered matcher that recognises `callee(args)`, or null (#2842).
33
+ * The single registry consultation every Go lowering path shares: the
34
+ * top-level `lowerRegisteredCall` early return, the ParsedExpr `call()`
35
+ * dispatcher (`go-template-adapter.ts`, so a registered call is recognised no
36
+ * matter how deep it sits in an expression tree — a ternary branch, a
37
+ * template-literal interpolation, a binary operand — not only when the call
38
+ * IS the whole expression), and the attribute-position `bf_attr` route all
39
+ * ask this one question. First-match-wins: a malformed helper id from one
40
+ * plugin must not be silently masked by falling through to another.
41
+ */
42
+ export declare function matchRegisteredCall(ctx: GoEmitContext, callee: ParsedExpr, args: readonly ParsedExpr[]): LoweringNode | null;
43
+ /**
44
+ * Render a recognised call's neutral node to its Go pipeline (unparenthesised
45
+ * — same contract as `lowerRegisteredCall`), or null when no plugin matches
46
+ * or the matched helper has no Go mapping.
47
+ */
48
+ export declare function lowerRegisteredCallNode(ctx: GoEmitContext, callee: ParsedExpr, args: readonly ParsedExpr[]): string | null;
31
49
  /**
32
50
  * Lower a helper call to a Go template expression, or null when no registered
33
51
  * plugin recognises it (→ the generic lowering). Matchers — including the
@@ -40,4 +58,38 @@ export declare function lowerTernary(ctx: GoEmitContext, test: ParsedExpr, conse
40
58
  * never pay for `parseExpression`.
41
59
  */
42
60
  export declare function lowerRegisteredCall(ctx: GoEmitContext, jsExpr: string, preParsed?: ParsedExpr): string | null;
61
+ /**
62
+ * Attribute-position twin of `lowerRegisteredCall` (#2743). When an intrinsic
63
+ * element attribute's value is a `query` guard-list (the neutral node the
64
+ * `queryHref` plugin — or any plugin reusing the `query` helper — produces),
65
+ * emit the WHOLE attribute as one `bf_attr` action returning
66
+ * `template.HTMLAttr`, instead of `name="{{bf_query …}}"`. html/template
67
+ * infers a URL context from the attribute NAME (`href`, `src`, `action`,
68
+ * `data-*`, anything containing `src`/`uri`/`url`, …) and percent-encodes the
69
+ * entire value there; the JS reference (Hono) only HTML-escapes. Keyed on the
70
+ * neutral `helper` id, not the attribute name (Go's URL-context table is a
71
+ * heuristic we must not re-implement) and not the JS API name. Returns null
72
+ * for a non-call, an unmatched call, or any other node kind/helper — the
73
+ * caller then takes its ordinary path.
74
+ *
75
+ * Also accepts a `conditional` node directly (#2743 follow-up, pullfrog
76
+ * review on #2841): a ternary with a real, non-`undefined` alternate
77
+ * (`cond ? queryHref(...) : '/fallback'`) is syntactically valid and already
78
+ * lowers its branches correctly via `lowerTernary` — but the CALLER used to
79
+ * still wrap the resulting `(bf_ternary …)` pipeline in the ordinary
80
+ * `name="{{...}}"` form, which leaves it exposed to the same URL-context
81
+ * percent-encoding this function exists to route around. Whenever EITHER
82
+ * branch (recursing through a right-folded nested ternary chain, the same
83
+ * shape `lowerTernary` itself right-folds) is a `query` guard-list call, the
84
+ * whole ternary is wrapped in `bf_attr` too — matching the reference, which
85
+ * HTML-escapes the picked branch's value the same way regardless of which
86
+ * branch won.
87
+ *
88
+ * The caller passes the CONSEQUENT ALONE (not the full ternary) for the
89
+ * `undefined`-alternate omission shape (`cond ? queryHref(...) : undefined`,
90
+ * #2842) — omission needs the `{{if}}` wrapper that shape's caller already
91
+ * builds; a `bf_ternary … ""` inside `bf_attr` can't express it (`Attr`
92
+ * renders `name=""` for an empty value, not attribute absence).
93
+ */
94
+ export declare function lowerRegisteredAttrCall(ctx: GoEmitContext, attrName: string, parsed: ParsedExpr): string | null;
43
95
  //# sourceMappingURL=url-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-builder.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/url-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,UAAU,EAIhB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAkDvD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,UAAU,GACpB,MAAM,CAGR;AAoCD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,UAAU,GACrB,MAAM,GAAG,IAAI,CAmBf"}
1
+ {"version":3,"file":"url-builder.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/url-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,UAAU,EAIhB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAkDvD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,UAAU,GACpB,MAAM,CAGR;AAoCD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,SAAS,UAAU,EAAE,GAC1B,YAAY,GAAG,IAAI,CAMrB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,SAAS,UAAU,EAAE,GAC1B,MAAM,GAAG,IAAI,CAIf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,UAAU,GACrB,MAAM,GAAG,IAAI,CAYf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,GACjB,MAAM,GAAG,IAAI,CAcf"}
@@ -1 +1 @@
1
- {"version":3,"file":"go-template-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/go-template-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"go-template-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/go-template-adapter.ts"],"names":[],"mappings":"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"}
@@ -889,9 +889,22 @@ function lowerTernaryTest(ctx, test) {
889
889
  const isBoolShape = test.kind === "binary" && BOOL_COMPARISON_OPS.has(test.op) || test.kind === "unary" && test.op === "!" || test.kind === "literal" && test.literalType === "boolean";
890
890
  return isBoolShape ? go : `(bf_truthy ${go})`;
891
891
  }
892
+ function matchRegisteredCall(ctx, callee, args) {
893
+ for (const matcher of ctx.state.loweringMatchers) {
894
+ const node = matcher(callee, args);
895
+ if (node)
896
+ return node;
897
+ }
898
+ return null;
899
+ }
900
+ function lowerRegisteredCallNode(ctx, callee, args) {
901
+ if (ctx.state.loweringMatchers.length === 0)
902
+ return null;
903
+ const node = matchRegisteredCall(ctx, callee, args);
904
+ return node ? renderLoweringNode(ctx, node) : null;
905
+ }
892
906
  function lowerRegisteredCall(ctx, jsExpr, preParsed) {
893
- const matchers = ctx.state.loweringMatchers;
894
- if (matchers.length === 0)
907
+ if (ctx.state.loweringMatchers.length === 0)
895
908
  return null;
896
909
  let call = preParsed?.kind === "call" ? preParsed : undefined;
897
910
  if (!call) {
@@ -902,15 +915,32 @@ function lowerRegisteredCall(ctx, jsExpr, preParsed) {
902
915
  return null;
903
916
  call = parsed;
904
917
  }
905
- for (const matcher of matchers) {
906
- const node = matcher(call.callee, call.args);
907
- if (!node)
908
- continue;
909
- const rendered = renderLoweringNode(ctx, node);
910
- if (rendered !== null)
911
- return rendered;
918
+ return lowerRegisteredCallNode(ctx, call.callee, call.args);
919
+ }
920
+ function lowerRegisteredAttrCall(ctx, attrName, parsed) {
921
+ if (parsed.kind === "conditional") {
922
+ if (!ternaryHasQueryBranch(ctx, parsed.consequent, parsed.alternate))
923
+ return null;
924
+ const rendered2 = lowerTernary(ctx, parsed.test, parsed.consequent, parsed.alternate);
925
+ return `{{bf_attr ${JSON.stringify(attrName)} ${rendered2}}}`;
912
926
  }
913
- return null;
927
+ if (parsed.kind !== "call")
928
+ return null;
929
+ const node = matchRegisteredCall(ctx, parsed.callee, parsed.args);
930
+ if (!node || node.kind !== "guard-list" || node.helper !== "query")
931
+ return null;
932
+ const rendered = renderLoweringNode(ctx, node);
933
+ return rendered === null ? null : `{{bf_attr ${JSON.stringify(attrName)} (${rendered})}}`;
934
+ }
935
+ function isQueryGuardListCall(ctx, node) {
936
+ if (node.kind !== "call")
937
+ return false;
938
+ const lowered = matchRegisteredCall(ctx, node.callee, node.args);
939
+ return lowered?.kind === "guard-list" && lowered.helper === "query";
940
+ }
941
+ function ternaryHasQueryBranch(ctx, consequent, alternate) {
942
+ const branchHasQuery = (n) => n.kind === "conditional" ? ternaryHasQueryBranch(ctx, n.consequent, n.alternate) : isQueryGuardListCall(ctx, n);
943
+ return branchHasQuery(consequent) || branchHasQuery(alternate);
914
944
  }
915
945
  function renderLoweringNode(ctx, node) {
916
946
  const helper = goHelperName(node.helper);
@@ -5234,6 +5264,9 @@ ${goFields.join(`
5234
5264
  return String(value);
5235
5265
  }
5236
5266
  call(callee, args, emit) {
5267
+ const lowered = lowerRegisteredCallNode(this.emitCtx, callee, args);
5268
+ if (lowered !== null)
5269
+ return lowered;
5237
5270
  if (callee.kind === "identifier" && args.length === 0) {
5238
5271
  return this.searchParamsFieldRef(callee.name) ?? this.rootFieldRef(callee.name);
5239
5272
  }
@@ -6819,15 +6852,21 @@ ${children}`;
6819
6852
  const test = parsed.test;
6820
6853
  if (undef(parsed.alternate) && !undef(parsed.consequent)) {
6821
6854
  const { condition: goCond, preamble } = this.convertConditionToGo(this.isTemplateFragment(this.renderParsedExpr(test), test.kind) ? value.expr : value.expr.slice(0, value.expr.indexOf("?")).trim());
6822
- const valueExpr = this.renderParsedExpr(parsed.consequent);
6823
- const body = `${name}="{{${valueExpr}}}"`;
6855
+ const attrConsequent = lowerRegisteredAttrCall(this.emitCtx, name, parsed.consequent);
6856
+ const body = attrConsequent !== null ? attrConsequent : `${name}="{{${this.renderParsedExpr(parsed.consequent)}}}"`;
6824
6857
  return `${preamble}{{if ${goCond}}}${body}{{end}}`;
6825
6858
  }
6859
+ const attrTernary = lowerRegisteredAttrCall(this.emitCtx, name, parsed);
6860
+ if (attrTernary !== null)
6861
+ return attrTernary;
6826
6862
  return `${name}="{{${this.renderParsedExpr(parsed)}}}"`;
6827
6863
  }
6828
6864
  if (parsed.kind === "template-literal") {
6829
6865
  return `${name}="${this.renderParsedExpr(parsed)}"`;
6830
6866
  }
6867
+ const attrAction = lowerRegisteredAttrCall(this.emitCtx, name, parsed);
6868
+ if (attrAction !== null)
6869
+ return attrAction;
6831
6870
  const bareId = value.expr.trim();
6832
6871
  const propName = this.state.propsObjectName && bareId.startsWith(`${this.state.propsObjectName}.`) ? bareId.slice(this.state.propsObjectName.length + 1) : bareId;
6833
6872
  if (/^[A-Za-z_$][\w$]*$/.test(propName) && this.state.nillablePropNames.has(propName)) {
package/dist/index.js CHANGED
@@ -889,9 +889,22 @@ function lowerTernaryTest(ctx, test) {
889
889
  const isBoolShape = test.kind === "binary" && BOOL_COMPARISON_OPS.has(test.op) || test.kind === "unary" && test.op === "!" || test.kind === "literal" && test.literalType === "boolean";
890
890
  return isBoolShape ? go : `(bf_truthy ${go})`;
891
891
  }
892
+ function matchRegisteredCall(ctx, callee, args) {
893
+ for (const matcher of ctx.state.loweringMatchers) {
894
+ const node = matcher(callee, args);
895
+ if (node)
896
+ return node;
897
+ }
898
+ return null;
899
+ }
900
+ function lowerRegisteredCallNode(ctx, callee, args) {
901
+ if (ctx.state.loweringMatchers.length === 0)
902
+ return null;
903
+ const node = matchRegisteredCall(ctx, callee, args);
904
+ return node ? renderLoweringNode(ctx, node) : null;
905
+ }
892
906
  function lowerRegisteredCall(ctx, jsExpr, preParsed) {
893
- const matchers = ctx.state.loweringMatchers;
894
- if (matchers.length === 0)
907
+ if (ctx.state.loweringMatchers.length === 0)
895
908
  return null;
896
909
  let call = preParsed?.kind === "call" ? preParsed : undefined;
897
910
  if (!call) {
@@ -902,15 +915,32 @@ function lowerRegisteredCall(ctx, jsExpr, preParsed) {
902
915
  return null;
903
916
  call = parsed;
904
917
  }
905
- for (const matcher of matchers) {
906
- const node = matcher(call.callee, call.args);
907
- if (!node)
908
- continue;
909
- const rendered = renderLoweringNode(ctx, node);
910
- if (rendered !== null)
911
- return rendered;
918
+ return lowerRegisteredCallNode(ctx, call.callee, call.args);
919
+ }
920
+ function lowerRegisteredAttrCall(ctx, attrName, parsed) {
921
+ if (parsed.kind === "conditional") {
922
+ if (!ternaryHasQueryBranch(ctx, parsed.consequent, parsed.alternate))
923
+ return null;
924
+ const rendered2 = lowerTernary(ctx, parsed.test, parsed.consequent, parsed.alternate);
925
+ return `{{bf_attr ${JSON.stringify(attrName)} ${rendered2}}}`;
912
926
  }
913
- return null;
927
+ if (parsed.kind !== "call")
928
+ return null;
929
+ const node = matchRegisteredCall(ctx, parsed.callee, parsed.args);
930
+ if (!node || node.kind !== "guard-list" || node.helper !== "query")
931
+ return null;
932
+ const rendered = renderLoweringNode(ctx, node);
933
+ return rendered === null ? null : `{{bf_attr ${JSON.stringify(attrName)} (${rendered})}}`;
934
+ }
935
+ function isQueryGuardListCall(ctx, node) {
936
+ if (node.kind !== "call")
937
+ return false;
938
+ const lowered = matchRegisteredCall(ctx, node.callee, node.args);
939
+ return lowered?.kind === "guard-list" && lowered.helper === "query";
940
+ }
941
+ function ternaryHasQueryBranch(ctx, consequent, alternate) {
942
+ const branchHasQuery = (n) => n.kind === "conditional" ? ternaryHasQueryBranch(ctx, n.consequent, n.alternate) : isQueryGuardListCall(ctx, n);
943
+ return branchHasQuery(consequent) || branchHasQuery(alternate);
914
944
  }
915
945
  function renderLoweringNode(ctx, node) {
916
946
  const helper = goHelperName(node.helper);
@@ -5234,6 +5264,9 @@ ${goFields.join(`
5234
5264
  return String(value);
5235
5265
  }
5236
5266
  call(callee, args, emit) {
5267
+ const lowered = lowerRegisteredCallNode(this.emitCtx, callee, args);
5268
+ if (lowered !== null)
5269
+ return lowered;
5237
5270
  if (callee.kind === "identifier" && args.length === 0) {
5238
5271
  return this.searchParamsFieldRef(callee.name) ?? this.rootFieldRef(callee.name);
5239
5272
  }
@@ -6819,15 +6852,21 @@ ${children}`;
6819
6852
  const test = parsed.test;
6820
6853
  if (undef(parsed.alternate) && !undef(parsed.consequent)) {
6821
6854
  const { condition: goCond, preamble } = this.convertConditionToGo(this.isTemplateFragment(this.renderParsedExpr(test), test.kind) ? value.expr : value.expr.slice(0, value.expr.indexOf("?")).trim());
6822
- const valueExpr = this.renderParsedExpr(parsed.consequent);
6823
- const body = `${name}="{{${valueExpr}}}"`;
6855
+ const attrConsequent = lowerRegisteredAttrCall(this.emitCtx, name, parsed.consequent);
6856
+ const body = attrConsequent !== null ? attrConsequent : `${name}="{{${this.renderParsedExpr(parsed.consequent)}}}"`;
6824
6857
  return `${preamble}{{if ${goCond}}}${body}{{end}}`;
6825
6858
  }
6859
+ const attrTernary = lowerRegisteredAttrCall(this.emitCtx, name, parsed);
6860
+ if (attrTernary !== null)
6861
+ return attrTernary;
6826
6862
  return `${name}="{{${this.renderParsedExpr(parsed)}}}"`;
6827
6863
  }
6828
6864
  if (parsed.kind === "template-literal") {
6829
6865
  return `${name}="${this.renderParsedExpr(parsed)}"`;
6830
6866
  }
6867
+ const attrAction = lowerRegisteredAttrCall(this.emitCtx, name, parsed);
6868
+ if (attrAction !== null)
6869
+ return attrAction;
6831
6870
  const bareId = value.expr.trim();
6832
6871
  const propName = this.state.propsObjectName && bareId.startsWith(`${this.state.propsObjectName}.`) ? bareId.slice(this.state.propsObjectName.length + 1) : bareId;
6833
6872
  if (/^[A-Za-z_$][\w$]*$/.test(propName) && this.state.nillablePropNames.has(propName)) {
package/dist/vite.js CHANGED
@@ -12,6 +12,41 @@ import ts10 from "typescript";
12
12
 
13
13
  // ../jsx/src/expression-parser.ts
14
14
  import ts from "typescript";
15
+
16
+ // ../jsx/src/lowering-registry.ts
17
+ var plugins = [];
18
+ function registerLoweringPlugin(plugin) {
19
+ const existing = plugins.findIndex((p) => p.name === plugin.name);
20
+ if (existing >= 0)
21
+ plugins[existing] = plugin;
22
+ else
23
+ plugins.push(plugin);
24
+ }
25
+ function prepareLoweringMatchers(metadata) {
26
+ const matchers = [];
27
+ for (const plugin of plugins) {
28
+ const matcher = plugin.prepare(metadata);
29
+ if (matcher)
30
+ matchers.push(matcher);
31
+ }
32
+ return matchers;
33
+ }
34
+ function loweringNodeChildren(node) {
35
+ if (node.kind === "helper-call")
36
+ return [...node.args];
37
+ const children = [node.base];
38
+ for (const t of node.triples) {
39
+ if (t.guard)
40
+ children.push(t.guard);
41
+ children.push(t.value);
42
+ }
43
+ return children;
44
+ }
45
+ function isValidHelperId(helper) {
46
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(helper);
47
+ }
48
+
49
+ // ../jsx/src/expression-parser.ts
15
50
  var UNSUPPORTED_METHODS = new Set([
16
51
  "filter",
17
52
  "map",
@@ -209,7 +244,7 @@ function convertNode(node, raw) {
209
244
  }
210
245
  if (n === undefined || Number.isNaN(n)) {
211
246
  const parsedDepth = convertNode(depthNode, raw);
212
- if (checkSupport(parsedDepth, "rendered").supported) {
247
+ if (checkSupport(parsedDepth, "rendered", []).supported) {
213
248
  depthExpr = parsedDepth;
214
249
  flatDepth = 1;
215
250
  } else {
@@ -987,13 +1022,13 @@ function getUnaryOperatorString(op) {
987
1022
  return "unknown";
988
1023
  }
989
1024
  }
990
- function isSupported(expr) {
991
- return checkSupport(expr, "rendered");
1025
+ function isSupported(expr, opts) {
1026
+ return checkSupport(expr, "rendered", opts?.loweringMatchers ?? []);
992
1027
  }
993
- function isSupportedValue(expr) {
994
- return checkSupport(expr, "value");
1028
+ function isSupportedValue(expr, opts) {
1029
+ return checkSupport(expr, "value", opts?.loweringMatchers ?? []);
995
1030
  }
996
- function checkSupport(expr, pos) {
1031
+ function checkSupport(expr, pos, matchers) {
997
1032
  switch (expr.kind) {
998
1033
  case "unsupported":
999
1034
  return { supported: false, reason: expr.reason };
@@ -1002,7 +1037,7 @@ function checkSupport(expr, pos) {
1002
1037
  return { supported: false, reason: "Unsupported syntax: ObjectLiteralExpression" };
1003
1038
  }
1004
1039
  for (const prop of expr.properties) {
1005
- const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos);
1040
+ const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos, matchers);
1006
1041
  if (!propSupport.supported)
1007
1042
  return propSupport;
1008
1043
  }
@@ -1017,7 +1052,7 @@ function checkSupport(expr, pos) {
1017
1052
  return { supported: false, reason: "Standalone arrow functions / regex literals are not supported" };
1018
1053
  case "array-literal": {
1019
1054
  for (const el of expr.elements) {
1020
- const elSupport = checkSupport(el, pos);
1055
+ const elSupport = checkSupport(el, pos, matchers);
1021
1056
  if (!elSupport.supported)
1022
1057
  return elSupport;
1023
1058
  }
@@ -1030,28 +1065,39 @@ function checkSupport(expr, pos) {
1030
1065
  reason: `String.prototype.${expr.method} supports only a string pattern + string replacement (the regex form is deferred); use a string pattern or wrap the expression in /* @client */`
1031
1066
  };
1032
1067
  }
1033
- const objSupport = checkSupport(expr.object, pos);
1068
+ const objSupport = checkSupport(expr.object, pos, matchers);
1034
1069
  if (!objSupport.supported)
1035
1070
  return objSupport;
1036
1071
  for (const arg of expr.args) {
1037
- const argSupport = checkSupport(arg, pos);
1072
+ const argSupport = checkSupport(arg, pos, matchers);
1038
1073
  if (!argSupport.supported)
1039
1074
  return argSupport;
1040
1075
  }
1041
1076
  if (expr.method === "flat" && expr.depthExpr) {
1042
- const depthSupport = checkSupport(expr.depthExpr, pos);
1077
+ const depthSupport = checkSupport(expr.depthExpr, pos, matchers);
1043
1078
  if (!depthSupport.supported)
1044
1079
  return depthSupport;
1045
1080
  }
1046
1081
  return { supported: true, level: "L2" };
1047
1082
  }
1048
1083
  case "call": {
1084
+ for (const matcher of matchers) {
1085
+ const node = matcher(expr.callee, expr.args);
1086
+ if (!node)
1087
+ continue;
1088
+ for (const child of loweringNodeChildren(node)) {
1089
+ const childSupport = checkSupport(child, pos, matchers);
1090
+ if (!childSupport.supported)
1091
+ return childSupport;
1092
+ }
1093
+ return { supported: true, level: "L2" };
1094
+ }
1049
1095
  const cb = asCallbackMethodCall(expr);
1050
1096
  if (cb) {
1051
- const objSupport = checkSupport(cb.object, pos);
1097
+ const objSupport = checkSupport(cb.object, pos, matchers);
1052
1098
  if (!objSupport.supported)
1053
1099
  return objSupport;
1054
- const bodySupport = checkSupport(cb.arrow.body, pos);
1100
+ const bodySupport = checkSupport(cb.arrow.body, pos, matchers);
1055
1101
  if (!bodySupport.supported) {
1056
1102
  return {
1057
1103
  supported: false,
@@ -1060,13 +1106,13 @@ function checkSupport(expr, pos) {
1060
1106
  };
1061
1107
  }
1062
1108
  for (const rest of cb.args) {
1063
- const restSupport = checkSupport(rest, pos);
1109
+ const restSupport = checkSupport(rest, pos, matchers);
1064
1110
  if (!restSupport.supported)
1065
1111
  return restSupport;
1066
1112
  }
1067
1113
  return { supported: true, level: "L5" };
1068
1114
  }
1069
- const calleeSupport = checkSupport(expr.callee, pos);
1115
+ const calleeSupport = checkSupport(expr.callee, pos, matchers);
1070
1116
  if (!calleeSupport.supported) {
1071
1117
  return calleeSupport;
1072
1118
  }
@@ -1085,7 +1131,7 @@ function checkSupport(expr, pos) {
1085
1131
  return { supported: true, level: "L1" };
1086
1132
  }
1087
1133
  for (const arg of expr.args) {
1088
- const argSupport = checkSupport(arg, pos);
1134
+ const argSupport = checkSupport(arg, pos, matchers);
1089
1135
  if (!argSupport.supported) {
1090
1136
  return argSupport;
1091
1137
  }
@@ -1093,7 +1139,7 @@ function checkSupport(expr, pos) {
1093
1139
  return { supported: true, level: "L2" };
1094
1140
  }
1095
1141
  case "member": {
1096
- const objSupport = checkSupport(expr.object, pos);
1142
+ const objSupport = checkSupport(expr.object, pos, matchers);
1097
1143
  if (!objSupport.supported) {
1098
1144
  return objSupport;
1099
1145
  }
@@ -1103,19 +1149,19 @@ function checkSupport(expr, pos) {
1103
1149
  return { supported: true, level: "L2" };
1104
1150
  }
1105
1151
  case "index-access": {
1106
- const objSupport = checkSupport(expr.object, pos);
1152
+ const objSupport = checkSupport(expr.object, pos, matchers);
1107
1153
  if (!objSupport.supported)
1108
1154
  return objSupport;
1109
- const indexSupport = checkSupport(expr.index, pos);
1155
+ const indexSupport = checkSupport(expr.index, pos, matchers);
1110
1156
  if (!indexSupport.supported)
1111
1157
  return indexSupport;
1112
1158
  return { supported: true, level: "L2" };
1113
1159
  }
1114
1160
  case "binary": {
1115
- const leftSupport = checkSupport(expr.left, pos);
1161
+ const leftSupport = checkSupport(expr.left, pos, matchers);
1116
1162
  if (!leftSupport.supported)
1117
1163
  return leftSupport;
1118
- const rightSupport = checkSupport(expr.right, pos);
1164
+ const rightSupport = checkSupport(expr.right, pos, matchers);
1119
1165
  if (!rightSupport.supported)
1120
1166
  return rightSupport;
1121
1167
  if (["===", "==", "!==", "!=", ">", "<", ">=", "<="].includes(expr.op)) {
@@ -1127,7 +1173,7 @@ function checkSupport(expr, pos) {
1127
1173
  return { supported: false, reason: `Unknown operator: ${expr.op}` };
1128
1174
  }
1129
1175
  case "unary": {
1130
- const argSupport = checkSupport(expr.argument, pos);
1176
+ const argSupport = checkSupport(expr.argument, pos, matchers);
1131
1177
  if (!argSupport.supported)
1132
1178
  return argSupport;
1133
1179
  if (expr.op === "!") {
@@ -1139,25 +1185,25 @@ function checkSupport(expr, pos) {
1139
1185
  return { supported: false, reason: `Unsupported unary operator: ${expr.op}` };
1140
1186
  }
1141
1187
  case "logical": {
1142
- const leftSupport = checkSupport(expr.left, pos);
1188
+ const leftSupport = checkSupport(expr.left, pos, matchers);
1143
1189
  if (!leftSupport.supported)
1144
1190
  return leftSupport;
1145
1191
  if (expr.op === "??" && expr.right.kind === "object-literal" && expr.right.properties.length === 0) {
1146
1192
  return { supported: true, level: "L4" };
1147
1193
  }
1148
- const rightSupport = checkSupport(expr.right, pos);
1194
+ const rightSupport = checkSupport(expr.right, pos, matchers);
1149
1195
  if (!rightSupport.supported)
1150
1196
  return rightSupport;
1151
1197
  return { supported: true, level: "L4" };
1152
1198
  }
1153
1199
  case "conditional": {
1154
- const testSupport = checkSupport(expr.test, pos);
1200
+ const testSupport = checkSupport(expr.test, pos, matchers);
1155
1201
  if (!testSupport.supported)
1156
1202
  return testSupport;
1157
- const consSupport = checkSupport(expr.consequent, pos);
1203
+ const consSupport = checkSupport(expr.consequent, pos, matchers);
1158
1204
  if (!consSupport.supported)
1159
1205
  return consSupport;
1160
- const altSupport = checkSupport(expr.alternate, pos);
1206
+ const altSupport = checkSupport(expr.alternate, pos, matchers);
1161
1207
  if (!altSupport.supported)
1162
1208
  return altSupport;
1163
1209
  return { supported: true, level: "L4" };
@@ -1165,7 +1211,7 @@ function checkSupport(expr, pos) {
1165
1211
  case "template-literal": {
1166
1212
  for (const part of expr.parts) {
1167
1213
  if (part.type === "expression") {
1168
- const partSupport = checkSupport(part.expr, pos);
1214
+ const partSupport = checkSupport(part.expr, pos, matchers);
1169
1215
  if (!partSupport.supported)
1170
1216
  return partSupport;
1171
1217
  }
@@ -3243,30 +3289,6 @@ import ts16 from "typescript";
3243
3289
 
3244
3290
  // ../jsx/src/relocate.ts
3245
3291
  import ts18 from "typescript";
3246
-
3247
- // ../jsx/src/lowering-registry.ts
3248
- var plugins = [];
3249
- function registerLoweringPlugin(plugin) {
3250
- const existing = plugins.findIndex((p) => p.name === plugin.name);
3251
- if (existing >= 0)
3252
- plugins[existing] = plugin;
3253
- else
3254
- plugins.push(plugin);
3255
- }
3256
- function prepareLoweringMatchers(metadata) {
3257
- const matchers = [];
3258
- for (const plugin of plugins) {
3259
- const matcher = plugin.prepare(metadata);
3260
- if (matcher)
3261
- matchers.push(matcher);
3262
- }
3263
- return matchers;
3264
- }
3265
- function isValidHelperId(helper) {
3266
- return /^[A-Za-z_][A-Za-z0-9_]*$/.test(helper);
3267
- }
3268
-
3269
- // ../jsx/src/relocate.ts
3270
3292
  var REGISTRY_SAFE_BINDING_KINDS = new Set([
3271
3293
  "global",
3272
3294
  "module-import",
@@ -4694,6 +4716,17 @@ function emitParsedExpr(expr, emitter) {
4694
4716
  case "literal":
4695
4717
  return emitter.literal(expr.value, expr.literalType);
4696
4718
  case "call": {
4719
+ if (emitter.lowering) {
4720
+ for (const matcher of emitter.lowering.matchers) {
4721
+ const node = matcher(expr.callee, expr.args);
4722
+ if (!node)
4723
+ continue;
4724
+ const rendered = emitter.lowering.render(node, emit);
4725
+ if (rendered !== null)
4726
+ return rendered;
4727
+ break;
4728
+ }
4729
+ }
4697
4730
  const cb = asCallbackMethodCall(expr);
4698
4731
  if (cb)
4699
4732
  return emitter.callbackMethod(cb.method, cb.object, cb.arrow, cb.args, emit);
@@ -6103,9 +6136,22 @@ function lowerTernaryTest(ctx, test) {
6103
6136
  const isBoolShape = test.kind === "binary" && BOOL_COMPARISON_OPS.has(test.op) || test.kind === "unary" && test.op === "!" || test.kind === "literal" && test.literalType === "boolean";
6104
6137
  return isBoolShape ? go : `(bf_truthy ${go})`;
6105
6138
  }
6139
+ function matchRegisteredCall(ctx, callee, args) {
6140
+ for (const matcher of ctx.state.loweringMatchers) {
6141
+ const node = matcher(callee, args);
6142
+ if (node)
6143
+ return node;
6144
+ }
6145
+ return null;
6146
+ }
6147
+ function lowerRegisteredCallNode(ctx, callee, args) {
6148
+ if (ctx.state.loweringMatchers.length === 0)
6149
+ return null;
6150
+ const node = matchRegisteredCall(ctx, callee, args);
6151
+ return node ? renderLoweringNode(ctx, node) : null;
6152
+ }
6106
6153
  function lowerRegisteredCall(ctx, jsExpr, preParsed) {
6107
- const matchers = ctx.state.loweringMatchers;
6108
- if (matchers.length === 0)
6154
+ if (ctx.state.loweringMatchers.length === 0)
6109
6155
  return null;
6110
6156
  let call = preParsed?.kind === "call" ? preParsed : undefined;
6111
6157
  if (!call) {
@@ -6116,15 +6162,32 @@ function lowerRegisteredCall(ctx, jsExpr, preParsed) {
6116
6162
  return null;
6117
6163
  call = parsed;
6118
6164
  }
6119
- for (const matcher of matchers) {
6120
- const node = matcher(call.callee, call.args);
6121
- if (!node)
6122
- continue;
6123
- const rendered = renderLoweringNode(ctx, node);
6124
- if (rendered !== null)
6125
- return rendered;
6165
+ return lowerRegisteredCallNode(ctx, call.callee, call.args);
6166
+ }
6167
+ function lowerRegisteredAttrCall(ctx, attrName, parsed) {
6168
+ if (parsed.kind === "conditional") {
6169
+ if (!ternaryHasQueryBranch(ctx, parsed.consequent, parsed.alternate))
6170
+ return null;
6171
+ const rendered2 = lowerTernary(ctx, parsed.test, parsed.consequent, parsed.alternate);
6172
+ return `{{bf_attr ${JSON.stringify(attrName)} ${rendered2}}}`;
6126
6173
  }
6127
- return null;
6174
+ if (parsed.kind !== "call")
6175
+ return null;
6176
+ const node = matchRegisteredCall(ctx, parsed.callee, parsed.args);
6177
+ if (!node || node.kind !== "guard-list" || node.helper !== "query")
6178
+ return null;
6179
+ const rendered = renderLoweringNode(ctx, node);
6180
+ return rendered === null ? null : `{{bf_attr ${JSON.stringify(attrName)} (${rendered})}}`;
6181
+ }
6182
+ function isQueryGuardListCall(ctx, node) {
6183
+ if (node.kind !== "call")
6184
+ return false;
6185
+ const lowered = matchRegisteredCall(ctx, node.callee, node.args);
6186
+ return lowered?.kind === "guard-list" && lowered.helper === "query";
6187
+ }
6188
+ function ternaryHasQueryBranch(ctx, consequent, alternate) {
6189
+ const branchHasQuery = (n) => n.kind === "conditional" ? ternaryHasQueryBranch(ctx, n.consequent, n.alternate) : isQueryGuardListCall(ctx, n);
6190
+ return branchHasQuery(consequent) || branchHasQuery(alternate);
6128
6191
  }
6129
6192
  function renderLoweringNode(ctx, node) {
6130
6193
  const helper = goHelperName(node.helper);
@@ -10427,6 +10490,9 @@ ${goFields.join(`
10427
10490
  return String(value);
10428
10491
  }
10429
10492
  call(callee, args, emit) {
10493
+ const lowered = lowerRegisteredCallNode(this.emitCtx, callee, args);
10494
+ if (lowered !== null)
10495
+ return lowered;
10430
10496
  if (callee.kind === "identifier" && args.length === 0) {
10431
10497
  return this.searchParamsFieldRef(callee.name) ?? this.rootFieldRef(callee.name);
10432
10498
  }
@@ -12012,15 +12078,21 @@ ${children}`;
12012
12078
  const test = parsed.test;
12013
12079
  if (undef(parsed.alternate) && !undef(parsed.consequent)) {
12014
12080
  const { condition: goCond, preamble } = this.convertConditionToGo(this.isTemplateFragment(this.renderParsedExpr(test), test.kind) ? value.expr : value.expr.slice(0, value.expr.indexOf("?")).trim());
12015
- const valueExpr = this.renderParsedExpr(parsed.consequent);
12016
- const body = `${name}="{{${valueExpr}}}"`;
12081
+ const attrConsequent = lowerRegisteredAttrCall(this.emitCtx, name, parsed.consequent);
12082
+ const body = attrConsequent !== null ? attrConsequent : `${name}="{{${this.renderParsedExpr(parsed.consequent)}}}"`;
12017
12083
  return `${preamble}{{if ${goCond}}}${body}{{end}}`;
12018
12084
  }
12085
+ const attrTernary = lowerRegisteredAttrCall(this.emitCtx, name, parsed);
12086
+ if (attrTernary !== null)
12087
+ return attrTernary;
12019
12088
  return `${name}="{{${this.renderParsedExpr(parsed)}}}"`;
12020
12089
  }
12021
12090
  if (parsed.kind === "template-literal") {
12022
12091
  return `${name}="${this.renderParsedExpr(parsed)}"`;
12023
12092
  }
12093
+ const attrAction = lowerRegisteredAttrCall(this.emitCtx, name, parsed);
12094
+ if (attrAction !== null)
12095
+ return attrAction;
12024
12096
  const bareId = value.expr.trim();
12025
12097
  const propName = this.state.propsObjectName && bareId.startsWith(`${this.state.propsObjectName}.`) ? bareId.slice(this.state.propsObjectName.length + 1) : bareId;
12026
12098
  if (/^[A-Za-z_$][\w$]*$/.test(propName) && this.state.nillablePropNames.has(propName)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/go-template",
3
- "version": "0.33.6",
3
+ "version": "0.34.0",
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.33.6"
52
+ "@barefootjs/shared": "0.34.0"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@barefootjs/jsx": ">=0.2.0",
@@ -67,9 +67,9 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@barefootjs/adapter-tests": "0.1.0",
70
- "@barefootjs/client": "0.33.6",
71
- "@barefootjs/jsx": "0.33.6",
72
- "@barefootjs/vite": "0.33.6",
70
+ "@barefootjs/client": "0.34.0",
71
+ "@barefootjs/jsx": "0.34.0",
72
+ "@barefootjs/vite": "0.34.0",
73
73
  "vite": "^6.0.0"
74
74
  }
75
75
  }
@@ -129,14 +129,6 @@ runAdapterConformanceTests({
129
129
  // produces no complete template.
130
130
  'jsx-element-prop-rest-bag-dynamic',
131
131
  ]),
132
- skipDataPoints: new Set<string>([
133
- // #2743: html/template's URL-context autoescape percent-encodes the
134
- // queryHref BASE in href position (`日本語` → `%e6%97%a5…`); the JS
135
- // reference only HTML-escapes. The bf_query helper itself is faithful —
136
- // the divergence is Go's contextual escaper on the whole href value.
137
- 'query-href:gen:base:markup',
138
- 'query-href:gen:base:multibyte',
139
- ]),
140
132
  onRenderError: (err, id) => {
141
133
  if (err instanceof GoNotAvailableError) {
142
134
  console.log(`Skipping [${id}]: ${err.message}`)
@@ -149,6 +149,11 @@ export function P(props: { config: object }) {
149
149
  // naming exactly — the formula generalises, it isn't a lookup table
150
150
  // limited to `query`.
151
151
  expect(template).toContain('bf_custom_serialize .Config')
152
+ // #2743: the whole-attribute `bf_attr` route is keyed on the neutral
153
+ // `guard-list` + `helper === 'query'` shape specifically — a
154
+ // `helper-call` node (this plugin's shape) is a different node kind and
155
+ // must not be routed through it.
156
+ expect(template).not.toContain('bf_attr')
152
157
  })
153
158
 
154
159
  test('without the plugin registered, the call falls back to the generic (unsupported) lowering', () => {
@@ -163,6 +168,39 @@ export function P(props: { config: object }) {
163
168
  expect(template).not.toContain('bf_custom_serialize')
164
169
  })
165
170
 
171
+ // #2842: a `helper-call` node (not the `query` guard-list) reached through
172
+ // the undef-alternate omission shape now routes through the fixed `call()`
173
+ // dispatcher — but NOT through `bf_attr` (only `query` needs the
174
+ // URL-context-escape bypass; a plain helper-call keeps the ordinary
175
+ // `name="{{…}}"` wrapper the `{{if}}` already builds around).
176
+ test('an undef-alternate helper-call consequent is registry-lowered without bf_attr (#2842)', () => {
177
+ registerLoweringPlugin(customSerializePlugin)
178
+ const src = `
179
+ 'use client'
180
+ import { customSerialize } from './lib'
181
+ export function P(props: { on: boolean; config: object }) {
182
+ return <div data-config={props.on ? customSerialize(props.config) : undefined}>x</div>
183
+ }
184
+ `
185
+ const { template } = generate(src)
186
+ expect(template).toContain('{{if .On}}data-config="{{bf_custom_serialize .Config}}"{{end}}')
187
+ expect(template).not.toContain('bf_attr')
188
+ })
189
+
190
+ // Same shape, plugin NOT registered — pins that an unmatched call keeps the
191
+ // existing generic Go-method-call convention (no new BF10x refusal).
192
+ test('an undef-alternate helper-call consequent with no plugin registered keeps the generic convention', () => {
193
+ const src = `
194
+ 'use client'
195
+ import { customSerialize } from './lib'
196
+ export function P(props: { on: boolean; config: object }) {
197
+ return <div data-config={props.on ? customSerialize(props.config) : undefined}>x</div>
198
+ }
199
+ `
200
+ const { template } = generate(src)
201
+ expect(template).toContain('{{if .On}}data-config="{{.CustomSerialize .Config}}"{{end}}')
202
+ })
203
+
166
204
  test('a CONDITIONAL helper-call arg renders as pipeline-position bf_ternary, not an {{if}} action', () => {
167
205
  // The #2324 union stage lowers a union-typed locale to a ternary
168
206
  // pattern arg. Go templates have no expression-level conditional, and
@@ -176,4 +176,130 @@ export function P(props: { base: string; q: Record<string, string> }) {
176
176
  const { template } = generate(src)
177
177
  expect(template).not.toContain('bf_query')
178
178
  })
179
+
180
+ // #2743: a `queryHref` value in an ATTRIBUTE position emits the whole
181
+ // attribute via `bf_attr` (template.HTMLAttr) so html/template's
182
+ // contextual URL-context autoescape (keyed off the attribute NAME) never
183
+ // percent-encodes the base — see `lowerRegisteredAttrCall`.
184
+ test('an href-attribute queryHref value routes through bf_attr, not `href="{{...}}"`', () => {
185
+ const src = `
186
+ 'use client'
187
+ import { queryHref } from '@barefootjs/client'
188
+ export function P(props: { base: string; tag: string }) {
189
+ return <a href={queryHref(props.base, { tag: props.tag })}>x</a>
190
+ }
191
+ `
192
+ const { template } = generate(src)
193
+ expect(template).toContain('{{bf_attr "href" (bf_query .Base (true) "tag" .Tag)}}')
194
+ expect(template).not.toContain('href="{{')
195
+ })
196
+
197
+ // The route is keyed on the neutral `helper === 'query'` fact, not on the
198
+ // attribute name `href` — any attribute (e.g. `title`) gets the same
199
+ // treatment, since `queryHref` returns a plain string with nothing
200
+ // href-specific about it.
201
+ test('a non-href attribute (title) with a queryHref value also routes through bf_attr', () => {
202
+ const src = `
203
+ 'use client'
204
+ import { queryHref } from '@barefootjs/client'
205
+ export function P(props: { base: string; tag: string }) {
206
+ return <a title={queryHref(props.base, { tag: props.tag })}>x</a>
207
+ }
208
+ `
209
+ const { template } = generate(src)
210
+ expect(template).toContain('{{bf_attr "title" (bf_query .Base (true) "tag" .Tag)}}')
211
+ expect(template).not.toContain('title="{{')
212
+ })
213
+
214
+ // Text-position (non-attribute) use is unaffected — `bf_attr` only wraps
215
+ // the whole-attribute case; a queryHref value read as text still lowers
216
+ // to a bare `bf_query` pipeline.
217
+ test('a queryHref value in text position is not wrapped in bf_attr', () => {
218
+ const src = `
219
+ 'use client'
220
+ import { queryHref } from '@barefootjs/client'
221
+ export function P(props: { base: string; tag: string }) {
222
+ return <span>{queryHref(props.base, { tag: props.tag })}</span>
223
+ }
224
+ `
225
+ const { template } = generate(src)
226
+ expect(template).toContain('bf_query .Base (true) "tag" .Tag')
227
+ expect(template).not.toContain('bf_attr')
228
+ })
229
+
230
+ // #2743 follow-up (pullfrog review on #2841): a ternary attribute value
231
+ // with a real (non-`undefined`) alternate is syntactically valid and
232
+ // already lowers both branches correctly via `bf_ternary` — but was still
233
+ // wrapped in the ordinary `name="{{...}}"` form, leaving it exposed to
234
+ // html/template's URL-context percent-encoding. This must route through
235
+ // `bf_attr` too, wrapping the whole `bf_ternary` pipeline.
236
+ test('a queryHref value in a ternary branch (non-undefined alternate) routes through bf_attr', () => {
237
+ const src = `
238
+ 'use client'
239
+ import { queryHref } from '@barefootjs/client'
240
+ export function P(props: { ok: boolean; base: string; tag: string }) {
241
+ return <a href={props.ok ? queryHref(props.base, { tag: props.tag }) : '/fallback'}>x</a>
242
+ }
243
+ `
244
+ const { template } = generate(src)
245
+ expect(template).toContain(
246
+ '{{bf_attr "href" (bf_ternary (bf_truthy .Ok) (bf_query .Base (true) "tag" .Tag) "/fallback")}}',
247
+ )
248
+ expect(template).not.toContain('href="{{')
249
+ })
250
+
251
+ // #2842: the `undefined`-alternate omission shape used to render only the
252
+ // consequent via a registry-blind path, emitting invalid Go syntax
253
+ // (`.QueryHref .Base bf_map "tag" .Tag`) with no diagnostic. The consequent
254
+ // now routes through `lowerRegisteredAttrCall` (the same whole-attribute
255
+ // `bf_attr` bypass the direct-call and non-undefined-ternary shapes use),
256
+ // inside the `{{if}}` that implements the omission.
257
+ test('the undefined-alternate omission shape routes the consequent through bf_attr inside the {{if}} (#2842)', () => {
258
+ const src = `
259
+ 'use client'
260
+ import { queryHref } from '@barefootjs/client'
261
+ export function P(props: { ok: boolean; base: string; tag: string }) {
262
+ return <a href={props.ok ? queryHref(props.base, { tag: props.tag }) : undefined}>x</a>
263
+ }
264
+ `
265
+ const { template } = generate(src)
266
+ expect(template).toContain('{{if .Ok}}{{bf_attr "href" (bf_query .Base (true) "tag" .Tag)}}{{end}}')
267
+ expect(template).not.toContain('.QueryHref')
268
+ expect(template).not.toContain('bf_map')
269
+ expect(template).not.toContain('href="{{')
270
+ })
271
+
272
+ // #2842: a registered call nested in a template-literal interpolation
273
+ // (not just a direct attribute value) is registry-lowered too — the fix
274
+ // lives in the shared ParsedExpr `call()` dispatcher, so any nested
275
+ // position benefits, not only the ternary/attribute cases above.
276
+ test('a queryHref call nested in a template-literal interpolation is registry-lowered (#2842)', () => {
277
+ const src = `
278
+ 'use client'
279
+ import { queryHref } from '@barefootjs/client'
280
+ export function P(props: { base: string; tag: string }) {
281
+ return <a title={\`pre \${queryHref(props.base, { tag: props.tag })}\`}>x</a>
282
+ }
283
+ `
284
+ const { template } = generate(src)
285
+ expect(template).toContain('title="pre {{bf_query .Base (true) "tag" .Tag}}"')
286
+ expect(template).not.toContain('.QueryHref')
287
+ })
288
+
289
+ // #2842: a nested ternary inside the undef-alternate consequent still
290
+ // recurses correctly — `lowerRegisteredAttrCall`'s `conditional` arm
291
+ // right-folds, matching `lowerTernary`'s own recursion.
292
+ test('a nested ternary inside the undef-alternate consequent still routes through bf_attr (#2842)', () => {
293
+ const src = `
294
+ 'use client'
295
+ import { queryHref } from '@barefootjs/client'
296
+ export function P(props: { a: boolean; b: boolean; base: string; tag: string }) {
297
+ return <a href={props.a ? (props.b ? queryHref(props.base, { tag: props.tag }) : '/x') : undefined}>x</a>
298
+ }
299
+ `
300
+ const { template } = generate(src)
301
+ expect(template).toContain(
302
+ '{{if .A}}{{bf_attr "href" (bf_ternary (bf_truthy .B) (bf_query .Base (true) "tag" .Tag) "/x")}}{{end}}',
303
+ )
304
+ })
179
305
  })
@@ -128,6 +128,44 @@ function lowerTernaryTest(ctx: GoEmitContext, test: ParsedExpr): string {
128
128
  return isBoolShape ? go : `(bf_truthy ${go})`
129
129
  }
130
130
 
131
+ /**
132
+ * First registered matcher that recognises `callee(args)`, or null (#2842).
133
+ * The single registry consultation every Go lowering path shares: the
134
+ * top-level `lowerRegisteredCall` early return, the ParsedExpr `call()`
135
+ * dispatcher (`go-template-adapter.ts`, so a registered call is recognised no
136
+ * matter how deep it sits in an expression tree — a ternary branch, a
137
+ * template-literal interpolation, a binary operand — not only when the call
138
+ * IS the whole expression), and the attribute-position `bf_attr` route all
139
+ * ask this one question. First-match-wins: a malformed helper id from one
140
+ * plugin must not be silently masked by falling through to another.
141
+ */
142
+ export function matchRegisteredCall(
143
+ ctx: GoEmitContext,
144
+ callee: ParsedExpr,
145
+ args: readonly ParsedExpr[],
146
+ ): LoweringNode | null {
147
+ for (const matcher of ctx.state.loweringMatchers) {
148
+ const node = matcher(callee, args)
149
+ if (node) return node
150
+ }
151
+ return null
152
+ }
153
+
154
+ /**
155
+ * Render a recognised call's neutral node to its Go pipeline (unparenthesised
156
+ * — same contract as `lowerRegisteredCall`), or null when no plugin matches
157
+ * or the matched helper has no Go mapping.
158
+ */
159
+ export function lowerRegisteredCallNode(
160
+ ctx: GoEmitContext,
161
+ callee: ParsedExpr,
162
+ args: readonly ParsedExpr[],
163
+ ): string | null {
164
+ if (ctx.state.loweringMatchers.length === 0) return null
165
+ const node = matchRegisteredCall(ctx, callee, args)
166
+ return node ? renderLoweringNode(ctx, node) : null
167
+ }
168
+
131
169
  /**
132
170
  * Lower a helper call to a Go template expression, or null when no registered
133
171
  * plugin recognises it (→ the generic lowering). Matchers — including the
@@ -144,8 +182,7 @@ export function lowerRegisteredCall(
144
182
  jsExpr: string,
145
183
  preParsed?: ParsedExpr,
146
184
  ): string | null {
147
- const matchers = ctx.state.loweringMatchers
148
- if (matchers.length === 0) return null
185
+ if (ctx.state.loweringMatchers.length === 0) return null
149
186
 
150
187
  let call: ParsedExpr | undefined = preParsed?.kind === 'call' ? preParsed : undefined
151
188
  if (!call) {
@@ -155,13 +192,82 @@ export function lowerRegisteredCall(
155
192
  call = parsed
156
193
  }
157
194
 
158
- for (const matcher of matchers) {
159
- const node = matcher(call.callee, call.args)
160
- if (!node) continue
161
- const rendered = renderLoweringNode(ctx, node)
162
- if (rendered !== null) return rendered
195
+ return lowerRegisteredCallNode(ctx, call.callee, call.args)
196
+ }
197
+
198
+ /**
199
+ * Attribute-position twin of `lowerRegisteredCall` (#2743). When an intrinsic
200
+ * element attribute's value is a `query` guard-list (the neutral node the
201
+ * `queryHref` plugin — or any plugin reusing the `query` helper — produces),
202
+ * emit the WHOLE attribute as one `bf_attr` action returning
203
+ * `template.HTMLAttr`, instead of `name="{{bf_query …}}"`. html/template
204
+ * infers a URL context from the attribute NAME (`href`, `src`, `action`,
205
+ * `data-*`, anything containing `src`/`uri`/`url`, …) and percent-encodes the
206
+ * entire value there; the JS reference (Hono) only HTML-escapes. Keyed on the
207
+ * neutral `helper` id, not the attribute name (Go's URL-context table is a
208
+ * heuristic we must not re-implement) and not the JS API name. Returns null
209
+ * for a non-call, an unmatched call, or any other node kind/helper — the
210
+ * caller then takes its ordinary path.
211
+ *
212
+ * Also accepts a `conditional` node directly (#2743 follow-up, pullfrog
213
+ * review on #2841): a ternary with a real, non-`undefined` alternate
214
+ * (`cond ? queryHref(...) : '/fallback'`) is syntactically valid and already
215
+ * lowers its branches correctly via `lowerTernary` — but the CALLER used to
216
+ * still wrap the resulting `(bf_ternary …)` pipeline in the ordinary
217
+ * `name="{{...}}"` form, which leaves it exposed to the same URL-context
218
+ * percent-encoding this function exists to route around. Whenever EITHER
219
+ * branch (recursing through a right-folded nested ternary chain, the same
220
+ * shape `lowerTernary` itself right-folds) is a `query` guard-list call, the
221
+ * whole ternary is wrapped in `bf_attr` too — matching the reference, which
222
+ * HTML-escapes the picked branch's value the same way regardless of which
223
+ * branch won.
224
+ *
225
+ * The caller passes the CONSEQUENT ALONE (not the full ternary) for the
226
+ * `undefined`-alternate omission shape (`cond ? queryHref(...) : undefined`,
227
+ * #2842) — omission needs the `{{if}}` wrapper that shape's caller already
228
+ * builds; a `bf_ternary … ""` inside `bf_attr` can't express it (`Attr`
229
+ * renders `name=""` for an empty value, not attribute absence).
230
+ */
231
+ export function lowerRegisteredAttrCall(
232
+ ctx: GoEmitContext,
233
+ attrName: string,
234
+ parsed: ParsedExpr,
235
+ ): string | null {
236
+ if (parsed.kind === 'conditional') {
237
+ if (!ternaryHasQueryBranch(ctx, parsed.consequent, parsed.alternate)) return null
238
+ // `lowerTernary` already returns a complete parenthesised `(bf_ternary …)`
239
+ // pipeline — pass it straight through as `bf_attr`'s value argument
240
+ // rather than re-wrapping it in a redundant second set of parens.
241
+ const rendered = lowerTernary(ctx, parsed.test, parsed.consequent, parsed.alternate)
242
+ return `{{bf_attr ${JSON.stringify(attrName)} ${rendered}}}`
163
243
  }
164
- return null
244
+ if (parsed.kind !== 'call') return null
245
+ const node = matchRegisteredCall(ctx, parsed.callee, parsed.args)
246
+ if (!node || node.kind !== 'guard-list' || node.helper !== 'query') return null
247
+ const rendered = renderLoweringNode(ctx, node)
248
+ return rendered === null ? null : `{{bf_attr ${JSON.stringify(attrName)} (${rendered})}}`
249
+ }
250
+
251
+ /** Whether a `call` node is a recognised `query` guard-list lowering. */
252
+ function isQueryGuardListCall(ctx: GoEmitContext, node: ParsedExpr): boolean {
253
+ if (node.kind !== 'call') return false
254
+ const lowered = matchRegisteredCall(ctx, node.callee, node.args)
255
+ return lowered?.kind === 'guard-list' && lowered.helper === 'query'
256
+ }
257
+
258
+ /**
259
+ * Whether either branch of a ternary is (or, for a right-folded chain,
260
+ * eventually resolves to) a `query` guard-list call — the trigger for
261
+ * routing the whole ternary through `bf_attr` in `lowerRegisteredAttrCall`.
262
+ */
263
+ function ternaryHasQueryBranch(
264
+ ctx: GoEmitContext,
265
+ consequent: ParsedExpr,
266
+ alternate: ParsedExpr,
267
+ ): boolean {
268
+ const branchHasQuery = (n: ParsedExpr): boolean =>
269
+ n.kind === 'conditional' ? ternaryHasQueryBranch(ctx, n.consequent, n.alternate) : isQueryGuardListCall(ctx, n)
270
+ return branchHasQuery(consequent) || branchHasQuery(alternate)
165
271
  }
166
272
 
167
273
  /**
@@ -127,7 +127,7 @@ import { analyzeBakeableStaticChildLoop, scalarToGoLiteral, type BakedStaticChil
127
127
  import { analyzeBakeableStaticElementLoop } from "./analysis/static-element-loop-bake.ts"
128
128
  import type { GoEmitContext } from "./emit-context.ts"
129
129
  import { inlineLocalHelperCall } from "./expr/helper-inline.ts"
130
- import { lowerRegisteredCall, lowerTernary } from "./expr/url-builder.ts"
130
+ import { lowerRegisteredAttrCall, lowerRegisteredCall, lowerRegisteredCallNode, lowerTernary } from "./expr/url-builder.ts"
131
131
  import {
132
132
  convertInitialValue,
133
133
  jsLiteralToGo,
@@ -4956,6 +4956,15 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
4956
4956
  }
4957
4957
 
4958
4958
  call(callee: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string {
4959
+ // #2842: a registered lowering (the built-in `queryHref`, or any userland
4960
+ // plugin) must win in EVERY position this shared dispatcher reaches — a
4961
+ // ternary branch, a template-literal interpolation, a binary operand —
4962
+ // not only when the call is the whole expression (`convertExpressionToGo`'s
4963
+ // own early return). Same precedence as that top-level path, where the
4964
+ // registry is consulted before signal-read resolution and template
4965
+ // primitives.
4966
+ const lowered = lowerRegisteredCallNode(this.emitCtx, callee, args)
4967
+ if (lowered !== null) return lowered
4959
4968
  // Signal call: count() -> .Count (or $.Count inside a loop). An env-signal
4960
4969
  // binding (`searchParams()`, or an aliased `sp()`) resolves to the canonical
4961
4970
  // `.SearchParams` field regardless of the JS name.
@@ -8021,10 +8030,30 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
8021
8030
  ? value.expr
8022
8031
  : value.expr.slice(0, value.expr.indexOf('?')).trim(),
8023
8032
  )
8024
- const valueExpr = this.renderParsedExpr(parsed.consequent)
8025
- const body = `${name}="{{${valueExpr}}}"`
8033
+ // #2842 / #2743: a `query` guard-list consequent (queryHref) takes
8034
+ // the whole-attribute `bf_attr` route INSIDE the `{{if}}`, so
8035
+ // html/template's URL-context inference never percent-encodes it —
8036
+ // the same route the direct-call and non-undefined-ternary shapes
8037
+ // take. The consequent is passed alone (not the ternary): omission
8038
+ // needs this `{{if}}` wrapper, which `bf_attr` can't express on its
8039
+ // own. Any other consequent (a `helper-call` plugin, an unmatched
8040
+ // call, a member/literal) keeps the ordinary `name="{{…}}"` form —
8041
+ // `call()` now consults the registry too, so a plugin call renders
8042
+ // its `bf_<helper>` pipeline there instead of invalid Go syntax.
8043
+ const attrConsequent = lowerRegisteredAttrCall(this.emitCtx, name, parsed.consequent)
8044
+ const body = attrConsequent !== null
8045
+ ? attrConsequent
8046
+ : `${name}="{{${this.renderParsedExpr(parsed.consequent)}}}"`
8026
8047
  return `${preamble}{{if ${goCond}}}${body}{{end}}`
8027
8048
  }
8049
+ // #2743 follow-up (pullfrog review on #2841): a `query` guard-list
8050
+ // value (queryHref) reachable through EITHER branch of this ternary
8051
+ // still needs the whole-attribute `bf_attr` route — otherwise the
8052
+ // pipeline below lands inside the ordinary `name="{{...}}"` wrapper
8053
+ // and html/template's URL-context inference still percent-encodes
8054
+ // whichever branch wins at render time. See `lowerRegisteredAttrCall`.
8055
+ const attrTernary = lowerRegisteredAttrCall(this.emitCtx, name, parsed)
8056
+ if (attrTernary !== null) return attrTernary
8028
8057
  // #2335: the ternary lowers to the pipeline-position `(bf_ternary …)`
8029
8058
  // value (no longer a `{{if}}…{{end}}` fragment), so wrap it in a single
8030
8059
  // `{{…}}` action inside the attribute string — `name="{{bf_ternary …}}"`.
@@ -8034,6 +8063,12 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
8034
8063
  // Inline Go template syntax with embedded `{{...}}` actions.
8035
8064
  return `${name}="${this.renderParsedExpr(parsed)}"`
8036
8065
  }
8066
+ // #2743: a `query` guard-list value (queryHref) emits the WHOLE
8067
+ // attribute via `bf_attr` (template.HTMLAttr) so html/template's
8068
+ // URL-context inference on the attribute name never percent-encodes
8069
+ // the base. See `lowerRegisteredAttrCall`.
8070
+ const attrAction = lowerRegisteredAttrCall(this.emitCtx, name, parsed)
8071
+ if (attrAction !== null) return attrAction
8037
8072
  // Nullish-attribute omission: when the attribute value is a BARE reference
8038
8073
  // to a nillable (`interface{}`) prop field, guard emission on `ne .X nil`
8039
8074
  // so an unset optional prop drops the attribute entirely instead of