@farthershore/backend 0.8.0 → 0.8.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/README.md +1 -1
- package/dist/index.js +5 -4
- package/dist/reflect/index.js +94 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Runtime metering and gateway-verification SDK for builder upstreams. Install one
|
|
|
4
4
|
package, set one token (`FS_RUNTIME_TOKEN`), and Farther Shore handles signed
|
|
5
5
|
gateway-to-upstream request verification plus response-bound usage reporting.
|
|
6
6
|
|
|
7
|
-
> **Status: `0.8.
|
|
7
|
+
> **Status: `0.8.1` (lockstep SDK family).** Published at the SAME version as
|
|
8
8
|
> `@farthershore/farthershore-js` and `@farthershore/product` — pin the three
|
|
9
9
|
> together. Pre-1.0: minor bumps may break.
|
|
10
10
|
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var __export = (target, all) => {
|
|
|
12
12
|
// src/reflect/route-canon.ts
|
|
13
13
|
import { createHash } from "node:crypto";
|
|
14
14
|
function normalizeSegment(seg) {
|
|
15
|
-
if (seg === "**") return "{
|
|
15
|
+
if (seg === "**") return "{__fs_rest}";
|
|
16
16
|
if (seg === "*") return "{splat}";
|
|
17
17
|
if (seg.startsWith(":")) return `{${seg.slice(1)}}`;
|
|
18
18
|
if (seg.startsWith("[") && seg.endsWith("]")) return `{${seg.slice(1, -1)}}`;
|
|
@@ -62,6 +62,7 @@ function methodsOf(route) {
|
|
|
62
62
|
for (const s of route.stack ?? []) {
|
|
63
63
|
if (typeof s.method === "string") out.add(s.method.toUpperCase());
|
|
64
64
|
}
|
|
65
|
+
if (out.has("GET")) out.delete("HEAD");
|
|
65
66
|
return [...out].filter((m) => VALID_METHODS.has(m));
|
|
66
67
|
}
|
|
67
68
|
function rootStack(app) {
|
|
@@ -105,7 +106,6 @@ function reflectRoutesDetailed(app, _opts) {
|
|
|
105
106
|
const seen = /* @__PURE__ */ new Set();
|
|
106
107
|
const routes = [];
|
|
107
108
|
for (const r of raw) {
|
|
108
|
-
if (r.method === "HEAD") continue;
|
|
109
109
|
const key2 = `${r.method} ${r.path}`;
|
|
110
110
|
if (seen.has(key2)) continue;
|
|
111
111
|
seen.add(key2);
|
|
@@ -123,6 +123,7 @@ var init_reflect = __esm({
|
|
|
123
123
|
init_route_canon();
|
|
124
124
|
VALID_METHODS = /* @__PURE__ */ new Set([
|
|
125
125
|
"GET",
|
|
126
|
+
"HEAD",
|
|
126
127
|
"POST",
|
|
127
128
|
"PUT",
|
|
128
129
|
"PATCH",
|
|
@@ -1337,8 +1338,8 @@ function headerGetter(headers) {
|
|
|
1337
1338
|
|
|
1338
1339
|
// src/core/runtime.ts
|
|
1339
1340
|
var DEFAULT_CORE_URL = "https://core.farthershore.com";
|
|
1340
|
-
var SDK_VERSION = "0.8.
|
|
1341
|
-
var CONTRACTS_FP = "
|
|
1341
|
+
var SDK_VERSION = "0.8.1".length > 0 ? "0.8.1" : "0.0.0-dev";
|
|
1342
|
+
var CONTRACTS_FP = "3c1f8e3d44799bd4".length > 0 ? "3c1f8e3d44799bd4" : "0000000000000000";
|
|
1342
1343
|
var FartherShore = class {
|
|
1343
1344
|
bootstrapClient;
|
|
1344
1345
|
fetchImpl;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from "node:module";const require=__createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/reflect/route-canon.ts
|
|
4
|
+
function normalizeSegment(seg) {
|
|
5
|
+
if (seg === "**") return "{__fs_rest}";
|
|
6
|
+
if (seg === "*") return "{splat}";
|
|
7
|
+
if (seg.startsWith(":")) return `{${seg.slice(1)}}`;
|
|
8
|
+
if (seg.startsWith("[") && seg.endsWith("]")) return `{${seg.slice(1, -1)}}`;
|
|
9
|
+
return seg;
|
|
10
|
+
}
|
|
11
|
+
function normalizePath(path) {
|
|
12
|
+
if (path === "/" || path === "") return "/";
|
|
13
|
+
const lead = path.startsWith("/");
|
|
14
|
+
const out = path.split("/").filter((s) => s.length > 0).map(normalizeSegment).join("/");
|
|
15
|
+
return lead ? `/${out}` : out;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/reflect/index.ts
|
|
19
|
+
var VALID_METHODS = /* @__PURE__ */ new Set([
|
|
20
|
+
"GET",
|
|
21
|
+
"HEAD",
|
|
22
|
+
"POST",
|
|
23
|
+
"PUT",
|
|
24
|
+
"PATCH",
|
|
25
|
+
"DELETE",
|
|
26
|
+
"OPTIONS"
|
|
27
|
+
]);
|
|
28
|
+
function methodsOf(route) {
|
|
29
|
+
const out = /* @__PURE__ */ new Set();
|
|
30
|
+
if (route.methods) {
|
|
31
|
+
for (const [m, on] of Object.entries(route.methods))
|
|
32
|
+
if (on) out.add(m.toUpperCase());
|
|
33
|
+
}
|
|
34
|
+
for (const s of route.stack ?? []) {
|
|
35
|
+
if (typeof s.method === "string") out.add(s.method.toUpperCase());
|
|
36
|
+
}
|
|
37
|
+
if (out.has("GET")) out.delete("HEAD");
|
|
38
|
+
return [...out].filter((m) => VALID_METHODS.has(m));
|
|
39
|
+
}
|
|
40
|
+
function rootStack(app) {
|
|
41
|
+
const a = app;
|
|
42
|
+
return a?.router?.stack ?? a?._router?.stack;
|
|
43
|
+
}
|
|
44
|
+
function prefixFromRegexp(re) {
|
|
45
|
+
if (!re) return void 0;
|
|
46
|
+
let s = re.source;
|
|
47
|
+
if (s === "^\\/?$" || s === "^\\/") return "";
|
|
48
|
+
s = s.replace(/^\^/, "").replace(/\\\/\?\(\?=\\\/\|\$\)$/, "").replace(/\(\?=\\\/\|\$\)$/, "").replace(/\\\/\?$/, "").replace(/\$$/, "");
|
|
49
|
+
s = s.replace(/\\\//g, "/");
|
|
50
|
+
if (/[()?:*+\[\]|]/.test(s)) return void 0;
|
|
51
|
+
return s.startsWith("/") ? s : `/${s}`;
|
|
52
|
+
}
|
|
53
|
+
function walk(stack, prefix, out, counters) {
|
|
54
|
+
for (const layer of stack) {
|
|
55
|
+
if (layer.route && typeof layer.route.path === "string") {
|
|
56
|
+
const path = normalizePath(`${prefix}${layer.route.path}`);
|
|
57
|
+
for (const method of methodsOf(layer.route)) {
|
|
58
|
+
out.push({ method, path });
|
|
59
|
+
}
|
|
60
|
+
} else if (layer.handle?.stack && Array.isArray(layer.handle.stack)) {
|
|
61
|
+
const sub = prefixFromRegexp(layer.regexp);
|
|
62
|
+
if (sub === void 0 && layer.name === "router") {
|
|
63
|
+
counters.unreflectable += layer.handle.stack.filter(
|
|
64
|
+
(l) => l.route
|
|
65
|
+
).length;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
walk(layer.handle.stack, `${prefix}${sub ?? ""}`, out, counters);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function reflectRoutesDetailed(app, _opts) {
|
|
73
|
+
const stack = rootStack(app);
|
|
74
|
+
if (!stack) return { routes: [], unreflectable: 0 };
|
|
75
|
+
const raw = [];
|
|
76
|
+
const counters = { unreflectable: 0 };
|
|
77
|
+
walk(stack, "", raw, counters);
|
|
78
|
+
const seen = /* @__PURE__ */ new Set();
|
|
79
|
+
const routes = [];
|
|
80
|
+
for (const r of raw) {
|
|
81
|
+
const key = `${r.method} ${r.path}`;
|
|
82
|
+
if (seen.has(key)) continue;
|
|
83
|
+
seen.add(key);
|
|
84
|
+
routes.push(r);
|
|
85
|
+
}
|
|
86
|
+
return { routes, unreflectable: counters.unreflectable };
|
|
87
|
+
}
|
|
88
|
+
function reflectRoutes(app, opts) {
|
|
89
|
+
return reflectRoutesDetailed(app, opts).routes;
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
reflectRoutes,
|
|
93
|
+
reflectRoutesDetailed
|
|
94
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farthershore/backend",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Farther Shore backend SDK for builder upstreams: signed response usage, fail-closed gateway request verification, health, and lifecycle from FS_RUNTIME_TOKEN",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|