@ihelpee/prumo-plugin-php-laravel 0.8.3 → 0.9.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/README.md CHANGED
@@ -1,16 +1,16 @@
1
1
  # @ihelpee/prumo-plugin-php-laravel
2
2
 
3
- Invariantes PHP/Laravel para o [Prumo](https://github.com/ihelpee/prumo). Analisa, nunca executa: o subprocesso PHP apenas tokeniza com `token_get_all` (stdlib) e serializa a AST canônica em JSON — nenhuma linha do código analisado roda, e o gate nunca toca `vendor/` do projeto-alvo.
3
+ PHP/Laravel invariants for [Prumo](https://github.com/ihelpee/prumo). It analyzes, never executes: the PHP subprocess only tokenizes with `token_get_all` (stdlib) and serializes the canonical AST into JSON — not a single line of the analyzed code runs, and the gate never touches the target project's `vendor/`.
4
4
 
5
- ## Instalação
5
+ ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install -D @ihelpee/prumo-plugin-php-laravel
9
9
  ```
10
10
 
11
- Requer `php >= 8.1` no host do gate (não no projeto analisado). Sem `php`, o gate reporta `php-runtime-missing` (warn) em vez de fingir que fiscalizou.
11
+ Requires `php >= 8.1` on the gate host (not in the analyzed project). Without `php`, the gate reports `php-runtime-missing` (warn) instead of pretending it audited.
12
12
 
13
- ## Uso
13
+ ## Usage
14
14
 
15
15
  ```ts
16
16
  // prumo.config.ts do consumidor Laravel
@@ -37,22 +37,33 @@ export default defineConfig({
37
37
  });
38
38
  ```
39
39
 
40
- ## Invariantes
40
+ ## Invariants
41
41
 
42
- | Regra | Sev | Pega | Não pega |
42
+ | Rule | Sev | Catches | Does not catch |
43
43
  |---|---|---|---|
44
- | `mutation-routes-guarded` | error | `Route::post/put/patch/delete` sem auth na rota, no grupo aninhado ou no controller; `throttle:api` NÃO conta como auth | middleware global do stack `web`/`api` (leia `bootstrap/app.php`/`Kernel` você mesmo); GET |
45
- | `form-request-validated` | error | `Request` cru com `all()/input()/json()` sem `validate()`; payload cru + `unguard()` | `$request->validate([...])` inline; FormRequest com `rules()` |
46
- | `form-request-hollow` | warn | FormRequest sem `rules()` preenchido | — |
47
- | `no-raw-queries` | error | `DB::raw/whereRaw/selectRaw/DB::select...` interpolado ou sem bindings | SQL bruto com `?`/named bindings |
48
- | `oracle-no-src` | error | `use App\...` **ou service-locator `app(FQCN::class)`/`resolve`/`->make`/`Container::make\|get`** dentro de `oracleDirs` (anti-burla: import dinâmico é import) | entrypoint (`bootstrap/app.php`) |
49
- | `src-no-oracle` | error | `app/**` com `use Tests\...` (fixture de teste vazando para produção) | — |
50
- | `oracle-no-auth-forge` | error | `withoutMiddleware()`/`actingAs()` no oráculo | login real via kernel HTTP (waiver para o caso legítimo) |
51
- | `oracle-no-container-fake` | error | `mock/partialMock/swap/fake/Container::set` no oráculo | — |
52
- | `test-mock-only` | warn | teste só com `expects/assertCalled` sem asserção de domínio | — |
53
- | `php-parse-error` | error | arquivo que o tokenizador não leu (sintaxe inválida detectada via `TOKEN_PARSE`) | — |
54
- | `php-runtime-missing` | warn | `php` ausente no host | — |
55
-
56
- ## Por que subprocesso PHP e não `nikic/php-parser`?
57
-
58
- `npx prumo gate` num repo Laravel precisa funcionar sem `composer install` do parser. O script `php/ast_extractor.php` é stdlib-only e embutido no pacote npm (`files: ["php"]`). `nikic/php-parser` empacotado no plugin é o upgrade path declarado para a fase de `fix`/`prune` — nunca o `vendor/` do consumidor. A lei mora no core Node; o PHP é só parser.
44
+ | `mutation-routes-guarded` | error | `Route::post/put/patch/delete` without auth on the route, on the nested group, or on the controller; `throttle:api` does NOT count as auth | global middleware of the `web`/`api` stack (read `bootstrap/app.php`/`Kernel` yourself); GET |
45
+ | `form-request-validated` | error | raw `Request` with `all()/input()/json()` without `validate()`; raw payload + `unguard()` | inline `$request->validate([...])`; FormRequest with `rules()` |
46
+ | `form-request-hollow` | warn | FormRequest without a filled-in `rules()` | — |
47
+ | `no-raw-queries` | error | interpolated `DB::raw/whereRaw/selectRaw/DB::select...` or without bindings | raw SQL with `?`/named bindings |
48
+ | `oracle-no-src` | error | `use App\...` **or service-locator `app(FQCN::class)`/`resolve`/`->make`/`Container::make\|get`** inside `oracleDirs` (anti-bypass: a dynamic import is an import) | entrypoint (`bootstrap/app.php`) |
49
+ | `src-no-oracle` | error | `app/**` with `use Tests\...` (test fixtures leaking into production) | — |
50
+ | `oracle-no-auth-forge` | error | `withoutMiddleware()`/`actingAs()` in the oracle | real login via the HTTP kernel (waiver for the legitimate case) |
51
+ | `oracle-no-container-fake` | error | `mock/partialMock/swap/fake/Container::set` in the oracle | — |
52
+ | `test-mock-only` | warn | tests with only `expects/assertCalled` and no domain assertion | — |
53
+ | `php-parse-error` | error | a file the tokenizer could not read (invalid syntax detected via `TOKEN_PARSE`) | — |
54
+ | `php-runtime-missing` | warn | `php` missing on the host | — |
55
+
56
+ ## Why a PHP subprocess instead of `nikic/php-parser`?
57
+
58
+ `npx prumo gate` in a Laravel repo must work without `composer install` of the parser. The `php/ast_extractor.php` script is stdlib-only and embedded in the npm package (`files: ["php"]`). `nikic/php-parser` packaged into the plugin is the declared upgrade path for the `fix`/`prune` phase — never the consumer's `vendor/`. The law lives in the Node core; PHP is just a parser.
59
+
60
+ ---
61
+
62
+ ## License & Brand
63
+
64
+ Copyright © 2026 **IHELPEE TECNOLOGIA LTDA** (<https://ihelpee.com>). All rights reserved.
65
+ Created and authored by [Alex Gotardi](https://github.com/alexgotardi).
66
+
67
+ Licensed under the [Apache License, Version 2.0](https://github.com/ihelpee/prumo/blob/main/LICENSE) (the "License"); you may not use this file except in compliance with the License. A copy is available at <http://www.apache.org/licenses/LICENSE-2.0>.
68
+
69
+ The **"Prumo"** name and logo are trademarks of IHELPEE TECNOLOGIA LTDA and are **not** licensed under the Apache 2.0 license.
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,OAAO,EAGZ,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AA6CnC,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AA+BD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EAAE,EACrB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CA+BT;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,SA2BvB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,SAsBpB,CAAC;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,SAuBf,CAAC;AAMX;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CA2C7D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAyBpF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CA8BnE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CA0BvE;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,SAuBf,CAAC;AAMX;;;;GAIG;AACH,eAAO,MAAM,aAAa,SAgBhB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,SAWpB,CAAC;AAyBX;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,WAAW,CA2BvE;AAED,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,OAAO,EAAuB,CAAC;AAE9D,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,OAAO,EAGZ,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AA6CnC,MAAM,WAAW,iBAAiB;IAChC,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AA+BD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EAAE,EACrB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CA+BT;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,SA2BvB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,SAsBpB,CAAC;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,SAuBf,CAAC;AAMX;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CA2C7D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAyBpF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CA8BnE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CA0BvE;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,SAuBf,CAAC;AAMX;;;;GAIG;AACH,eAAO,MAAM,aAAa,SAgBhB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,SAWpB,CAAC;AAyBX;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,WAAW,CA2BvE;AAED,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,OAAO,EAAuB,CAAC;AAE9D,eAAe,UAAU,CAAC"}
package/dist/rules.js CHANGED
@@ -1,3 +1,4 @@
1
+ import pkg from '../package.json' with { type: 'json' };
1
2
  import { rule, definePlugin, } from '@ihelpee/prumo/invariants';
2
3
  import { extractPhpModel } from './ast.js';
3
4
  /**
@@ -482,7 +483,7 @@ export function phpLaravel(options = {}) {
482
483
  };
483
484
  return definePlugin({
484
485
  name: 'php-laravel',
485
- version: '0.8.3',
486
+ version: pkg.version,
486
487
  description: 'PHP/Laravel invariants: guarded mutation routes, FormRequest discipline, parameterized SQL, oracle isolation (no auth forge, no container fakes, anti-burla service-locator).',
487
488
  extractors: {
488
489
  php: async (ctx) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ihelpee/prumo-plugin-php-laravel",
3
- "version": "0.8.3",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "description": "PHP/Laravel plugin for Prumo: guarded mutation routes, FormRequest discipline, parameterized SQL, and oracle isolation invariants.",
6
6
  "author": "Alex Gotardi <alexgotardi@gmail.com> (https://github.com/alexgotardi)",
@@ -33,6 +33,6 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@ihelpee/prumo": "0.8.3"
36
+ "@ihelpee/prumo": "0.9.0"
37
37
  }
38
38
  }