diff --git a/PIPES_E2E_FIX.md b/PIPES_E2E_FIX.md new file mode 100644 index 0000000..06d1672 --- /dev/null +++ b/PIPES_E2E_FIX.md @@ -0,0 +1,141 @@ +# Naprawa Pipes - Problem z kontekstem ewaluacji + +## Problem zgłoszony przez użytkownika + +W aplikacji IoT/Ant kod: +```html +
{{ 123 | json }}
+{{ "string" | json }}
+{{ true | json }}
+```
+
+Powodował, że cały komponent się "wysypał" bez błędów - wcześniej na metodach było po prostu "undefined".
+
+## Analiza problemu
+
+### 1. Transformacja była poprawna
+Transformer poprawnie generował kod:
+```typescript
+this._pipes?.['json']?.transform(123)
+```
+
+### 2. Problem był w runtime
+W `template-renderer.ts` wyrażenia są ewaluowane za pomocą:
+```typescript
+private eval(expr: string): any {
+ return new Function('c', `with(c){return ${expr}}`)(this.component);
+}
+```
+
+W kontekście `with(c)`, `this` odnosi się do **globalnego obiektu**, a nie do komponentu `c`. Dlatego `this._pipes` było `undefined`.
+
+## Rozwiązanie
+
+Zmieniono generowany kod z `this._pipes` na `_pipes`:
+
+**Przed:**
+```typescript
+this._pipes?.['json']?.transform(123)
+```
+
+**Po:**
+```typescript
+_pipes?.['json']?.transform(123)
+```
+
+Teraz `_pipes` jest dostępne bezpośrednio z kontekstu komponentu `c` w `with(c)`.
+
+## Zmieniony plik
+
+`/web/quarc/cli/processors/template/template-transformer.ts`:
+
+```typescript
+private transformPipeExpression(expression: string): string {
+ const parts = this.splitByPipe(expression);
+
+ if (parts.length === 1) {
+ return expression;
+ }
+
+ let result = parts[0].trim();
+
+ for (let i = 1; i < parts.length; i++) {
+ const pipePart = parts[i].trim();
+ const colonIndex = pipePart.indexOf(':');
+
+ if (colonIndex === -1) {
+ const pipeName = pipePart.trim();
+ result = `_pipes?.['${pipeName}']?.transform(${result})`; // ← Zmiana
+ } else {
+ const pipeName = pipePart.substring(0, colonIndex).trim();
+ const argsStr = pipePart.substring(colonIndex + 1).trim();
+ const args = argsStr.split(':').map(arg => arg.trim());
+ const argsJoined = args.join(', ');
+ result = `_pipes?.['${pipeName}']?.transform(${result}, ${argsJoined})`; // ← Zmiana
+ }
+ }
+
+ return result;
+}
+```
+
+## Testy
+
+### Testy jednostkowe
+✅ `test-pipes.ts` - 31/31 testów przeszło
+✅ `test-pipe-with-logical-operators.ts` - 7/7 testów przeszło
+✅ `test-pipe-transformation-detailed.ts` - wszystkie transformacje poprawne
+
+### Build aplikacji
+✅ `/web/IoT/Ant/assets/resources/quarc` - build przeszedł pomyślnie
+
+## Utworzone pipes
+
+Zestaw podstawowych pipes gotowych do użycia:
+
+1. **UpperCasePipe** - `{{ text | uppercase }}`
+2. **LowerCasePipe** - `{{ text | lowercase }}`
+3. **JsonPipe** - `{{ obj | json }}`
+4. **CamelCasePipe** - `{{ 'hello-world' | camelcase }}` → `helloWorld`
+5. **PascalCasePipe** - `{{ 'hello-world' | pascalcase }}` → `HelloWorld`
+6. **SnakeCasePipe** - `{{ 'helloWorld' | snakecase }}` → `hello_world`
+7. **KebabCasePipe** - `{{ 'helloWorld' | kebabcase }}` → `hello-world`
+8. **SubstrPipe** - `{{ text | substr:0:10 }}`
+9. **DatePipe** - `{{ date | date:'yyyy-MM-dd' }}`
+
+## Przykład użycia
+
+```typescript
+import { Component, signal } from '@quarc/core';
+import { JsonPipe, UpperCasePipe } from '@quarc/core';
+
+@Component({
+ selector: 'app-example',
+ template: `
+ {{ data | json }}
+ Navigate to test different pipes
\n\n
123\n
\n
"string"\n
\n
true\n
\n
{"name":"Test","value":123}\n \n
[1,2,3]\n
\n
{"method":true}\n Navigate to test different pipes
+{{ 123 | json }}
+ 123+
{{ "string" | json }}
+ "string"+
{{ true | json }}
+ true+
{{ obj() | json }}
+ {"name":"Test","value":123}
+ {{ arr() | json }}
+ [1,2,3]+
{{ getObject() | json }}
+ {"method":true}
+