@barefootjs/jinja 0.31.4 → 0.31.6
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/adapter/index.js +14 -42
- package/dist/adapter/jinja-adapter.d.ts +32 -36
- package/dist/adapter/jinja-adapter.d.ts.map +1 -1
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +25 -47
- package/dist/vite.js +145 -191
- package/package.json +5 -5
- package/src/__tests__/jinja-adapter-unit.test.ts +59 -21
- package/src/adapter/jinja-adapter.ts +77 -83
- package/src/conformance-pins.ts +14 -5
package/dist/adapter/index.js
CHANGED
|
@@ -187314,8 +187314,8 @@ import {
|
|
|
187314
187314
|
dangerousInnerHtmlMetacharViolation,
|
|
187315
187315
|
dangerousInnerHtmlDiagnostic,
|
|
187316
187316
|
resolveStaticLoopSource,
|
|
187317
|
-
|
|
187318
|
-
|
|
187317
|
+
derivesScopeFromSlot,
|
|
187318
|
+
BindingScope
|
|
187319
187319
|
} from "@barefootjs/jsx";
|
|
187320
187320
|
|
|
187321
187321
|
// src/adapter/boolean-result.ts
|
|
@@ -188320,8 +188320,7 @@ class JinjaAdapter extends BaseAdapter {
|
|
|
188320
188320
|
_searchParamsLocals = new Set;
|
|
188321
188321
|
_loweringMatchers = [];
|
|
188322
188322
|
localConstants = [];
|
|
188323
|
-
|
|
188324
|
-
loopBoundNames = new Map;
|
|
188323
|
+
scope = BindingScope.EMPTY;
|
|
188325
188324
|
nullableOptionalProps = new Set;
|
|
188326
188325
|
constructor(options = {}) {
|
|
188327
188326
|
super();
|
|
@@ -188337,8 +188336,7 @@ class JinjaAdapter extends BaseAdapter {
|
|
|
188337
188336
|
this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
|
|
188338
188337
|
this.booleanTypedProps = collectBooleanTypedProps(ir);
|
|
188339
188338
|
this.localConstants = ir.metadata.localConstants ?? [];
|
|
188340
|
-
this.
|
|
188341
|
-
this.loopBoundNames.clear();
|
|
188339
|
+
this.scope = BindingScope.EMPTY;
|
|
188342
188340
|
this.nullableOptionalProps = collectNullableOptionalProps(ir);
|
|
188343
188341
|
this.stringValueNames = collectStringValueNames(ir);
|
|
188344
188342
|
this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
|
|
@@ -188633,7 +188631,7 @@ ${whenTrue}
|
|
|
188633
188631
|
});
|
|
188634
188632
|
}
|
|
188635
188633
|
const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
|
|
188636
|
-
isNameShadowed:
|
|
188634
|
+
isNameShadowed: this.scope.asShadowPredicate()
|
|
188637
188635
|
});
|
|
188638
188636
|
const staticArray = staticItems !== null ? staticValueToJinja(staticItems) : null;
|
|
188639
188637
|
const arrayName = loop.array.trim();
|
|
@@ -188646,7 +188644,8 @@ ${whenTrue}
|
|
|
188646
188644
|
message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the Jinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
|
|
188647
188645
|
loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
|
|
188648
188646
|
suggestion: {
|
|
188649
|
-
message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client."
|
|
188647
|
+
message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client.",
|
|
188648
|
+
escape: [{ kind: "prop-precompute" }, { kind: "client-directive" }]
|
|
188650
188649
|
}
|
|
188651
188650
|
});
|
|
188652
188651
|
}
|
|
@@ -188687,40 +188686,15 @@ ${whenTrue}
|
|
|
188687
188686
|
this.inLoop = true;
|
|
188688
188687
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
188689
188688
|
this.currentLoopKeyDepth = loop.depth;
|
|
188689
|
+
const prevScope = this.scope;
|
|
188690
|
+
this.scope = prevScope.enterLoopRow(loop);
|
|
188690
188691
|
const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `{% set ${jinjaIdent(d.name)} = ${this.convertExpressionToJinja(d.raw, d.valueParsed)} %}`);
|
|
188691
|
-
const loopBound = [];
|
|
188692
|
-
if (loop.objectIteration === "entries") {
|
|
188693
|
-
loopBound.push(loop.index ?? param, param);
|
|
188694
|
-
} else if (loop.objectIteration === "keys" || loop.objectIteration === "values") {
|
|
188695
|
-
loopBound.push(param);
|
|
188696
|
-
} else if (loop.iterationShape === "keys") {
|
|
188697
|
-
loopBound.push("__bf_item", param);
|
|
188698
|
-
} else if (supportableDestructure) {
|
|
188699
|
-
loopBound.push("__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name));
|
|
188700
|
-
if (loop.index)
|
|
188701
|
-
loopBound.push(loop.index);
|
|
188702
|
-
} else {
|
|
188703
|
-
loopBound.push(param);
|
|
188704
|
-
if (loop.index)
|
|
188705
|
-
loopBound.push(loop.index);
|
|
188706
|
-
}
|
|
188707
|
-
for (const d of loop.preamble?.declarations ?? [])
|
|
188708
|
-
loopBound.push(d.name);
|
|
188709
|
-
for (const n of loopBound) {
|
|
188710
|
-
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188711
|
-
}
|
|
188712
188692
|
const childrenUnderLoop = this.renderChildren(loop.children);
|
|
188713
|
-
for (const n of loopBound) {
|
|
188714
|
-
const c = (this.loopBoundNames.get(n) ?? 1) - 1;
|
|
188715
|
-
if (c <= 0)
|
|
188716
|
-
this.loopBoundNames.delete(n);
|
|
188717
|
-
else
|
|
188718
|
-
this.loopBoundNames.set(n, c);
|
|
188719
|
-
}
|
|
188720
188693
|
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
188721
188694
|
this.inLoop = prevInLoop;
|
|
188722
188695
|
const bodyChildren = loop.bodyIsItemConditional && loop.key ? `{{ bf.comment("loop-i:" ~ bf.string(${this.convertExpressionToJinja(loop.key)})) | safe }}
|
|
188723
188696
|
${childrenUnderLoop}` : childrenUnderLoop;
|
|
188697
|
+
this.scope = prevScope;
|
|
188724
188698
|
const lines = [];
|
|
188725
188699
|
lines.push(`{{ bf.comment("loop:${loop.markerId}") | safe }}`);
|
|
188726
188700
|
const forHeader = loop.objectIteration === "entries" ? `{% for ${jinjaIdent(loop.index ?? param)}, ${jinjaIdent(param)} in ${array}.items() %}` : loop.objectIteration === "keys" ? `{% for ${jinjaIdent(param)} in ${array}.keys() %}` : loop.objectIteration === "values" ? `{% for ${jinjaIdent(param)} in ${array}.values() %}` : `{% for ${jinjaIdent(loopVar)} in ${array} %}`;
|
|
@@ -188952,7 +188926,7 @@ ${name}="{{ bf.string(${val}) }}"
|
|
|
188952
188926
|
if (ternaryDict !== null) {
|
|
188953
188927
|
return `{{ bf.spread_attrs(${ternaryDict}) | safe }}`;
|
|
188954
188928
|
}
|
|
188955
|
-
if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.
|
|
188929
|
+
if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
|
|
188956
188930
|
const localConst = (this.localConstants ?? []).find((c) => c.name === trimmed && !c.isModule);
|
|
188957
188931
|
if (localConst?.value !== undefined) {
|
|
188958
188932
|
const initTrimmed = localConst.value.trim();
|
|
@@ -189187,7 +189161,7 @@ Options:
|
|
|
189187
189161
|
return this.booleanTypedProps.has(bare);
|
|
189188
189162
|
}
|
|
189189
189163
|
isLoopBoundName(name) {
|
|
189190
|
-
return this.
|
|
189164
|
+
return this.scope.isBound(name);
|
|
189191
189165
|
}
|
|
189192
189166
|
shouldBoolStr(expr, name) {
|
|
189193
189167
|
if (isExplicitStringCall(expr))
|
|
@@ -189195,7 +189169,7 @@ Options:
|
|
|
189195
189169
|
return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
|
|
189196
189170
|
}
|
|
189197
189171
|
_resolveLiteralConst(name) {
|
|
189198
|
-
if (this.
|
|
189172
|
+
if (this.scope.isBound(name))
|
|
189199
189173
|
return null;
|
|
189200
189174
|
const c = (this.localConstants ?? []).find((lc) => lc.name === name);
|
|
189201
189175
|
if (c?.value === undefined)
|
|
@@ -189209,9 +189183,7 @@ Options:
|
|
|
189209
189183
|
return null;
|
|
189210
189184
|
}
|
|
189211
189185
|
_resolveStaticRecordLiteral(objectName, key) {
|
|
189212
|
-
|
|
189213
|
-
return null;
|
|
189214
|
-
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
|
|
189186
|
+
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
|
|
189215
189187
|
if (!hit)
|
|
189216
189188
|
return null;
|
|
189217
189189
|
return hit.kind === "number" ? hit.text : `'${escapeJinjaSingleQuoted(hit.text)}'`;
|
|
@@ -168,29 +168,24 @@ export declare class JinjaAdapter extends BaseAdapter implements IRNodeEmitter<J
|
|
|
168
168
|
*/
|
|
169
169
|
private localConstants;
|
|
170
170
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* `
|
|
186
|
-
*
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
* local-const fallback (#2489) need to know whether a name is loop-bound
|
|
190
|
-
* AT THIS POSITION, because for those the coarse fallback would silently
|
|
191
|
-
* mis-render a genuine occurrence of the same name outside the loop too.
|
|
192
|
-
*/
|
|
193
|
-
private loopBoundNames;
|
|
171
|
+
* The one canonical, position-accurate "names bound by an enclosing loop
|
|
172
|
+
* callback" service (#2482 Stage 2) — replaces the two ad-hoc devices
|
|
173
|
+
* this adapter used to carry side by side: a coarse whole-component
|
|
174
|
+
* shadow-name Set (built once at `generate()` entry, used only to guard
|
|
175
|
+
* static-const inlining) and a ref-counted, position-accurate live map
|
|
176
|
+
* (pushed/popped around `renderLoop`'s body, used for the boolean-prop/
|
|
177
|
+
* nullable-optional classification sites (#2488) and `emitSpread`'s
|
|
178
|
+
* local-const fallback (#2489)). Both consulted the "is this name
|
|
179
|
+
* loop-bound" question with DIFFERENT meanings — the coarse/live drift
|
|
180
|
+
* #2482 Stage 2 ends. Every shadow-guard site now reads this ONE
|
|
181
|
+
* threaded, immutable scope: `enterLoopRow`/pop-by-reference around
|
|
182
|
+
* `renderChildren(loop.children)` in `renderLoop`, mirroring the Stage
|
|
183
|
+
* 1a/1b `ctx.scope` precedent in `jsx-to-ir.ts`. `IRLoop` already
|
|
184
|
+
* structurally satisfies `LoopBindingSource`
|
|
185
|
+
* (`param`/`index`/`paramBindings`/`preamble`), so `renderLoop` passes
|
|
186
|
+
* the loop node straight to `enterLoopRow`.
|
|
187
|
+
*/
|
|
188
|
+
private scope;
|
|
194
189
|
/**
|
|
195
190
|
* Optional, no-default props that are `None` when the caller omits them.
|
|
196
191
|
* Their bare-reference attribute emission is guarded with a Jinja
|
|
@@ -403,7 +398,7 @@ export declare class JinjaAdapter extends BaseAdapter implements IRNodeEmitter<J
|
|
|
403
398
|
consequent: string;
|
|
404
399
|
} | null;
|
|
405
400
|
isBooleanTypedPropRef(expr: string): boolean;
|
|
406
|
-
/** Position-accurate loop-bound-name check — see `
|
|
401
|
+
/** Position-accurate loop-bound-name check — see `this.scope`'s docstring. */
|
|
407
402
|
private isLoopBoundName;
|
|
408
403
|
/**
|
|
409
404
|
* Whether an attribute-value expression should route through
|
|
@@ -425,14 +420,13 @@ export declare class JinjaAdapter extends BaseAdapter implements IRNodeEmitter<J
|
|
|
425
420
|
* context, so a bare reference would resolve to Undefined.
|
|
426
421
|
*
|
|
427
422
|
* The lookup is a flat name match with no notion of AST scope, so a
|
|
428
|
-
* name
|
|
429
|
-
* inlines (#2221) — the occurrence may be the
|
|
430
|
-
* binding, and substituting the outer const's
|
|
431
|
-
* iteration with the same hard-coded literal.
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
* `collectStringValueNames`.
|
|
423
|
+
* name bound by the CURRENTLY ENCLOSING loop's item/index/destructure/
|
|
424
|
+
* preamble param never inlines (#2221) — the occurrence may be the
|
|
425
|
+
* loop's own (shadowing) binding, and substituting the outer const's
|
|
426
|
+
* value there renders every iteration with the same hard-coded literal.
|
|
427
|
+
* Position-accurate via the threaded `this.scope` (#2482 Stage 2) — a
|
|
428
|
+
* same-named const elsewhere in the component, outside any loop that
|
|
429
|
+
* shadows it, still inlines.
|
|
436
430
|
*/
|
|
437
431
|
private _resolveLiteralConst;
|
|
438
432
|
/**
|
|
@@ -443,11 +437,13 @@ export declare class JinjaAdapter extends BaseAdapter implements IRNodeEmitter<J
|
|
|
443
437
|
* scope, so an enclosing loop callback's own param of the same name
|
|
444
438
|
* (`.map((cfg) => <li>{cfg.x}</li>)` shadowing a module `const cfg = {…}`)
|
|
445
439
|
* still resolved to the OUTER const's member value at every iteration
|
|
446
|
-
* (#2237) — the sibling hazard to #2221's `_resolveLiteralConst`.
|
|
447
|
-
*
|
|
448
|
-
*
|
|
440
|
+
* (#2237) — the sibling hazard to #2221's `_resolveLiteralConst`.
|
|
441
|
+
* Position-accurate via the threaded `this.scope` (#2482 Stage 2), passed
|
|
442
|
+
* as `lookupStaticRecordLiteral`'s required guard: a name the CURRENTLY
|
|
443
|
+
* ENCLOSING loop binds never inlines, falling back to the bare
|
|
449
444
|
* `cfg['x']` member expression (which a Jinja for-loop binds correctly
|
|
450
|
-
* at the shadowed
|
|
445
|
+
* at the shadowed occurrence); a same-named const elsewhere, outside any
|
|
446
|
+
* loop that shadows it, still inlines.
|
|
451
447
|
*/
|
|
452
448
|
private _resolveStaticRecordLiteral;
|
|
453
449
|
private _resolveModuleStringConst;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/jinja-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,EAgChB,MAAM,iBAAiB,CAAA;AAKxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAkCpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEzD,qBAAa,YAAa,SAAQ,WAAY,YAAW,aAAa,CAAC,cAAc,CAAC;IACpF,IAAI,SAAU;IACd,SAAS,SAAW;IACpB,qBAAqB,UAAO;IAE5B;;;;;OAKG;IACH,kBAAkB,EAAE,yBAAyB,CAA2B;IAExE,OAAO,CAAC,aAAa,CAAa;IAClC;;;uCAGmC;IACnC,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAiB;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB,CAAI;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,iBAAiB,CAAyB;IAClD;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAAyB;IAEjD;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB,CAAiC;IAE3D;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB,CAAyB;IAEpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAwB;IAEjD;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAmC;IAEzD
|
|
1
|
+
{"version":3,"file":"jinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/jinja-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,EAgChB,MAAM,iBAAiB,CAAA;AAKxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAkCpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEzD,qBAAa,YAAa,SAAQ,WAAY,YAAW,aAAa,CAAC,cAAc,CAAC;IACpF,IAAI,SAAU;IACd,SAAS,SAAW;IACpB,qBAAqB,UAAO;IAE5B;;;;;OAKG;IACH,kBAAkB,EAAE,yBAAyB,CAA2B;IAExE,OAAO,CAAC,aAAa,CAAa;IAClC;;;uCAGmC;IACnC,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAiB;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB,CAAI;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,iBAAiB,CAAyB;IAClD;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAAyB;IAEjD;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB,CAAiC;IAE3D;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB,CAAyB;IAEpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAwB;IAEjD;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAmC;IAEzD;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,KAAK,CAAmC;IAEhD;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB,CAAyB;IAEtD,YAAY,OAAO,GAAE,mBAAwB,EAM5C;IAED,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,aAAa,CA6EzE;IAMD,OAAO,CAAC,2BAA2B;IAkDnC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/B;IAMD,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAE5F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI7B;IAED,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEzC;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEpG;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEtF;IAED,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEhG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAE9F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEpG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAe9F;IAED,uEAAuE;IACvE,OAAO,CAAC,kBAAkB;IAmB1B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,0BAA0B;IAYlC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAExF;IAMD,aAAa,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAqCxC;IAED;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IA2BhC,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CA6B3C;IAMD,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAuC7C;IAED,OAAO,CAAC,gBAAgB;IAOxB;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAcnC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkT/B;IAMD;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAoCpC;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,2BAA2B;IAUnC;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,4BAA4B;IAiBpC,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CA8FzC;IAED,OAAO,CAAC,sBAAsB,CAAI;IAElC;+DAC2D;IAC3D,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,UAAU;IAYT,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAQ1C;IAMD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAqKlC;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,gBAAgB;IAoCxB,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAIjD;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAMD;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,kCAAkC;IA8B1C;;;;;OAKG;IACH,OAAO,CAAC,iCAAiC;IAmBzC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAuBvC;;;;;;;OAOG;IACH,OAAO,KAAK,OAAO,GASlB;IAED;;;;;OAKG;IACH,OAAO,KAAK,SAAS,GASpB;IAED,sEAAsE;IACtE,OAAO,KAAK,OAAO,GAKlB;IAED,OAAO,CAAC,wBAAwB;IAyEhC;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAK/B;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;gFAE4E;IAC5E,OAAO,CAAC,kBAAkB;IAI1B;;;;OAIG;IACH,8BAA8B,CAC5B,IAAI,EAAE,MAAM,GACX;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAgBlD;IAED,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAW3C;IAED,8EAA8E;IAC9E,OAAO,CAAC,eAAe;IAIvB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAKrB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,2BAA2B;IAQnC,OAAO,CAAC,yBAAyB;IAUjC,OAAO,CAAC,gBAAgB;IAcxB,iFAAiF;IACjF,OAAO,CAAC,4BAA4B;CAGrC;AAED,eAAO,MAAM,YAAY,cAAqB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAkJ7B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -187314,8 +187314,8 @@ import {
|
|
|
187314
187314
|
dangerousInnerHtmlMetacharViolation,
|
|
187315
187315
|
dangerousInnerHtmlDiagnostic,
|
|
187316
187316
|
resolveStaticLoopSource,
|
|
187317
|
-
|
|
187318
|
-
|
|
187317
|
+
derivesScopeFromSlot,
|
|
187318
|
+
BindingScope
|
|
187319
187319
|
} from "@barefootjs/jsx";
|
|
187320
187320
|
|
|
187321
187321
|
// src/adapter/boolean-result.ts
|
|
@@ -188320,8 +188320,7 @@ class JinjaAdapter extends BaseAdapter {
|
|
|
188320
188320
|
_searchParamsLocals = new Set;
|
|
188321
188321
|
_loweringMatchers = [];
|
|
188322
188322
|
localConstants = [];
|
|
188323
|
-
|
|
188324
|
-
loopBoundNames = new Map;
|
|
188323
|
+
scope = BindingScope.EMPTY;
|
|
188325
188324
|
nullableOptionalProps = new Set;
|
|
188326
188325
|
constructor(options = {}) {
|
|
188327
188326
|
super();
|
|
@@ -188337,8 +188336,7 @@ class JinjaAdapter extends BaseAdapter {
|
|
|
188337
188336
|
this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
|
|
188338
188337
|
this.booleanTypedProps = collectBooleanTypedProps(ir);
|
|
188339
188338
|
this.localConstants = ir.metadata.localConstants ?? [];
|
|
188340
|
-
this.
|
|
188341
|
-
this.loopBoundNames.clear();
|
|
188339
|
+
this.scope = BindingScope.EMPTY;
|
|
188342
188340
|
this.nullableOptionalProps = collectNullableOptionalProps(ir);
|
|
188343
188341
|
this.stringValueNames = collectStringValueNames(ir);
|
|
188344
188342
|
this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
|
|
@@ -188633,7 +188631,7 @@ ${whenTrue}
|
|
|
188633
188631
|
});
|
|
188634
188632
|
}
|
|
188635
188633
|
const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
|
|
188636
|
-
isNameShadowed:
|
|
188634
|
+
isNameShadowed: this.scope.asShadowPredicate()
|
|
188637
188635
|
});
|
|
188638
188636
|
const staticArray = staticItems !== null ? staticValueToJinja(staticItems) : null;
|
|
188639
188637
|
const arrayName = loop.array.trim();
|
|
@@ -188646,7 +188644,8 @@ ${whenTrue}
|
|
|
188646
188644
|
message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the Jinja adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
|
|
188647
188645
|
loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
|
|
188648
188646
|
suggestion: {
|
|
188649
|
-
message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client."
|
|
188647
|
+
message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client.",
|
|
188648
|
+
escape: [{ kind: "prop-precompute" }, { kind: "client-directive" }]
|
|
188650
188649
|
}
|
|
188651
188650
|
});
|
|
188652
188651
|
}
|
|
@@ -188687,40 +188686,15 @@ ${whenTrue}
|
|
|
188687
188686
|
this.inLoop = true;
|
|
188688
188687
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
188689
188688
|
this.currentLoopKeyDepth = loop.depth;
|
|
188689
|
+
const prevScope = this.scope;
|
|
188690
|
+
this.scope = prevScope.enterLoopRow(loop);
|
|
188690
188691
|
const preambleLines = (loop.preamble?.declarations ?? []).map((d) => `{% set ${jinjaIdent(d.name)} = ${this.convertExpressionToJinja(d.raw, d.valueParsed)} %}`);
|
|
188691
|
-
const loopBound = [];
|
|
188692
|
-
if (loop.objectIteration === "entries") {
|
|
188693
|
-
loopBound.push(loop.index ?? param, param);
|
|
188694
|
-
} else if (loop.objectIteration === "keys" || loop.objectIteration === "values") {
|
|
188695
|
-
loopBound.push(param);
|
|
188696
|
-
} else if (loop.iterationShape === "keys") {
|
|
188697
|
-
loopBound.push("__bf_item", param);
|
|
188698
|
-
} else if (supportableDestructure) {
|
|
188699
|
-
loopBound.push("__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name));
|
|
188700
|
-
if (loop.index)
|
|
188701
|
-
loopBound.push(loop.index);
|
|
188702
|
-
} else {
|
|
188703
|
-
loopBound.push(param);
|
|
188704
|
-
if (loop.index)
|
|
188705
|
-
loopBound.push(loop.index);
|
|
188706
|
-
}
|
|
188707
|
-
for (const d of loop.preamble?.declarations ?? [])
|
|
188708
|
-
loopBound.push(d.name);
|
|
188709
|
-
for (const n of loopBound) {
|
|
188710
|
-
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188711
|
-
}
|
|
188712
188692
|
const childrenUnderLoop = this.renderChildren(loop.children);
|
|
188713
|
-
for (const n of loopBound) {
|
|
188714
|
-
const c = (this.loopBoundNames.get(n) ?? 1) - 1;
|
|
188715
|
-
if (c <= 0)
|
|
188716
|
-
this.loopBoundNames.delete(n);
|
|
188717
|
-
else
|
|
188718
|
-
this.loopBoundNames.set(n, c);
|
|
188719
|
-
}
|
|
188720
188693
|
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
188721
188694
|
this.inLoop = prevInLoop;
|
|
188722
188695
|
const bodyChildren = loop.bodyIsItemConditional && loop.key ? `{{ bf.comment("loop-i:" ~ bf.string(${this.convertExpressionToJinja(loop.key)})) | safe }}
|
|
188723
188696
|
${childrenUnderLoop}` : childrenUnderLoop;
|
|
188697
|
+
this.scope = prevScope;
|
|
188724
188698
|
const lines = [];
|
|
188725
188699
|
lines.push(`{{ bf.comment("loop:${loop.markerId}") | safe }}`);
|
|
188726
188700
|
const forHeader = loop.objectIteration === "entries" ? `{% for ${jinjaIdent(loop.index ?? param)}, ${jinjaIdent(param)} in ${array}.items() %}` : loop.objectIteration === "keys" ? `{% for ${jinjaIdent(param)} in ${array}.keys() %}` : loop.objectIteration === "values" ? `{% for ${jinjaIdent(param)} in ${array}.values() %}` : `{% for ${jinjaIdent(loopVar)} in ${array} %}`;
|
|
@@ -188952,7 +188926,7 @@ ${name}="{{ bf.string(${val}) }}"
|
|
|
188952
188926
|
if (ternaryDict !== null) {
|
|
188953
188927
|
return `{{ bf.spread_attrs(${ternaryDict}) | safe }}`;
|
|
188954
188928
|
}
|
|
188955
|
-
if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.
|
|
188929
|
+
if (/^[A-Za-z_$][\w$]*$/.test(trimmed) && !this.scope.isBound(trimmed)) {
|
|
188956
188930
|
const localConst = (this.localConstants ?? []).find((c) => c.name === trimmed && !c.isModule);
|
|
188957
188931
|
if (localConst?.value !== undefined) {
|
|
188958
188932
|
const initTrimmed = localConst.value.trim();
|
|
@@ -189187,7 +189161,7 @@ Options:
|
|
|
189187
189161
|
return this.booleanTypedProps.has(bare);
|
|
189188
189162
|
}
|
|
189189
189163
|
isLoopBoundName(name) {
|
|
189190
|
-
return this.
|
|
189164
|
+
return this.scope.isBound(name);
|
|
189191
189165
|
}
|
|
189192
189166
|
shouldBoolStr(expr, name) {
|
|
189193
189167
|
if (isExplicitStringCall(expr))
|
|
@@ -189195,7 +189169,7 @@ Options:
|
|
|
189195
189169
|
return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
|
|
189196
189170
|
}
|
|
189197
189171
|
_resolveLiteralConst(name) {
|
|
189198
|
-
if (this.
|
|
189172
|
+
if (this.scope.isBound(name))
|
|
189199
189173
|
return null;
|
|
189200
189174
|
const c = (this.localConstants ?? []).find((lc) => lc.name === name);
|
|
189201
189175
|
if (c?.value === undefined)
|
|
@@ -189209,9 +189183,7 @@ Options:
|
|
|
189209
189183
|
return null;
|
|
189210
189184
|
}
|
|
189211
189185
|
_resolveStaticRecordLiteral(objectName, key) {
|
|
189212
|
-
|
|
189213
|
-
return null;
|
|
189214
|
-
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
|
|
189186
|
+
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants, (name) => this.scope.isBound(name));
|
|
189215
189187
|
if (!hit)
|
|
189216
189188
|
return null;
|
|
189217
189189
|
return hit.kind === "number" ? hit.text : `'${escapeJinjaSingleQuoted(hit.text)}'`;
|
|
@@ -189261,17 +189233,23 @@ var conformancePins = {
|
|
|
189261
189233
|
"tag-cloud": [{ code: "BF021", severity: "error" }],
|
|
189262
189234
|
"preamble-cells": [{ code: "BF021", severity: "error" }],
|
|
189263
189235
|
"static-array-from-props": [
|
|
189264
|
-
{
|
|
189236
|
+
{
|
|
189237
|
+
code: "BF101",
|
|
189238
|
+
severity: "error",
|
|
189239
|
+
issue: "https://github.com/piconic-ai/barefootjs/issues/2321"
|
|
189240
|
+
}
|
|
189265
189241
|
],
|
|
189266
189242
|
"static-array-from-props-with-component": [
|
|
189267
|
-
{
|
|
189243
|
+
{
|
|
189244
|
+
code: "BF101",
|
|
189245
|
+
severity: "error",
|
|
189246
|
+
issue: "https://github.com/piconic-ai/barefootjs/issues/2321"
|
|
189247
|
+
}
|
|
189268
189248
|
],
|
|
189269
189249
|
"filter-nested-callback-predicate": [
|
|
189270
189250
|
{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }
|
|
189271
189251
|
],
|
|
189272
|
-
"filter-nested-find-predicate": [
|
|
189273
|
-
{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }
|
|
189274
|
-
],
|
|
189252
|
+
"filter-nested-find-predicate": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2320" }],
|
|
189275
189253
|
"date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }]
|
|
189276
189254
|
};
|
|
189277
189255
|
// src/render-divergences.ts
|