@barefootjs/rust 0.18.5 → 0.19.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.
- package/dist/adapter/index.js +74 -6
- package/dist/adapter/lib/static-value.d.ts +13 -0
- package/dist/adapter/lib/static-value.d.ts.map +1 -0
- package/dist/adapter/minijinja-adapter.d.ts +41 -0
- package/dist/adapter/minijinja-adapter.d.ts.map +1 -1
- package/dist/adapter/props/prop-classes.d.ts +3 -2
- package/dist/adapter/props/prop-classes.d.ts.map +1 -1
- package/dist/build.js +74 -6
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +75 -12
- package/dist/render-divergences.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/minijinja-adapter-unit.test.ts +119 -0
- package/src/__tests__/minijinja-adapter.test.ts +13 -0
- package/src/adapter/lib/static-value.ts +39 -0
- package/src/adapter/minijinja-adapter.ts +102 -5
- package/src/adapter/props/prop-classes.ts +4 -3
- package/src/conformance-pins.ts +24 -25
- package/src/render-divergences.ts +6 -1
- package/src/test-render.ts +11 -144
package/dist/adapter/index.js
CHANGED
|
@@ -187308,7 +187308,13 @@ import {
|
|
|
187308
187308
|
prepareLoweringMatchers,
|
|
187309
187309
|
queryHrefArgs,
|
|
187310
187310
|
isValidHelperId,
|
|
187311
|
-
sortComparatorFromArrow as sortComparatorFromArrow2
|
|
187311
|
+
sortComparatorFromArrow as sortComparatorFromArrow2,
|
|
187312
|
+
isDangerousInnerHtmlAttr,
|
|
187313
|
+
resolveDangerousInnerHtml,
|
|
187314
|
+
dangerousInnerHtmlMetacharViolation,
|
|
187315
|
+
dangerousInnerHtmlDiagnostic,
|
|
187316
|
+
resolveStaticLoopSource,
|
|
187317
|
+
collectLoopBoundNames
|
|
187312
187318
|
} from "@barefootjs/jsx";
|
|
187313
187319
|
|
|
187314
187320
|
// src/adapter/boolean-result.ts
|
|
@@ -187686,6 +187692,39 @@ function renderFlatMethod(recv, depth, emit) {
|
|
|
187686
187692
|
return `bf.flat(${recv}, ${d})`;
|
|
187687
187693
|
}
|
|
187688
187694
|
|
|
187695
|
+
// src/adapter/lib/static-value.ts
|
|
187696
|
+
function staticValueToMinijinja(value) {
|
|
187697
|
+
if (value === null || value === undefined)
|
|
187698
|
+
return "none";
|
|
187699
|
+
if (typeof value === "boolean")
|
|
187700
|
+
return value ? "true" : "false";
|
|
187701
|
+
if (typeof value === "number")
|
|
187702
|
+
return String(value);
|
|
187703
|
+
if (typeof value === "string")
|
|
187704
|
+
return `'${escapeMinijinjaSingleQuoted(value)}'`;
|
|
187705
|
+
if (Array.isArray(value)) {
|
|
187706
|
+
const items = [];
|
|
187707
|
+
for (const el of value) {
|
|
187708
|
+
const serialized = staticValueToMinijinja(el);
|
|
187709
|
+
if (serialized === null)
|
|
187710
|
+
return null;
|
|
187711
|
+
items.push(serialized);
|
|
187712
|
+
}
|
|
187713
|
+
return `[${items.join(", ")}]`;
|
|
187714
|
+
}
|
|
187715
|
+
if (typeof value === "object") {
|
|
187716
|
+
const entries = [];
|
|
187717
|
+
for (const [key, val] of Object.entries(value)) {
|
|
187718
|
+
const serialized = staticValueToMinijinja(val);
|
|
187719
|
+
if (serialized === null)
|
|
187720
|
+
return null;
|
|
187721
|
+
entries.push(`${minijinjaHashKey(key)}: ${serialized}`);
|
|
187722
|
+
}
|
|
187723
|
+
return `{${entries.join(", ")}}`;
|
|
187724
|
+
}
|
|
187725
|
+
return null;
|
|
187726
|
+
}
|
|
187727
|
+
|
|
187689
187728
|
// src/adapter/expr/emitters.ts
|
|
187690
187729
|
import {
|
|
187691
187730
|
groupBinaryOperand,
|
|
@@ -188231,7 +188270,7 @@ function collectBooleanTypedProps(ir) {
|
|
|
188231
188270
|
return new Set(ir.metadata.propsParams.filter((prop) => prop.type?.primitive === "boolean" || prop.type?.raw === "boolean").map((prop) => prop.name));
|
|
188232
188271
|
}
|
|
188233
188272
|
function collectNullableOptionalProps(ir) {
|
|
188234
|
-
return new Set(ir.metadata.propsParams.filter((p) => p.defaultValue === undefined && !p.isRest && p.type?.kind !== "primitive").map((p) => p.name));
|
|
188273
|
+
return new Set(ir.metadata.propsParams.filter((p) => p.defaultValue === undefined && !p.isRest && (p.type?.kind !== "primitive" || p.optional)).map((p) => p.name));
|
|
188235
188274
|
}
|
|
188236
188275
|
function collectStringValueNames(ir) {
|
|
188237
188276
|
const names = new Set;
|
|
@@ -188276,6 +188315,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188276
188315
|
_searchParamsLocals = new Set;
|
|
188277
188316
|
_loweringMatchers = [];
|
|
188278
188317
|
localConstants = [];
|
|
188318
|
+
staticLoopSourceBoundNames = new Set;
|
|
188279
188319
|
nullableOptionalProps = new Set;
|
|
188280
188320
|
constructor(options = {}) {
|
|
188281
188321
|
super();
|
|
@@ -188291,6 +188331,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188291
188331
|
this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
|
|
188292
188332
|
this.booleanTypedProps = collectBooleanTypedProps(ir);
|
|
188293
188333
|
this.localConstants = ir.metadata.localConstants ?? [];
|
|
188334
|
+
this.staticLoopSourceBoundNames = collectLoopBoundNames(ir);
|
|
188294
188335
|
this.nullableOptionalProps = collectNullableOptionalProps(ir);
|
|
188295
188336
|
this.stringValueNames = collectStringValueNames(ir);
|
|
188296
188337
|
this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
|
|
@@ -188412,7 +188453,8 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188412
188453
|
renderElement(element) {
|
|
188413
188454
|
const tag = element.tag;
|
|
188414
188455
|
const attrs = this.renderAttributes(element);
|
|
188415
|
-
const
|
|
188456
|
+
const dangerousHtml = this.renderDangerousInnerHtml(element);
|
|
188457
|
+
const children = dangerousHtml !== null ? dangerousHtml : this.renderChildren(element.children);
|
|
188416
188458
|
let hydrationAttrs = "";
|
|
188417
188459
|
if (element.needsScope) {
|
|
188418
188460
|
hydrationAttrs += ` ${this.renderScopeMarker("")}`;
|
|
@@ -188447,6 +188489,22 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188447
188489
|
}
|
|
188448
188490
|
return `<${tag}${attrs}${hydrationAttrs}>${children}</${tag}>`;
|
|
188449
188491
|
}
|
|
188492
|
+
renderDangerousInnerHtml(element) {
|
|
188493
|
+
const resolution = resolveDangerousInnerHtml(element);
|
|
188494
|
+
if (!resolution)
|
|
188495
|
+
return null;
|
|
188496
|
+
if (resolution.kind === "dynamic") {
|
|
188497
|
+
this.errors.push(dangerousInnerHtmlDiagnostic(resolution.expr, resolution.loc));
|
|
188498
|
+
return "";
|
|
188499
|
+
}
|
|
188500
|
+
const violation = dangerousInnerHtmlMetacharViolation(resolution.html, this.name);
|
|
188501
|
+
if (violation) {
|
|
188502
|
+
const attr = element.attrs.find(isDangerousInnerHtmlAttr);
|
|
188503
|
+
this.errors.push(dangerousInnerHtmlDiagnostic(`{ __html: ${JSON.stringify(resolution.html)} }`, attr.loc, violation));
|
|
188504
|
+
return "";
|
|
188505
|
+
}
|
|
188506
|
+
return resolution.html;
|
|
188507
|
+
}
|
|
188450
188508
|
renderExpression(expr) {
|
|
188451
188509
|
if (expr.clientOnly) {
|
|
188452
188510
|
if (expr.slotId) {
|
|
@@ -188454,7 +188512,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188454
188512
|
}
|
|
188455
188513
|
return "";
|
|
188456
188514
|
}
|
|
188457
|
-
const jinjaExpr = `bf.string(${this.convertExpressionToJinja(expr.expr)})`;
|
|
188515
|
+
const jinjaExpr = `bf.string(${this.convertExpressionToJinja(expr.expr, expr.parsed)})`;
|
|
188458
188516
|
if (expr.slotId) {
|
|
188459
188517
|
return `{{ bf.text_start("${expr.slotId}") | safe }}{{ ${jinjaExpr} }}{{ bf.text_end() | safe }}`;
|
|
188460
188518
|
}
|
|
@@ -188545,8 +188603,12 @@ ${whenTrue}
|
|
|
188545
188603
|
}
|
|
188546
188604
|
});
|
|
188547
188605
|
}
|
|
188606
|
+
const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
|
|
188607
|
+
isNameShadowed: (name) => this.staticLoopSourceBoundNames.has(name)
|
|
188608
|
+
});
|
|
188609
|
+
const staticArray = staticItems !== null ? staticValueToMinijinja(staticItems) : null;
|
|
188548
188610
|
const arrayName = loop.array.trim();
|
|
188549
|
-
if (/^[A-Za-z_$][\w$]*$/.test(arrayName)) {
|
|
188611
|
+
if (staticArray === null && /^[A-Za-z_$][\w$]*$/.test(arrayName)) {
|
|
188550
188612
|
const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
|
|
188551
188613
|
if (arrayConst && !arrayConst.isModule && this._resolveLiteralConst(arrayName) === null) {
|
|
188552
188614
|
this.errors.push({
|
|
@@ -188560,7 +188622,7 @@ ${whenTrue}
|
|
|
188560
188622
|
});
|
|
188561
188623
|
}
|
|
188562
188624
|
}
|
|
188563
|
-
const rawArray = this.convertExpressionToJinja(loop.array);
|
|
188625
|
+
const rawArray = staticArray ?? this.convertExpressionToJinja(loop.array);
|
|
188564
188626
|
let array = rawArray;
|
|
188565
188627
|
if (loop.sortComparator) {
|
|
188566
188628
|
const sort = loop.sortComparator;
|
|
@@ -188872,6 +188934,8 @@ ${name}="{{ bf.string(${val}) }}"
|
|
|
188872
188934
|
for (const attr of element.attrs) {
|
|
188873
188935
|
if (attr.clientOnly)
|
|
188874
188936
|
continue;
|
|
188937
|
+
if (isDangerousInnerHtmlAttr(attr))
|
|
188938
|
+
continue;
|
|
188875
188939
|
let attrName;
|
|
188876
188940
|
if (attr.name === "className")
|
|
188877
188941
|
attrName = "class";
|
|
@@ -189071,6 +189135,8 @@ Options:
|
|
|
189071
189135
|
return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
|
|
189072
189136
|
}
|
|
189073
189137
|
_resolveLiteralConst(name) {
|
|
189138
|
+
if (this.staticLoopSourceBoundNames.has(name))
|
|
189139
|
+
return null;
|
|
189074
189140
|
const c = (this.localConstants ?? []).find((lc) => lc.name === name);
|
|
189075
189141
|
if (c?.value === undefined)
|
|
189076
189142
|
return null;
|
|
@@ -189083,6 +189149,8 @@ Options:
|
|
|
189083
189149
|
return null;
|
|
189084
189150
|
}
|
|
189085
189151
|
_resolveStaticRecordLiteral(objectName, key) {
|
|
189152
|
+
if (this.staticLoopSourceBoundNames.has(objectName))
|
|
189153
|
+
return null;
|
|
189086
189154
|
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
|
|
189087
189155
|
if (!hit)
|
|
189088
189156
|
return null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize a compile-time-evaluated JS value (`@barefootjs/jsx`'s
|
|
3
|
+
* `evaluateStaticLiteral`/`resolveStaticLoopSource`, #2208) into a native
|
|
4
|
+
* MiniJinja literal. Used to inline a fully-static loop source (an inline
|
|
5
|
+
* array literal, or a function-scope local const with a static
|
|
6
|
+
* initializer) directly in a `{% for %}` header, rather than requiring a
|
|
7
|
+
* bound template variable.
|
|
8
|
+
*
|
|
9
|
+
* Returns `null` for a value this adapter can't represent as a literal —
|
|
10
|
+
* the caller falls back to its existing BF101 refusal instead of guessing.
|
|
11
|
+
*/
|
|
12
|
+
export declare function staticValueToMinijinja(value: unknown): string | null;
|
|
13
|
+
//# sourceMappingURL=static-value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-value.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/static-value.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAwBpE"}
|
|
@@ -193,6 +193,16 @@ export declare class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitt
|
|
|
193
193
|
* const (`const sizeAttrs = size ? {…} : {}`) to its initializer text.
|
|
194
194
|
*/
|
|
195
195
|
private localConstants;
|
|
196
|
+
/**
|
|
197
|
+
* Every name a `.map()`/`.filter()` loop callback binds as its item/index
|
|
198
|
+
* parameter anywhere in the component (#2208 fable review). A static
|
|
199
|
+
* loop-SOURCE name (e.g. a function-scope `const items = [...]`) must
|
|
200
|
+
* never resolve through `resolveStaticLoopSource` at a use site where a
|
|
201
|
+
* DIFFERENT, enclosing loop's own callback param shadows it — same
|
|
202
|
+
* shadowing hazard, and same coarse-but-safe mitigation, as #2212's
|
|
203
|
+
* `collectLoopBoundNames` use in `collectStringValueNames`.
|
|
204
|
+
*/
|
|
205
|
+
private staticLoopSourceBoundNames;
|
|
196
206
|
/**
|
|
197
207
|
* Optional, no-default props that are `None` when the caller omits them.
|
|
198
208
|
* Their bare-reference attribute emission is guarded with a Jinja
|
|
@@ -244,6 +254,13 @@ export declare class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitt
|
|
|
244
254
|
private providerObjectLiteralJinja;
|
|
245
255
|
emitAsync(node: IRAsync, _ctx: JinjaRenderCtx, _emit: EmitIRNode<JinjaRenderCtx>): string;
|
|
246
256
|
renderElement(element: IRElement): string;
|
|
257
|
+
/**
|
|
258
|
+
* `dangerouslySetInnerHTML={{ __html: '...' }}` (#2207) — see the Blade
|
|
259
|
+
* adapter's identical helper for the full rationale. `null` means the
|
|
260
|
+
* attribute is absent (caller falls through to normal `renderChildren`);
|
|
261
|
+
* a non-`null` string (possibly `''`) replaces the children outright.
|
|
262
|
+
*/
|
|
263
|
+
private renderDangerousInnerHtml;
|
|
247
264
|
renderExpression(expr: IRExpression): string;
|
|
248
265
|
renderConditional(cond: IRConditional): string;
|
|
249
266
|
private renderNodeOrNull;
|
|
@@ -417,8 +434,32 @@ export declare class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitt
|
|
|
417
434
|
* single-quoted string literal (`const totalPages = 5`, #1897
|
|
418
435
|
* pagination) — function-scope consts never reach the per-render
|
|
419
436
|
* context, so a bare reference would resolve to Undefined.
|
|
437
|
+
*
|
|
438
|
+
* The lookup is a flat name match with no notion of AST scope, so a
|
|
439
|
+
* name that any loop callback binds as its item/index param never
|
|
440
|
+
* inlines (#2221) — the occurrence may be the loop's own (shadowing)
|
|
441
|
+
* binding, and substituting the outer const's value there renders every
|
|
442
|
+
* iteration with the same hard-coded literal. Coarse (a genuinely
|
|
443
|
+
* non-shadowed same-named const elsewhere in the component also stops
|
|
444
|
+
* inlining, falling back to the bare identifier) but safe — the same
|
|
445
|
+
* trade-off as #2212's `collectLoopBoundNames` use in
|
|
446
|
+
* `collectStringValueNames`.
|
|
420
447
|
*/
|
|
421
448
|
private _resolveLiteralConst;
|
|
449
|
+
/**
|
|
450
|
+
* Resolve `IDENT.key` where `IDENT` is a module-scope object-literal const
|
|
451
|
+
* (`variantClasses.ghost`, #1896/#1897) to the looked-up scalar.
|
|
452
|
+
*
|
|
453
|
+
* The lookup is a flat name match on `objectName` with no notion of AST
|
|
454
|
+
* scope, so an enclosing loop callback's own param of the same name
|
|
455
|
+
* (`.map((cfg) => <li>{cfg.x}</li>)` shadowing a module `const cfg = {…}`)
|
|
456
|
+
* still resolved to the OUTER const's member value at every iteration
|
|
457
|
+
* (#2237) — the sibling hazard to #2221's `_resolveLiteralConst`. Same
|
|
458
|
+
* coarse-but-safe `staticLoopSourceBoundNames` guard: any name a loop
|
|
459
|
+
* binds anywhere in the component never inlines, falling back to the bare
|
|
460
|
+
* `cfg.x` member expression (which a minijinja `for` loop binds correctly
|
|
461
|
+
* at the shadowed occurrences).
|
|
462
|
+
*/
|
|
422
463
|
private _resolveStaticRecordLiteral;
|
|
423
464
|
private _resolveModuleStringConst;
|
|
424
465
|
private _recordExprBF101;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiHG;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,
|
|
1
|
+
{"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,8 +14,9 @@ import type { ComponentIR } from '@barefootjs/jsx';
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function collectBooleanTypedProps(ir: ComponentIR): Set<string>;
|
|
16
16
|
/**
|
|
17
|
-
* Bare references to
|
|
18
|
-
* textarea's `rows`) are
|
|
17
|
+
* Bare references to presence-uncertain no-default props (non-primitive
|
|
18
|
+
* typed OR declared optional, #2259 — e.g. textarea's `rows`) are
|
|
19
|
+
* `None` when omitted → guarded with
|
|
19
20
|
* `is defined and is not none` in `emitExpression`. See the
|
|
20
21
|
* `nullableOptionalProps` field docstring in `minijinja-adapter.ts`.
|
|
21
22
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prop-classes.d.ts","sourceRoot":"","sources":["../../../src/adapter/props/prop-classes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAGlD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAMrE;AAED
|
|
1
|
+
{"version":3,"file":"prop-classes.d.ts","sourceRoot":"","sources":["../../../src/adapter/props/prop-classes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAGlD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAMrE;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAWzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAWpE"}
|
package/dist/build.js
CHANGED
|
@@ -187308,7 +187308,13 @@ import {
|
|
|
187308
187308
|
prepareLoweringMatchers,
|
|
187309
187309
|
queryHrefArgs,
|
|
187310
187310
|
isValidHelperId,
|
|
187311
|
-
sortComparatorFromArrow as sortComparatorFromArrow2
|
|
187311
|
+
sortComparatorFromArrow as sortComparatorFromArrow2,
|
|
187312
|
+
isDangerousInnerHtmlAttr,
|
|
187313
|
+
resolveDangerousInnerHtml,
|
|
187314
|
+
dangerousInnerHtmlMetacharViolation,
|
|
187315
|
+
dangerousInnerHtmlDiagnostic,
|
|
187316
|
+
resolveStaticLoopSource,
|
|
187317
|
+
collectLoopBoundNames
|
|
187312
187318
|
} from "@barefootjs/jsx";
|
|
187313
187319
|
|
|
187314
187320
|
// src/adapter/boolean-result.ts
|
|
@@ -187686,6 +187692,39 @@ function renderFlatMethod(recv, depth, emit) {
|
|
|
187686
187692
|
return `bf.flat(${recv}, ${d})`;
|
|
187687
187693
|
}
|
|
187688
187694
|
|
|
187695
|
+
// src/adapter/lib/static-value.ts
|
|
187696
|
+
function staticValueToMinijinja(value) {
|
|
187697
|
+
if (value === null || value === undefined)
|
|
187698
|
+
return "none";
|
|
187699
|
+
if (typeof value === "boolean")
|
|
187700
|
+
return value ? "true" : "false";
|
|
187701
|
+
if (typeof value === "number")
|
|
187702
|
+
return String(value);
|
|
187703
|
+
if (typeof value === "string")
|
|
187704
|
+
return `'${escapeMinijinjaSingleQuoted(value)}'`;
|
|
187705
|
+
if (Array.isArray(value)) {
|
|
187706
|
+
const items = [];
|
|
187707
|
+
for (const el of value) {
|
|
187708
|
+
const serialized = staticValueToMinijinja(el);
|
|
187709
|
+
if (serialized === null)
|
|
187710
|
+
return null;
|
|
187711
|
+
items.push(serialized);
|
|
187712
|
+
}
|
|
187713
|
+
return `[${items.join(", ")}]`;
|
|
187714
|
+
}
|
|
187715
|
+
if (typeof value === "object") {
|
|
187716
|
+
const entries = [];
|
|
187717
|
+
for (const [key, val] of Object.entries(value)) {
|
|
187718
|
+
const serialized = staticValueToMinijinja(val);
|
|
187719
|
+
if (serialized === null)
|
|
187720
|
+
return null;
|
|
187721
|
+
entries.push(`${minijinjaHashKey(key)}: ${serialized}`);
|
|
187722
|
+
}
|
|
187723
|
+
return `{${entries.join(", ")}}`;
|
|
187724
|
+
}
|
|
187725
|
+
return null;
|
|
187726
|
+
}
|
|
187727
|
+
|
|
187689
187728
|
// src/adapter/expr/emitters.ts
|
|
187690
187729
|
import {
|
|
187691
187730
|
groupBinaryOperand,
|
|
@@ -188231,7 +188270,7 @@ function collectBooleanTypedProps(ir) {
|
|
|
188231
188270
|
return new Set(ir.metadata.propsParams.filter((prop) => prop.type?.primitive === "boolean" || prop.type?.raw === "boolean").map((prop) => prop.name));
|
|
188232
188271
|
}
|
|
188233
188272
|
function collectNullableOptionalProps(ir) {
|
|
188234
|
-
return new Set(ir.metadata.propsParams.filter((p) => p.defaultValue === undefined && !p.isRest && p.type?.kind !== "primitive").map((p) => p.name));
|
|
188273
|
+
return new Set(ir.metadata.propsParams.filter((p) => p.defaultValue === undefined && !p.isRest && (p.type?.kind !== "primitive" || p.optional)).map((p) => p.name));
|
|
188235
188274
|
}
|
|
188236
188275
|
function collectStringValueNames(ir) {
|
|
188237
188276
|
const names = new Set;
|
|
@@ -188276,6 +188315,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188276
188315
|
_searchParamsLocals = new Set;
|
|
188277
188316
|
_loweringMatchers = [];
|
|
188278
188317
|
localConstants = [];
|
|
188318
|
+
staticLoopSourceBoundNames = new Set;
|
|
188279
188319
|
nullableOptionalProps = new Set;
|
|
188280
188320
|
constructor(options = {}) {
|
|
188281
188321
|
super();
|
|
@@ -188291,6 +188331,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188291
188331
|
this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
|
|
188292
188332
|
this.booleanTypedProps = collectBooleanTypedProps(ir);
|
|
188293
188333
|
this.localConstants = ir.metadata.localConstants ?? [];
|
|
188334
|
+
this.staticLoopSourceBoundNames = collectLoopBoundNames(ir);
|
|
188294
188335
|
this.nullableOptionalProps = collectNullableOptionalProps(ir);
|
|
188295
188336
|
this.stringValueNames = collectStringValueNames(ir);
|
|
188296
188337
|
this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
|
|
@@ -188412,7 +188453,8 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188412
188453
|
renderElement(element) {
|
|
188413
188454
|
const tag = element.tag;
|
|
188414
188455
|
const attrs = this.renderAttributes(element);
|
|
188415
|
-
const
|
|
188456
|
+
const dangerousHtml = this.renderDangerousInnerHtml(element);
|
|
188457
|
+
const children = dangerousHtml !== null ? dangerousHtml : this.renderChildren(element.children);
|
|
188416
188458
|
let hydrationAttrs = "";
|
|
188417
188459
|
if (element.needsScope) {
|
|
188418
188460
|
hydrationAttrs += ` ${this.renderScopeMarker("")}`;
|
|
@@ -188447,6 +188489,22 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188447
188489
|
}
|
|
188448
188490
|
return `<${tag}${attrs}${hydrationAttrs}>${children}</${tag}>`;
|
|
188449
188491
|
}
|
|
188492
|
+
renderDangerousInnerHtml(element) {
|
|
188493
|
+
const resolution = resolveDangerousInnerHtml(element);
|
|
188494
|
+
if (!resolution)
|
|
188495
|
+
return null;
|
|
188496
|
+
if (resolution.kind === "dynamic") {
|
|
188497
|
+
this.errors.push(dangerousInnerHtmlDiagnostic(resolution.expr, resolution.loc));
|
|
188498
|
+
return "";
|
|
188499
|
+
}
|
|
188500
|
+
const violation = dangerousInnerHtmlMetacharViolation(resolution.html, this.name);
|
|
188501
|
+
if (violation) {
|
|
188502
|
+
const attr = element.attrs.find(isDangerousInnerHtmlAttr);
|
|
188503
|
+
this.errors.push(dangerousInnerHtmlDiagnostic(`{ __html: ${JSON.stringify(resolution.html)} }`, attr.loc, violation));
|
|
188504
|
+
return "";
|
|
188505
|
+
}
|
|
188506
|
+
return resolution.html;
|
|
188507
|
+
}
|
|
188450
188508
|
renderExpression(expr) {
|
|
188451
188509
|
if (expr.clientOnly) {
|
|
188452
188510
|
if (expr.slotId) {
|
|
@@ -188454,7 +188512,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188454
188512
|
}
|
|
188455
188513
|
return "";
|
|
188456
188514
|
}
|
|
188457
|
-
const jinjaExpr = `bf.string(${this.convertExpressionToJinja(expr.expr)})`;
|
|
188515
|
+
const jinjaExpr = `bf.string(${this.convertExpressionToJinja(expr.expr, expr.parsed)})`;
|
|
188458
188516
|
if (expr.slotId) {
|
|
188459
188517
|
return `{{ bf.text_start("${expr.slotId}") | safe }}{{ ${jinjaExpr} }}{{ bf.text_end() | safe }}`;
|
|
188460
188518
|
}
|
|
@@ -188545,8 +188603,12 @@ ${whenTrue}
|
|
|
188545
188603
|
}
|
|
188546
188604
|
});
|
|
188547
188605
|
}
|
|
188606
|
+
const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
|
|
188607
|
+
isNameShadowed: (name) => this.staticLoopSourceBoundNames.has(name)
|
|
188608
|
+
});
|
|
188609
|
+
const staticArray = staticItems !== null ? staticValueToMinijinja(staticItems) : null;
|
|
188548
188610
|
const arrayName = loop.array.trim();
|
|
188549
|
-
if (/^[A-Za-z_$][\w$]*$/.test(arrayName)) {
|
|
188611
|
+
if (staticArray === null && /^[A-Za-z_$][\w$]*$/.test(arrayName)) {
|
|
188550
188612
|
const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
|
|
188551
188613
|
if (arrayConst && !arrayConst.isModule && this._resolveLiteralConst(arrayName) === null) {
|
|
188552
188614
|
this.errors.push({
|
|
@@ -188560,7 +188622,7 @@ ${whenTrue}
|
|
|
188560
188622
|
});
|
|
188561
188623
|
}
|
|
188562
188624
|
}
|
|
188563
|
-
const rawArray = this.convertExpressionToJinja(loop.array);
|
|
188625
|
+
const rawArray = staticArray ?? this.convertExpressionToJinja(loop.array);
|
|
188564
188626
|
let array = rawArray;
|
|
188565
188627
|
if (loop.sortComparator) {
|
|
188566
188628
|
const sort = loop.sortComparator;
|
|
@@ -188872,6 +188934,8 @@ ${name}="{{ bf.string(${val}) }}"
|
|
|
188872
188934
|
for (const attr of element.attrs) {
|
|
188873
188935
|
if (attr.clientOnly)
|
|
188874
188936
|
continue;
|
|
188937
|
+
if (isDangerousInnerHtmlAttr(attr))
|
|
188938
|
+
continue;
|
|
188875
188939
|
let attrName;
|
|
188876
188940
|
if (attr.name === "className")
|
|
188877
188941
|
attrName = "class";
|
|
@@ -189071,6 +189135,8 @@ Options:
|
|
|
189071
189135
|
return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
|
|
189072
189136
|
}
|
|
189073
189137
|
_resolveLiteralConst(name) {
|
|
189138
|
+
if (this.staticLoopSourceBoundNames.has(name))
|
|
189139
|
+
return null;
|
|
189074
189140
|
const c = (this.localConstants ?? []).find((lc) => lc.name === name);
|
|
189075
189141
|
if (c?.value === undefined)
|
|
189076
189142
|
return null;
|
|
@@ -189083,6 +189149,8 @@ Options:
|
|
|
189083
189149
|
return null;
|
|
189084
189150
|
}
|
|
189085
189151
|
_resolveStaticRecordLiteral(objectName, key) {
|
|
189152
|
+
if (this.staticLoopSourceBoundNames.has(objectName))
|
|
189153
|
+
return null;
|
|
189086
189154
|
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
|
|
189087
189155
|
if (!hit)
|
|
189088
189156
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;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;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eA4F7B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -187308,7 +187308,13 @@ import {
|
|
|
187308
187308
|
prepareLoweringMatchers,
|
|
187309
187309
|
queryHrefArgs,
|
|
187310
187310
|
isValidHelperId,
|
|
187311
|
-
sortComparatorFromArrow as sortComparatorFromArrow2
|
|
187311
|
+
sortComparatorFromArrow as sortComparatorFromArrow2,
|
|
187312
|
+
isDangerousInnerHtmlAttr,
|
|
187313
|
+
resolveDangerousInnerHtml,
|
|
187314
|
+
dangerousInnerHtmlMetacharViolation,
|
|
187315
|
+
dangerousInnerHtmlDiagnostic,
|
|
187316
|
+
resolveStaticLoopSource,
|
|
187317
|
+
collectLoopBoundNames
|
|
187312
187318
|
} from "@barefootjs/jsx";
|
|
187313
187319
|
|
|
187314
187320
|
// src/adapter/boolean-result.ts
|
|
@@ -187686,6 +187692,39 @@ function renderFlatMethod(recv, depth, emit) {
|
|
|
187686
187692
|
return `bf.flat(${recv}, ${d})`;
|
|
187687
187693
|
}
|
|
187688
187694
|
|
|
187695
|
+
// src/adapter/lib/static-value.ts
|
|
187696
|
+
function staticValueToMinijinja(value) {
|
|
187697
|
+
if (value === null || value === undefined)
|
|
187698
|
+
return "none";
|
|
187699
|
+
if (typeof value === "boolean")
|
|
187700
|
+
return value ? "true" : "false";
|
|
187701
|
+
if (typeof value === "number")
|
|
187702
|
+
return String(value);
|
|
187703
|
+
if (typeof value === "string")
|
|
187704
|
+
return `'${escapeMinijinjaSingleQuoted(value)}'`;
|
|
187705
|
+
if (Array.isArray(value)) {
|
|
187706
|
+
const items = [];
|
|
187707
|
+
for (const el of value) {
|
|
187708
|
+
const serialized = staticValueToMinijinja(el);
|
|
187709
|
+
if (serialized === null)
|
|
187710
|
+
return null;
|
|
187711
|
+
items.push(serialized);
|
|
187712
|
+
}
|
|
187713
|
+
return `[${items.join(", ")}]`;
|
|
187714
|
+
}
|
|
187715
|
+
if (typeof value === "object") {
|
|
187716
|
+
const entries = [];
|
|
187717
|
+
for (const [key, val] of Object.entries(value)) {
|
|
187718
|
+
const serialized = staticValueToMinijinja(val);
|
|
187719
|
+
if (serialized === null)
|
|
187720
|
+
return null;
|
|
187721
|
+
entries.push(`${minijinjaHashKey(key)}: ${serialized}`);
|
|
187722
|
+
}
|
|
187723
|
+
return `{${entries.join(", ")}}`;
|
|
187724
|
+
}
|
|
187725
|
+
return null;
|
|
187726
|
+
}
|
|
187727
|
+
|
|
187689
187728
|
// src/adapter/expr/emitters.ts
|
|
187690
187729
|
import {
|
|
187691
187730
|
groupBinaryOperand,
|
|
@@ -188231,7 +188270,7 @@ function collectBooleanTypedProps(ir) {
|
|
|
188231
188270
|
return new Set(ir.metadata.propsParams.filter((prop) => prop.type?.primitive === "boolean" || prop.type?.raw === "boolean").map((prop) => prop.name));
|
|
188232
188271
|
}
|
|
188233
188272
|
function collectNullableOptionalProps(ir) {
|
|
188234
|
-
return new Set(ir.metadata.propsParams.filter((p) => p.defaultValue === undefined && !p.isRest && p.type?.kind !== "primitive").map((p) => p.name));
|
|
188273
|
+
return new Set(ir.metadata.propsParams.filter((p) => p.defaultValue === undefined && !p.isRest && (p.type?.kind !== "primitive" || p.optional)).map((p) => p.name));
|
|
188235
188274
|
}
|
|
188236
188275
|
function collectStringValueNames(ir) {
|
|
188237
188276
|
const names = new Set;
|
|
@@ -188276,6 +188315,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188276
188315
|
_searchParamsLocals = new Set;
|
|
188277
188316
|
_loweringMatchers = [];
|
|
188278
188317
|
localConstants = [];
|
|
188318
|
+
staticLoopSourceBoundNames = new Set;
|
|
188279
188319
|
nullableOptionalProps = new Set;
|
|
188280
188320
|
constructor(options = {}) {
|
|
188281
188321
|
super();
|
|
@@ -188291,6 +188331,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188291
188331
|
this.propsParams = ir.metadata.propsParams.map((p) => ({ name: p.name }));
|
|
188292
188332
|
this.booleanTypedProps = collectBooleanTypedProps(ir);
|
|
188293
188333
|
this.localConstants = ir.metadata.localConstants ?? [];
|
|
188334
|
+
this.staticLoopSourceBoundNames = collectLoopBoundNames(ir);
|
|
188294
188335
|
this.nullableOptionalProps = collectNullableOptionalProps(ir);
|
|
188295
188336
|
this.stringValueNames = collectStringValueNames(ir);
|
|
188296
188337
|
this.moduleStringConsts = collectModuleStringConsts(ir.metadata.localConstants);
|
|
@@ -188412,7 +188453,8 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188412
188453
|
renderElement(element) {
|
|
188413
188454
|
const tag = element.tag;
|
|
188414
188455
|
const attrs = this.renderAttributes(element);
|
|
188415
|
-
const
|
|
188456
|
+
const dangerousHtml = this.renderDangerousInnerHtml(element);
|
|
188457
|
+
const children = dangerousHtml !== null ? dangerousHtml : this.renderChildren(element.children);
|
|
188416
188458
|
let hydrationAttrs = "";
|
|
188417
188459
|
if (element.needsScope) {
|
|
188418
188460
|
hydrationAttrs += ` ${this.renderScopeMarker("")}`;
|
|
@@ -188447,6 +188489,22 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188447
188489
|
}
|
|
188448
188490
|
return `<${tag}${attrs}${hydrationAttrs}>${children}</${tag}>`;
|
|
188449
188491
|
}
|
|
188492
|
+
renderDangerousInnerHtml(element) {
|
|
188493
|
+
const resolution = resolveDangerousInnerHtml(element);
|
|
188494
|
+
if (!resolution)
|
|
188495
|
+
return null;
|
|
188496
|
+
if (resolution.kind === "dynamic") {
|
|
188497
|
+
this.errors.push(dangerousInnerHtmlDiagnostic(resolution.expr, resolution.loc));
|
|
188498
|
+
return "";
|
|
188499
|
+
}
|
|
188500
|
+
const violation = dangerousInnerHtmlMetacharViolation(resolution.html, this.name);
|
|
188501
|
+
if (violation) {
|
|
188502
|
+
const attr = element.attrs.find(isDangerousInnerHtmlAttr);
|
|
188503
|
+
this.errors.push(dangerousInnerHtmlDiagnostic(`{ __html: ${JSON.stringify(resolution.html)} }`, attr.loc, violation));
|
|
188504
|
+
return "";
|
|
188505
|
+
}
|
|
188506
|
+
return resolution.html;
|
|
188507
|
+
}
|
|
188450
188508
|
renderExpression(expr) {
|
|
188451
188509
|
if (expr.clientOnly) {
|
|
188452
188510
|
if (expr.slotId) {
|
|
@@ -188454,7 +188512,7 @@ class MinijinjaAdapter extends BaseAdapter {
|
|
|
188454
188512
|
}
|
|
188455
188513
|
return "";
|
|
188456
188514
|
}
|
|
188457
|
-
const jinjaExpr = `bf.string(${this.convertExpressionToJinja(expr.expr)})`;
|
|
188515
|
+
const jinjaExpr = `bf.string(${this.convertExpressionToJinja(expr.expr, expr.parsed)})`;
|
|
188458
188516
|
if (expr.slotId) {
|
|
188459
188517
|
return `{{ bf.text_start("${expr.slotId}") | safe }}{{ ${jinjaExpr} }}{{ bf.text_end() | safe }}`;
|
|
188460
188518
|
}
|
|
@@ -188545,8 +188603,12 @@ ${whenTrue}
|
|
|
188545
188603
|
}
|
|
188546
188604
|
});
|
|
188547
188605
|
}
|
|
188606
|
+
const staticItems = resolveStaticLoopSource(loop.arrayParsed, this.localConstants, {
|
|
188607
|
+
isNameShadowed: (name) => this.staticLoopSourceBoundNames.has(name)
|
|
188608
|
+
});
|
|
188609
|
+
const staticArray = staticItems !== null ? staticValueToMinijinja(staticItems) : null;
|
|
188548
188610
|
const arrayName = loop.array.trim();
|
|
188549
|
-
if (/^[A-Za-z_$][\w$]*$/.test(arrayName)) {
|
|
188611
|
+
if (staticArray === null && /^[A-Za-z_$][\w$]*$/.test(arrayName)) {
|
|
188550
188612
|
const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
|
|
188551
188613
|
if (arrayConst && !arrayConst.isModule && this._resolveLiteralConst(arrayName) === null) {
|
|
188552
188614
|
this.errors.push({
|
|
@@ -188560,7 +188622,7 @@ ${whenTrue}
|
|
|
188560
188622
|
});
|
|
188561
188623
|
}
|
|
188562
188624
|
}
|
|
188563
|
-
const rawArray = this.convertExpressionToJinja(loop.array);
|
|
188625
|
+
const rawArray = staticArray ?? this.convertExpressionToJinja(loop.array);
|
|
188564
188626
|
let array = rawArray;
|
|
188565
188627
|
if (loop.sortComparator) {
|
|
188566
188628
|
const sort = loop.sortComparator;
|
|
@@ -188872,6 +188934,8 @@ ${name}="{{ bf.string(${val}) }}"
|
|
|
188872
188934
|
for (const attr of element.attrs) {
|
|
188873
188935
|
if (attr.clientOnly)
|
|
188874
188936
|
continue;
|
|
188937
|
+
if (isDangerousInnerHtmlAttr(attr))
|
|
188938
|
+
continue;
|
|
188875
188939
|
let attrName;
|
|
188876
188940
|
if (attr.name === "className")
|
|
188877
188941
|
attrName = "class";
|
|
@@ -189071,6 +189135,8 @@ Options:
|
|
|
189071
189135
|
return isBooleanResultExpr(expr) || isAriaBooleanAttr(name) || this.isBooleanTypedPropRef(expr);
|
|
189072
189136
|
}
|
|
189073
189137
|
_resolveLiteralConst(name) {
|
|
189138
|
+
if (this.staticLoopSourceBoundNames.has(name))
|
|
189139
|
+
return null;
|
|
189074
189140
|
const c = (this.localConstants ?? []).find((lc) => lc.name === name);
|
|
189075
189141
|
if (c?.value === undefined)
|
|
189076
189142
|
return null;
|
|
@@ -189083,6 +189149,8 @@ Options:
|
|
|
189083
189149
|
return null;
|
|
189084
189150
|
}
|
|
189085
189151
|
_resolveStaticRecordLiteral(objectName, key) {
|
|
189152
|
+
if (this.staticLoopSourceBoundNames.has(objectName))
|
|
189153
|
+
return null;
|
|
189086
189154
|
const hit = lookupStaticRecordLiteral(objectName, key, this.localConstants);
|
|
189087
189155
|
if (!hit)
|
|
189088
189156
|
return null;
|
|
@@ -189120,14 +189188,10 @@ Options:
|
|
|
189120
189188
|
var minijinjaAdapter = new MinijinjaAdapter;
|
|
189121
189189
|
// src/conformance-pins.ts
|
|
189122
189190
|
var conformancePins = {
|
|
189123
|
-
"static-array-children": [{ code: "BF103", severity: "error" }],
|
|
189124
|
-
"todo-app": [{ code: "BF103", severity: "error" }],
|
|
189125
|
-
"todo-app-ssr": [{ code: "BF103", severity: "error" }],
|
|
189126
189191
|
"static-array-from-props": [
|
|
189127
189192
|
{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2087" }
|
|
189128
189193
|
],
|
|
189129
189194
|
"static-array-from-props-with-component": [
|
|
189130
|
-
{ code: "BF103", severity: "error" },
|
|
189131
189195
|
{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2087" }
|
|
189132
189196
|
],
|
|
189133
189197
|
"filter-nested-callback-predicate": [
|
|
@@ -189136,8 +189200,7 @@ var conformancePins = {
|
|
|
189136
189200
|
"filter-nested-find-predicate": [
|
|
189137
189201
|
{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2038" }
|
|
189138
189202
|
],
|
|
189139
|
-
"
|
|
189140
|
-
"dangerous-inner-html": [{ code: "BF101", severity: "error" }]
|
|
189203
|
+
"dangerous-inner-html-dynamic": [{ code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2215" }]
|
|
189141
189204
|
};
|
|
189142
189205
|
// src/render-divergences.ts
|
|
189143
189206
|
var renderDivergences = {};
|
|
@@ -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,
|
|
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,iBAK/B,CAAA"}
|