@agentcash/router 1.0.0 → 1.0.1
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/index.cjs +28 -15
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +28 -15
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -90,33 +90,46 @@ module.exports = __toCommonJS(index_exports);
|
|
|
90
90
|
// src/registry.ts
|
|
91
91
|
var RouteRegistry = class {
|
|
92
92
|
routes = /* @__PURE__ */ new Map();
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
93
|
+
// Internal map key includes the HTTP method so that POST and DELETE on the
|
|
94
|
+
// same path coexist. Within the same path+method, last-write-wins is still
|
|
95
|
+
// intentional — Next.js module loading order is non-deterministic during
|
|
96
|
+
// build and discovery stubs may register the same route in either order.
|
|
96
97
|
// Prior art: ElysiaJS uses the same pattern (silent overwrite in router.history).
|
|
98
|
+
mapKey(entry) {
|
|
99
|
+
return `${entry.key}:${entry.method}`;
|
|
100
|
+
}
|
|
97
101
|
register(entry) {
|
|
98
|
-
|
|
102
|
+
const k = this.mapKey(entry);
|
|
103
|
+
if (this.routes.has(k) && typeof process !== "undefined" && process.env?.["NODE_ENV"] !== "production") {
|
|
99
104
|
console.warn(
|
|
100
|
-
`[agentcash/router] route '${entry.key}' registered twice \u2014 overwriting (this is expected for discovery stubs during next build)`
|
|
105
|
+
`[agentcash/router] route '${entry.key}' (${entry.method}) registered twice \u2014 overwriting (this is expected for discovery stubs during next build)`
|
|
101
106
|
);
|
|
102
107
|
}
|
|
103
|
-
this.routes.set(
|
|
108
|
+
this.routes.set(k, entry);
|
|
104
109
|
}
|
|
110
|
+
// Accepts either a compound key ("site/domain:DELETE") or a path-only key
|
|
111
|
+
// ("site/domain") — path-only returns the first registered method for that path.
|
|
105
112
|
get(key) {
|
|
106
|
-
|
|
113
|
+
const direct = this.routes.get(key);
|
|
114
|
+
if (direct) return direct;
|
|
115
|
+
for (const entry of this.routes.values()) {
|
|
116
|
+
if (entry.key === key) return entry;
|
|
117
|
+
}
|
|
118
|
+
return void 0;
|
|
107
119
|
}
|
|
108
120
|
entries() {
|
|
109
121
|
return this.routes.entries();
|
|
110
122
|
}
|
|
111
123
|
has(key) {
|
|
112
|
-
return this.
|
|
124
|
+
return this.get(key) !== void 0;
|
|
113
125
|
}
|
|
114
126
|
get size() {
|
|
115
127
|
return this.routes.size;
|
|
116
128
|
}
|
|
117
129
|
validate(expectedKeys) {
|
|
118
130
|
if (!expectedKeys) return;
|
|
119
|
-
const
|
|
131
|
+
const registeredPathKeys = new Set([...this.routes.values()].map((e) => e.key));
|
|
132
|
+
const missing = expectedKeys.filter((k) => !registeredPathKeys.has(k));
|
|
120
133
|
if (missing.length > 0) {
|
|
121
134
|
throw new Error(
|
|
122
135
|
`route${missing.length > 1 ? "s" : ""} ${missing.map((k) => `'${k}'`).join(", ")} in prices map but not registered \u2014 add to barrel imports`
|
|
@@ -1475,8 +1488,8 @@ function createWellKnownHandler(registry, baseUrl, pricesKeys, discovery) {
|
|
|
1475
1488
|
const x402Set = /* @__PURE__ */ new Set();
|
|
1476
1489
|
const mppSet = /* @__PURE__ */ new Set();
|
|
1477
1490
|
const methodHints = discovery.methodHints ?? "non-default";
|
|
1478
|
-
for (const [
|
|
1479
|
-
const url = `${normalizedBase}/api/${entry.path ?? key}`;
|
|
1491
|
+
for (const [, entry] of registry.entries()) {
|
|
1492
|
+
const url = `${normalizedBase}/api/${entry.path ?? entry.key}`;
|
|
1480
1493
|
const resource = toDiscoveryResource(entry.method, url, methodHints);
|
|
1481
1494
|
if (entry.authMode !== "unprotected") x402Set.add(resource);
|
|
1482
1495
|
if (entry.protocols.includes("mpp")) mppSet.add(resource);
|
|
@@ -1532,12 +1545,12 @@ function createOpenAPIHandler(registry, baseUrl, pricesKeys, discovery) {
|
|
|
1532
1545
|
const tagSet = /* @__PURE__ */ new Set();
|
|
1533
1546
|
let requiresSiwxScheme = false;
|
|
1534
1547
|
let requiresApiKeyScheme = false;
|
|
1535
|
-
for (const [
|
|
1536
|
-
const apiPath = `/api/${entry.path ?? key}`;
|
|
1548
|
+
for (const [, entry] of registry.entries()) {
|
|
1549
|
+
const apiPath = `/api/${entry.path ?? entry.key}`;
|
|
1537
1550
|
const method = entry.method.toLowerCase();
|
|
1538
|
-
const tag = deriveTag(key);
|
|
1551
|
+
const tag = deriveTag(entry.key);
|
|
1539
1552
|
tagSet.add(tag);
|
|
1540
|
-
const built = buildOperation(key, entry, tag);
|
|
1553
|
+
const built = buildOperation(entry.key, entry, tag);
|
|
1541
1554
|
if (built.requiresSiwxScheme) requiresSiwxScheme = true;
|
|
1542
1555
|
if (built.requiresApiKeyScheme) requiresApiKeyScheme = true;
|
|
1543
1556
|
paths[apiPath] = { ...paths[apiPath], [method]: built.operation };
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -51,33 +51,46 @@ var init_server = __esm({
|
|
|
51
51
|
// src/registry.ts
|
|
52
52
|
var RouteRegistry = class {
|
|
53
53
|
routes = /* @__PURE__ */ new Map();
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
54
|
+
// Internal map key includes the HTTP method so that POST and DELETE on the
|
|
55
|
+
// same path coexist. Within the same path+method, last-write-wins is still
|
|
56
|
+
// intentional — Next.js module loading order is non-deterministic during
|
|
57
|
+
// build and discovery stubs may register the same route in either order.
|
|
57
58
|
// Prior art: ElysiaJS uses the same pattern (silent overwrite in router.history).
|
|
59
|
+
mapKey(entry) {
|
|
60
|
+
return `${entry.key}:${entry.method}`;
|
|
61
|
+
}
|
|
58
62
|
register(entry) {
|
|
59
|
-
|
|
63
|
+
const k = this.mapKey(entry);
|
|
64
|
+
if (this.routes.has(k) && typeof process !== "undefined" && process.env?.["NODE_ENV"] !== "production") {
|
|
60
65
|
console.warn(
|
|
61
|
-
`[agentcash/router] route '${entry.key}' registered twice \u2014 overwriting (this is expected for discovery stubs during next build)`
|
|
66
|
+
`[agentcash/router] route '${entry.key}' (${entry.method}) registered twice \u2014 overwriting (this is expected for discovery stubs during next build)`
|
|
62
67
|
);
|
|
63
68
|
}
|
|
64
|
-
this.routes.set(
|
|
69
|
+
this.routes.set(k, entry);
|
|
65
70
|
}
|
|
71
|
+
// Accepts either a compound key ("site/domain:DELETE") or a path-only key
|
|
72
|
+
// ("site/domain") — path-only returns the first registered method for that path.
|
|
66
73
|
get(key) {
|
|
67
|
-
|
|
74
|
+
const direct = this.routes.get(key);
|
|
75
|
+
if (direct) return direct;
|
|
76
|
+
for (const entry of this.routes.values()) {
|
|
77
|
+
if (entry.key === key) return entry;
|
|
78
|
+
}
|
|
79
|
+
return void 0;
|
|
68
80
|
}
|
|
69
81
|
entries() {
|
|
70
82
|
return this.routes.entries();
|
|
71
83
|
}
|
|
72
84
|
has(key) {
|
|
73
|
-
return this.
|
|
85
|
+
return this.get(key) !== void 0;
|
|
74
86
|
}
|
|
75
87
|
get size() {
|
|
76
88
|
return this.routes.size;
|
|
77
89
|
}
|
|
78
90
|
validate(expectedKeys) {
|
|
79
91
|
if (!expectedKeys) return;
|
|
80
|
-
const
|
|
92
|
+
const registeredPathKeys = new Set([...this.routes.values()].map((e) => e.key));
|
|
93
|
+
const missing = expectedKeys.filter((k) => !registeredPathKeys.has(k));
|
|
81
94
|
if (missing.length > 0) {
|
|
82
95
|
throw new Error(
|
|
83
96
|
`route${missing.length > 1 ? "s" : ""} ${missing.map((k) => `'${k}'`).join(", ")} in prices map but not registered \u2014 add to barrel imports`
|
|
@@ -1436,8 +1449,8 @@ function createWellKnownHandler(registry, baseUrl, pricesKeys, discovery) {
|
|
|
1436
1449
|
const x402Set = /* @__PURE__ */ new Set();
|
|
1437
1450
|
const mppSet = /* @__PURE__ */ new Set();
|
|
1438
1451
|
const methodHints = discovery.methodHints ?? "non-default";
|
|
1439
|
-
for (const [
|
|
1440
|
-
const url = `${normalizedBase}/api/${entry.path ?? key}`;
|
|
1452
|
+
for (const [, entry] of registry.entries()) {
|
|
1453
|
+
const url = `${normalizedBase}/api/${entry.path ?? entry.key}`;
|
|
1441
1454
|
const resource = toDiscoveryResource(entry.method, url, methodHints);
|
|
1442
1455
|
if (entry.authMode !== "unprotected") x402Set.add(resource);
|
|
1443
1456
|
if (entry.protocols.includes("mpp")) mppSet.add(resource);
|
|
@@ -1493,12 +1506,12 @@ function createOpenAPIHandler(registry, baseUrl, pricesKeys, discovery) {
|
|
|
1493
1506
|
const tagSet = /* @__PURE__ */ new Set();
|
|
1494
1507
|
let requiresSiwxScheme = false;
|
|
1495
1508
|
let requiresApiKeyScheme = false;
|
|
1496
|
-
for (const [
|
|
1497
|
-
const apiPath = `/api/${entry.path ?? key}`;
|
|
1509
|
+
for (const [, entry] of registry.entries()) {
|
|
1510
|
+
const apiPath = `/api/${entry.path ?? entry.key}`;
|
|
1498
1511
|
const method = entry.method.toLowerCase();
|
|
1499
|
-
const tag = deriveTag(key);
|
|
1512
|
+
const tag = deriveTag(entry.key);
|
|
1500
1513
|
tagSet.add(tag);
|
|
1501
|
-
const built = buildOperation(key, entry, tag);
|
|
1514
|
+
const built = buildOperation(entry.key, entry, tag);
|
|
1502
1515
|
if (built.requiresSiwxScheme) requiresSiwxScheme = true;
|
|
1503
1516
|
if (built.requiresApiKeyScheme) requiresApiKeyScheme = true;
|
|
1504
1517
|
paths[apiPath] = { ...paths[apiPath], [method]: built.operation };
|