@solvapay/server 1.0.8-preview.5 → 1.0.8-preview.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/chunk-R5U7XKVJ.js +16 -0
- package/dist/dist-EPVKJAIP.js +94 -0
- package/dist/dist-JBJ4HMP7.js +94 -0
- package/dist/esm-5GYCIXIY.js +3475 -0
- package/dist/esm-UW7WCMEK.js +3475 -0
- package/dist/index.cjs +293 -12
- package/dist/index.d.cts +35 -3
- package/dist/index.d.ts +35 -3
- package/dist/index.js +289 -12
- package/dist/src/adapters/base.d.ts +57 -0
- package/dist/src/adapters/base.d.ts.map +1 -0
- package/dist/src/adapters/base.js +73 -0
- package/dist/src/adapters/base.js.map +1 -0
- package/dist/src/adapters/http.d.ts +25 -0
- package/dist/src/adapters/http.d.ts.map +1 -0
- package/dist/src/adapters/http.js +99 -0
- package/dist/src/adapters/http.js.map +1 -0
- package/dist/src/adapters/index.d.ts +11 -0
- package/dist/src/adapters/index.d.ts.map +1 -0
- package/dist/src/adapters/index.js +10 -0
- package/dist/src/adapters/index.js.map +1 -0
- package/dist/src/adapters/mcp.d.ts +24 -0
- package/dist/src/adapters/mcp.d.ts.map +1 -0
- package/dist/src/adapters/mcp.js +75 -0
- package/dist/src/adapters/mcp.js.map +1 -0
- package/dist/src/adapters/next.d.ts +24 -0
- package/dist/src/adapters/next.d.ts.map +1 -0
- package/dist/src/adapters/next.js +109 -0
- package/dist/src/adapters/next.js.map +1 -0
- package/dist/src/client.d.ts +58 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/client.js +495 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/edge.d.ts +22 -0
- package/dist/src/edge.d.ts.map +1 -0
- package/dist/src/edge.js +91 -0
- package/dist/src/edge.js.map +1 -0
- package/dist/src/factory.d.ts +605 -0
- package/dist/src/factory.d.ts.map +1 -0
- package/dist/src/factory.js +215 -0
- package/dist/src/factory.js.map +1 -0
- package/dist/src/helpers/auth.d.ts +47 -0
- package/dist/src/helpers/auth.d.ts.map +1 -0
- package/dist/src/helpers/auth.js +73 -0
- package/dist/src/helpers/auth.js.map +1 -0
- package/dist/src/helpers/checkout.d.ts +45 -0
- package/dist/src/helpers/checkout.d.ts.map +1 -0
- package/dist/src/helpers/checkout.js +89 -0
- package/dist/src/helpers/checkout.js.map +1 -0
- package/dist/src/helpers/customer.d.ts +51 -0
- package/dist/src/helpers/customer.d.ts.map +1 -0
- package/dist/src/helpers/customer.js +77 -0
- package/dist/src/helpers/customer.js.map +1 -0
- package/dist/src/helpers/error.d.ts +15 -0
- package/dist/src/helpers/error.d.ts.map +1 -0
- package/dist/src/helpers/error.js +35 -0
- package/dist/src/helpers/error.js.map +1 -0
- package/dist/src/helpers/index.d.ts +17 -0
- package/dist/src/helpers/index.d.ts.map +1 -0
- package/dist/src/helpers/index.js +23 -0
- package/dist/src/helpers/index.js.map +1 -0
- package/dist/src/helpers/payment.d.ts +107 -0
- package/dist/src/helpers/payment.d.ts.map +1 -0
- package/dist/src/helpers/payment.js +150 -0
- package/dist/src/helpers/payment.js.map +1 -0
- package/dist/src/helpers/plans.d.ts +19 -0
- package/dist/src/helpers/plans.d.ts.map +1 -0
- package/dist/src/helpers/plans.js +53 -0
- package/dist/src/helpers/plans.js.map +1 -0
- package/dist/src/helpers/renewal.d.ts +23 -0
- package/dist/src/helpers/renewal.d.ts.map +1 -0
- package/dist/src/helpers/renewal.js +90 -0
- package/dist/src/helpers/renewal.js.map +1 -0
- package/dist/src/helpers/subscription.d.ts +23 -0
- package/dist/src/helpers/subscription.d.ts.map +1 -0
- package/dist/src/helpers/subscription.js +101 -0
- package/dist/src/helpers/subscription.js.map +1 -0
- package/dist/src/helpers/types.d.ts +22 -0
- package/dist/src/helpers/types.d.ts.map +1 -0
- package/dist/src/helpers/types.js +7 -0
- package/dist/src/helpers/types.js.map +1 -0
- package/dist/src/index.d.ts +73 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +106 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/auth-bridge.d.ts +9 -0
- package/dist/src/mcp/auth-bridge.d.ts.map +1 -0
- package/dist/src/mcp/auth-bridge.js +46 -0
- package/dist/src/mcp/auth-bridge.js.map +1 -0
- package/dist/src/mcp/oauth-bridge.d.ts +48 -0
- package/dist/src/mcp/oauth-bridge.d.ts.map +1 -0
- package/dist/src/mcp/oauth-bridge.js +110 -0
- package/dist/src/mcp/oauth-bridge.js.map +1 -0
- package/dist/src/mcp-auth.d.ts +17 -0
- package/dist/src/mcp-auth.d.ts.map +1 -0
- package/dist/src/mcp-auth.js +57 -0
- package/dist/src/mcp-auth.js.map +1 -0
- package/dist/src/paywall.d.ts +119 -0
- package/dist/src/paywall.d.ts.map +1 -0
- package/dist/src/paywall.js +700 -0
- package/dist/src/paywall.js.map +1 -0
- package/dist/src/register-virtual-tools-mcp.d.ts +23 -0
- package/dist/src/register-virtual-tools-mcp.d.ts.map +1 -0
- package/dist/src/register-virtual-tools-mcp.js +86 -0
- package/dist/src/register-virtual-tools-mcp.js.map +1 -0
- package/dist/src/types/client.d.ts +216 -0
- package/dist/src/types/client.d.ts.map +1 -0
- package/dist/src/types/client.js +7 -0
- package/dist/src/types/client.js.map +1 -0
- package/dist/src/types/generated.d.ts +2834 -0
- package/dist/src/types/generated.d.ts.map +1 -0
- package/dist/src/types/generated.js +6 -0
- package/dist/src/types/generated.js.map +1 -0
- package/dist/src/types/index.d.ts +13 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +8 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/options.d.ts +126 -0
- package/dist/src/types/options.d.ts.map +1 -0
- package/dist/src/types/options.js +8 -0
- package/dist/src/types/options.js.map +1 -0
- package/dist/src/types/paywall.d.ts +64 -0
- package/dist/src/types/paywall.d.ts.map +1 -0
- package/dist/src/types/paywall.js +7 -0
- package/dist/src/types/paywall.js.map +1 -0
- package/dist/src/types/webhook.d.ts +50 -0
- package/dist/src/types/webhook.d.ts.map +1 -0
- package/dist/src/types/webhook.js +2 -0
- package/dist/src/types/webhook.js.map +1 -0
- package/dist/src/utils.d.ts +110 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +217 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/src/virtual-tools.d.ts +44 -0
- package/dist/src/virtual-tools.d.ts.map +1 -0
- package/dist/src/virtual-tools.js +140 -0
- package/dist/src/virtual-tools.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1826,15 +1826,31 @@ function buildAuthInfoFromBearer(authorization, options = {}) {
|
|
|
1826
1826
|
}
|
|
1827
1827
|
|
|
1828
1828
|
// src/mcp/oauth-bridge.ts
|
|
1829
|
+
var DEFAULT_OAUTH_PATHS = {
|
|
1830
|
+
register: "/oauth/register",
|
|
1831
|
+
authorize: "/oauth/authorize",
|
|
1832
|
+
token: "/oauth/token",
|
|
1833
|
+
revoke: "/oauth/revoke"
|
|
1834
|
+
};
|
|
1835
|
+
var NATIVE_CLIENT_ORIGIN_SCHEMES = ["cursor:", "vscode:", "vscode-webview:", "claude:"];
|
|
1829
1836
|
function withoutTrailingSlash(value) {
|
|
1830
1837
|
return value.replace(/\/$/, "");
|
|
1831
1838
|
}
|
|
1839
|
+
function resolvePaths(paths = {}) {
|
|
1840
|
+
return { ...DEFAULT_OAUTH_PATHS, ...paths };
|
|
1841
|
+
}
|
|
1832
1842
|
function getRequestAuthHeader(req) {
|
|
1833
1843
|
const header = req.headers?.authorization;
|
|
1834
1844
|
if (typeof header === "string") return header;
|
|
1835
1845
|
if (Array.isArray(header)) return header[0] || null;
|
|
1836
1846
|
return null;
|
|
1837
1847
|
}
|
|
1848
|
+
function getHeader(req, name) {
|
|
1849
|
+
const header = req.headers?.[name.toLowerCase()];
|
|
1850
|
+
if (typeof header === "string") return header;
|
|
1851
|
+
if (Array.isArray(header)) return header[0] || null;
|
|
1852
|
+
return null;
|
|
1853
|
+
}
|
|
1838
1854
|
function getRequestJsonRpcId(body) {
|
|
1839
1855
|
if (body && typeof body === "object" && "id" in body) {
|
|
1840
1856
|
const id = body.id;
|
|
@@ -1858,6 +1874,100 @@ function setMcpChallengeHeader(res, publicBaseUrl, protectedResourcePath) {
|
|
|
1858
1874
|
`Bearer resource_metadata="${withoutTrailingSlash(publicBaseUrl)}${protectedResourcePath}"`
|
|
1859
1875
|
);
|
|
1860
1876
|
}
|
|
1877
|
+
function getRequestQuery(req) {
|
|
1878
|
+
const raw = req.url ?? req.path ?? "";
|
|
1879
|
+
const qIndex = raw.indexOf("?");
|
|
1880
|
+
return qIndex === -1 ? "" : raw.slice(qIndex);
|
|
1881
|
+
}
|
|
1882
|
+
function isNativeClientOrigin(origin) {
|
|
1883
|
+
try {
|
|
1884
|
+
const url = new URL(origin);
|
|
1885
|
+
return NATIVE_CLIENT_ORIGIN_SCHEMES.includes(
|
|
1886
|
+
url.protocol
|
|
1887
|
+
);
|
|
1888
|
+
} catch {
|
|
1889
|
+
return false;
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
function applyCorsHeaders(req, res) {
|
|
1893
|
+
const origin = getHeader(req, "origin");
|
|
1894
|
+
if (!origin) return;
|
|
1895
|
+
if (isNativeClientOrigin(origin)) {
|
|
1896
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
1897
|
+
res.setHeader("Vary", "Origin");
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
function handlePreflight(req, res) {
|
|
1901
|
+
applyCorsHeaders(req, res);
|
|
1902
|
+
const requestedMethod = getHeader(req, "access-control-request-method") ?? "POST";
|
|
1903
|
+
const requestedHeaders = getHeader(req, "access-control-request-headers") ?? "authorization, content-type";
|
|
1904
|
+
res.setHeader("Access-Control-Allow-Methods", `${requestedMethod}, OPTIONS`);
|
|
1905
|
+
res.setHeader("Access-Control-Allow-Headers", requestedHeaders);
|
|
1906
|
+
res.setHeader("Access-Control-Max-Age", "600");
|
|
1907
|
+
res.status(204);
|
|
1908
|
+
if (typeof res.end === "function") {
|
|
1909
|
+
res.end();
|
|
1910
|
+
} else {
|
|
1911
|
+
res.json({});
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
async function readJsonFromResponse(upstream) {
|
|
1915
|
+
const text = await upstream.text();
|
|
1916
|
+
if (!text) return { body: {}, text: "" };
|
|
1917
|
+
try {
|
|
1918
|
+
return { body: JSON.parse(text), text };
|
|
1919
|
+
} catch {
|
|
1920
|
+
return { body: text, text };
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
async function relayJsonResponse(upstream, res) {
|
|
1924
|
+
const { body, text } = await readJsonFromResponse(upstream);
|
|
1925
|
+
res.status(upstream.status);
|
|
1926
|
+
const contentType = upstream.headers.get("content-type");
|
|
1927
|
+
if (contentType) res.setHeader("Content-Type", contentType);
|
|
1928
|
+
if (text === "" && upstream.status === 204) {
|
|
1929
|
+
if (typeof res.end === "function") {
|
|
1930
|
+
res.end();
|
|
1931
|
+
return;
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
res.json(body);
|
|
1935
|
+
}
|
|
1936
|
+
function sendUpstreamError(res, _error) {
|
|
1937
|
+
res.status(502);
|
|
1938
|
+
res.setHeader("Content-Type", "application/json");
|
|
1939
|
+
res.json({ error: "upstream_unreachable" });
|
|
1940
|
+
}
|
|
1941
|
+
function serializeRegisterBody(body) {
|
|
1942
|
+
if (typeof body === "string") return body;
|
|
1943
|
+
if (body instanceof Uint8Array) return Buffer.from(body).toString("utf8");
|
|
1944
|
+
return JSON.stringify(body ?? {});
|
|
1945
|
+
}
|
|
1946
|
+
function serializeFormBody(body) {
|
|
1947
|
+
if (typeof body === "string") return body;
|
|
1948
|
+
if (body instanceof Uint8Array) return Buffer.from(body).toString("utf8");
|
|
1949
|
+
if (body && typeof body === "object") {
|
|
1950
|
+
const params = new URLSearchParams();
|
|
1951
|
+
for (const [key, value] of Object.entries(body)) {
|
|
1952
|
+
if (value === void 0 || value === null) continue;
|
|
1953
|
+
if (Array.isArray(value)) {
|
|
1954
|
+
for (const entry of value) params.append(key, String(entry));
|
|
1955
|
+
} else {
|
|
1956
|
+
params.append(key, String(value));
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
return params.toString();
|
|
1960
|
+
}
|
|
1961
|
+
return "";
|
|
1962
|
+
}
|
|
1963
|
+
function serializeRequestBody(contentType, body) {
|
|
1964
|
+
if (contentType && contentType.includes("application/x-www-form-urlencoded")) {
|
|
1965
|
+
return serializeFormBody(body);
|
|
1966
|
+
}
|
|
1967
|
+
if (typeof body === "string") return body;
|
|
1968
|
+
if (body instanceof Uint8Array) return Buffer.from(body).toString("utf8");
|
|
1969
|
+
return JSON.stringify(body ?? {});
|
|
1970
|
+
}
|
|
1861
1971
|
function getOAuthProtectedResourceResponse(publicBaseUrl) {
|
|
1862
1972
|
const resource = withoutTrailingSlash(publicBaseUrl);
|
|
1863
1973
|
return {
|
|
@@ -1867,16 +1977,17 @@ function getOAuthProtectedResourceResponse(publicBaseUrl) {
|
|
|
1867
1977
|
};
|
|
1868
1978
|
}
|
|
1869
1979
|
function getOAuthAuthorizationServerResponse({
|
|
1870
|
-
|
|
1871
|
-
|
|
1980
|
+
publicBaseUrl,
|
|
1981
|
+
paths
|
|
1872
1982
|
}) {
|
|
1873
|
-
const
|
|
1874
|
-
const
|
|
1983
|
+
const base = withoutTrailingSlash(publicBaseUrl);
|
|
1984
|
+
const p = resolvePaths(paths);
|
|
1875
1985
|
return {
|
|
1876
|
-
issuer:
|
|
1877
|
-
authorization_endpoint: `${
|
|
1878
|
-
token_endpoint: `${
|
|
1879
|
-
registration_endpoint:
|
|
1986
|
+
issuer: base,
|
|
1987
|
+
authorization_endpoint: `${base}${p.authorize}`,
|
|
1988
|
+
token_endpoint: `${base}${p.token}`,
|
|
1989
|
+
registration_endpoint: `${base}${p.register}`,
|
|
1990
|
+
revocation_endpoint: `${base}${p.revoke}`,
|
|
1880
1991
|
token_endpoint_auth_methods_supported: ["client_secret_basic", "client_secret_post"],
|
|
1881
1992
|
response_types_supported: ["code"],
|
|
1882
1993
|
grant_types_supported: ["authorization_code", "refresh_token"],
|
|
@@ -1884,6 +1995,134 @@ function getOAuthAuthorizationServerResponse({
|
|
|
1884
1995
|
code_challenge_methods_supported: ["S256"]
|
|
1885
1996
|
};
|
|
1886
1997
|
}
|
|
1998
|
+
function createOAuthRegisterHandler(options) {
|
|
1999
|
+
const path = options.path ?? DEFAULT_OAUTH_PATHS.register;
|
|
2000
|
+
const api = withoutTrailingSlash(options.apiBaseUrl);
|
|
2001
|
+
const upstream = `${api}/v1/customer/auth/register?product_ref=${encodeURIComponent(options.productRef)}`;
|
|
2002
|
+
return async (req, res, next) => {
|
|
2003
|
+
if (req.path !== path) {
|
|
2004
|
+
next();
|
|
2005
|
+
return;
|
|
2006
|
+
}
|
|
2007
|
+
if (req.method === "OPTIONS") {
|
|
2008
|
+
handlePreflight(req, res);
|
|
2009
|
+
return;
|
|
2010
|
+
}
|
|
2011
|
+
if (req.method !== "POST") {
|
|
2012
|
+
next();
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2015
|
+
try {
|
|
2016
|
+
const response = await fetch(upstream, {
|
|
2017
|
+
method: "POST",
|
|
2018
|
+
headers: { "content-type": "application/json" },
|
|
2019
|
+
body: serializeRegisterBody(req.body)
|
|
2020
|
+
});
|
|
2021
|
+
applyCorsHeaders(req, res);
|
|
2022
|
+
await relayJsonResponse(response, res);
|
|
2023
|
+
} catch (error) {
|
|
2024
|
+
applyCorsHeaders(req, res);
|
|
2025
|
+
sendUpstreamError(res, error);
|
|
2026
|
+
}
|
|
2027
|
+
};
|
|
2028
|
+
}
|
|
2029
|
+
function createOAuthAuthorizeHandler(options) {
|
|
2030
|
+
const path = options.path ?? DEFAULT_OAUTH_PATHS.authorize;
|
|
2031
|
+
const api = withoutTrailingSlash(options.apiBaseUrl);
|
|
2032
|
+
return (req, res, next) => {
|
|
2033
|
+
if (req.path !== path) {
|
|
2034
|
+
next();
|
|
2035
|
+
return;
|
|
2036
|
+
}
|
|
2037
|
+
if (req.method === "OPTIONS") {
|
|
2038
|
+
handlePreflight(req, res);
|
|
2039
|
+
return;
|
|
2040
|
+
}
|
|
2041
|
+
if (req.method !== "GET") {
|
|
2042
|
+
next();
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
const query = getRequestQuery(req);
|
|
2046
|
+
const location = `${api}/v1/customer/auth/authorize${query}`;
|
|
2047
|
+
res.setHeader("Location", location);
|
|
2048
|
+
res.status(302);
|
|
2049
|
+
if (typeof res.end === "function") {
|
|
2050
|
+
res.end();
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
res.json({});
|
|
2054
|
+
};
|
|
2055
|
+
}
|
|
2056
|
+
function createOAuthTokenHandler(options) {
|
|
2057
|
+
const path = options.path ?? DEFAULT_OAUTH_PATHS.token;
|
|
2058
|
+
const api = withoutTrailingSlash(options.apiBaseUrl);
|
|
2059
|
+
const upstream = `${api}/v1/customer/auth/token`;
|
|
2060
|
+
return async (req, res, next) => {
|
|
2061
|
+
if (req.path !== path) {
|
|
2062
|
+
next();
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
if (req.method === "OPTIONS") {
|
|
2066
|
+
handlePreflight(req, res);
|
|
2067
|
+
return;
|
|
2068
|
+
}
|
|
2069
|
+
if (req.method !== "POST") {
|
|
2070
|
+
next();
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
const contentType = getHeader(req, "content-type") ?? "application/x-www-form-urlencoded";
|
|
2074
|
+
const authorization = getHeader(req, "authorization");
|
|
2075
|
+
const headers = { "content-type": contentType };
|
|
2076
|
+
if (authorization) headers["authorization"] = authorization;
|
|
2077
|
+
try {
|
|
2078
|
+
const response = await fetch(upstream, {
|
|
2079
|
+
method: "POST",
|
|
2080
|
+
headers,
|
|
2081
|
+
body: serializeRequestBody(contentType, req.body)
|
|
2082
|
+
});
|
|
2083
|
+
applyCorsHeaders(req, res);
|
|
2084
|
+
await relayJsonResponse(response, res);
|
|
2085
|
+
} catch (error) {
|
|
2086
|
+
applyCorsHeaders(req, res);
|
|
2087
|
+
sendUpstreamError(res, error);
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
2091
|
+
function createOAuthRevokeHandler(options) {
|
|
2092
|
+
const path = options.path ?? DEFAULT_OAUTH_PATHS.revoke;
|
|
2093
|
+
const api = withoutTrailingSlash(options.apiBaseUrl);
|
|
2094
|
+
const upstream = `${api}/v1/customer/auth/revoke`;
|
|
2095
|
+
return async (req, res, next) => {
|
|
2096
|
+
if (req.path !== path) {
|
|
2097
|
+
next();
|
|
2098
|
+
return;
|
|
2099
|
+
}
|
|
2100
|
+
if (req.method === "OPTIONS") {
|
|
2101
|
+
handlePreflight(req, res);
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
if (req.method !== "POST") {
|
|
2105
|
+
next();
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
const contentType = getHeader(req, "content-type") ?? "application/x-www-form-urlencoded";
|
|
2109
|
+
const authorization = getHeader(req, "authorization");
|
|
2110
|
+
const headers = { "content-type": contentType };
|
|
2111
|
+
if (authorization) headers["authorization"] = authorization;
|
|
2112
|
+
try {
|
|
2113
|
+
const response = await fetch(upstream, {
|
|
2114
|
+
method: "POST",
|
|
2115
|
+
headers,
|
|
2116
|
+
body: serializeRequestBody(contentType, req.body)
|
|
2117
|
+
});
|
|
2118
|
+
applyCorsHeaders(req, res);
|
|
2119
|
+
await relayJsonResponse(response, res);
|
|
2120
|
+
} catch (error) {
|
|
2121
|
+
applyCorsHeaders(req, res);
|
|
2122
|
+
sendUpstreamError(res, error);
|
|
2123
|
+
}
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
1887
2126
|
function createMcpOAuthBridge(options) {
|
|
1888
2127
|
const {
|
|
1889
2128
|
publicBaseUrl,
|
|
@@ -1893,8 +2132,10 @@ function createMcpOAuthBridge(options) {
|
|
|
1893
2132
|
requireAuth = true,
|
|
1894
2133
|
authInfo,
|
|
1895
2134
|
protectedResourcePath = "/.well-known/oauth-protected-resource",
|
|
1896
|
-
authorizationServerPath = "/.well-known/oauth-authorization-server"
|
|
2135
|
+
authorizationServerPath = "/.well-known/oauth-authorization-server",
|
|
2136
|
+
oauthPaths
|
|
1897
2137
|
} = options;
|
|
2138
|
+
const paths = resolvePaths(oauthPaths);
|
|
1898
2139
|
const protectedResourceMiddleware = (req, res, next) => {
|
|
1899
2140
|
if (req.method !== "GET" || req.path !== protectedResourcePath) {
|
|
1900
2141
|
next();
|
|
@@ -1913,16 +2154,38 @@ function createMcpOAuthBridge(options) {
|
|
|
1913
2154
|
}
|
|
1914
2155
|
res.json(
|
|
1915
2156
|
getOAuthAuthorizationServerResponse({
|
|
1916
|
-
|
|
1917
|
-
|
|
2157
|
+
publicBaseUrl,
|
|
2158
|
+
paths
|
|
1918
2159
|
})
|
|
1919
2160
|
);
|
|
1920
2161
|
};
|
|
2162
|
+
const registerMiddleware = createOAuthRegisterHandler({
|
|
2163
|
+
apiBaseUrl,
|
|
2164
|
+
productRef,
|
|
2165
|
+
path: paths.register
|
|
2166
|
+
});
|
|
2167
|
+
const authorizeMiddleware = createOAuthAuthorizeHandler({
|
|
2168
|
+
apiBaseUrl,
|
|
2169
|
+
path: paths.authorize
|
|
2170
|
+
});
|
|
2171
|
+
const tokenMiddleware = createOAuthTokenHandler({ apiBaseUrl, path: paths.token });
|
|
2172
|
+
const revokeMiddleware = createOAuthRevokeHandler({ apiBaseUrl, path: paths.revoke });
|
|
1921
2173
|
const mcpAuthMiddleware = (req, res, next) => {
|
|
1922
2174
|
if (req.path !== mcpPath) {
|
|
1923
2175
|
next();
|
|
1924
2176
|
return;
|
|
1925
2177
|
}
|
|
2178
|
+
if (req.method && req.method !== "POST" && req.method !== "OPTIONS") {
|
|
2179
|
+
applyCorsHeaders(req, res);
|
|
2180
|
+
res.setHeader("Allow", "POST, OPTIONS");
|
|
2181
|
+
res.status(405);
|
|
2182
|
+
if (typeof res.end === "function") {
|
|
2183
|
+
res.end();
|
|
2184
|
+
} else {
|
|
2185
|
+
res.json({ error: "method_not_allowed" });
|
|
2186
|
+
}
|
|
2187
|
+
return;
|
|
2188
|
+
}
|
|
1926
2189
|
const authHeader = getRequestAuthHeader(req);
|
|
1927
2190
|
const id = getRequestJsonRpcId(req.body);
|
|
1928
2191
|
if (!authHeader && !requireAuth) {
|
|
@@ -1937,6 +2200,8 @@ function createMcpOAuthBridge(options) {
|
|
|
1937
2200
|
req.auth = auth;
|
|
1938
2201
|
next();
|
|
1939
2202
|
} catch {
|
|
2203
|
+
applyCorsHeaders(req, res);
|
|
2204
|
+
res.setHeader("Access-Control-Expose-Headers", "WWW-Authenticate, Mcp-Session-Id");
|
|
1940
2205
|
setMcpChallengeHeader(res, publicBaseUrl, protectedResourcePath);
|
|
1941
2206
|
if (req.method === "POST") {
|
|
1942
2207
|
res.status(401).json(makeUnauthorizedJsonRpc(id));
|
|
@@ -1945,7 +2210,15 @@ function createMcpOAuthBridge(options) {
|
|
|
1945
2210
|
res.status(401).json({ error: "Unauthorized" });
|
|
1946
2211
|
}
|
|
1947
2212
|
};
|
|
1948
|
-
return [
|
|
2213
|
+
return [
|
|
2214
|
+
protectedResourceMiddleware,
|
|
2215
|
+
authorizationServerMiddleware,
|
|
2216
|
+
registerMiddleware,
|
|
2217
|
+
authorizeMiddleware,
|
|
2218
|
+
tokenMiddleware,
|
|
2219
|
+
revokeMiddleware,
|
|
2220
|
+
mcpAuthMiddleware
|
|
2221
|
+
];
|
|
1949
2222
|
}
|
|
1950
2223
|
|
|
1951
2224
|
// src/helpers/error.ts
|
|
@@ -2628,6 +2901,10 @@ export {
|
|
|
2628
2901
|
createCheckoutSessionCore,
|
|
2629
2902
|
createCustomerSessionCore,
|
|
2630
2903
|
createMcpOAuthBridge,
|
|
2904
|
+
createOAuthAuthorizeHandler,
|
|
2905
|
+
createOAuthRegisterHandler,
|
|
2906
|
+
createOAuthRevokeHandler,
|
|
2907
|
+
createOAuthTokenHandler,
|
|
2631
2908
|
createPaymentIntentCore,
|
|
2632
2909
|
createSolvaPay,
|
|
2633
2910
|
createSolvaPayClient,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Adapter Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract for all framework adapters.
|
|
5
|
+
* Each adapter handles extraction, transformation, and formatting for its specific context.
|
|
6
|
+
*/
|
|
7
|
+
import type { SolvaPayPaywall } from '../paywall';
|
|
8
|
+
import type { PaywallMetadata } from '../types';
|
|
9
|
+
/**
|
|
10
|
+
* Base adapter interface that all framework adapters implement
|
|
11
|
+
*/
|
|
12
|
+
export interface Adapter<TContext = any, TResult = any> {
|
|
13
|
+
/**
|
|
14
|
+
* Extract plain arguments from the framework-specific context
|
|
15
|
+
*/
|
|
16
|
+
extractArgs(context: TContext): Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Extract customer reference from the context
|
|
19
|
+
*/
|
|
20
|
+
getCustomerRef(context: TContext, extra?: unknown): Promise<string> | string;
|
|
21
|
+
/**
|
|
22
|
+
* Format the business logic result for the framework
|
|
23
|
+
*/
|
|
24
|
+
formatResponse(result: unknown, context: TContext): TResult;
|
|
25
|
+
/**
|
|
26
|
+
* Format errors for the framework
|
|
27
|
+
*/
|
|
28
|
+
formatError(error: Error, context: TContext): TResult;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Shared utilities for adapters
|
|
32
|
+
*/
|
|
33
|
+
export declare class AdapterUtils {
|
|
34
|
+
/**
|
|
35
|
+
* Ensure customer reference is properly formatted
|
|
36
|
+
*/
|
|
37
|
+
static ensureCustomerRef(customerRef: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Extract customer ref from JWT token
|
|
40
|
+
*/
|
|
41
|
+
static extractFromJWT(token: string, options?: {
|
|
42
|
+
secret?: string;
|
|
43
|
+
issuer?: string;
|
|
44
|
+
audience?: string;
|
|
45
|
+
}): Promise<string | null>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create a protected handler using an adapter.
|
|
49
|
+
*
|
|
50
|
+
* The returned closure caches:
|
|
51
|
+
* - `backendRefCache`: resolved customer ref (input → cus_xxx) so ensureCustomer
|
|
52
|
+
* is only called once per distinct customer identity.
|
|
53
|
+
* - `protectedHandler`: the closure returned by paywall.protect() is created once
|
|
54
|
+
* and reused across invocations.
|
|
55
|
+
*/
|
|
56
|
+
export declare function createAdapterHandler<TContext, TResult>(adapter: Adapter<TContext, TResult>, paywall: SolvaPayPaywall, metadata: PaywallMetadata, businessLogic: (args: any) => Promise<any>): Promise<(context: TContext, extra?: unknown) => Promise<TResult>>;
|
|
57
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/adapters/base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,UAAU,CAAA;AAE5D;;GAEG;AAEH,MAAM,WAAW,OAAO,CAAC,QAAQ,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG;IACpD;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE1F;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAA;IAE5E;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAA;IAE3D;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAA;CACtD;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IASrD;;OAEG;WACU,cAAc,CACzB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB,GACA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAkB1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAC1D,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,EACnC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,eAAe,EAEzB,aAAa,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GACzC,OAAO,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAwBnE"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Adapter Interface
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract for all framework adapters.
|
|
5
|
+
* Each adapter handles extraction, transformation, and formatting for its specific context.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Shared utilities for adapters
|
|
9
|
+
*/
|
|
10
|
+
export class AdapterUtils {
|
|
11
|
+
/**
|
|
12
|
+
* Ensure customer reference is properly formatted
|
|
13
|
+
*/
|
|
14
|
+
static ensureCustomerRef(customerRef) {
|
|
15
|
+
if (!customerRef || customerRef === 'anonymous') {
|
|
16
|
+
return 'anonymous';
|
|
17
|
+
}
|
|
18
|
+
// Return customer ref as-is (preserve UUIDs with hyphens, etc.)
|
|
19
|
+
return customerRef;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Extract customer ref from JWT token
|
|
23
|
+
*/
|
|
24
|
+
static async extractFromJWT(token, options) {
|
|
25
|
+
try {
|
|
26
|
+
const { jwtVerify } = await import('jose');
|
|
27
|
+
const jwtSecret = new TextEncoder().encode(options?.secret || process.env.OAUTH_JWKS_SECRET || 'test-jwt-secret');
|
|
28
|
+
const { payload } = await jwtVerify(token, jwtSecret, {
|
|
29
|
+
issuer: options?.issuer || process.env.OAUTH_ISSUER || 'http://localhost:3000',
|
|
30
|
+
audience: options?.audience || process.env.OAUTH_CLIENT_ID || 'test-client-id',
|
|
31
|
+
});
|
|
32
|
+
return payload.sub || null;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// JWT verification failed, return null
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a protected handler using an adapter.
|
|
42
|
+
*
|
|
43
|
+
* The returned closure caches:
|
|
44
|
+
* - `backendRefCache`: resolved customer ref (input → cus_xxx) so ensureCustomer
|
|
45
|
+
* is only called once per distinct customer identity.
|
|
46
|
+
* - `protectedHandler`: the closure returned by paywall.protect() is created once
|
|
47
|
+
* and reused across invocations.
|
|
48
|
+
*/
|
|
49
|
+
export async function createAdapterHandler(adapter, paywall, metadata,
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
51
|
+
businessLogic) {
|
|
52
|
+
const backendRefCache = new Map();
|
|
53
|
+
const getCustomerRef = (args) => args.auth?.customer_ref || 'anonymous';
|
|
54
|
+
const protectedHandler = await paywall.protect(businessLogic, metadata, getCustomerRef);
|
|
55
|
+
return async (context, extra) => {
|
|
56
|
+
try {
|
|
57
|
+
const args = await adapter.extractArgs(context);
|
|
58
|
+
const customerRef = await adapter.getCustomerRef(context, extra);
|
|
59
|
+
let backendRef = backendRefCache.get(customerRef);
|
|
60
|
+
if (!backendRef) {
|
|
61
|
+
backendRef = await paywall.ensureCustomer(customerRef, customerRef);
|
|
62
|
+
backendRefCache.set(customerRef, backendRef);
|
|
63
|
+
}
|
|
64
|
+
args.auth = { customer_ref: backendRef };
|
|
65
|
+
const result = await protectedHandler(args);
|
|
66
|
+
return adapter.formatResponse(result, context);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return adapter.formatError(error, context);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/adapters/base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+BH;;GAEG;AACH,MAAM,OAAO,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,WAAmB;QAC1C,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;YAChD,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,gEAAgE;QAChE,OAAO,WAAW,CAAA;IACpB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,cAAc,CACzB,KAAa,EACb,OAIC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;YAC1C,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CACxC,OAAO,EAAE,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,iBAAiB,CACtE,CAAA;YAED,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE;gBACpD,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,uBAAuB;gBAC9E,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,gBAAgB;aAC/E,CAAC,CAAA;YAEF,OAAQ,OAAO,CAAC,GAAc,IAAI,IAAI,CAAA;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;YACvC,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAmC,EACnC,OAAwB,EACxB,QAAyB;AACzB,8DAA8D;AAC9D,aAA0C;IAE1C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAA;IACjD,MAAM,cAAc,GAAG,CAAC,IAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,IAAI,WAAW,CAAA;IACpF,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAA;IAEvF,OAAO,KAAK,EAAE,OAAiB,EAAE,KAAe,EAAoB,EAAE;QACpE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAC/C,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;YAEhE,IAAI,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YACjD,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,UAAU,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;gBACnE,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;YAC9C,CAAC;YAED,IAAI,CAAC,IAAI,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,CAAA;YAExC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAA;YAC3C,OAAO,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,OAAO,CAAC,WAAW,CAAC,KAAc,EAAE,OAAO,CAAC,CAAA;QACrD,CAAC;IACH,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Adapter for Express and Fastify
|
|
3
|
+
*
|
|
4
|
+
* Handles Express and Fastify HTTP frameworks with automatic detection
|
|
5
|
+
* of request/response patterns.
|
|
6
|
+
*/
|
|
7
|
+
import type { Adapter } from './base';
|
|
8
|
+
import type { HttpAdapterOptions } from '../types';
|
|
9
|
+
/**
|
|
10
|
+
* HTTP context (Express or Fastify)
|
|
11
|
+
*/
|
|
12
|
+
type HttpContext = [req: any, reply: any];
|
|
13
|
+
/**
|
|
14
|
+
* HTTP Adapter implementation
|
|
15
|
+
*/
|
|
16
|
+
export declare class HttpAdapter implements Adapter<HttpContext, unknown> {
|
|
17
|
+
private options;
|
|
18
|
+
constructor(options?: HttpAdapterOptions);
|
|
19
|
+
extractArgs([req, _reply]: HttpContext): Record<string, unknown>;
|
|
20
|
+
getCustomerRef([req, _reply]: HttpContext): Promise<string>;
|
|
21
|
+
formatResponse(result: unknown, [_req, reply]: HttpContext): unknown;
|
|
22
|
+
formatError(error: Error, [_req, reply]: HttpContext): unknown;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/adapters/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAErC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAGlD;;GAEG;AAEH,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;AAEzC;;GAEG;AACH,qBAAa,WAAY,YAAW,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC;IACnD,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE,kBAAuB;IAEpD,WAAW,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAa1D,cAAc,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BjE,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO;IAepE,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO;CAyC/D"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Adapter for Express and Fastify
|
|
3
|
+
*
|
|
4
|
+
* Handles Express and Fastify HTTP frameworks with automatic detection
|
|
5
|
+
* of request/response patterns.
|
|
6
|
+
*/
|
|
7
|
+
import { AdapterUtils } from './base';
|
|
8
|
+
import { PaywallError } from '../paywall';
|
|
9
|
+
/**
|
|
10
|
+
* HTTP Adapter implementation
|
|
11
|
+
*/
|
|
12
|
+
export class HttpAdapter {
|
|
13
|
+
options;
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
this.options = options;
|
|
16
|
+
}
|
|
17
|
+
extractArgs([req, _reply]) {
|
|
18
|
+
if (this.options.extractArgs) {
|
|
19
|
+
return this.options.extractArgs(req);
|
|
20
|
+
}
|
|
21
|
+
// Default extraction from req.body, req.params, req.query
|
|
22
|
+
return {
|
|
23
|
+
...(req.body || {}),
|
|
24
|
+
...(req.params || {}),
|
|
25
|
+
...(req.query || {}),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
async getCustomerRef([req, _reply]) {
|
|
29
|
+
if (this.options.getCustomerRef) {
|
|
30
|
+
const ref = await this.options.getCustomerRef(req);
|
|
31
|
+
return AdapterUtils.ensureCustomerRef(ref);
|
|
32
|
+
}
|
|
33
|
+
// Try x-customer-ref header first
|
|
34
|
+
const headerRef = req.headers?.['x-customer-ref'];
|
|
35
|
+
if (headerRef) {
|
|
36
|
+
return AdapterUtils.ensureCustomerRef(headerRef);
|
|
37
|
+
}
|
|
38
|
+
// Try JWT token if available
|
|
39
|
+
const authHeader = req.headers?.['authorization'];
|
|
40
|
+
if (authHeader && authHeader.startsWith('Bearer ')) {
|
|
41
|
+
const token = authHeader.substring(7);
|
|
42
|
+
const jwtSub = await AdapterUtils.extractFromJWT(token);
|
|
43
|
+
if (jwtSub) {
|
|
44
|
+
return AdapterUtils.ensureCustomerRef(jwtSub);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Fallback to anonymous
|
|
48
|
+
return 'anonymous';
|
|
49
|
+
}
|
|
50
|
+
formatResponse(result, [_req, reply]) {
|
|
51
|
+
if (this.options.transformResponse) {
|
|
52
|
+
return this.options.transformResponse(result, reply);
|
|
53
|
+
}
|
|
54
|
+
// Express: has reply.status method
|
|
55
|
+
if (reply && reply.status && typeof reply.json === 'function') {
|
|
56
|
+
reply.json(result);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Fastify: return value for auto-serialization
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
formatError(error, [_req, reply]) {
|
|
63
|
+
if (error instanceof PaywallError) {
|
|
64
|
+
const errorResponse = {
|
|
65
|
+
success: false,
|
|
66
|
+
error: 'Payment required',
|
|
67
|
+
product: error.structuredContent.product,
|
|
68
|
+
checkoutUrl: error.structuredContent.checkoutUrl,
|
|
69
|
+
message: error.structuredContent.message,
|
|
70
|
+
};
|
|
71
|
+
// Express: has reply.status method
|
|
72
|
+
if (reply && reply.status && typeof reply.json === 'function') {
|
|
73
|
+
reply.status(402).json(errorResponse);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// Fastify: use reply.code
|
|
77
|
+
if (reply && reply.code) {
|
|
78
|
+
reply.code(402);
|
|
79
|
+
}
|
|
80
|
+
return errorResponse;
|
|
81
|
+
}
|
|
82
|
+
// Generic error
|
|
83
|
+
const errorResponse = {
|
|
84
|
+
success: false,
|
|
85
|
+
error: error instanceof Error ? error.message : 'Internal server error',
|
|
86
|
+
};
|
|
87
|
+
// Express: has reply.status method
|
|
88
|
+
if (reply && reply.status && typeof reply.json === 'function') {
|
|
89
|
+
reply.status(500).json(errorResponse);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// Fastify: use reply.code
|
|
93
|
+
if (reply && reply.code) {
|
|
94
|
+
reply.code(500);
|
|
95
|
+
}
|
|
96
|
+
return errorResponse;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/adapters/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapters Export
|
|
3
|
+
*
|
|
4
|
+
* Exports all framework adapters and utilities
|
|
5
|
+
*/
|
|
6
|
+
export type { Adapter } from './base';
|
|
7
|
+
export { AdapterUtils, createAdapterHandler } from './base';
|
|
8
|
+
export { HttpAdapter } from './http';
|
|
9
|
+
export { NextAdapter } from './next';
|
|
10
|
+
export { McpAdapter } from './mcp';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA"}
|