@nodefony/framework 10.0.0-beta.5 → 10.0.0-beta.7
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/_virtual/{_@oxc-project_runtime@0.155.0 → _@oxc-project_runtime@0.158.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/_@oxc-project_runtime@0.158.0/helpers/esm/decorateParam.js +7 -0
- package/dist/index.js +14 -10
- package/dist/nodefony/config/config.js +16 -2
- package/dist/nodefony/controller/AdminApiController.js +18 -5
- package/dist/nodefony/controller/BenchController.js +1 -1
- package/dist/nodefony/controller/CspReportController.js +70 -0
- package/dist/nodefony/controller/IssuerMetadataController.js +3 -3
- package/dist/nodefony/controller/LoginPageController.js +5 -7
- package/dist/nodefony/controller/ProtectedResourceMetadataController.js +75 -10
- package/dist/nodefony/controller/SessionAuthController.js +6 -7
- package/dist/nodefony/controller/TokenAuthController.js +3 -3
- package/dist/nodefony/decorators/routerDecorators.js +103 -15
- package/dist/nodefony/grpc/GrpcController.js +138 -0
- package/dist/nodefony/grpc/GrpcService.js +75 -0
- package/dist/nodefony/grpc/declarations.js +33 -0
- package/dist/nodefony/grpc/index.js +3 -0
- package/dist/nodefony/service/AdminBroker.js +1 -1
- package/dist/nodefony/service/IdempotencyStore.js +1 -1
- package/dist/nodefony/service/router.js +15 -12
- package/dist/nodefony/src/Controller.js +330 -115
- package/dist/nodefony/src/PlaygroundAdminApi.js +1 -1
- package/dist/nodefony/src/Resolver.js +85 -51
- package/dist/nodefony/src/Route.js +45 -45
- package/dist/nodefony/src/SecurityApiController.js +30 -7
- package/dist/nodefony/src/conditionalRequest.js +103 -0
- package/dist/nodefony/src/docsReader.js +1 -1
- package/dist/nodefony/src/idempotency.js +1 -1
- package/dist/nodefony/src/loginPage.js +3 -2
- package/dist/nodefony/src/scopeCatalog.js +1 -1
- package/dist/nodefony/src/viewNonce.js +58 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/nodefony/config/config.d.ts +20 -0
- package/dist/types/nodefony/controller/AdminApiController.d.ts +4 -2
- package/dist/types/nodefony/controller/CspReportController.d.ts +35 -0
- package/dist/types/nodefony/controller/LoginPageController.d.ts +3 -2
- package/dist/types/nodefony/controller/ProtectedResourceMetadataController.d.ts +21 -1
- package/dist/types/nodefony/controller/SessionAuthController.d.ts +5 -6
- package/dist/types/nodefony/controller/TokenAuthController.d.ts +3 -3
- package/dist/types/nodefony/decorators/routerDecorators.d.ts +2 -1
- package/dist/types/nodefony/grpc/GrpcController.d.ts +75 -0
- package/dist/types/nodefony/grpc/GrpcService.d.ts +51 -0
- package/dist/types/nodefony/grpc/declarations.d.ts +12 -0
- package/dist/types/nodefony/grpc/index.d.ts +13 -0
- package/dist/types/nodefony/interfaces/IController.d.ts +4 -4
- package/dist/types/nodefony/service/router.d.ts +8 -6
- package/dist/types/nodefony/src/Controller.d.ts +124 -14
- package/dist/types/nodefony/src/Resolver.d.ts +35 -8
- package/dist/types/nodefony/src/Route.d.ts +35 -0
- package/dist/types/nodefony/src/SecurityApiController.d.ts +17 -4
- package/dist/types/nodefony/src/conditionalRequest.d.ts +82 -0
- package/dist/types/nodefony/src/loginPage.d.ts +1 -1
- package/dist/types/nodefony/src/viewNonce.d.ts +33 -0
- package/docs/controller.md +234 -35
- package/docs/decorateurs.md +1 -1
- package/docs/grpc.md +690 -0
- package/docs/idempotence.md +13 -8
- package/docs/index.md +16 -10
- package/docs/routing.md +30 -2
- package/docs/templates.md +15 -0
- package/package.json +28 -11
package/docs/idempotence.md
CHANGED
|
@@ -263,7 +263,7 @@ Deux mécanismes rendent ça possible côté socket :
|
|
|
263
263
|
`resolveIdempotencyKey()` (`idempotency.ts#resolveIdempotencyKey`) donne la **priorité à l'ALS** sur l'en-tête HTTP.
|
|
264
264
|
- **La méthode logique voyage par `methodOverride`** — sur une socket, `context.method` vaut
|
|
265
265
|
`WEBSOCKET`, qui n'est **pas** une mutation. Sans override, la porte serait sautée et un rejeu de
|
|
266
|
-
frame `socket.
|
|
266
|
+
frame `socket.post` créerait un doublon. Le Resolver teste donc
|
|
267
267
|
`isMutationMethod(this.methodOverride ?? context.method)` (`Resolver.ts#Resolver.action`).
|
|
268
268
|
|
|
269
269
|
Le pont utilise `executeActionGuarded()` (`Resolver.ts#Resolver.executeActionGuarded`) : porte d'idempotence **sans** rendu HTTP
|
|
@@ -304,16 +304,21 @@ sequenceDiagram
|
|
|
304
304
|
comparaison, flux normal, **zéro** lookup de store et zéro allocation.
|
|
305
305
|
2. **No-op sur méthode sûre.** Une action `GET` sous une classe `@Idempotent` repart directement en
|
|
306
306
|
exécution (`Resolver.ts#Resolver._callWithIdempotency`).
|
|
307
|
-
3. **
|
|
308
|
-
|
|
307
|
+
3. **La garde d'abord.** `@IsGranted`, `@RequireScope` et le rôle de la zone sont jugés AVANT
|
|
308
|
+
la porte (`Resolver.ts#Resolver._enforceActionSecurity`), comme avant la validation d'un schéma :
|
|
309
|
+
un appelant sans le droit reçoit 401/403, jamais un 400 « clé requise » ni un 422 qui lui
|
|
310
|
+
apprendrait le contrat de la route ; aucune clé n'est réservée pour lui ; et un **rejeu est
|
|
311
|
+
rejugé** — un droit retiré entre-temps rend 403, pas la réponse mémorisée.
|
|
312
|
+
4. **Empreinte du payload.** `computeFingerprint()` (`idempotency.ts#computeFingerprint`) hache
|
|
313
|
+
`[nom de route, params de route, corps]` (`Resolver.ts#Resolver._callWithIdempotency`). Le corps vient de l'ALS (pont WS) ou
|
|
309
314
|
du body HTTP parsé.
|
|
310
|
-
|
|
315
|
+
5. **Identité.** `resolveIdentity()` (`idempotency.ts#resolveIdentity`) rend l'`identifier` de l'utilisateur
|
|
311
316
|
AUTHENTIFIÉ de la requête (`RequestContext.getAuthenticatedUser()`, la règle unique du cœur).
|
|
312
317
|
L'anonyme d'une zone `anonymous` n'a pas d'identité : tous les visiteurs anonymes partagent le
|
|
313
318
|
même `identifier`, ils partageraient donc le même cache. **`null` = pas de cache** : le verdict
|
|
314
319
|
devient `execute` — jamais de partage cross-identité.
|
|
315
|
-
|
|
316
|
-
|
|
320
|
+
6. **Réservation.** `store.begin()` compose la clé scopée et tranche.
|
|
321
|
+
7. **Mémorisation.** En succès, `complete(clé, {status, body})` où `status` est le code de réponse
|
|
317
322
|
courant et `body` la **valeur retournée** par l'action (`Resolver.ts#Resolver._callWithIdempotency`). En erreur,
|
|
318
323
|
`abort(clé)` libère la clé : **un échec ne se mémorise pas**, il doit rester réessayable.
|
|
319
324
|
|
|
@@ -323,7 +328,7 @@ sequenceDiagram
|
|
|
323
328
|
> double-effet reste évité, mais le corps rejoué est vide. Pire, si le corps retourné n'est pas
|
|
324
329
|
> sérialisable (retour d'un objet Response circulaire), un store SQL/Redis lève au `stringify`. Le
|
|
325
330
|
> Resolver attrape ce cas : il **journalise un WARNING explicite** puis mémorise le statut avec un
|
|
326
|
-
> corps `null` (`Resolver.ts#Resolver.
|
|
331
|
+
> corps `null` (`Resolver.ts#Resolver._callWithIdempotency`) — la dédup est préservée plutôt que perdue en silence.
|
|
327
332
|
|
|
328
333
|
### Où la porte est câblée
|
|
329
334
|
|
|
@@ -656,7 +661,7 @@ pour l'affichage Studio, `idempotencyStoreRegistry.ts#listIdempotencyBackends`).
|
|
|
656
661
|
<!-- prettier-ignore -->
|
|
657
662
|
| Sujet | Norme | Ancrage |
|
|
658
663
|
| --- | --- | --- |
|
|
659
|
-
| En-tête `Idempotency-Key`, statuts, rejeu | `draft-ietf-httpapi-idempotency-key-header-
|
|
664
|
+
| En-tête `Idempotency-Key`, statuts, rejeu | `draft-ietf-httpapi-idempotency-key-header-08` | `evaluateIdempotency()` (`idempotency.ts#evaluateIdempotency`) |
|
|
660
665
|
| Clé réutilisée avec un autre payload → 422 | draft §2.2 / §2.7 | `idempotency.ts#evaluateIdempotency` |
|
|
661
666
|
| Exécution concurrente identique → 409 | draft §2.6 | `idempotency.ts#evaluateIdempotency` |
|
|
662
667
|
| Clé requise absente → 400 | draft §2.7 | `idempotency.ts#evaluateIdempotency` |
|
package/docs/index.md
CHANGED
|
@@ -53,14 +53,15 @@ Trois parcours selon ce que tu viens faire. L'ordre compte : chaque étape suppo
|
|
|
53
53
|
|
|
54
54
|
Le tableau pour choisir vite ; les cards en dessous pour savoir ce qu'on y trouve.
|
|
55
55
|
|
|
56
|
-
| Brique | Ce qu'elle résout | Tu en as besoin quand…
|
|
57
|
-
| ------------------------------- | -------------------------------------------------- |
|
|
58
|
-
| [Décorateurs](decorateurs.md) | déclarer routes, paramètres, réponses, gardes | toujours — c'est la surface d'écriture
|
|
59
|
-
| [Contrôleurs](controller.md) | recevoir la requête, répondre, gérer l'erreur | toujours
|
|
60
|
-
| [Routage](routing.md) | apparier une URL à une action, arbitrer, expliquer | deux routes se disputent, ou un 404/405 surprend
|
|
61
|
-
| [Idempotence](idempotence.md) | empêcher le double effet d'une mutation rejouée | paiement, commande, tout effet non rejouable
|
|
62
|
-
| [
|
|
63
|
-
| [
|
|
56
|
+
| Brique | Ce qu'elle résout | Tu en as besoin quand… |
|
|
57
|
+
| ------------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
58
|
+
| [Décorateurs](decorateurs.md) | déclarer routes, paramètres, réponses, gardes | toujours — c'est la surface d'écriture |
|
|
59
|
+
| [Contrôleurs](controller.md) | recevoir la requête, répondre, gérer l'erreur | toujours |
|
|
60
|
+
| [Routage](routing.md) | apparier une URL à une action, arbitrer, expliquer | deux routes se disputent, ou un 404/405 surprend |
|
|
61
|
+
| [Idempotence](idempotence.md) | empêcher le double effet d'une mutation rejouée | paiement, commande, tout effet non rejouable |
|
|
62
|
+
| [gRPC](grpc.md) | servir un service gRPC, gRPC-Web et Connect | des programmes d'autres langages, des sondes ou un navigateur appellent un contrat typé |
|
|
63
|
+
| [Admin (data plane)](admin.md) | monter les API d'admin `/nodefony/<ns>/api/*` | ton module expose des stats ou actions à Studio et au CLI |
|
|
64
|
+
| [Templates (Eta)](templates.md) | rendre des vues HTML côté serveur | tu renvoies des pages HTML plutôt que du JSON |
|
|
64
65
|
|
|
65
66
|
```nodefony-cards
|
|
66
67
|
[
|
|
@@ -76,6 +77,9 @@ Le tableau pour choisir vite ; les cards en dessous pour savoir ce qu'on y trouv
|
|
|
76
77
|
{ "icon": "🔁", "title": "idempotence", "href": "idempotence.md",
|
|
77
78
|
"desc": "@Idempotent, la clé d'idempotence, les quatre stores (mémoire, Redis, SQL, MongoDB) et leurs capacités réelles, le GC des entrées expirées, et ce que le client observe quand il rejoue la même clé.",
|
|
78
79
|
"meta": "paiement, commande, tout effet non rejouable" },
|
|
80
|
+
{ "icon": "📡", "title": "grpc", "href": "grpc.md",
|
|
81
|
+
"desc": "Déclarer un service gRPC par un contrôleur : le contrat et sa génération, les trois protocoles et leurs ports, les limites, les refus 16/7, les erreurs, l'arrêt, CORS et le journal — avec le pourquoi de chaque choix. Surface expérimentale.",
|
|
82
|
+
"meta": "un contrat typé appelé par d'autres langages, des sondes ou un navigateur" },
|
|
79
83
|
{ "icon": "🛡️", "title": "admin", "href": "admin.md",
|
|
80
84
|
"desc": "Le data plane d'administration : comment un module déclare son API d'admin via AdminBroker, la convention de route /nodefony/<ns>/api/*, le RBAC fail-closed (ROLE_NODEFONY_ADMIN), le duplex HTTP/WebSocket, le catalogue et le Playground.",
|
|
81
85
|
"meta": "exposer une API d'admin cohérente CLI ↔ Web" },
|
|
@@ -108,8 +112,10 @@ dans `.ai/symbols.json` et les types générés — jamais recopiées ici, où e
|
|
|
108
112
|
## ⚙️ Configuration
|
|
109
113
|
|
|
110
114
|
Bloc Zod (`nodefony/config/config.ts`), déclaré depuis l'application via
|
|
111
|
-
`use("@nodefony/framework", { … })` : `router`, `adminBroker`,
|
|
112
|
-
réglages du GC — détaillé dans la page [Idempotence](idempotence.md))
|
|
115
|
+
`use("@nodefony/framework", { … })` : `router`, `adminBroker`, `idempotency` (choix du store et
|
|
116
|
+
réglages du GC — détaillé dans la page [Idempotence](idempotence.md)), et `fileServing` (validateurs
|
|
117
|
+
et `Cache-Control` des fichiers servis par une action — détaillé dans la page
|
|
118
|
+
[Contrôleur](controller.md#requêtes-conditionnelles--304-412-reprise)).
|
|
113
119
|
|
|
114
120
|
## 📜 Normes appliquées
|
|
115
121
|
|
package/docs/routing.md
CHANGED
|
@@ -457,11 +457,14 @@ que fait le data plane d'administration pour toutes ses lectures (`AdminBroker.m
|
|
|
457
457
|
(RFC 9110 §10.2.1), elle est retirée de l'agrégat. Un chemin qui n'existe qu'en WebSocket, appelé
|
|
458
458
|
en HTTP, répond `426 Upgrade Required` avec `Upgrade: websocket` plutôt qu'un 405
|
|
459
459
|
(`routing-nonregression.test.ts`).
|
|
460
|
-
- **Une invocation WS
|
|
460
|
+
- **Une invocation WS dit toujours quelle méthode logique elle vise, GET compris.** Sur une socket,
|
|
461
461
|
`context.method` vaut toujours `WEBSOCKET` : insuffisant pour distinguer un GET d'un POST sur le même
|
|
462
462
|
chemin. Le pont transporte donc une **méthode logique** (`methodOverride`, `Resolver.ts#Resolver.methodOverride`) que la
|
|
463
463
|
route doit déclarer **en plus** du transport — une route `POST` qui n'annonce pas `WEBSOCKET` reste
|
|
464
|
-
**injoignable** par socket (
|
|
464
|
+
**injoignable** par socket, et un GET n'atteint jamais l'action POST voisine (qui contournerait sa
|
|
465
|
+
porte `@Idempotent`). Seule tolérance : une route qui ne déclare QUE `WEBSOCKET` sert un GET. La
|
|
466
|
+
règle est UNIQUE, au cœur (`routePath.ts#bridgeServesVerb`) : le routeur
|
|
467
|
+
(`Route.ts#Route.matchRequirements`) et la vérification des contrats au démarrage l'appellent tous deux.
|
|
465
468
|
|
|
466
469
|
Le routage par **message** (invoquer un chemin porté par une frame, sans toucher l'URL de la connexion)
|
|
467
470
|
passe par le même `resolve()`, avec un chemin fourni en argument — l'état partagé de la socket n'est
|
|
@@ -538,6 +541,31 @@ chemin ; pour un appel interne, utilise `forward()`.
|
|
|
538
541
|
dans le **même** contexte de requête, sans repasser par le réseau (`Resolver.parsePathernController()`,
|
|
539
542
|
`Resolver.ts#Resolver.parsePathernController`). Une vraie redirection HTTP passe par `this.redirect(url, 302)` ou `@Redirect`.
|
|
540
543
|
|
|
544
|
+
## ⏱️ Délai de réponse — par route
|
|
545
|
+
|
|
546
|
+
Une action muette au-delà du délai de réponse reçoit **503**, en HTTP/1.1 comme en HTTP/2, et son
|
|
547
|
+
`ctx.signal` est annulé AVANT le rendu de l'erreur : une requête SQL ou un `fetch` qui l'honore
|
|
548
|
+
s'arrête. Le délai est celui du serveur (`responseTimeout`, 30 s par défaut), sauf si la route
|
|
549
|
+
déclare le sien (`Route.ts#RouteOptions.responseTimeout`) — dans les deux sens :
|
|
550
|
+
|
|
551
|
+
```ts ignore
|
|
552
|
+
@Get("/export", { responseTimeout: 120_000 }) // un export lent, sans relever les autres routes
|
|
553
|
+
exportAll(): unknown {
|
|
554
|
+
return this.reports.buildAll();
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
Les bornes d'envoi suivent le même modèle : `upload: { maxFileSize, maxFiles, hashAlgorithm, … }`
|
|
559
|
+
(`Route.ts#RouteOptions.upload`) remplace, pour la seule route, celles de la configuration http —
|
|
560
|
+
le fichier trop gros reçoit 413 pendant son flux. Détail : [Upload](../../http/docs/upload.md#par-route--loption-upload).
|
|
561
|
+
|
|
562
|
+
C'est un délai d'**inactivité** : une action qui envoie au fil de l'eau (flux, SSE) n'est pas
|
|
563
|
+
coupée. Entier de `0` à 2³¹−1 ms, vérifié à la déclaration ; `0` désactive le délai pour la route.
|
|
564
|
+
Le 408 reste réservé à une requête que le serveur n'a pas **reçue** à temps (`requestTimeout`,
|
|
565
|
+
RFC 9110 §15.5.9) ; le 503 dit « traitement impossible dans le délai » (§15.6.4), sans inviter le
|
|
566
|
+
client à rejouer un `POST`. Une route gRPC termine l'appel au format du protocole (4
|
|
567
|
+
`DEADLINE_EXCEEDED`), jamais par ce 503.
|
|
568
|
+
|
|
541
569
|
## 🧰 API publique
|
|
542
570
|
|
|
543
571
|
Le routage s'utilise **par décorateurs** ; l'API impérative sert l'outillage (introspection, tests,
|
package/docs/templates.md
CHANGED
|
@@ -249,6 +249,21 @@ inerte `<script>alert(1)</script>`.
|
|
|
249
249
|
> par un utilisateur (pseudo, commentaire, champ de formulaire, paramètre d'URL). Réserve-le à des
|
|
250
250
|
> fragments HTML que ton propre code a construits.
|
|
251
251
|
|
|
252
|
+
**La politique de sécurité du contenu (CSP) est signée pour toi.** La politique par défaut n'exécute
|
|
253
|
+
un `<script>` et n'applique un `<style>` que s'ils portent le nonce de la requête. `renderView` le
|
|
254
|
+
pose seul sur chaque balise ÉCRITE dans le gabarit (`viewNonce.ts#signTemplateTags`) — rien à
|
|
255
|
+
ajouter. Il ne signe jamais :
|
|
256
|
+
|
|
257
|
+
- une balise que les données apportent (`<%~ %>`) : c'est ce qui laisse au nonce sa valeur contre
|
|
258
|
+
l'injection ;
|
|
259
|
+
- un `<script>` dont un attribut vient des données (`src="<%= it.url %>"`) : le signer exécuterait
|
|
260
|
+
l'URL qu'elles apportent. Si tu la tiens pour sûre, écris le nonce toi-même :
|
|
261
|
+
`<script nonce="<%= it.cspNonce %>" src="<%= it.url %>">` ;
|
|
262
|
+
- un gestionnaire en attribut (`onclick="…"`, `onload="…"`) : aucun nonce ne s'y pose, la politique
|
|
263
|
+
le refuse. Attache l'écouteur depuis un `<script>` du gabarit (`addEventListener`).
|
|
264
|
+
|
|
265
|
+
Le détail de la politique et ses réglages : [En-têtes de sécurité](../../security/docs/headers.md).
|
|
266
|
+
|
|
252
267
|
## 🧰 API publique
|
|
253
268
|
|
|
254
269
|
Deux niveaux : ce que le **service Eta** expose, et ce que le **contrôleur** t'offre au-dessus.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodefony/framework",
|
|
3
|
-
"version": "10.0.0-beta.
|
|
3
|
+
"version": "10.0.0-beta.7",
|
|
4
4
|
"description": "Le modèle de programmation Nodefony : routeur, contrôleurs, décorateurs et vues — HTTP et WebSocket dans le même contexte",
|
|
5
5
|
"author": "Christophe CAMENSULI <ccamensuli@gmail.com>",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -12,6 +12,12 @@
|
|
|
12
12
|
"types": "./dist/types/index.d.ts",
|
|
13
13
|
"import": "./dist/index.js",
|
|
14
14
|
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./grpc": {
|
|
17
|
+
"nodefony-source": "./nodefony/grpc/index.ts",
|
|
18
|
+
"types": "./dist/types/nodefony/grpc/index.d.ts",
|
|
19
|
+
"import": "./dist/nodefony/grpc/index.js",
|
|
20
|
+
"default": "./dist/nodefony/grpc/index.js"
|
|
15
21
|
}
|
|
16
22
|
},
|
|
17
23
|
"scripts": {
|
|
@@ -25,7 +31,7 @@
|
|
|
25
31
|
},
|
|
26
32
|
"private": false,
|
|
27
33
|
"engines": {
|
|
28
|
-
"node": "
|
|
34
|
+
"node": "^24.16.0 || >=26.0.0"
|
|
29
35
|
},
|
|
30
36
|
"keywords": [
|
|
31
37
|
"nodefony",
|
|
@@ -46,25 +52,36 @@
|
|
|
46
52
|
"dependencies": {
|
|
47
53
|
"eta": "4.6.0",
|
|
48
54
|
"reflect-metadata": "0.2.2",
|
|
49
|
-
"tslib": "2.
|
|
55
|
+
"tslib": "2.9.1"
|
|
50
56
|
},
|
|
51
57
|
"devDependencies": {
|
|
52
|
-
"@nodefony/http": "^10.0.0-beta.
|
|
58
|
+
"@nodefony/http": "^10.0.0-beta.7",
|
|
53
59
|
"@types/chai": "5.2.3",
|
|
54
|
-
"@types/node": "26.6.
|
|
55
|
-
"@vitest/coverage-v8": "5.0
|
|
56
|
-
"nodefony": "^10.0.0-beta.
|
|
60
|
+
"@types/node": "26.6.6",
|
|
61
|
+
"@vitest/coverage-v8": "5.1.0",
|
|
62
|
+
"nodefony": "^10.0.0-beta.7",
|
|
57
63
|
"tsx": "4.23.15",
|
|
58
|
-
"vitest": "5.0
|
|
64
|
+
"vitest": "5.1.0",
|
|
65
|
+
"ws": "8.23.0"
|
|
59
66
|
},
|
|
60
67
|
"license": "Apache-2.0",
|
|
61
68
|
"readmeFilename": "README.md",
|
|
62
69
|
"contributors": [],
|
|
63
70
|
"peerDependencies": {
|
|
64
|
-
"@
|
|
65
|
-
"
|
|
71
|
+
"@bufbuild/protobuf": "^2.7.0",
|
|
72
|
+
"@connectrpc/connect": "^2.3.0",
|
|
73
|
+
"@nodefony/http": "^10.0.0-beta.7",
|
|
74
|
+
"nodefony": "^10.0.0-beta.7",
|
|
66
75
|
"zod": "^4.6.7"
|
|
67
76
|
},
|
|
77
|
+
"peerDependenciesMeta": {
|
|
78
|
+
"@bufbuild/protobuf": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@connectrpc/connect": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
84
|
+
},
|
|
68
85
|
"files": [
|
|
69
86
|
"dist",
|
|
70
87
|
"docs"
|
|
@@ -72,7 +89,7 @@
|
|
|
72
89
|
"publishConfig": {
|
|
73
90
|
"access": "public"
|
|
74
91
|
},
|
|
75
|
-
"homepage": "https://nodefony.
|
|
92
|
+
"homepage": "https://nodefony.net/",
|
|
76
93
|
"bugs": {
|
|
77
94
|
"url": "https://github.com/nodefony/nodefony-core/issues"
|
|
78
95
|
}
|