@barefootjs/erb 0.35.1 → 0.35.3
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/expr/emitters.d.ts.map +1 -1
- package/dist/adapter/index.js +11 -3
- package/dist/index.js +11 -3
- package/dist/vite.js +15 -7
- package/package.json +5 -5
- package/src/__tests__/erb-adapter.test.ts +56 -0
- package/src/adapter/expr/emitters.ts +19 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,YAAY,EAMjB,KAAK,eAAe,EAIrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -187732,6 +187732,11 @@ var PREDICATE_METHODS = new Set([
|
|
|
187732
187732
|
function unusedIsStringName(_n) {
|
|
187733
187733
|
return false;
|
|
187734
187734
|
}
|
|
187735
|
+
function flattenPropsMember(object, property) {
|
|
187736
|
+
if (object.kind === "identifier" && object.name === "props")
|
|
187737
|
+
return `v[${rubySymbolLiteral(property)}]`;
|
|
187738
|
+
return null;
|
|
187739
|
+
}
|
|
187735
187740
|
|
|
187736
187741
|
class ErbFilterEmitter {
|
|
187737
187742
|
param;
|
|
@@ -187768,6 +187773,9 @@ class ErbFilterEmitter {
|
|
|
187768
187773
|
return String(value);
|
|
187769
187774
|
}
|
|
187770
187775
|
member(object, property, _computed, optional, emit) {
|
|
187776
|
+
const flat = flattenPropsMember(object, property);
|
|
187777
|
+
if (flat !== null)
|
|
187778
|
+
return flat;
|
|
187771
187779
|
if (property === "length")
|
|
187772
187780
|
return `bf.length(${emit(object)})`;
|
|
187773
187781
|
if (optional)
|
|
@@ -187909,9 +187917,9 @@ class ErbTopLevelEmitter {
|
|
|
187909
187917
|
return String(value);
|
|
187910
187918
|
}
|
|
187911
187919
|
member(object, property, _computed, optional, emit) {
|
|
187912
|
-
|
|
187913
|
-
|
|
187914
|
-
|
|
187920
|
+
const flat = flattenPropsMember(object, property);
|
|
187921
|
+
if (flat !== null)
|
|
187922
|
+
return flat;
|
|
187915
187923
|
if (object.kind === "identifier") {
|
|
187916
187924
|
const staticValue = this.ctx.resolveStaticRecordLiteral(object.name, property);
|
|
187917
187925
|
if (staticValue !== null)
|
package/dist/index.js
CHANGED
|
@@ -187732,6 +187732,11 @@ var PREDICATE_METHODS = new Set([
|
|
|
187732
187732
|
function unusedIsStringName(_n) {
|
|
187733
187733
|
return false;
|
|
187734
187734
|
}
|
|
187735
|
+
function flattenPropsMember(object, property) {
|
|
187736
|
+
if (object.kind === "identifier" && object.name === "props")
|
|
187737
|
+
return `v[${rubySymbolLiteral(property)}]`;
|
|
187738
|
+
return null;
|
|
187739
|
+
}
|
|
187735
187740
|
|
|
187736
187741
|
class ErbFilterEmitter {
|
|
187737
187742
|
param;
|
|
@@ -187768,6 +187773,9 @@ class ErbFilterEmitter {
|
|
|
187768
187773
|
return String(value);
|
|
187769
187774
|
}
|
|
187770
187775
|
member(object, property, _computed, optional, emit) {
|
|
187776
|
+
const flat = flattenPropsMember(object, property);
|
|
187777
|
+
if (flat !== null)
|
|
187778
|
+
return flat;
|
|
187771
187779
|
if (property === "length")
|
|
187772
187780
|
return `bf.length(${emit(object)})`;
|
|
187773
187781
|
if (optional)
|
|
@@ -187909,9 +187917,9 @@ class ErbTopLevelEmitter {
|
|
|
187909
187917
|
return String(value);
|
|
187910
187918
|
}
|
|
187911
187919
|
member(object, property, _computed, optional, emit) {
|
|
187912
|
-
|
|
187913
|
-
|
|
187914
|
-
|
|
187920
|
+
const flat = flattenPropsMember(object, property);
|
|
187921
|
+
if (flat !== null)
|
|
187922
|
+
return flat;
|
|
187915
187923
|
if (object.kind === "identifier") {
|
|
187916
187924
|
const staticValue = this.ctx.resolveStaticRecordLiteral(object.name, property);
|
|
187917
187925
|
if (staticValue !== null)
|
package/dist/vite.js
CHANGED
|
@@ -3421,8 +3421,11 @@ function matchSearchParamsMethodCall(callee, args, localNames) {
|
|
|
3421
3421
|
// ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
|
|
3422
3422
|
import ts19 from "typescript";
|
|
3423
3423
|
|
|
3424
|
-
// ../jsx/src/ir-to-client-js/
|
|
3424
|
+
// ../jsx/src/ir-to-client-js/emit-reactive.ts
|
|
3425
3425
|
import ts20 from "typescript";
|
|
3426
|
+
|
|
3427
|
+
// ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
|
|
3428
|
+
import ts21 from "typescript";
|
|
3426
3429
|
var NO_PREAMBLE = {
|
|
3427
3430
|
lazySafe: true,
|
|
3428
3431
|
facts: { declaredNames: new Set, freeNames: new Set }
|
|
@@ -3471,9 +3474,6 @@ var INERT_BINDING_GLOBALS = new Set([
|
|
|
3471
3474
|
"decodeURI"
|
|
3472
3475
|
]);
|
|
3473
3476
|
|
|
3474
|
-
// ../jsx/src/ir-to-client-js/emit-reactive.ts
|
|
3475
|
-
import ts21 from "typescript";
|
|
3476
|
-
|
|
3477
3477
|
// ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
|
|
3478
3478
|
var NON_BUBBLING_EVENTS = new Set([
|
|
3479
3479
|
"blur",
|
|
@@ -5619,6 +5619,11 @@ var PREDICATE_METHODS = new Set([
|
|
|
5619
5619
|
function unusedIsStringName(_n) {
|
|
5620
5620
|
return false;
|
|
5621
5621
|
}
|
|
5622
|
+
function flattenPropsMember(object, property) {
|
|
5623
|
+
if (object.kind === "identifier" && object.name === "props")
|
|
5624
|
+
return `v[${rubySymbolLiteral(property)}]`;
|
|
5625
|
+
return null;
|
|
5626
|
+
}
|
|
5622
5627
|
|
|
5623
5628
|
class ErbFilterEmitter {
|
|
5624
5629
|
param;
|
|
@@ -5655,6 +5660,9 @@ class ErbFilterEmitter {
|
|
|
5655
5660
|
return String(value);
|
|
5656
5661
|
}
|
|
5657
5662
|
member(object, property, _computed, optional, emit) {
|
|
5663
|
+
const flat = flattenPropsMember(object, property);
|
|
5664
|
+
if (flat !== null)
|
|
5665
|
+
return flat;
|
|
5658
5666
|
if (property === "length")
|
|
5659
5667
|
return `bf.length(${emit(object)})`;
|
|
5660
5668
|
if (optional)
|
|
@@ -5796,9 +5804,9 @@ class ErbTopLevelEmitter {
|
|
|
5796
5804
|
return String(value);
|
|
5797
5805
|
}
|
|
5798
5806
|
member(object, property, _computed, optional, emit) {
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5807
|
+
const flat = flattenPropsMember(object, property);
|
|
5808
|
+
if (flat !== null)
|
|
5809
|
+
return flat;
|
|
5802
5810
|
if (object.kind === "identifier") {
|
|
5803
5811
|
const staticValue = this.ctx.resolveStaticRecordLiteral(object.name, property);
|
|
5804
5812
|
if (staticValue !== null)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/erb",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.3",
|
|
4
4
|
"description": "ERB (Embedded Ruby) adapter for BarefootJS — compiles IR to .erb templates and ships the Ruby rendering backend; runs under any Rack app (Sinatra, Rails)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"directory": "packages/adapter-erb"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@barefootjs/shared": "0.35.
|
|
57
|
+
"@barefootjs/shared": "0.35.3"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"@barefootjs/jsx": ">=0.2.0",
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
74
|
-
"@barefootjs/jsx": "0.35.
|
|
75
|
-
"@barefootjs/vite": "0.35.
|
|
76
|
-
"@barefootjs/client": "0.35.
|
|
74
|
+
"@barefootjs/jsx": "0.35.3",
|
|
75
|
+
"@barefootjs/vite": "0.35.3",
|
|
76
|
+
"@barefootjs/client": "0.35.3",
|
|
77
77
|
"typescript": "^5.0.0",
|
|
78
78
|
"vite": "^6.0.0"
|
|
79
79
|
}
|
|
@@ -669,3 +669,59 @@ describe('ErbAdapter - Ruby double-quote escaping order (#2698 review)', () => {
|
|
|
669
669
|
expect(rubySymbolKey('a\\"b')).toBe('"a\\\\\\"b":')
|
|
670
670
|
})
|
|
671
671
|
})
|
|
672
|
+
|
|
673
|
+
// #2894 — investigated as the ERB sibling of #2883 (Mojolicious) and
|
|
674
|
+
// go-template's own fix in this same PR: `collectStringValueNames`'s
|
|
675
|
+
// string-typed-name witness has the identical missing-alias gap for a
|
|
676
|
+
// bare-props-form BODY-destructured, RENAMED prop (`const { fallbackKey:
|
|
677
|
+
// skipKey } = props`, the #2788 alias family) used as an index-access key.
|
|
678
|
+
// Unlike Mojolicious/go-template, this is NOT a live bug on ERB: since
|
|
679
|
+
// #2491, `emitIndexAccessRuby` (`adapter/expr/operand.ts`) ignores its
|
|
680
|
+
// `isStringName` parameter entirely and always lowers `obj[index]` to the
|
|
681
|
+
// runtime's polymorphic `bf.get(obj, index)` helper (Hash-key-or-Symbol-or-
|
|
682
|
+
// String-or-Array, tried in that order) rather than choosing a lowering at
|
|
683
|
+
// compile time — so the missing witness never reaches a decision point.
|
|
684
|
+
// This test pins that a renamed alias used as an index key resolves
|
|
685
|
+
// correctly end-to-end regardless, as evidence for that closed-out finding
|
|
686
|
+
// (no code change needed here; see the #2894 PR/issue for the full trail).
|
|
687
|
+
describe('ErbAdapter - #2894 index access by a renamed body-destructured prop already works via bf.get', () => {
|
|
688
|
+
test('renders the correct value: bf.get resolves the key regardless of collectStringValueNames', async () => {
|
|
689
|
+
const source = `
|
|
690
|
+
'use client'
|
|
691
|
+
import { createSignal } from '@barefootjs/client'
|
|
692
|
+
|
|
693
|
+
export function IndexAccessRenamedProp(props: { fallbackKey: string }) {
|
|
694
|
+
const { fallbackKey: skipKey } = props
|
|
695
|
+
const [labels] = createSignal<Record<string, string>>({ a: 'Apple', b: 'Banana' })
|
|
696
|
+
return <div>{labels()[skipKey]}</div>
|
|
697
|
+
}
|
|
698
|
+
`
|
|
699
|
+
let html: string
|
|
700
|
+
try {
|
|
701
|
+
html = await renderErbComponent({
|
|
702
|
+
source,
|
|
703
|
+
adapter: new ErbAdapter(),
|
|
704
|
+
props: { fallbackKey: 'b' },
|
|
705
|
+
})
|
|
706
|
+
} catch (err) {
|
|
707
|
+
if (err instanceof ErbNotAvailableError) return // Ruby toolchain not installed on this host
|
|
708
|
+
throw err
|
|
709
|
+
}
|
|
710
|
+
expect(html).toContain('Banana')
|
|
711
|
+
})
|
|
712
|
+
|
|
713
|
+
test('the emitted template routes through bf.get, not a compile-time Hash/Array branch', () => {
|
|
714
|
+
const ir = compileToIR(`
|
|
715
|
+
'use client'
|
|
716
|
+
import { createSignal } from '@barefootjs/client'
|
|
717
|
+
|
|
718
|
+
export function IndexAccessRenamedProp(props: { fallbackKey: string }) {
|
|
719
|
+
const { fallbackKey: skipKey } = props
|
|
720
|
+
const [labels] = createSignal<Record<string, string>>({ a: 'Apple', b: 'Banana' })
|
|
721
|
+
return <div>{labels()[skipKey]}</div>
|
|
722
|
+
}
|
|
723
|
+
`)
|
|
724
|
+
const { template } = new ErbAdapter().generate(ir)
|
|
725
|
+
expect(template).toContain('bf.get(v[:labels], v[:skipKey])')
|
|
726
|
+
})
|
|
727
|
+
})
|
|
@@ -92,6 +92,21 @@ function unusedIsStringName(_n: string): boolean {
|
|
|
92
92
|
return false
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* `props.x` on a bare-props-form component flattens to the `v[:x]` the ERB
|
|
97
|
+
* SSR caller seeds each prop under (props arrive as vars-Hash entries, not
|
|
98
|
+
* a nested `props` Hash). Single door for BOTH `member()` emitters below
|
|
99
|
+
* (#2886) — `ErbFilterEmitter` lacked this decision entirely (#2879's
|
|
100
|
+
* cross-adapter follow-up), silently reaching `v[:props][:x]`, which is
|
|
101
|
+
* `nil[...]` at runtime (`NoMethodError`). Returns null for any other
|
|
102
|
+
* receiver so callers fall through to their generic member lowering —
|
|
103
|
+
* `props.a.b` flattens only the inner hop.
|
|
104
|
+
*/
|
|
105
|
+
function flattenPropsMember(object: ParsedExpr, property: string): string | null {
|
|
106
|
+
if (object.kind === 'identifier' && object.name === 'props') return `v[${rubySymbolLiteral(property)}]`
|
|
107
|
+
return null
|
|
108
|
+
}
|
|
109
|
+
|
|
95
110
|
export class ErbFilterEmitter implements ParsedExprEmitter {
|
|
96
111
|
// Plain field declarations + assignment, NOT TS constructor-parameter-
|
|
97
112
|
// property shorthand: Vite's `bundleConfigFile` externalizes any bare
|
|
@@ -164,6 +179,8 @@ export class ErbFilterEmitter implements ParsedExprEmitter {
|
|
|
164
179
|
}
|
|
165
180
|
|
|
166
181
|
member(object: ParsedExpr, property: string, _computed: boolean, optional: boolean, emit: (e: ParsedExpr) => string): string {
|
|
182
|
+
const flat = flattenPropsMember(object, property)
|
|
183
|
+
if (flat !== null) return flat
|
|
167
184
|
// `.length` needs no special higher-order form here — see the file
|
|
168
185
|
// docstring's simplification (2): `.select { ... }.length` just works
|
|
169
186
|
// in Ruby, unlike Perl's anonymous-arrayref `scalar(@{...})` detour.
|
|
@@ -411,11 +428,8 @@ export class ErbTopLevelEmitter implements ParsedExprEmitter {
|
|
|
411
428
|
}
|
|
412
429
|
|
|
413
430
|
member(object: ParsedExpr, property: string, _computed: boolean, optional: boolean, emit: (e: ParsedExpr) => string): string {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
if (object.kind === 'identifier' && object.name === 'props') {
|
|
417
|
-
return `v[${rubySymbolLiteral(property)}]`
|
|
418
|
-
}
|
|
431
|
+
const flat = flattenPropsMember(object, property)
|
|
432
|
+
if (flat !== null) return flat
|
|
419
433
|
// Static property access on a module object-literal const
|
|
420
434
|
// (`variantClasses.ghost`) resolves at compile time — the generic Hash
|
|
421
435
|
// lowering below would read a vars-Hash key that doesn't exist
|