@wefunder/sdk 0.1.0-beta.10 → 0.1.0-beta.12
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 +69 -20
- package/dist/index.cjs +258 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +134 -1
- package/dist/index.d.ts +134 -1
- package/dist/index.js +256 -28
- package/dist/index.js.map +1 -1
- package/examples_manifest.json +9 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1022,6 +1022,20 @@ var WefunderAuthError = class extends WefunderError {
|
|
|
1022
1022
|
};
|
|
1023
1023
|
|
|
1024
1024
|
// src/token-manager.ts
|
|
1025
|
+
var WefunderTokenPersistenceError = class extends Error {
|
|
1026
|
+
tokens;
|
|
1027
|
+
constructor(tokens, cause) {
|
|
1028
|
+
super(
|
|
1029
|
+
`Token store failed to save the rotated token set: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
1030
|
+
{ cause }
|
|
1031
|
+
);
|
|
1032
|
+
this.name = "WefunderTokenPersistenceError";
|
|
1033
|
+
this.tokens = tokens;
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
function sameTokenSet(a, b) {
|
|
1037
|
+
return a.accessToken === b.accessToken && a.refreshToken === b.refreshToken;
|
|
1038
|
+
}
|
|
1025
1039
|
var TokenManager = class {
|
|
1026
1040
|
#tokens;
|
|
1027
1041
|
#clientId;
|
|
@@ -1034,6 +1048,7 @@ var TokenManager = class {
|
|
|
1034
1048
|
#now;
|
|
1035
1049
|
#leeway;
|
|
1036
1050
|
#inflight;
|
|
1051
|
+
#pending;
|
|
1037
1052
|
constructor(opts) {
|
|
1038
1053
|
this.#tokens = opts.tokens;
|
|
1039
1054
|
this.#clientId = opts.clientId;
|
|
@@ -1046,15 +1061,40 @@ var TokenManager = class {
|
|
|
1046
1061
|
this.#now = opts.now ?? Date.now;
|
|
1047
1062
|
this.#leeway = opts.expiryLeewayMs ?? 3e4;
|
|
1048
1063
|
}
|
|
1064
|
+
/** The durable, in-use token set. A rotated set that could not be persisted sits in `pendingTokens`. */
|
|
1049
1065
|
get current() {
|
|
1050
1066
|
return this.#tokens;
|
|
1051
1067
|
}
|
|
1052
1068
|
/** True if the manager can recover an expired token (rotate a refresh token or re-mint). */
|
|
1053
1069
|
get canRefresh() {
|
|
1054
|
-
return Boolean(
|
|
1070
|
+
return Boolean(
|
|
1071
|
+
this.#tokens.refreshToken && this.#clientId || this.#reMint
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
/** A rotated set awaiting a successful `store.save` (see `WefunderTokenPersistenceError`). */
|
|
1075
|
+
get pendingTokens() {
|
|
1076
|
+
return this.#pending;
|
|
1055
1077
|
}
|
|
1056
|
-
/**
|
|
1078
|
+
/**
|
|
1079
|
+
* Tell the manager you persisted `tokens` (the set from a `WefunderTokenPersistenceError`)
|
|
1080
|
+
* yourself. Publishes it only if it is still the pending set — a stale acknowledgment (the
|
|
1081
|
+
* manager has since rotated again) is a no-op and returns false, so an older save can never
|
|
1082
|
+
* publish a newer, unsaved set.
|
|
1083
|
+
*/
|
|
1084
|
+
async markPersisted(tokens) {
|
|
1085
|
+
const pending = this.#pending;
|
|
1086
|
+
if (!pending || !sameTokenSet(pending, tokens)) return false;
|
|
1087
|
+
this.#pending = void 0;
|
|
1088
|
+
this.#tokens = pending;
|
|
1089
|
+
return true;
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Returns a valid access token, refreshing proactively if it's expired/near-expiry. If a
|
|
1093
|
+
* rotated set is pending persistence, the save is retried first — no request uses an
|
|
1094
|
+
* undurable token.
|
|
1095
|
+
*/
|
|
1057
1096
|
async getAccessToken() {
|
|
1097
|
+
if (this.#pending) await this.refresh();
|
|
1058
1098
|
const { expiresAt } = this.#tokens;
|
|
1059
1099
|
if (expiresAt !== void 0 && this.#now() >= expiresAt - this.#leeway && this.canRefresh) {
|
|
1060
1100
|
await this.refresh();
|
|
@@ -1068,6 +1108,14 @@ var TokenManager = class {
|
|
|
1068
1108
|
*/
|
|
1069
1109
|
async refresh() {
|
|
1070
1110
|
if (this.#inflight) return this.#inflight;
|
|
1111
|
+
if (this.#pending) {
|
|
1112
|
+
this.#inflight = this.#publishPending();
|
|
1113
|
+
try {
|
|
1114
|
+
return await this.#inflight;
|
|
1115
|
+
} finally {
|
|
1116
|
+
this.#inflight = void 0;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1071
1119
|
const strategy = this.#recoveryStrategy();
|
|
1072
1120
|
if (!strategy) {
|
|
1073
1121
|
throw new WefunderAuthError(
|
|
@@ -1075,11 +1123,8 @@ var TokenManager = class {
|
|
|
1075
1123
|
);
|
|
1076
1124
|
}
|
|
1077
1125
|
this.#inflight = (async () => {
|
|
1078
|
-
|
|
1079
|
-
this.#
|
|
1080
|
-
await this.#store?.save(next);
|
|
1081
|
-
await this.#onTokenRefresh?.(next);
|
|
1082
|
-
return next;
|
|
1126
|
+
this.#pending = await strategy();
|
|
1127
|
+
return this.#publishPending();
|
|
1083
1128
|
})();
|
|
1084
1129
|
try {
|
|
1085
1130
|
return await this.#inflight;
|
|
@@ -1087,6 +1132,22 @@ var TokenManager = class {
|
|
|
1087
1132
|
this.#inflight = void 0;
|
|
1088
1133
|
}
|
|
1089
1134
|
}
|
|
1135
|
+
// Persist BEFORE publishing: no caller may use the rotated token until it is durable, and a
|
|
1136
|
+
// failed save must not leave the process working in memory but unable to reconnect after a
|
|
1137
|
+
// restart. On failure the set stays pending and WefunderTokenPersistenceError is thrown; the
|
|
1138
|
+
// next call retries the save.
|
|
1139
|
+
async #publishPending() {
|
|
1140
|
+
const tokens = this.#pending;
|
|
1141
|
+
try {
|
|
1142
|
+
await this.#store?.save(tokens);
|
|
1143
|
+
await this.#onTokenRefresh?.(tokens);
|
|
1144
|
+
} catch (err) {
|
|
1145
|
+
throw new WefunderTokenPersistenceError(tokens, err);
|
|
1146
|
+
}
|
|
1147
|
+
this.#pending = void 0;
|
|
1148
|
+
this.#tokens = tokens;
|
|
1149
|
+
return tokens;
|
|
1150
|
+
}
|
|
1090
1151
|
// Pick the recovery strategy: refresh_token rotation, else cc re-mint, else none.
|
|
1091
1152
|
#recoveryStrategy() {
|
|
1092
1153
|
const refreshTokenValue = this.#tokens.refreshToken;
|
|
@@ -1779,12 +1840,22 @@ var Wefunder = class _Wefunder {
|
|
|
1779
1840
|
});
|
|
1780
1841
|
}
|
|
1781
1842
|
/** The live token set (e.g. to persist after construction). */
|
|
1843
|
+
/** A rotated set awaiting a successful save (see `WefunderTokenPersistenceError`). */
|
|
1844
|
+
get pendingTokens() {
|
|
1845
|
+
return this.#tokens.pendingTokens;
|
|
1846
|
+
}
|
|
1847
|
+
/** Acknowledge an out-of-band save of `tokens`; false if that set is no longer pending. */
|
|
1848
|
+
markPersisted(tokens) {
|
|
1849
|
+
return this.#tokens.markPersisted(tokens);
|
|
1850
|
+
}
|
|
1782
1851
|
get tokens() {
|
|
1783
1852
|
return this.#tokens.current;
|
|
1784
1853
|
}
|
|
1785
1854
|
// ---- unwrap: turn the {data,error,response} result into data-or-throw ----
|
|
1786
1855
|
async #unwrap(p) {
|
|
1787
1856
|
const { data, error, response } = await p;
|
|
1857
|
+
if (error instanceof WefunderTokenPersistenceError || error instanceof WefunderError)
|
|
1858
|
+
throw error;
|
|
1788
1859
|
if (response && response.ok && error === void 0) return data;
|
|
1789
1860
|
const status = response?.status ?? 0;
|
|
1790
1861
|
const env = error ?? {};
|
|
@@ -1793,7 +1864,10 @@ var Wefunder = class _Wefunder {
|
|
|
1793
1864
|
type: env.error?.type ?? "api_error",
|
|
1794
1865
|
message: env.error?.message ?? response?.statusText ?? "Request failed",
|
|
1795
1866
|
// X-Wf-Request-Id header is primary (present even on non-JSON edge errors).
|
|
1796
|
-
requestId: requestIdFrom(
|
|
1867
|
+
requestId: requestIdFrom(
|
|
1868
|
+
response,
|
|
1869
|
+
env.error?.request_id ?? env.request_id
|
|
1870
|
+
),
|
|
1797
1871
|
details: env.error?.details,
|
|
1798
1872
|
remediation: env.error?.remediation
|
|
1799
1873
|
});
|
|
@@ -1819,6 +1893,32 @@ var Wefunder = class _Wefunder {
|
|
|
1819
1893
|
unwrap(p) {
|
|
1820
1894
|
return this.#unwrap(p);
|
|
1821
1895
|
}
|
|
1896
|
+
/**
|
|
1897
|
+
* Untyped escape hatch: call ANY API path with the SDK's full envelope —
|
|
1898
|
+
* bearer auth (incl. refresh / client_credentials re-mint on 401), the pinned
|
|
1899
|
+
* `Wefunder-Version` header, the retry policy, and a typed `WefunderError` on
|
|
1900
|
+
* failure. For endpoints outside the generated surface: preview-tier ops
|
|
1901
|
+
* (e.g. partner SPVs) or ops newer than this SDK build.
|
|
1902
|
+
*
|
|
1903
|
+
* `path` is relative to the client's `baseUrl` (e.g. `"/partner/spvs"`).
|
|
1904
|
+
* Returns the raw response body (no `{ data }` unwrapping — envelopes vary
|
|
1905
|
+
* across unshipped endpoints).
|
|
1906
|
+
*/
|
|
1907
|
+
async request(method, path, opts = {}) {
|
|
1908
|
+
return this.#unwrap(
|
|
1909
|
+
this.#client.request({
|
|
1910
|
+
method,
|
|
1911
|
+
url: path,
|
|
1912
|
+
// Same security descriptor the generated ops pass — this is what makes
|
|
1913
|
+
// the client attach (and on 401, refresh/re-mint) the bearer token.
|
|
1914
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1915
|
+
query: opts.query,
|
|
1916
|
+
body: opts.body,
|
|
1917
|
+
// JSON by default when a body is present; caller headers win.
|
|
1918
|
+
headers: opts.body !== void 0 ? { "Content-Type": "application/json", ...opts.headers } : opts.headers
|
|
1919
|
+
})
|
|
1920
|
+
);
|
|
1921
|
+
}
|
|
1822
1922
|
// Generic page helper: forwards the endpoint's full query (cursor + documented
|
|
1823
1923
|
// params like `sort`), not just the cursor. (Stress-test finding B.)
|
|
1824
1924
|
#page(fn) {
|
|
@@ -1829,11 +1929,23 @@ var Wefunder = class _Wefunder {
|
|
|
1829
1929
|
me: () => this.#unwrapData(getCurrentUser({ client: this.#client }))
|
|
1830
1930
|
};
|
|
1831
1931
|
offerings = {
|
|
1832
|
-
list: this.#page(
|
|
1932
|
+
list: this.#page(
|
|
1933
|
+
listOfferings
|
|
1934
|
+
),
|
|
1833
1935
|
all: (query) => paginate((cursor) => this.offerings.list({ ...query, cursor })),
|
|
1834
1936
|
collect: (query) => collect((cursor) => this.offerings.list({ ...query, cursor })),
|
|
1835
1937
|
get: (externalId) => this.#unwrapData(
|
|
1836
|
-
getOffering({
|
|
1938
|
+
getOffering({
|
|
1939
|
+
client: this.#client,
|
|
1940
|
+
path: { external_id: externalId }
|
|
1941
|
+
})
|
|
1942
|
+
),
|
|
1943
|
+
/** Aggregate investment stats (count / committed / raised, by status) for one offering. */
|
|
1944
|
+
stats: (externalId) => this.#unwrapData(
|
|
1945
|
+
getOfferingStats({
|
|
1946
|
+
client: this.#client,
|
|
1947
|
+
path: { offering_id: externalId }
|
|
1948
|
+
})
|
|
1837
1949
|
)
|
|
1838
1950
|
};
|
|
1839
1951
|
/**
|
|
@@ -1842,20 +1954,40 @@ var Wefunder = class _Wefunder {
|
|
|
1842
1954
|
* from your last page — it is always present — and resume from it next time.
|
|
1843
1955
|
*/
|
|
1844
1956
|
investments = {
|
|
1845
|
-
list: this.#page(
|
|
1846
|
-
|
|
1847
|
-
|
|
1957
|
+
list: this.#page(
|
|
1958
|
+
listInvestments
|
|
1959
|
+
),
|
|
1960
|
+
all: (query) => paginate(
|
|
1961
|
+
(cursor) => this.investments.list({
|
|
1962
|
+
...query,
|
|
1963
|
+
cursor
|
|
1964
|
+
})
|
|
1965
|
+
),
|
|
1966
|
+
collect: (query) => collect(
|
|
1967
|
+
(cursor) => this.investments.list({
|
|
1968
|
+
...query,
|
|
1969
|
+
cursor
|
|
1970
|
+
})
|
|
1971
|
+
),
|
|
1848
1972
|
/** The current record (not the published projection) for one investment (`inv_…`). */
|
|
1849
|
-
get: (id) => this.#unwrapData(
|
|
1973
|
+
get: (id) => this.#unwrapData(
|
|
1974
|
+
getInvestment({ client: this.#client, path: { id } })
|
|
1975
|
+
)
|
|
1850
1976
|
};
|
|
1851
1977
|
portfolio = {
|
|
1852
|
-
get: (query) => this.#unwrapData(
|
|
1978
|
+
get: (query) => this.#unwrapData(
|
|
1979
|
+
getPortfolio({ client: this.#client, query })
|
|
1980
|
+
),
|
|
1853
1981
|
positions: {
|
|
1854
1982
|
list: this.#page(
|
|
1855
1983
|
listPortfolioPositions
|
|
1856
1984
|
),
|
|
1857
|
-
all: (query) => paginate(
|
|
1858
|
-
|
|
1985
|
+
all: (query) => paginate(
|
|
1986
|
+
(cursor) => this.portfolio.positions.list({ ...query, cursor })
|
|
1987
|
+
),
|
|
1988
|
+
collect: (query) => collect(
|
|
1989
|
+
(cursor) => this.portfolio.positions.list({ ...query, cursor })
|
|
1990
|
+
)
|
|
1859
1991
|
}
|
|
1860
1992
|
};
|
|
1861
1993
|
campaigns = {
|
|
@@ -1864,17 +1996,91 @@ var Wefunder = class _Wefunder {
|
|
|
1864
1996
|
collect: () => collect((cursor) => this.campaigns.list({ cursor }))
|
|
1865
1997
|
};
|
|
1866
1998
|
syndicates = {
|
|
1867
|
-
list: this.#page(
|
|
1999
|
+
list: this.#page(
|
|
2000
|
+
listSyndicates
|
|
2001
|
+
),
|
|
1868
2002
|
all: (query) => paginate((cursor) => this.syndicates.list({ ...query, cursor })),
|
|
1869
|
-
get: (id) => this.#unwrapData(
|
|
2003
|
+
get: (id) => this.#unwrapData(
|
|
2004
|
+
getSyndicate({ client: this.#client, path: { id } })
|
|
2005
|
+
)
|
|
1870
2006
|
};
|
|
1871
2007
|
intents = {
|
|
1872
2008
|
list: this.#page(listIntents),
|
|
1873
2009
|
all: (query) => paginate((cursor) => this.intents.list({ ...query, cursor })),
|
|
1874
|
-
get: (id) => this.#unwrapData(
|
|
2010
|
+
get: (id) => this.#unwrapData(
|
|
2011
|
+
getIntent({ client: this.#client, path: { id } })
|
|
2012
|
+
)
|
|
1875
2013
|
};
|
|
1876
2014
|
attribution = {
|
|
1877
|
-
me: () => this.#unwrapData(
|
|
2015
|
+
me: () => this.#unwrapData(
|
|
2016
|
+
getAttributionMe({ client: this.#client })
|
|
2017
|
+
)
|
|
2018
|
+
};
|
|
2019
|
+
/**
|
|
2020
|
+
* Installations (`/installations`, scopes `read:installations` / `write:installations`;
|
|
2021
|
+
* write does not imply read). An install lets your app act AS a company or syndicate:
|
|
2022
|
+
* `create` and `mintToken` return a company-owned token (shown once, no expiry, no
|
|
2023
|
+
* refresh) — build a second client with it. Installing is also what makes a company
|
|
2024
|
+
* or syndicate an audience for your webhooks.
|
|
2025
|
+
*/
|
|
2026
|
+
installations = {
|
|
2027
|
+
/** Companies / syndicates the token's user may install your app on (empty for an investor). */
|
|
2028
|
+
eligibleTargets: (query) => this.#unwrapData(
|
|
2029
|
+
listEligibleInstallTargets({ client: this.#client, query })
|
|
2030
|
+
).then((rows) => rows ?? []),
|
|
2031
|
+
/** Every install of your app (`meta.count`). */
|
|
2032
|
+
list: () => this.#unwrap(
|
|
2033
|
+
listInstallations({ client: this.#client })
|
|
2034
|
+
),
|
|
2035
|
+
get: (id) => this.#unwrapData(
|
|
2036
|
+
getInstallation({
|
|
2037
|
+
client: this.#client,
|
|
2038
|
+
path: { external_id: id }
|
|
2039
|
+
})
|
|
2040
|
+
),
|
|
2041
|
+
/**
|
|
2042
|
+
* Install on a target. Store `token.access_token` — it is never shown again. If the
|
|
2043
|
+
* app is already installed there the API answers 409 `already_installed` with
|
|
2044
|
+
* `details.installation` = the existing id; mint a token for that instead
|
|
2045
|
+
* (see `installOrMintToken`).
|
|
2046
|
+
*/
|
|
2047
|
+
create: (input) => this.#unwrap(
|
|
2048
|
+
createInstallation({ client: this.#client, body: input })
|
|
2049
|
+
),
|
|
2050
|
+
/**
|
|
2051
|
+
* A fresh company-owned token for an existing install. `scopes` narrows within the
|
|
2052
|
+
* install's ceiling; omit it for the ceiling, and note an explicit `[]` grants nothing.
|
|
2053
|
+
*/
|
|
2054
|
+
mintToken: (id, scopes) => this.#unwrap(
|
|
2055
|
+
createInstallationToken({
|
|
2056
|
+
client: this.#client,
|
|
2057
|
+
path: { external_id: id },
|
|
2058
|
+
body: scopes ? { scopes } : void 0
|
|
2059
|
+
})
|
|
2060
|
+
),
|
|
2061
|
+
/**
|
|
2062
|
+
* `create`, falling back to `mintToken` for the existing install on 409
|
|
2063
|
+
* `already_installed`. The mint re-requests `input.scopes` so a retry never widens the
|
|
2064
|
+
* grant. Any other error (revoked install, missing scope) still throws.
|
|
2065
|
+
*/
|
|
2066
|
+
installOrMintToken: async (input) => {
|
|
2067
|
+
try {
|
|
2068
|
+
return await this.installations.create(input);
|
|
2069
|
+
} catch (err) {
|
|
2070
|
+
if (!(err instanceof WefunderError) || err.type !== "already_installed")
|
|
2071
|
+
throw err;
|
|
2072
|
+
const existingId = err.details?.installation;
|
|
2073
|
+
if (!existingId) throw err;
|
|
2074
|
+
return this.installations.mintToken(existingId, input.scopes);
|
|
2075
|
+
}
|
|
2076
|
+
},
|
|
2077
|
+
/** Revoke an install: its tokens stop working at once. Returns the install, now `revoked`. */
|
|
2078
|
+
revoke: (id) => this.#unwrapData(
|
|
2079
|
+
revokeInstallation({
|
|
2080
|
+
client: this.#client,
|
|
2081
|
+
path: { external_id: id }
|
|
2082
|
+
})
|
|
2083
|
+
)
|
|
1878
2084
|
};
|
|
1879
2085
|
/**
|
|
1880
2086
|
* Webhook endpoints (`/webhook_endpoints`, scopes `read:webhooks` / `write:webhooks`).
|
|
@@ -1885,30 +2091,50 @@ var Wefunder = class _Wefunder {
|
|
|
1885
2091
|
*/
|
|
1886
2092
|
webhookEndpoints = {
|
|
1887
2093
|
/** All of your app's endpoints (secret omitted). `meta.quota` is the per-app limit. */
|
|
1888
|
-
list: () => this.#unwrap(
|
|
2094
|
+
list: () => this.#unwrap(
|
|
2095
|
+
listWebhookEndpoints({ client: this.#client })
|
|
2096
|
+
),
|
|
1889
2097
|
get: (id) => this.#unwrapData(
|
|
1890
|
-
getWebhookEndpoint({
|
|
2098
|
+
getWebhookEndpoint({
|
|
2099
|
+
client: this.#client,
|
|
2100
|
+
path: { external_id: id }
|
|
2101
|
+
})
|
|
1891
2102
|
),
|
|
1892
2103
|
/** Store `attributes.secret` from the result — it is never shown again. */
|
|
1893
|
-
create: (input) => this.#unwrapData(
|
|
2104
|
+
create: (input) => this.#unwrapData(
|
|
2105
|
+
createWebhookEndpoint({ client: this.#client, body: input })
|
|
2106
|
+
),
|
|
1894
2107
|
/** `events` replaces the subscription list wholesale (no merge); omit to leave unchanged. */
|
|
1895
2108
|
update: (id, input) => this.#unwrapData(
|
|
1896
|
-
updateWebhookEndpoint({
|
|
2109
|
+
updateWebhookEndpoint({
|
|
2110
|
+
client: this.#client,
|
|
2111
|
+
path: { external_id: id },
|
|
2112
|
+
body: input
|
|
2113
|
+
})
|
|
1897
2114
|
),
|
|
1898
2115
|
/** Stops deliveries immediately. Removal is permanent — create a new endpoint to resume. */
|
|
1899
2116
|
remove: (id) => this.#unwrapData(
|
|
1900
|
-
deleteWebhookEndpoint({
|
|
2117
|
+
deleteWebhookEndpoint({
|
|
2118
|
+
client: this.#client,
|
|
2119
|
+
path: { external_id: id }
|
|
2120
|
+
})
|
|
1901
2121
|
),
|
|
1902
2122
|
/**
|
|
1903
2123
|
* New secret (shown once). The old one keeps signing for a 24h overlap — deliveries
|
|
1904
2124
|
* carry a `v1` for both, and `constructEvent` accepts either.
|
|
1905
2125
|
*/
|
|
1906
2126
|
rotateSecret: (id) => this.#unwrapData(
|
|
1907
|
-
rotateWebhookEndpointSecret({
|
|
2127
|
+
rotateWebhookEndpointSecret({
|
|
2128
|
+
client: this.#client,
|
|
2129
|
+
path: { external_id: id }
|
|
2130
|
+
})
|
|
1908
2131
|
),
|
|
1909
2132
|
/** Recover an auto-disabled endpoint after fixing your server. Idempotent. */
|
|
1910
2133
|
reenable: (id) => this.#unwrapData(
|
|
1911
|
-
reenableWebhookEndpoint({
|
|
2134
|
+
reenableWebhookEndpoint({
|
|
2135
|
+
client: this.#client,
|
|
2136
|
+
path: { external_id: id }
|
|
2137
|
+
})
|
|
1912
2138
|
),
|
|
1913
2139
|
/**
|
|
1914
2140
|
* POST a real, signed example event at the endpoint (production envelope + signature)
|
|
@@ -2103,10 +2329,12 @@ export {
|
|
|
2103
2329
|
REQUEST_ID_HEADER,
|
|
2104
2330
|
SANDBOX_AUTHORIZE_BASE_URL,
|
|
2105
2331
|
SIGNATURE_HEADER,
|
|
2332
|
+
TokenManager,
|
|
2106
2333
|
WebhookSignatureError,
|
|
2107
2334
|
Wefunder,
|
|
2108
2335
|
WefunderAuthError,
|
|
2109
2336
|
WefunderError,
|
|
2337
|
+
WefunderTokenPersistenceError,
|
|
2110
2338
|
checkWebhookSignature,
|
|
2111
2339
|
clientCredentialsGrant,
|
|
2112
2340
|
collect,
|