@peaje/next 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.
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # @peaje/next
2
+
3
+ Peaje for Next.js. Two pieces:
4
+
5
+ - `withPeaje(nextConfig, { slug })` adds the proxy rewrites that make your domain serve the Peaje catalog, the MCP server, the OpenAPI spec and the priced links (HTTP 402) that your gateway already publishes.
6
+ - `<PeajeHead slug="..." />` renders the JSON-LD `WebAPI` block and the discovery `<link>` tags in your `<head>`.
7
+
8
+ Both are additive: your existing rewrites, config and head stay as they are.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ npm install @peaje/next
14
+ ```
15
+
16
+ Requires Next.js 14 or newer. `PeajeHead` needs the app router (it is an async server component).
17
+
18
+ ## 1. Rewrites
19
+
20
+ ```ts
21
+ // next.config.ts
22
+ import { withPeaje } from '@peaje/next'
23
+
24
+ const nextConfig = {
25
+ // your config, including any existing rewrites()
26
+ }
27
+
28
+ export default withPeaje(nextConfig, { slug: 'cafe-andino' })
29
+ ```
30
+
31
+ `withPeaje` prepends the Peaje rules to `rewrites().beforeFiles` and keeps what you had: an array becomes `afterFiles`, an object keeps its `beforeFiles`, `afterFiles` and `fallback`. It accepts sync or async `rewrites()` and a config written as a function `(phase, { defaultConfig }) => config`. Wrapping twice does not duplicate rules.
32
+
33
+ Options: `slug` (required, the one from your Peaje dashboard) and `gateway` (defaults to `https://peaje-gateway.up.railway.app`, overridable with the `PEAJE_GATEWAY_URL` environment variable).
34
+
35
+ If you have a `middleware.ts` or `proxy.ts` with a `matcher`, exclude `mcp`, `r/`, `discovery/`, `checkout_sessions`, `agentic_commerce/` and `docs` from it: middleware runs before rewrites.
36
+
37
+ ## 2. Head
38
+
39
+ ```tsx
40
+ // app/layout.tsx
41
+ import { PeajeHead } from '@peaje/next/head'
42
+
43
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
44
+ return (
45
+ <html lang="en">
46
+ <head>
47
+ <PeajeHead slug="cafe-andino" />
48
+ </head>
49
+ <body>{children}</body>
50
+ </html>
51
+ )
52
+ }
53
+ ```
54
+
55
+ The offers in the JSON-LD come from your gateway (`/discovery/resources`) and are revalidated hourly. If the gateway is unreachable, the component renders the block without offers and never throws: a Peaje outage cannot break your build or your pages.
56
+
57
+ Props: `slug` (required), `gateway`, `originHost` and `name`. Without `originHost` the component reads the request host through `next/headers`, which makes the layout dynamic; pass `originHost="cafeandino.com"` to keep static rendering.
58
+
59
+ ## 3. Footer
60
+
61
+ Auditors look for documentation linked from the homepage, visibly. Add this to your footer or nav:
62
+
63
+ ```html
64
+ <a href="/developers">API for agents</a>
65
+ ```
66
+
67
+ ## Verify
68
+
69
+ After the deploy is live:
70
+
71
+ ```sh
72
+ npx @peaje/cli@1 verify cafe-andino --wait 600
73
+ ```
74
+
75
+ ## License
76
+
77
+ MIT
@@ -0,0 +1,233 @@
1
+ // ../shared/src/kit/rutas.ts
2
+ var RUTAS_PROXY = [
3
+ { path: "/llms.txt", nota: "gu\xEDa para agentes (fusionada con la tuya)" },
4
+ { path: "/pricing.md", nota: "precios por endpoint" },
5
+ { path: "/auth.md", nota: 'c\xF3mo pagar (el "auth" ac\xE1 es el pago)' },
6
+ { path: "/agents.md", nota: "qu\xE9 es y cu\xE1ndo usarte" },
7
+ { path: "/openapi.json", nota: "discovery con precios" },
8
+ { path: "/mcp", nota: "MCP server con tools pagas, en TU dominio" },
9
+ { path: "/.well-known/mcp", nota: "el MCP tambi\xE9n ac\xE1: es donde lo buscan los auditores" },
10
+ { path: "/.well-known/ard.json", nota: "cat\xE1logo ARD (path can\xF3nico)" },
11
+ { path: "/.well-known/ai-catalog.json", nota: "cat\xE1logo ARD (alias legacy)" },
12
+ { path: "/.well-known/api-catalog", nota: "linkset RFC 9727" },
13
+ { path: "/.well-known/agent-card.json", nota: "agent card A2A" },
14
+ { path: "/.well-known/mcp/server-card.json", nota: "server card MCP" },
15
+ { path: "/discovery/resources", nota: "lista x402 Bazaar: lo que cobra 402 de verdad" },
16
+ { path: "/.well-known/ucp", nota: "perfil UCP: qu\xE9 sabe hacer tu negocio" },
17
+ { path: "/checkout_sessions", nota: "checkout ACP (el de OpenAI)" },
18
+ { path: "/agentic_commerce/delegate_payment", nota: "delegate payment ACP" },
19
+ { path: "/developers", nota: "portal de desarrolladores, renderizado con tus precios" },
20
+ { path: "/.well-known/peaje-indexnow.txt", nota: "clave IndexNow: avisa a Bing y Copilot cuando cambian precios" },
21
+ // Los auditores prueban /docs y /developers; el gateway redirige uno al otro.
22
+ { path: "/docs", nota: "alias del portal: los auditores prueban ambos" }
23
+ ];
24
+ var RUTAS_DINAMICAS = [
25
+ { path: "/r/:slug", prefijo: "/r/", nota: "links con precio: el 402 en tu dominio" },
26
+ { path: "/checkout_sessions/:id", prefijo: "/checkout_sessions/", nota: "leer una sesi\xF3n de checkout ACP" }
27
+ ];
28
+ var PEAJE_FETCH_HEADER = "x-peaje-fetch";
29
+ function reglasNext(base) {
30
+ return [
31
+ ...RUTAS_PROXY.map((r) => ({
32
+ source: r.path,
33
+ destination: `${base}${r.path}`,
34
+ ...r.path === "/llms.txt" ? { missing: [{ type: "header", key: PEAJE_FETCH_HEADER }] } : {}
35
+ })),
36
+ ...RUTAS_DINAMICAS.map((r) => ({ source: r.path, destination: `${base}${r.path}` }))
37
+ ];
38
+ }
39
+
40
+ // ../shared/src/kit/bloques.ts
41
+ function rutaDe(url, slug) {
42
+ try {
43
+ const path = new URL(url).pathname;
44
+ const prefijo = `/${slug}`;
45
+ return path.startsWith(`${prefijo}/`) ? path.slice(prefijo.length) : path;
46
+ } catch {
47
+ return url;
48
+ }
49
+ }
50
+ function jsonParaScript(valor) {
51
+ return JSON.stringify(valor, null, 2).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
52
+ }
53
+ function jsonLdWebApi({
54
+ nombre,
55
+ slug,
56
+ originHost,
57
+ ofertas
58
+ }) {
59
+ return {
60
+ "@context": "https://schema.org",
61
+ "@type": "WebAPI",
62
+ "@id": `https://${originHost}/#api`,
63
+ name: nombre,
64
+ // URLs del dominio del negocio, no del gateway: después del proxy
65
+ // responden acá, y es acá donde el auditor las va a buscar.
66
+ documentation: `https://${originHost}/openapi.json`,
67
+ termsOfService: `https://${originHost}/auth.md`,
68
+ provider: { "@id": `https://${originHost}/#organization` },
69
+ potentialAction: {
70
+ "@type": "ConsumeAction",
71
+ target: {
72
+ "@type": "EntryPoint",
73
+ urlTemplate: `https://${originHost}/mcp`,
74
+ actionPlatform: "MCP"
75
+ }
76
+ },
77
+ offers: ofertas.map((o) => ({
78
+ "@type": "Offer",
79
+ name: o.titulo,
80
+ price: o.priceUsd,
81
+ priceCurrency: "USD",
82
+ url: `https://${originHost}${rutaDe(o.url, slug)}`,
83
+ availability: "https://schema.org/InStock"
84
+ }))
85
+ };
86
+ }
87
+ var LINKS_HEAD = [
88
+ { rel: "service-desc", type: "application/openapi+json", href: "/openapi.json" },
89
+ { rel: "service-doc", type: "text/plain", href: "/llms.txt" },
90
+ { rel: "service-meta", type: "text/markdown", href: "/pricing.md" },
91
+ { rel: "ard", type: "application/ai-catalog+json", href: "/.well-known/ard.json" }
92
+ ];
93
+
94
+ // ../shared/src/index.ts
95
+ var TEMPO = {
96
+ mainnet: {
97
+ chainId: 4217,
98
+ rpcUrl: "https://rpc.tempo.xyz",
99
+ explorerUrl: "https://explore.tempo.xyz"
100
+ },
101
+ testnet: {
102
+ chainId: 42431,
103
+ rpcUrl: "https://rpc.moderato.tempo.xyz",
104
+ explorerUrl: "https://explore.testnet.tempo.xyz"
105
+ }
106
+ };
107
+ var TOKENS = {
108
+ pathUsd: "0x20c0000000000000000000000000000000000000",
109
+ usdc: "0x20C000000000000000000000b9537d11c60E8b50"
110
+ };
111
+ var DEFAULT_CURRENCY = TOKENS.pathUsd;
112
+ var NETWORKS = {
113
+ tempo: {
114
+ id: "tempo",
115
+ label: "Tempo",
116
+ token: TOKENS.pathUsd,
117
+ tokenSymbol: "pathUSD",
118
+ decimals: 6,
119
+ mainnet: TEMPO.mainnet,
120
+ testnet: TEMPO.testnet
121
+ },
122
+ arc: {
123
+ id: "arc",
124
+ label: "Arc",
125
+ // Interfaz ERC-20 del USDC nativo de Arc; el gas de la red se paga en ese mismo USDC.
126
+ token: "0x3600000000000000000000000000000000000000",
127
+ tokenSymbol: "USDC",
128
+ decimals: 6,
129
+ // Leído on-chain del contrato: name() = "USDC", version() = "2".
130
+ eip3009: { name: "USDC", version: "2" },
131
+ // Arc no publica direcciones de mainnet todavía (sept 2026).
132
+ mainnet: null,
133
+ testnet: {
134
+ chainId: 5042002,
135
+ rpcUrl: "https://rpc.testnet.arc.io",
136
+ explorerUrl: "https://testnet.arcscan.app"
137
+ }
138
+ },
139
+ arbitrum: {
140
+ id: "arbitrum",
141
+ label: "Arbitrum",
142
+ // USDC de Circle en Arbitrum Sepolia. En Arbitrum One vive en otra dirección,
143
+ // por eso mainnet queda en null hasta que el gateway opere allá.
144
+ token: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
145
+ tokenSymbol: "USDC",
146
+ decimals: 6,
147
+ // Leído on-chain: name() = "USD Coin", version() = "2" (distinto al USDC de Arc).
148
+ eip3009: { name: "USD Coin", version: "2" },
149
+ mainnet: null,
150
+ testnet: {
151
+ chainId: 421614,
152
+ rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
153
+ explorerUrl: "https://sepolia.arbiscan.io"
154
+ }
155
+ },
156
+ "arbitrum-usdg": {
157
+ id: "arbitrum-usdg",
158
+ label: "Arbitrum \xB7 USDG",
159
+ // Mismo contrato y misma cadena que el riel USDC: cambia el stablecoin.
160
+ // Un riel es (cadena, token), y el saldo del negocio se lleva por token.
161
+ token: "0xFFC95faa3d63Cde504a05B567C600B78C0b41892",
162
+ tokenSymbol: "USDG",
163
+ decimals: 6,
164
+ eip3009: { name: "Global Dollar", version: "1" },
165
+ mainnet: null,
166
+ testnet: {
167
+ chainId: 421614,
168
+ rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
169
+ explorerUrl: "https://sepolia.arbiscan.io"
170
+ }
171
+ },
172
+ robinhood: {
173
+ id: "robinhood",
174
+ label: "Robinhood",
175
+ // USDG de Paxos en Robinhood Chain Testnet (el "USDC" de esa testnet es un
176
+ // mock sin EIP-3009). Leído on-chain: dominio "Global Dollar", versión "1".
177
+ token: "0x7E955252E15c84f5768B83c41a71F9eba181802F",
178
+ tokenSymbol: "USDG",
179
+ decimals: 6,
180
+ eip3009: { name: "Global Dollar", version: "1" },
181
+ mainnet: null,
182
+ testnet: {
183
+ chainId: 46630,
184
+ rpcUrl: "https://rpc.testnet.chain.robinhood.com",
185
+ explorerUrl: "https://explorer.testnet.chain.robinhood.com"
186
+ }
187
+ }
188
+ };
189
+ var NETWORK_IDS = Object.keys(NETWORKS);
190
+
191
+ // src/index.ts
192
+ var GATEWAY_POR_DEFECTO = "https://peaje-gateway.up.railway.app";
193
+ function baseDe({ slug, gateway }) {
194
+ const raiz = (gateway ?? process.env.PEAJE_GATEWAY_URL ?? GATEWAY_POR_DEFECTO).replace(/\/+$/, "");
195
+ return `${raiz}/${slug}`;
196
+ }
197
+ function fusionarRewrites(previo, reglas) {
198
+ const objeto = Array.isArray(previo) ? { afterFiles: previo } : { ...previo ?? {} };
199
+ const antes = objeto.beforeFiles ?? [];
200
+ const destinos = new Set(antes.map((r) => r.destination));
201
+ const nuevas = reglas.filter((r) => !destinos.has(r.destination));
202
+ return { ...objeto, beforeFiles: [...nuevas, ...antes] };
203
+ }
204
+ function envolverConfig(config, reglas) {
205
+ const original = config.rewrites;
206
+ return {
207
+ ...config,
208
+ async rewrites() {
209
+ const previo = original ? await original.call(config) : void 0;
210
+ return fusionarRewrites(previo, reglas);
211
+ }
212
+ };
213
+ }
214
+ function withPeaje(nextConfig, opciones) {
215
+ if (!opciones?.slug) throw new Error("withPeaje: `slug` is required (the business slug from your Peaje dashboard).");
216
+ const reglas = reglasNext(baseDe(opciones));
217
+ if (typeof nextConfig === "function") {
218
+ return async (phase, contexto) => envolverConfig(await nextConfig(phase, contexto), reglas);
219
+ }
220
+ return envolverConfig(nextConfig ?? {}, reglas);
221
+ }
222
+ var src_default = withPeaje;
223
+
224
+ export {
225
+ jsonParaScript,
226
+ jsonLdWebApi,
227
+ LINKS_HEAD,
228
+ GATEWAY_POR_DEFECTO,
229
+ baseDe,
230
+ fusionarRewrites,
231
+ withPeaje,
232
+ src_default
233
+ };
package/dist/head.cjs ADDED
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/head.tsx
31
+ var head_exports = {};
32
+ __export(head_exports, {
33
+ PeajeHead: () => PeajeHead,
34
+ default: () => head_default,
35
+ ofertasDesdeGateway: () => ofertasDesdeGateway
36
+ });
37
+ module.exports = __toCommonJS(head_exports);
38
+
39
+ // ../shared/src/kit/bloques.ts
40
+ function rutaDe(url, slug) {
41
+ try {
42
+ const path = new URL(url).pathname;
43
+ const prefijo = `/${slug}`;
44
+ return path.startsWith(`${prefijo}/`) ? path.slice(prefijo.length) : path;
45
+ } catch {
46
+ return url;
47
+ }
48
+ }
49
+ function jsonParaScript(valor) {
50
+ return JSON.stringify(valor, null, 2).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
51
+ }
52
+ function jsonLdWebApi({
53
+ nombre,
54
+ slug,
55
+ originHost,
56
+ ofertas
57
+ }) {
58
+ return {
59
+ "@context": "https://schema.org",
60
+ "@type": "WebAPI",
61
+ "@id": `https://${originHost}/#api`,
62
+ name: nombre,
63
+ // URLs del dominio del negocio, no del gateway: después del proxy
64
+ // responden acá, y es acá donde el auditor las va a buscar.
65
+ documentation: `https://${originHost}/openapi.json`,
66
+ termsOfService: `https://${originHost}/auth.md`,
67
+ provider: { "@id": `https://${originHost}/#organization` },
68
+ potentialAction: {
69
+ "@type": "ConsumeAction",
70
+ target: {
71
+ "@type": "EntryPoint",
72
+ urlTemplate: `https://${originHost}/mcp`,
73
+ actionPlatform: "MCP"
74
+ }
75
+ },
76
+ offers: ofertas.map((o) => ({
77
+ "@type": "Offer",
78
+ name: o.titulo,
79
+ price: o.priceUsd,
80
+ priceCurrency: "USD",
81
+ url: `https://${originHost}${rutaDe(o.url, slug)}`,
82
+ availability: "https://schema.org/InStock"
83
+ }))
84
+ };
85
+ }
86
+ var LINKS_HEAD = [
87
+ { rel: "service-desc", type: "application/openapi+json", href: "/openapi.json" },
88
+ { rel: "service-doc", type: "text/plain", href: "/llms.txt" },
89
+ { rel: "service-meta", type: "text/markdown", href: "/pricing.md" },
90
+ { rel: "ard", type: "application/ai-catalog+json", href: "/.well-known/ard.json" }
91
+ ];
92
+
93
+ // ../shared/src/index.ts
94
+ var TEMPO = {
95
+ mainnet: {
96
+ chainId: 4217,
97
+ rpcUrl: "https://rpc.tempo.xyz",
98
+ explorerUrl: "https://explore.tempo.xyz"
99
+ },
100
+ testnet: {
101
+ chainId: 42431,
102
+ rpcUrl: "https://rpc.moderato.tempo.xyz",
103
+ explorerUrl: "https://explore.testnet.tempo.xyz"
104
+ }
105
+ };
106
+ var TOKENS = {
107
+ pathUsd: "0x20c0000000000000000000000000000000000000",
108
+ usdc: "0x20C000000000000000000000b9537d11c60E8b50"
109
+ };
110
+ var DEFAULT_CURRENCY = TOKENS.pathUsd;
111
+ var NETWORKS = {
112
+ tempo: {
113
+ id: "tempo",
114
+ label: "Tempo",
115
+ token: TOKENS.pathUsd,
116
+ tokenSymbol: "pathUSD",
117
+ decimals: 6,
118
+ mainnet: TEMPO.mainnet,
119
+ testnet: TEMPO.testnet
120
+ },
121
+ arc: {
122
+ id: "arc",
123
+ label: "Arc",
124
+ // Interfaz ERC-20 del USDC nativo de Arc; el gas de la red se paga en ese mismo USDC.
125
+ token: "0x3600000000000000000000000000000000000000",
126
+ tokenSymbol: "USDC",
127
+ decimals: 6,
128
+ // Leído on-chain del contrato: name() = "USDC", version() = "2".
129
+ eip3009: { name: "USDC", version: "2" },
130
+ // Arc no publica direcciones de mainnet todavía (sept 2026).
131
+ mainnet: null,
132
+ testnet: {
133
+ chainId: 5042002,
134
+ rpcUrl: "https://rpc.testnet.arc.io",
135
+ explorerUrl: "https://testnet.arcscan.app"
136
+ }
137
+ },
138
+ arbitrum: {
139
+ id: "arbitrum",
140
+ label: "Arbitrum",
141
+ // USDC de Circle en Arbitrum Sepolia. En Arbitrum One vive en otra dirección,
142
+ // por eso mainnet queda en null hasta que el gateway opere allá.
143
+ token: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
144
+ tokenSymbol: "USDC",
145
+ decimals: 6,
146
+ // Leído on-chain: name() = "USD Coin", version() = "2" (distinto al USDC de Arc).
147
+ eip3009: { name: "USD Coin", version: "2" },
148
+ mainnet: null,
149
+ testnet: {
150
+ chainId: 421614,
151
+ rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
152
+ explorerUrl: "https://sepolia.arbiscan.io"
153
+ }
154
+ },
155
+ "arbitrum-usdg": {
156
+ id: "arbitrum-usdg",
157
+ label: "Arbitrum \xB7 USDG",
158
+ // Mismo contrato y misma cadena que el riel USDC: cambia el stablecoin.
159
+ // Un riel es (cadena, token), y el saldo del negocio se lleva por token.
160
+ token: "0xFFC95faa3d63Cde504a05B567C600B78C0b41892",
161
+ tokenSymbol: "USDG",
162
+ decimals: 6,
163
+ eip3009: { name: "Global Dollar", version: "1" },
164
+ mainnet: null,
165
+ testnet: {
166
+ chainId: 421614,
167
+ rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
168
+ explorerUrl: "https://sepolia.arbiscan.io"
169
+ }
170
+ },
171
+ robinhood: {
172
+ id: "robinhood",
173
+ label: "Robinhood",
174
+ // USDG de Paxos en Robinhood Chain Testnet (el "USDC" de esa testnet es un
175
+ // mock sin EIP-3009). Leído on-chain: dominio "Global Dollar", versión "1".
176
+ token: "0x7E955252E15c84f5768B83c41a71F9eba181802F",
177
+ tokenSymbol: "USDG",
178
+ decimals: 6,
179
+ eip3009: { name: "Global Dollar", version: "1" },
180
+ mainnet: null,
181
+ testnet: {
182
+ chainId: 46630,
183
+ rpcUrl: "https://rpc.testnet.chain.robinhood.com",
184
+ explorerUrl: "https://explorer.testnet.chain.robinhood.com"
185
+ }
186
+ }
187
+ };
188
+ var NETWORK_IDS = Object.keys(NETWORKS);
189
+
190
+ // src/index.ts
191
+ var GATEWAY_POR_DEFECTO = "https://peaje-gateway.up.railway.app";
192
+ function baseDe({ slug, gateway }) {
193
+ const raiz = (gateway ?? process.env.PEAJE_GATEWAY_URL ?? GATEWAY_POR_DEFECTO).replace(/\/+$/, "");
194
+ return `${raiz}/${slug}`;
195
+ }
196
+
197
+ // src/head.tsx
198
+ var import_jsx_runtime = require("react/jsx-runtime");
199
+ var TIMEOUT_MS = 2e3;
200
+ async function leerJson(url) {
201
+ try {
202
+ const res = await fetch(url, {
203
+ signal: AbortSignal.timeout(TIMEOUT_MS),
204
+ // `next` es la extensión de Next.js al RequestInit; fuera de Next se ignora.
205
+ ...{ next: { revalidate: 3600 } }
206
+ });
207
+ if (!res.ok) return null;
208
+ return await res.json();
209
+ } catch {
210
+ return null;
211
+ }
212
+ }
213
+ async function ofertasDesdeGateway(base) {
214
+ const cuerpo = await leerJson(`${base}/discovery/resources`);
215
+ return (cuerpo?.items ?? []).filter((i) => typeof i.resource === "string" && esUrlConcreta(i.resource)).map((i) => ({
216
+ titulo: i.extensions?.bazaar?.info?.title ?? i.resource,
217
+ priceUsd: Number(i.extensions?.bazaar?.info?.priceUsd ?? 0),
218
+ url: i.resource
219
+ }));
220
+ }
221
+ function esUrlConcreta(url) {
222
+ try {
223
+ return !/[*:]/.test(new URL(url).pathname);
224
+ } catch {
225
+ return false;
226
+ }
227
+ }
228
+ async function nombreDesdeGateway(base) {
229
+ const card = await leerJson(`${base}/.well-known/agent-card.json`);
230
+ return card?.name ?? null;
231
+ }
232
+ async function hostDeLaRequest() {
233
+ try {
234
+ const mod = await import("next/headers");
235
+ const h = await mod.headers();
236
+ const host = h.get("x-forwarded-host") ?? h.get("host");
237
+ return host ? host.split(",")[0].trim() : null;
238
+ } catch {
239
+ return null;
240
+ }
241
+ }
242
+ async function PeajeHead(props) {
243
+ const base = baseDe(props);
244
+ const [ofertas, nombreRemoto, hostRequest] = await Promise.all([
245
+ ofertasDesdeGateway(base),
246
+ props.name ? Promise.resolve(null) : nombreDesdeGateway(base),
247
+ props.originHost ? Promise.resolve(null) : hostDeLaRequest()
248
+ ]);
249
+ const originHost = props.originHost ?? hostRequest ?? "localhost";
250
+ const datos = jsonLdWebApi({
251
+ nombre: props.name ?? nombreRemoto ?? props.slug,
252
+ slug: props.slug,
253
+ originHost,
254
+ ofertas
255
+ });
256
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
257
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: jsonParaScript(datos) } }),
258
+ LINKS_HEAD.map((l) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("link", { rel: l.rel, type: l.type, href: l.href }, l.rel))
259
+ ] });
260
+ }
261
+ var head_default = PeajeHead;
262
+ // Annotate the CommonJS export names for ESM import in node:
263
+ 0 && (module.exports = {
264
+ PeajeHead,
265
+ ofertasDesdeGateway
266
+ });
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { OpcionesPeaje } from './index.cjs';
3
+
4
+ /** Igual al `Oferta` de shared, redeclarado para que el .d.ts publicado no apunte a un paquete privado. */
5
+ type Oferta = {
6
+ titulo: string;
7
+ priceUsd: number;
8
+ url: string;
9
+ };
10
+ type PropsPeajeHead = OpcionesPeaje & {
11
+ /** Host del negocio para las URLs del JSON-LD. Por defecto, el de la request. */
12
+ originHost?: string;
13
+ /** Nombre del negocio. Por defecto se lee del gateway, o se usa el slug. */
14
+ name?: string;
15
+ };
16
+ /**
17
+ * Ofertas desde `/discovery/resources`, el catálogo canónico: así el JSON-LD
18
+ * dice lo mismo que el 402 cobra. Los patrones (`/*`, `/:id`) no son una URL
19
+ * que un comprador pueda abrir, así que quedan fuera.
20
+ */
21
+ declare function ofertasDesdeGateway(base: string): Promise<Oferta[]>;
22
+ declare function PeajeHead(props: PropsPeajeHead): Promise<react.JSX.Element>;
23
+
24
+ export { type Oferta, PeajeHead, type PropsPeajeHead, PeajeHead as default, ofertasDesdeGateway };
package/dist/head.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { OpcionesPeaje } from './index.js';
3
+
4
+ /** Igual al `Oferta` de shared, redeclarado para que el .d.ts publicado no apunte a un paquete privado. */
5
+ type Oferta = {
6
+ titulo: string;
7
+ priceUsd: number;
8
+ url: string;
9
+ };
10
+ type PropsPeajeHead = OpcionesPeaje & {
11
+ /** Host del negocio para las URLs del JSON-LD. Por defecto, el de la request. */
12
+ originHost?: string;
13
+ /** Nombre del negocio. Por defecto se lee del gateway, o se usa el slug. */
14
+ name?: string;
15
+ };
16
+ /**
17
+ * Ofertas desde `/discovery/resources`, el catálogo canónico: así el JSON-LD
18
+ * dice lo mismo que el 402 cobra. Los patrones (`/*`, `/:id`) no son una URL
19
+ * que un comprador pueda abrir, así que quedan fuera.
20
+ */
21
+ declare function ofertasDesdeGateway(base: string): Promise<Oferta[]>;
22
+ declare function PeajeHead(props: PropsPeajeHead): Promise<react.JSX.Element>;
23
+
24
+ export { type Oferta, PeajeHead, type PropsPeajeHead, PeajeHead as default, ofertasDesdeGateway };
package/dist/head.js ADDED
@@ -0,0 +1,77 @@
1
+ import {
2
+ LINKS_HEAD,
3
+ baseDe,
4
+ jsonLdWebApi,
5
+ jsonParaScript
6
+ } from "./chunk-7KJLR3FN.js";
7
+
8
+ // src/head.tsx
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ var TIMEOUT_MS = 2e3;
11
+ async function leerJson(url) {
12
+ try {
13
+ const res = await fetch(url, {
14
+ signal: AbortSignal.timeout(TIMEOUT_MS),
15
+ // `next` es la extensión de Next.js al RequestInit; fuera de Next se ignora.
16
+ ...{ next: { revalidate: 3600 } }
17
+ });
18
+ if (!res.ok) return null;
19
+ return await res.json();
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
24
+ async function ofertasDesdeGateway(base) {
25
+ const cuerpo = await leerJson(`${base}/discovery/resources`);
26
+ return (cuerpo?.items ?? []).filter((i) => typeof i.resource === "string" && esUrlConcreta(i.resource)).map((i) => ({
27
+ titulo: i.extensions?.bazaar?.info?.title ?? i.resource,
28
+ priceUsd: Number(i.extensions?.bazaar?.info?.priceUsd ?? 0),
29
+ url: i.resource
30
+ }));
31
+ }
32
+ function esUrlConcreta(url) {
33
+ try {
34
+ return !/[*:]/.test(new URL(url).pathname);
35
+ } catch {
36
+ return false;
37
+ }
38
+ }
39
+ async function nombreDesdeGateway(base) {
40
+ const card = await leerJson(`${base}/.well-known/agent-card.json`);
41
+ return card?.name ?? null;
42
+ }
43
+ async function hostDeLaRequest() {
44
+ try {
45
+ const mod = await import("next/headers");
46
+ const h = await mod.headers();
47
+ const host = h.get("x-forwarded-host") ?? h.get("host");
48
+ return host ? host.split(",")[0].trim() : null;
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+ async function PeajeHead(props) {
54
+ const base = baseDe(props);
55
+ const [ofertas, nombreRemoto, hostRequest] = await Promise.all([
56
+ ofertasDesdeGateway(base),
57
+ props.name ? Promise.resolve(null) : nombreDesdeGateway(base),
58
+ props.originHost ? Promise.resolve(null) : hostDeLaRequest()
59
+ ]);
60
+ const originHost = props.originHost ?? hostRequest ?? "localhost";
61
+ const datos = jsonLdWebApi({
62
+ nombre: props.name ?? nombreRemoto ?? props.slug,
63
+ slug: props.slug,
64
+ originHost,
65
+ ofertas
66
+ });
67
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
68
+ /* @__PURE__ */ jsx("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: jsonParaScript(datos) } }),
69
+ LINKS_HEAD.map((l) => /* @__PURE__ */ jsx("link", { rel: l.rel, type: l.type, href: l.href }, l.rel))
70
+ ] });
71
+ }
72
+ var head_default = PeajeHead;
73
+ export {
74
+ PeajeHead,
75
+ head_default as default,
76
+ ofertasDesdeGateway
77
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ GATEWAY_POR_DEFECTO: () => GATEWAY_POR_DEFECTO,
24
+ baseDe: () => baseDe,
25
+ default: () => src_default,
26
+ fusionarRewrites: () => fusionarRewrites,
27
+ withPeaje: () => withPeaje
28
+ });
29
+ module.exports = __toCommonJS(src_exports);
30
+
31
+ // ../shared/src/kit/rutas.ts
32
+ var RUTAS_PROXY = [
33
+ { path: "/llms.txt", nota: "gu\xEDa para agentes (fusionada con la tuya)" },
34
+ { path: "/pricing.md", nota: "precios por endpoint" },
35
+ { path: "/auth.md", nota: 'c\xF3mo pagar (el "auth" ac\xE1 es el pago)' },
36
+ { path: "/agents.md", nota: "qu\xE9 es y cu\xE1ndo usarte" },
37
+ { path: "/openapi.json", nota: "discovery con precios" },
38
+ { path: "/mcp", nota: "MCP server con tools pagas, en TU dominio" },
39
+ { path: "/.well-known/mcp", nota: "el MCP tambi\xE9n ac\xE1: es donde lo buscan los auditores" },
40
+ { path: "/.well-known/ard.json", nota: "cat\xE1logo ARD (path can\xF3nico)" },
41
+ { path: "/.well-known/ai-catalog.json", nota: "cat\xE1logo ARD (alias legacy)" },
42
+ { path: "/.well-known/api-catalog", nota: "linkset RFC 9727" },
43
+ { path: "/.well-known/agent-card.json", nota: "agent card A2A" },
44
+ { path: "/.well-known/mcp/server-card.json", nota: "server card MCP" },
45
+ { path: "/discovery/resources", nota: "lista x402 Bazaar: lo que cobra 402 de verdad" },
46
+ { path: "/.well-known/ucp", nota: "perfil UCP: qu\xE9 sabe hacer tu negocio" },
47
+ { path: "/checkout_sessions", nota: "checkout ACP (el de OpenAI)" },
48
+ { path: "/agentic_commerce/delegate_payment", nota: "delegate payment ACP" },
49
+ { path: "/developers", nota: "portal de desarrolladores, renderizado con tus precios" },
50
+ { path: "/.well-known/peaje-indexnow.txt", nota: "clave IndexNow: avisa a Bing y Copilot cuando cambian precios" },
51
+ // Los auditores prueban /docs y /developers; el gateway redirige uno al otro.
52
+ { path: "/docs", nota: "alias del portal: los auditores prueban ambos" }
53
+ ];
54
+ var RUTAS_DINAMICAS = [
55
+ { path: "/r/:slug", prefijo: "/r/", nota: "links con precio: el 402 en tu dominio" },
56
+ { path: "/checkout_sessions/:id", prefijo: "/checkout_sessions/", nota: "leer una sesi\xF3n de checkout ACP" }
57
+ ];
58
+ var PEAJE_FETCH_HEADER = "x-peaje-fetch";
59
+ function reglasNext(base) {
60
+ return [
61
+ ...RUTAS_PROXY.map((r) => ({
62
+ source: r.path,
63
+ destination: `${base}${r.path}`,
64
+ ...r.path === "/llms.txt" ? { missing: [{ type: "header", key: PEAJE_FETCH_HEADER }] } : {}
65
+ })),
66
+ ...RUTAS_DINAMICAS.map((r) => ({ source: r.path, destination: `${base}${r.path}` }))
67
+ ];
68
+ }
69
+
70
+ // ../shared/src/index.ts
71
+ var TEMPO = {
72
+ mainnet: {
73
+ chainId: 4217,
74
+ rpcUrl: "https://rpc.tempo.xyz",
75
+ explorerUrl: "https://explore.tempo.xyz"
76
+ },
77
+ testnet: {
78
+ chainId: 42431,
79
+ rpcUrl: "https://rpc.moderato.tempo.xyz",
80
+ explorerUrl: "https://explore.testnet.tempo.xyz"
81
+ }
82
+ };
83
+ var TOKENS = {
84
+ pathUsd: "0x20c0000000000000000000000000000000000000",
85
+ usdc: "0x20C000000000000000000000b9537d11c60E8b50"
86
+ };
87
+ var DEFAULT_CURRENCY = TOKENS.pathUsd;
88
+ var NETWORKS = {
89
+ tempo: {
90
+ id: "tempo",
91
+ label: "Tempo",
92
+ token: TOKENS.pathUsd,
93
+ tokenSymbol: "pathUSD",
94
+ decimals: 6,
95
+ mainnet: TEMPO.mainnet,
96
+ testnet: TEMPO.testnet
97
+ },
98
+ arc: {
99
+ id: "arc",
100
+ label: "Arc",
101
+ // Interfaz ERC-20 del USDC nativo de Arc; el gas de la red se paga en ese mismo USDC.
102
+ token: "0x3600000000000000000000000000000000000000",
103
+ tokenSymbol: "USDC",
104
+ decimals: 6,
105
+ // Leído on-chain del contrato: name() = "USDC", version() = "2".
106
+ eip3009: { name: "USDC", version: "2" },
107
+ // Arc no publica direcciones de mainnet todavía (sept 2026).
108
+ mainnet: null,
109
+ testnet: {
110
+ chainId: 5042002,
111
+ rpcUrl: "https://rpc.testnet.arc.io",
112
+ explorerUrl: "https://testnet.arcscan.app"
113
+ }
114
+ },
115
+ arbitrum: {
116
+ id: "arbitrum",
117
+ label: "Arbitrum",
118
+ // USDC de Circle en Arbitrum Sepolia. En Arbitrum One vive en otra dirección,
119
+ // por eso mainnet queda en null hasta que el gateway opere allá.
120
+ token: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
121
+ tokenSymbol: "USDC",
122
+ decimals: 6,
123
+ // Leído on-chain: name() = "USD Coin", version() = "2" (distinto al USDC de Arc).
124
+ eip3009: { name: "USD Coin", version: "2" },
125
+ mainnet: null,
126
+ testnet: {
127
+ chainId: 421614,
128
+ rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
129
+ explorerUrl: "https://sepolia.arbiscan.io"
130
+ }
131
+ },
132
+ "arbitrum-usdg": {
133
+ id: "arbitrum-usdg",
134
+ label: "Arbitrum \xB7 USDG",
135
+ // Mismo contrato y misma cadena que el riel USDC: cambia el stablecoin.
136
+ // Un riel es (cadena, token), y el saldo del negocio se lleva por token.
137
+ token: "0xFFC95faa3d63Cde504a05B567C600B78C0b41892",
138
+ tokenSymbol: "USDG",
139
+ decimals: 6,
140
+ eip3009: { name: "Global Dollar", version: "1" },
141
+ mainnet: null,
142
+ testnet: {
143
+ chainId: 421614,
144
+ rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc",
145
+ explorerUrl: "https://sepolia.arbiscan.io"
146
+ }
147
+ },
148
+ robinhood: {
149
+ id: "robinhood",
150
+ label: "Robinhood",
151
+ // USDG de Paxos en Robinhood Chain Testnet (el "USDC" de esa testnet es un
152
+ // mock sin EIP-3009). Leído on-chain: dominio "Global Dollar", versión "1".
153
+ token: "0x7E955252E15c84f5768B83c41a71F9eba181802F",
154
+ tokenSymbol: "USDG",
155
+ decimals: 6,
156
+ eip3009: { name: "Global Dollar", version: "1" },
157
+ mainnet: null,
158
+ testnet: {
159
+ chainId: 46630,
160
+ rpcUrl: "https://rpc.testnet.chain.robinhood.com",
161
+ explorerUrl: "https://explorer.testnet.chain.robinhood.com"
162
+ }
163
+ }
164
+ };
165
+ var NETWORK_IDS = Object.keys(NETWORKS);
166
+
167
+ // src/index.ts
168
+ var GATEWAY_POR_DEFECTO = "https://peaje-gateway.up.railway.app";
169
+ function baseDe({ slug, gateway }) {
170
+ const raiz = (gateway ?? process.env.PEAJE_GATEWAY_URL ?? GATEWAY_POR_DEFECTO).replace(/\/+$/, "");
171
+ return `${raiz}/${slug}`;
172
+ }
173
+ function fusionarRewrites(previo, reglas) {
174
+ const objeto = Array.isArray(previo) ? { afterFiles: previo } : { ...previo ?? {} };
175
+ const antes = objeto.beforeFiles ?? [];
176
+ const destinos = new Set(antes.map((r) => r.destination));
177
+ const nuevas = reglas.filter((r) => !destinos.has(r.destination));
178
+ return { ...objeto, beforeFiles: [...nuevas, ...antes] };
179
+ }
180
+ function envolverConfig(config, reglas) {
181
+ const original = config.rewrites;
182
+ return {
183
+ ...config,
184
+ async rewrites() {
185
+ const previo = original ? await original.call(config) : void 0;
186
+ return fusionarRewrites(previo, reglas);
187
+ }
188
+ };
189
+ }
190
+ function withPeaje(nextConfig, opciones) {
191
+ if (!opciones?.slug) throw new Error("withPeaje: `slug` is required (the business slug from your Peaje dashboard).");
192
+ const reglas = reglasNext(baseDe(opciones));
193
+ if (typeof nextConfig === "function") {
194
+ return async (phase, contexto) => envolverConfig(await nextConfig(phase, contexto), reglas);
195
+ }
196
+ return envolverConfig(nextConfig ?? {}, reglas);
197
+ }
198
+ var src_default = withPeaje;
199
+ // Annotate the CommonJS export names for ESM import in node:
200
+ 0 && (module.exports = {
201
+ GATEWAY_POR_DEFECTO,
202
+ baseDe,
203
+ fusionarRewrites,
204
+ withPeaje
205
+ });
@@ -0,0 +1,48 @@
1
+ declare const GATEWAY_POR_DEFECTO = "https://peaje-gateway.up.railway.app";
2
+ type OpcionesPeaje = {
3
+ /** El slug del negocio en Peaje (el mismo del dashboard). */
4
+ slug: string;
5
+ /** URL pública del gateway. Por defecto la de producción, o `PEAJE_GATEWAY_URL`. */
6
+ gateway?: string;
7
+ };
8
+ /**
9
+ * Tipos mínimos y locales en vez de importar `NextConfig`: así el paquete
10
+ * compila y se usa sin `next` instalado en tiempo de tipos (peer opcional) y
11
+ * acepta cualquier versión desde 14.
12
+ */
13
+ type ReglaRewrite = {
14
+ source: string;
15
+ destination: string;
16
+ basePath?: false;
17
+ locale?: false;
18
+ has?: unknown[];
19
+ missing?: unknown[];
20
+ };
21
+ type RewritesObjeto = {
22
+ beforeFiles?: ReglaRewrite[];
23
+ afterFiles?: ReglaRewrite[];
24
+ fallback?: ReglaRewrite[];
25
+ };
26
+ type ResultadoRewrites = ReglaRewrite[] | RewritesObjeto;
27
+ type ConfigConRewrites = {
28
+ rewrites?: () => ResultadoRewrites | Promise<ResultadoRewrites>;
29
+ [clave: string]: unknown;
30
+ };
31
+ type ConfigOFuncion<C extends ConfigConRewrites = ConfigConRewrites> = C | ((phase: string, contexto: {
32
+ defaultConfig: unknown;
33
+ }) => C | Promise<C>);
34
+ /** Base `${gateway}/${slug}` sin barra final, con el env como override. */
35
+ declare function baseDe({ slug, gateway }: OpcionesPeaje): string;
36
+ /**
37
+ * Fusiona las reglas de Peaje con lo que devolvía el `rewrites()` original.
38
+ * Un array pasa a `afterFiles`: es lo que Next hace internamente con el array,
39
+ * y así las nuestras siguen ganando en `beforeFiles`.
40
+ */
41
+ declare function fusionarRewrites(previo: ResultadoRewrites | undefined, reglas: ReglaRewrite[]): RewritesObjeto;
42
+ /**
43
+ * Acepta la config como objeto o como función `(phase, { defaultConfig })`,
44
+ * y un `rewrites()` sync o async que devuelva array u objeto.
45
+ */
46
+ declare function withPeaje<C extends ConfigConRewrites>(nextConfig: ConfigOFuncion<C>, opciones: OpcionesPeaje): ConfigOFuncion<C>;
47
+
48
+ export { type ConfigConRewrites, type ConfigOFuncion, GATEWAY_POR_DEFECTO, type OpcionesPeaje, type ReglaRewrite, type ResultadoRewrites, type RewritesObjeto, baseDe, withPeaje as default, fusionarRewrites, withPeaje };
@@ -0,0 +1,48 @@
1
+ declare const GATEWAY_POR_DEFECTO = "https://peaje-gateway.up.railway.app";
2
+ type OpcionesPeaje = {
3
+ /** El slug del negocio en Peaje (el mismo del dashboard). */
4
+ slug: string;
5
+ /** URL pública del gateway. Por defecto la de producción, o `PEAJE_GATEWAY_URL`. */
6
+ gateway?: string;
7
+ };
8
+ /**
9
+ * Tipos mínimos y locales en vez de importar `NextConfig`: así el paquete
10
+ * compila y se usa sin `next` instalado en tiempo de tipos (peer opcional) y
11
+ * acepta cualquier versión desde 14.
12
+ */
13
+ type ReglaRewrite = {
14
+ source: string;
15
+ destination: string;
16
+ basePath?: false;
17
+ locale?: false;
18
+ has?: unknown[];
19
+ missing?: unknown[];
20
+ };
21
+ type RewritesObjeto = {
22
+ beforeFiles?: ReglaRewrite[];
23
+ afterFiles?: ReglaRewrite[];
24
+ fallback?: ReglaRewrite[];
25
+ };
26
+ type ResultadoRewrites = ReglaRewrite[] | RewritesObjeto;
27
+ type ConfigConRewrites = {
28
+ rewrites?: () => ResultadoRewrites | Promise<ResultadoRewrites>;
29
+ [clave: string]: unknown;
30
+ };
31
+ type ConfigOFuncion<C extends ConfigConRewrites = ConfigConRewrites> = C | ((phase: string, contexto: {
32
+ defaultConfig: unknown;
33
+ }) => C | Promise<C>);
34
+ /** Base `${gateway}/${slug}` sin barra final, con el env como override. */
35
+ declare function baseDe({ slug, gateway }: OpcionesPeaje): string;
36
+ /**
37
+ * Fusiona las reglas de Peaje con lo que devolvía el `rewrites()` original.
38
+ * Un array pasa a `afterFiles`: es lo que Next hace internamente con el array,
39
+ * y así las nuestras siguen ganando en `beforeFiles`.
40
+ */
41
+ declare function fusionarRewrites(previo: ResultadoRewrites | undefined, reglas: ReglaRewrite[]): RewritesObjeto;
42
+ /**
43
+ * Acepta la config como objeto o como función `(phase, { defaultConfig })`,
44
+ * y un `rewrites()` sync o async que devuelva array u objeto.
45
+ */
46
+ declare function withPeaje<C extends ConfigConRewrites>(nextConfig: ConfigOFuncion<C>, opciones: OpcionesPeaje): ConfigOFuncion<C>;
47
+
48
+ export { type ConfigConRewrites, type ConfigOFuncion, GATEWAY_POR_DEFECTO, type OpcionesPeaje, type ReglaRewrite, type ResultadoRewrites, type RewritesObjeto, baseDe, withPeaje as default, fusionarRewrites, withPeaje };
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import {
2
+ GATEWAY_POR_DEFECTO,
3
+ baseDe,
4
+ fusionarRewrites,
5
+ src_default,
6
+ withPeaje
7
+ } from "./chunk-7KJLR3FN.js";
8
+ export {
9
+ GATEWAY_POR_DEFECTO,
10
+ baseDe,
11
+ src_default as default,
12
+ fusionarRewrites,
13
+ withPeaje
14
+ };
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@peaje/next",
3
+ "version": "0.1.0",
4
+ "description": "Peaje for Next.js: proxy rewrites and the head block that make your site speak MPP, MCP and OpenAPI on your own domain.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "main": "./dist/index.cjs",
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "import": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "require": {
21
+ "types": "./dist/index.d.cts",
22
+ "default": "./dist/index.cjs"
23
+ }
24
+ },
25
+ "./head": {
26
+ "import": {
27
+ "types": "./dist/head.d.ts",
28
+ "default": "./dist/head.js"
29
+ },
30
+ "require": {
31
+ "types": "./dist/head.d.cts",
32
+ "default": "./dist/head.cjs"
33
+ }
34
+ }
35
+ },
36
+ "scripts": {
37
+ "build": "tsup",
38
+ "typecheck": "tsc --noEmit",
39
+ "test": "tsx --test test/*.test.ts"
40
+ },
41
+ "keywords": [
42
+ "peaje",
43
+ "next",
44
+ "mpp",
45
+ "x402",
46
+ "mcp",
47
+ "agents"
48
+ ],
49
+ "peerDependencies": {
50
+ "next": ">=14",
51
+ "react": ">=18"
52
+ },
53
+ "peerDependenciesMeta": {
54
+ "next": {
55
+ "optional": true
56
+ },
57
+ "react": {
58
+ "optional": true
59
+ }
60
+ },
61
+ "devDependencies": {
62
+ "@peaje/shared": "workspace:*",
63
+ "@types/node": "^20",
64
+ "@types/react": "^19",
65
+ "next": "16.3.1",
66
+ "react": "19.2.8",
67
+ "tsup": "^8.5.1",
68
+ "tsx": "^4.23.12",
69
+ "typescript": "^5.9.0"
70
+ }
71
+ }