@barefootjs/blade 0.1.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.
Files changed (72) hide show
  1. package/README.md +73 -0
  2. package/dist/adapter/analysis/component-tree.d.ts +26 -0
  3. package/dist/adapter/analysis/component-tree.d.ts.map +1 -0
  4. package/dist/adapter/blade-adapter.d.ts +537 -0
  5. package/dist/adapter/blade-adapter.d.ts.map +1 -0
  6. package/dist/adapter/boolean-result.d.ts +76 -0
  7. package/dist/adapter/boolean-result.d.ts.map +1 -0
  8. package/dist/adapter/emit-context.d.ts +105 -0
  9. package/dist/adapter/emit-context.d.ts.map +1 -0
  10. package/dist/adapter/expr/array-method.d.ts +74 -0
  11. package/dist/adapter/expr/array-method.d.ts.map +1 -0
  12. package/dist/adapter/expr/emitters.d.ts +176 -0
  13. package/dist/adapter/expr/emitters.d.ts.map +1 -0
  14. package/dist/adapter/expr/operand.d.ts +25 -0
  15. package/dist/adapter/expr/operand.d.ts.map +1 -0
  16. package/dist/adapter/index.d.ts +6 -0
  17. package/dist/adapter/index.d.ts.map +1 -0
  18. package/dist/adapter/index.js +189060 -0
  19. package/dist/adapter/lib/blade-naming.d.ts +128 -0
  20. package/dist/adapter/lib/blade-naming.d.ts.map +1 -0
  21. package/dist/adapter/lib/constants.d.ts +21 -0
  22. package/dist/adapter/lib/constants.d.ts.map +1 -0
  23. package/dist/adapter/lib/ir-scope.d.ts +48 -0
  24. package/dist/adapter/lib/ir-scope.d.ts.map +1 -0
  25. package/dist/adapter/lib/types.d.ts +27 -0
  26. package/dist/adapter/lib/types.d.ts.map +1 -0
  27. package/dist/adapter/memo/seed.d.ts +84 -0
  28. package/dist/adapter/memo/seed.d.ts.map +1 -0
  29. package/dist/adapter/props/prop-classes.d.ts +34 -0
  30. package/dist/adapter/props/prop-classes.d.ts.map +1 -0
  31. package/dist/adapter/spread/spread-codegen.d.ts +72 -0
  32. package/dist/adapter/spread/spread-codegen.d.ts.map +1 -0
  33. package/dist/adapter/value/parsed-literal.d.ts +27 -0
  34. package/dist/adapter/value/parsed-literal.d.ts.map +1 -0
  35. package/dist/build.d.ts +28 -0
  36. package/dist/build.d.ts.map +1 -0
  37. package/dist/build.js +189080 -0
  38. package/dist/conformance-pins.d.ts +12 -0
  39. package/dist/conformance-pins.d.ts.map +1 -0
  40. package/dist/index.d.ts +9 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +189079 -0
  43. package/package.json +67 -0
  44. package/php/composer.json +32 -0
  45. package/php/src/BladeBackend.php +197 -0
  46. package/php/src/naming.php +84 -0
  47. package/php/tests/test_render.php +159 -0
  48. package/src/__tests__/blade-adapter-unit.test.ts +392 -0
  49. package/src/__tests__/blade-adapter.test.ts +52 -0
  50. package/src/__tests__/blade-counter.test.ts +63 -0
  51. package/src/__tests__/blade-query-href.test.ts +113 -0
  52. package/src/__tests__/blade-spread-attrs.test.ts +235 -0
  53. package/src/adapter/analysis/component-tree.ts +119 -0
  54. package/src/adapter/blade-adapter.ts +1912 -0
  55. package/src/adapter/boolean-result.ts +168 -0
  56. package/src/adapter/emit-context.ts +117 -0
  57. package/src/adapter/expr/array-method.ts +345 -0
  58. package/src/adapter/expr/emitters.ts +636 -0
  59. package/src/adapter/expr/operand.ts +35 -0
  60. package/src/adapter/index.ts +6 -0
  61. package/src/adapter/lib/blade-naming.ts +180 -0
  62. package/src/adapter/lib/constants.ts +33 -0
  63. package/src/adapter/lib/ir-scope.ts +83 -0
  64. package/src/adapter/lib/types.ts +30 -0
  65. package/src/adapter/memo/seed.ts +135 -0
  66. package/src/adapter/props/prop-classes.ts +66 -0
  67. package/src/adapter/spread/spread-codegen.ts +179 -0
  68. package/src/adapter/value/parsed-literal.ts +75 -0
  69. package/src/build.ts +37 -0
  70. package/src/conformance-pins.ts +86 -0
  71. package/src/index.ts +9 -0
  72. package/src/test-render.ts +782 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Structural classifier for JS expressions whose result is a boolean value
3
+ * (or unambiguously stringifies to "true"/"false" in JS).
4
+ *
5
+ * Ported from `packages/adapter-jinja/src/adapter/boolean-result.ts`
6
+ * (itself ported from the Xslate/Mojo adapters' `bf->bool_str` classifier).
7
+ * Used by the Blade adapter for TWO purposes:
8
+ *
9
+ * 1. **Attribute/text stringification**: route a boolean-shaped reactive
10
+ * binding through the runtime `bf.bool_str` helper so the serialised
11
+ * value matches JS `String(boolean)` ("true"/"false"). PHP has a real
12
+ * `bool` type, but PHP's own `(string) true` == `"1"` (not `"true"`) and
13
+ * `(string) false` == `""` — still wrong for HTML output — so the same
14
+ * explicit routing is required.
15
+ * 2. **Condition-position truthy wrapping**: PHP truthiness diverges from JS
16
+ * specifically on the string `'0'` (falsy in PHP, truthy in JS) and empty
17
+ * arrays (`[]` — JS objects/arrays are unconditionally truthy; a PHP
18
+ * empty array is falsy). The Blade adapter's condition-emission call sites
19
+ * (see `blade-adapter.ts`'s `convertConditionToBlade`) reuse this SAME
20
+ * structural classifier: a condition that is already unambiguously
21
+ * boolean-shaped emits directly; everything else is wrapped in
22
+ * `bf.truthy(...)` (a JS-faithful `ToBoolean`) before being used as an
23
+ * `{% if %}` / ternary test.
24
+ *
25
+ * The classifier walks a `ParsedExpr` produced by
26
+ * `@barefootjs/jsx::parseExpression` — same AST the filter / loop lowerings
27
+ * already use — so detection is structural rather than regex-text-matching.
28
+ * Wrapped expression text is left to the caller's existing
29
+ * `convertExpressionToBlade` pipeline; this module only decides whether to
30
+ * wrap.
31
+ *
32
+ * Detected shapes:
33
+ * - `binary` with a comparison operator (`<`, `>`, `<=`, `>=`, `==`, `===`,
34
+ * `!=`, `!==`)
35
+ * - `unary` with logical `!`
36
+ * - `literal` with `literalType: 'boolean'`
37
+ * - `logical` (`&&` / `||` / `??`) when both sides are themselves
38
+ * boolean-result (catches `x > 0 && y < 10`; intentionally does NOT
39
+ * catch `x() || 'fallback'` whose right side stringifies as a regular
40
+ * value)
41
+ * - `conditional` (`?:`) when both branches are themselves boolean-result
42
+ *
43
+ * Anything else returns `false` — including bare identifiers (`accepted`)
44
+ * and call expressions (`accepted()`) whose return type the adapter has no
45
+ * way to infer from source text alone.
46
+ */
47
+ import { type ParsedExpr } from '@barefootjs/jsx';
48
+ /**
49
+ * Structural boolean-result check over an already-parsed `ParsedExpr` tree.
50
+ * Exported so the condition-position truthy-wrapping call sites can reuse it
51
+ * without a stringify → re-parse round-trip.
52
+ */
53
+ export declare function isBooleanResultParsed(node: ParsedExpr): boolean;
54
+ export declare function isBooleanResultExpr(expr: string): boolean;
55
+ /**
56
+ * True when `expr`'s top-level shape is an explicit JS `String(x)` call
57
+ * (the `EVAL_BUILTIN_IDENTS` builtin the compiler recognizes structurally —
58
+ * `packages/jsx/src/expression-parser.ts`'s `EVAL_BUILTIN_IDENTS`; lowered
59
+ * by this adapter's `String` template primitive to `bf.string(x)`, see
60
+ * `lib/constants.ts`).
61
+ *
62
+ * Guards the `isAriaBooleanAttr`-driven `bf.bool_str(...)` override in
63
+ * `blade-adapter.ts`'s `elementAttrEmitter`: `bf.string` and `bf.bool_str`
64
+ * produce IDENTICAL text for a real PHP `bool` (both are `"true"` /
65
+ * `"false"`), so applying `bf.bool_str` to `String(x)`'s ALREADY-STRINGIFIED
66
+ * result is not a no-op — it is a PHP-truthiness test over that STRING
67
+ * ("false" is a non-empty PHP string, hence truthy, so
68
+ * `bf.bool_str(bf.string(false))` would wrongly render `"true"`). An author
69
+ * who explicitly writes `String(...)` has already opted into JS `String()`
70
+ * semantics — `bf.string(x)` alone (which DOES special-case booleans, see
71
+ * the PHP runtime's `string()` helper) is the complete, correct lowering; no
72
+ * attribute-name-driven override should run again on top of it.
73
+ */
74
+ export declare function isExplicitStringCall(expr: string): boolean;
75
+ export declare function isAriaBooleanAttr(name: string): boolean;
76
+ //# sourceMappingURL=boolean-result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boolean-result.d.ts","sourceRoot":"","sources":["../../src/adapter/boolean-result.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAalE;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAuB/D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAS1D;AAyCD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The contract the extracted expression-emitter modules depend on instead of
3
+ * the concrete `BladeAdapter`.
4
+ *
5
+ * Ported from `packages/adapter-jinja/src/adapter/emit-context.ts`. The Blade
6
+ * adapter's top-level expression lowering is mutually recursive with the
7
+ * adapter's own const/record resolution and its filter-predicate emitter, so
8
+ * the extracted `BladeTopLevelEmitter` still needs to call back into shared
9
+ * per-compile state and recursive entry points. `BladeEmitContext` is that
10
+ * seam: the emitter takes a `BladeEmitContext` built by the adapter's private
11
+ * `emitCtx` getter (the adapter does NOT `implements` this interface, so the
12
+ * wrapped members stay private and off its exported public type). The
13
+ * emitter depends on this narrow interface rather than the full class, so
14
+ * the coupling is explicit and it's unit-testable against a stub.
15
+ *
16
+ * Keep this surface minimal: add a member only when an extracted module
17
+ * genuinely needs it, so the seam documents the real cross-module coupling
18
+ * rather than re-exposing the whole adapter.
19
+ */
20
+ import type { ParsedExpr, CompilerError, IRMetadata } from '@barefootjs/jsx';
21
+ export interface BladeEmitContext {
22
+ /**
23
+ * (#1922) Local binding names the request-scoped `searchParams()` env signal
24
+ * is imported under. Non-empty enables the env-signal method-call lowering.
25
+ */
26
+ readonly _searchParamsLocals: Set<string>;
27
+ /**
28
+ * Inline a module-scope pure string-literal const by name as the resolved
29
+ * literal value, or null when the name is not such a const.
30
+ */
31
+ _resolveModuleStringConst(name: string): string | null;
32
+ /** Resolve a literal const (`const totalPages = 5`) to its Blade value, or null. */
33
+ _resolveLiteralConst(name: string): string | null;
34
+ /**
35
+ * Resolve a static property access on a module object-literal const
36
+ * (`variantClasses.ghost`) to its Blade value at compile time, or null.
37
+ */
38
+ _resolveStaticRecordLiteral(objectName: string, key: string): string | null;
39
+ /** Record a BF101 unsupported-expression diagnostic. */
40
+ _recordExprBF101(message: string, reason?: string): void;
41
+ /** Lower a filter/predicate body to its Blade form, bound to `param`. */
42
+ _renderBladeFilterExprPublic(expr: ParsedExpr, param: string): string;
43
+ }
44
+ /**
45
+ * The contract the extracted object-literal / conditional-spread lowering
46
+ * (`spread/spread-codegen.ts`) depends on. Declared separately from
47
+ * `BladeEmitContext` so each extracted module's real coupling is documented
48
+ * precisely. Mirror of the Jinja adapter's `JinjaSpreadContext`.
49
+ */
50
+ export interface BladeSpreadContext {
51
+ /** Component name, for diagnostic source locations. */
52
+ readonly componentName: string;
53
+ /** Per-compile diagnostic list the spread lowering appends to. */
54
+ readonly errors: CompilerError[];
55
+ /** Local-constant metadata, for resolving `Record[key]` spread values. */
56
+ readonly localConstants: IRMetadata['localConstants'];
57
+ /** Prop params, for classifying a bare-identifier index as a prop. */
58
+ readonly propsParams: {
59
+ name: string;
60
+ }[];
61
+ /**
62
+ * Lower a JS expression to its Blade form (the core recursive entry).
63
+ *
64
+ * When the IR already carries a structured `ParsedExpr` tree, pass it as
65
+ * `preParsed` so the converter threads it straight through instead of
66
+ * re-parsing `expr`. With `preParsed` set, `expr` is unused for parsing
67
+ * (the converter derives any diagnostic text from the tree), so callers
68
+ * may pass `''`.
69
+ */
70
+ convertExpressionToBlade(expr: string, preParsed?: ParsedExpr): string;
71
+ /**
72
+ * Lower a JS expression to a Blade CONDITION (routes through `bf.truthy`
73
+ * unless the expression is structurally already boolean-shaped — see
74
+ * `boolean-result.ts`). Used for the conditional-spread ternary's test,
75
+ * which is a condition position, not a value position. Same `preParsed`
76
+ * contract as `convertExpressionToBlade`.
77
+ */
78
+ convertConditionToBlade(expr: string, preParsed?: ParsedExpr): string;
79
+ }
80
+ /**
81
+ * The contract the extracted in-template memo / context seeding
82
+ * (`memo/seed.ts`) depends on. The seed lowering recurses into the core
83
+ * expression lowering to compute a derived signal/memo value or a context
84
+ * default; that recursive entry is its only adapter coupling.
85
+ */
86
+ export interface BladeMemoContext {
87
+ /**
88
+ * Lower a JS expression to its Blade form (the core recursive entry). See
89
+ * `BladeSpreadContext.convertExpressionToBlade` for the `preParsed` contract.
90
+ */
91
+ convertExpressionToBlade(expr: string, preParsed?: ParsedExpr): string;
92
+ /**
93
+ * Per-compile diagnostic list `convertExpressionToBlade` appends to on an
94
+ * unsupported shape (`_recordExprBF101`). `memo/seed.ts`'s
95
+ * `generateDerivedMemoSeed` is a SPECULATIVE "try this in-template
96
+ * recomputation, else fall back to the static ssrDefault seed" attempt per
97
+ * plan step — unlike every other `convertExpressionToBlade` call site, a
98
+ * failure here must NOT become a hard compile error, so it snapshots this
99
+ * array's length before calling in and truncates back to it on failure
100
+ * (discarding whatever `_recordExprBF101` appended) rather than letting
101
+ * the error escape.
102
+ */
103
+ readonly errors: CompilerError[];
104
+ }
105
+ //# sourceMappingURL=emit-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-context.d.ts","sourceRoot":"","sources":["../../src/adapter/emit-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5E,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzC;;;OAGG;IACH,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEtD,oFAAoF;IACpF,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEjD;;;OAGG;IACH,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAE3E,wDAAwD;IACxD,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExD,yEAAyE;IACzE,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;IAEhC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAErD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAExC;;;;;;;;OAQG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CACjC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Array / string method lowering for the Blade template adapter.
3
+ *
4
+ * Ported from `packages/adapter-jinja/src/adapter/expr/array-method.ts`.
5
+ * Pure free functions shared by both the filter-context emitter and the
6
+ * top-level emitter — they take an `emit` callback for receiver / argument
7
+ * recursion and read no adapter instance state.
8
+ *
9
+ * The receiver/array helpers are the same runtime methods the Jinja adapter
10
+ * calls, invoked as `$bf->NAME(...)`.
11
+ */
12
+ import type { ParsedExpr, ArrayMethod, SortComparator, FlatDepth } from '@barefootjs/jsx';
13
+ export declare function renderArrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
14
+ /**
15
+ * Emit a `.sort(cmp)` / `.toSorted(cmp)` via the runtime evaluator (#2018):
16
+ * the comparator body travels as serialized-ParsedExpr JSON, evaluated per
17
+ * comparison against `{paramA, paramB, …captured}`. Returns null when the
18
+ * body is outside the evaluator surface (e.g. a `localeCompare` comparator —
19
+ * `serializeParsedExpr` refuses it), so the caller falls back to the
20
+ * structured `$bf->sort`. `params` are the comparator arrow's two params
21
+ * (`[paramA, paramB]`).
22
+ */
23
+ export declare function renderSortEval(recv: string, body: ParsedExpr, params: string[], emit: (e: ParsedExpr) => string): string | null;
24
+ /**
25
+ * Emit a `.reduce(fn, init)` / `.reduceRight(fn, init)` via the runtime
26
+ * evaluator (#2018): the reducer body travels as serialized-ParsedExpr JSON,
27
+ * folded over the receiver from `init` in `direction` order. `params` are the
28
+ * reducer arrow's params (`[paramAcc, paramItem]`); `init` is the initial-value
29
+ * `ParsedExpr` from the call's trailing argument. Returns null when the body is
30
+ * outside the evaluator surface, or when `init` is not a literal string/number
31
+ * (→ caller refuses with BF101). A numeric seed passes through as a bare
32
+ * Blade number; a string seed as a single-quoted literal.
33
+ */
34
+ export declare function renderReduceEval(recv: string, body: ParsedExpr, params: string[], init: ParsedExpr, direction: 'left' | 'right', emit: (e: ParsedExpr) => string): string | null;
35
+ /**
36
+ * Emit a higher-order predicate call via the runtime evaluator (#2018, P2):
37
+ * `$bf->filter_eval` / `$bf->every_eval` / `$bf->some_eval` / `$bf->find_eval` /
38
+ * `$bf->find_index_eval`, carrying the serialized predicate body + captured env
39
+ * dict. Generalizes the lambda lowering to the same JS-faithful evaluator
40
+ * the Go/Jinja adapters use. Returns null when the predicate is outside the
41
+ * evaluator surface (e.g. a method-call predicate — `serializeParsedExpr`
42
+ * refuses it), so the caller falls back to the lambda form. `forward`
43
+ * (find / findIndex family only) selects the search direction — `false` =
44
+ * findLast / findLastIndex.
45
+ */
46
+ export declare function renderPredicateEval(funcName: string, recv: string, predicate: ParsedExpr, param: string, emit: (e: ParsedExpr) => string, forward?: boolean): string | null;
47
+ /**
48
+ * Emit a `.flatMap(proj)` via the runtime evaluator (#2018, P3): the projection
49
+ * body serializes to JSON and `$bf->flat_map_eval` projects + flattens one
50
+ * level. `param` is the projection arrow's single param. Returns null when the
51
+ * projection is outside the evaluator surface (→ caller refuses with BF101).
52
+ */
53
+ export declare function renderFlatMapEval(recv: string, body: ParsedExpr, param: string, emit: (e: ParsedExpr) => string): string | null;
54
+ /**
55
+ * Emit a value-producing `.map(cb)` via the runtime evaluator (#2073): the
56
+ * projection body serializes to JSON and `$bf->map_eval` projects each element,
57
+ * one result per element (no flatten — the JS `.map` contract). Composes
58
+ * through the array-method chain (`.map(cb).join(' ')`). Returns null when
59
+ * the projection is outside the evaluator surface (→ caller refuses with
60
+ * BF101). The JSX-returning `.map` is an IRLoop upstream and never reaches
61
+ * this emit.
62
+ */
63
+ export declare function renderMapEval(recv: string, body: ParsedExpr, param: string, emit: (e: ParsedExpr) => string): string | null;
64
+ /**
65
+ * Shared Blade emit for `.sort(cmp)` / `.toSorted(cmp)`. Used by both the
66
+ * filter-context emitter and the top-level emitter, plus the loop-array
67
+ * wrap in `renderLoop`. The runtime `$bf->sort` accepts an opts dict and
68
+ * returns a fresh list.
69
+ */
70
+ export declare function renderSortMethod(recv: string, c: SortComparator): string;
71
+ export declare function renderFlatMethod(recv: string, depth: FlatDepth | {
72
+ expr: ParsedExpr;
73
+ }, emit: (e: ParsedExpr) => string): string;
74
+ //# sourceMappingURL=array-method.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array-method.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/array-method.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAA;AAGxB,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CA6HR;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAkBf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CASxE;AAGD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAmBR"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * ParsedExpr → Blade emitters for the Blade template adapter.
3
+ *
4
+ * Ported from `packages/adapter-twig/src/adapter/expr/emitters.ts`
5
+ * (`TwigFilterEmitter` / `TwigTopLevelEmitter`), itself a port of the Jinja
6
+ * adapter's. Two `ParsedExprEmitter` implementations:
7
+ *
8
+ * - `BladeFilterEmitter` — filter/predicate context (loop param + local
9
+ * aliases + bare identifier signal fallback); self-contained, reads no
10
+ * adapter state.
11
+ * - `BladeTopLevelEmitter` — top-level / per-render-var context; depends on
12
+ * the adapter only through the narrow `BladeEmitContext` seam.
13
+ *
14
+ * Divergences from the Twig port, documented at their definition site below:
15
+ *
16
+ * 1. **`$` sigil on every variable reference/read.** Twig has no sigil —
17
+ * `twigIdent(name)` was both the mangled NAME and the value expression.
18
+ * Blade compiles to raw PHP, so every read is `$name` — `bladeVar(name)`
19
+ * (this adapter's helper, `lib/blade-naming.ts`) wraps `bladeIdent`
20
+ * with the `$`. Every `identifier`/zero-arg-`call` (signal getter) site
21
+ * below uses `bladeVar`, not `bladeIdent` alone.
22
+ * 2. **Member/index access lowers to `data_get(...)`, not `.`/`[]`.**
23
+ * Twig's dot/bracket are polymorphic over {stdClass, array, null}; raw
24
+ * PHP has no equivalent single operator. See `blade-naming.ts`'s file
25
+ * header (divergence 3) for the full rationale — every `member`/
26
+ * `indexAccess` call below routes through `bladeMemberAccess`/
27
+ * `bladeIndexAccess` uniformly, including the `.length` special case
28
+ * (still `$bf->length(...)`, unchanged mechanism, just `$bf->` syntax).
29
+ * 3. **Symbolic ternary, not word-based `if`/`else`** (unchanged from
30
+ * Twig, still a Twig→Jinja divergence carried through) — Blade/PHP has
31
+ * no `X if T else Y` inline-conditional form — `logical`'s `&&`/`||`
32
+ * lowering and `conditional`'s ternary lowering both emit `(T ? A : B)`.
33
+ * 4. **JS-truthy condition wrapping** (`truthyTest`) — unchanged from the
34
+ * Twig port: PHP truthiness diverges from JS (`'0'` is PHP-falsy,
35
+ * JS-truthy; empty arrays are PHP-falsy, JS-truthy for both `[]` and
36
+ * `{}`). Every condition-TEST position (`!x`, the left operand of
37
+ * `&&`/`||`, a ternary's test) routes through the shared
38
+ * `$bf->truthy(...)` runtime helper unless the operand is structurally
39
+ * already boolean-shaped (`isBooleanResultParsed`). `&&`/`||` still
40
+ * return the ORIGINAL operand VALUE (not a coerced bool) on the taken
41
+ * branch — matching JS `a || b` returning `a` itself — only the BRANCH
42
+ * TEST uses `$bf->truthy`. The left operand's rendered text is emitted
43
+ * TWICE (once as the test, once as the value) — safe because every
44
+ * operand reaching this pipeline is a pure, side-effect-free read.
45
+ * 5. **`??` is PHP-native**, covering undefined AND null in ONE operator —
46
+ * PHP's `??` silences BOTH an undefined-variable/index notice and a
47
+ * real `null` (`$missing ?? 'fb'` and `$x ?? 'fb'` with `$x = null`
48
+ * both yield `'fb'`) — verified empirically, same as Twig's own native
49
+ * `??` (this REPLACES Twig's `strict_variables: false` forgiveness with
50
+ * a uniform per-use-site policy, since raw PHP has no engine-wide
51
+ * "never warn on unset var" switch).
52
+ * 6. **`!` (bang), not `not`.** Blade/PHP's unary logical-not is `!`, not
53
+ * Twig's word-form `not` — `unary`'s `op === '!'` branch emits
54
+ * `!${truthyTest(...)}`; `truthyTest` already wraps its operand in a
55
+ * function call (`$bf->truthy(...)`), which binds tighter than `!` in
56
+ * PHP regardless of the surrounding expression, so no extra parens are
57
+ * needed.
58
+ * 7. **`.` (dot) is PHP string concatenation, not member access.** Twig's
59
+ * `~` operator becomes PHP's `.` in `templateLiteral`'s join — every
60
+ * interpolated (non-string-literal) segment still routes through
61
+ * `$bf->string(...)` first (PHP's own `(string)` cast, which `.`
62
+ * invokes internally, diverges from JS `String(x)` — see
63
+ * `blade-adapter.ts`'s file header, "Stringification").
64
+ * 8. **`===`/`!==` route through `$bf->eq`/`$bf->neq`, never PHP's own
65
+ * `==`/`!=`/`===`/`!==`.** PHP's `==` is loose equality (`'1' == 1` is
66
+ * `true` — wrong for JS strict equality), and PHP's OWN `===` is wrong
67
+ * the other direction (`1 === 1.0` is `false` in PHP, but JS has one
68
+ * number type — `1 === 1.0` is `true`). `$bf->eq`/`$bf->neq` are the
69
+ * ONE shared JS-strict-equality implementation (mirrored by the
70
+ * Evaluator's `_strict_eq`), so binary `===`/`!==` ALWAYS lower to a
71
+ * method call here — same as the Twig port's divergence 4.
72
+ * 9. **No Blade lambda for the predicate-callback fallback** — unchanged
73
+ * from Twig. `BladeTopLevelEmitter` uses ONE mechanism for every
74
+ * higher-order callback (the evaluator-JSON `*_eval` payload). When
75
+ * `serializeParsedExpr` refuses the body, the call surfaces `BF101`
76
+ * instead of silently degrading — `.sort`/`.toSorted` is the one
77
+ * exception, whose non-lambda STRUCTURED fallback (`$bf->sort` with a
78
+ * `['keys' => […]]` descriptor) survives the port unchanged.
79
+ * `BladeFilterEmitter` (the loop `.filter().map()` INLINE predicate,
80
+ * rendered as a plain boolean expression, never a lambda) is otherwise
81
+ * unaffected and still used for that path plus the filter-predicate
82
+ * entry point `_renderBladeFilterExprPublic`.
83
+ */
84
+ import { type ParsedExprEmitter, type ArrayMethod, type LiteralType, type ParsedExpr, type ObjectLiteralProperty, type FlatDepth, type TemplatePart } from '@barefootjs/jsx';
85
+ import type { BladeEmitContext } from '../emit-context.ts';
86
+ /**
87
+ * Route a condition-TEST position through `$bf->truthy(...)` unless the node
88
+ * is structurally already boolean-shaped. See the file header (divergence
89
+ * 4). Shared by both emitters below and reused by the adapter's top-level
90
+ * `convertConditionToBlade` for IR-level `if` / loop-filter conditions.
91
+ */
92
+ export declare function truthyTest(node: ParsedExpr, rendered: string): string;
93
+ /**
94
+ * Lowering for the predicate body of a filter / every / some / find, plus the
95
+ * same shape used by the loop-hoist `.filter().map()` inline condition.
96
+ * Higher-order predicates are emitted using PHP's own scalar comparison
97
+ * operators.
98
+ *
99
+ * NOTE: Blade/PHP has no `[x for x in … if …]`-as-expression form usable
100
+ * inline here (a comprehension is a value producer, not a boolean test), so
101
+ * a nested higher-order call (`x.tags.filter(...)`, `other.some(...)`)
102
+ * inside a predicate has no faithful scalar lowering here either — same
103
+ * BF101 surfacing as the Twig/Jinja ports (#2038) instead of silently
104
+ * degrading to the callback's receiver.
105
+ */
106
+ export declare class BladeFilterEmitter implements ParsedExprEmitter {
107
+ private readonly param;
108
+ private readonly localVarMap;
109
+ private readonly isStringName;
110
+ private readonly onUnsupported?;
111
+ constructor(param: string, localVarMap: Map<string, string>, isStringName?: (n: string) => boolean, onUnsupported?: ((message: string, reason?: string) => void) | undefined);
112
+ identifier(name: string): string;
113
+ literal(value: string | number | boolean | null, literalType: LiteralType): string;
114
+ member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string;
115
+ indexAccess(object: ParsedExpr, index: ParsedExpr, emit: (e: ParsedExpr) => string): string;
116
+ call(callee: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
117
+ unary(op: string, argument: ParsedExpr, emit: (e: ParsedExpr) => string): string;
118
+ binary(op: string, left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string;
119
+ logical(op: '&&' | '||' | '??', left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string;
120
+ callbackMethod(method: string, object: ParsedExpr, _arrow: Extract<ParsedExpr, {
121
+ kind: 'arrow';
122
+ }>, _restArgs: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
123
+ arrayLiteral(elements: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
124
+ arrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
125
+ flatMethod(object: ParsedExpr, depth: FlatDepth | {
126
+ expr: ParsedExpr;
127
+ }, emit: (e: ParsedExpr) => string): string;
128
+ conditional(_test: ParsedExpr, _consequent: ParsedExpr, _alternate: ParsedExpr): string;
129
+ templateLiteral(_parts: TemplatePart[]): string;
130
+ arrow(_params: string[], _body: ParsedExpr): string;
131
+ regex(_raw: string): string;
132
+ unsupported(_raw: string, _reason: string): string;
133
+ objectLiteral(_properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
134
+ }
135
+ /**
136
+ * Lowering for top-level expressions whose identifiers resolve against the
137
+ * Blade template's per-render context vars (signals, props, locals
138
+ * introduced by `@php($x = …)`). Differs from the filter emitter mainly in
139
+ * - `conditional` is supported (filter predicates can't return ternaries),
140
+ * - higher-order methods route through `$bf->*` array/evaluator helpers,
141
+ * - no lambda fallback exists (see the file header, divergence 9).
142
+ */
143
+ export declare class BladeTopLevelEmitter implements ParsedExprEmitter {
144
+ private readonly ctx;
145
+ constructor(ctx: BladeEmitContext);
146
+ identifier(name: string): string;
147
+ literal(value: string | number | boolean | null, literalType: LiteralType): string;
148
+ member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string;
149
+ indexAccess(object: ParsedExpr, index: ParsedExpr, emit: (e: ParsedExpr) => string): string;
150
+ call(callee: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
151
+ unary(op: string, argument: ParsedExpr, emit: (e: ParsedExpr) => string): string;
152
+ binary(op: string, left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string;
153
+ logical(op: '&&' | '||' | '??', left: ParsedExpr, right: ParsedExpr, emit: (e: ParsedExpr) => string): string;
154
+ callbackMethod(method: string, object: ParsedExpr, arrow: Extract<ParsedExpr, {
155
+ kind: 'arrow';
156
+ }>, restArgs: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
157
+ /**
158
+ * Lower a boolean-predicate callback (`filter` / `find*` / `every` /
159
+ * `some`). See the file header, divergence 9: Blade has no lambda
160
+ * expression, so — unlike Kolon — there is no non-evaluator fallback here.
161
+ * A predicate the evaluator can't model surfaces `BF101`.
162
+ */
163
+ private _emitPredicateCallback;
164
+ arrayLiteral(elements: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
165
+ arrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
166
+ flatMethod(object: ParsedExpr, depth: FlatDepth | {
167
+ expr: ParsedExpr;
168
+ }, emit: (e: ParsedExpr) => string): string;
169
+ conditional(test: ParsedExpr, consequent: ParsedExpr, alternate: ParsedExpr, emit: (e: ParsedExpr) => string): string;
170
+ templateLiteral(parts: TemplatePart[], emit: (e: ParsedExpr) => string): string;
171
+ arrow(_params: string[], _body: ParsedExpr): string;
172
+ regex(_raw: string): string;
173
+ unsupported(_raw: string, _reason: string): string;
174
+ objectLiteral(properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
175
+ }
176
+ //# sourceMappingURL=emitters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Operand-type classification for the Blade template adapter.
3
+ *
4
+ * Ported from `packages/adapter-jinja/src/adapter/expr/operand.ts`. Pure
5
+ * function over `ParsedExpr` taking an `isStringName` predicate rather than
6
+ * reading adapter instance state.
7
+ *
8
+ * NOTE: unlike Kolon/Jinja, `===`/`!==` on this adapter ALWAYS route through
9
+ * `bf.eq`/`bf.neq` (see `blade-adapter.ts`'s file header, divergence 7) —
10
+ * Blade's own `==`/`!=` compile to PHP loose equality, which is wrong for JS
11
+ * strict-equality semantics regardless of operand type. This helper is
12
+ * therefore not consumed by the Blade lowering either — kept only as the
13
+ * parallel of the Jinja/Xslate/Mojo adapters' `expr/operand.ts` (groundwork
14
+ * for a future shared codegen surface).
15
+ */
16
+ import type { ParsedExpr } from '@barefootjs/jsx';
17
+ /**
18
+ * Whether a comparison operand is string-typed. In the Mojo adapter this
19
+ * selects Perl `eq`/`ne` over numeric `==`/`!=` for a `===`/`!==` against a
20
+ * string operand. Not consumed by the Blade emitters — `===`/`!==` always
21
+ * lowers to `bf.eq`/`bf.neq` regardless of operand type. Kept only as the
22
+ * parallel of the Jinja/Xslate/Mojo helper.
23
+ */
24
+ export declare function isStringTypedOperand(expr: ParsedExpr, isStringName: (n: string) => boolean): boolean;
25
+ //# sourceMappingURL=operand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operand.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/operand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CASpG"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Blade Template Adapter Exports
3
+ */
4
+ export { BladeAdapter, bladeAdapter } from './blade-adapter.ts';
5
+ export type { BladeAdapterOptions } from './blade-adapter.ts';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA"}