@wefunder/sdk 0.1.0-beta.2 → 0.1.0-beta.4

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 CHANGED
@@ -8,10 +8,11 @@ Official TypeScript SDK for the [Wefunder API](https://docs.wefunder.com/api-ref
8
8
  > stabilize. Feedback welcome.
9
9
 
10
10
  ```bash
11
- npm install @wefunder/sdk
11
+ npm install @wefunder/sdk@beta
12
12
  ```
13
13
 
14
- Node 20+ (uses the global `fetch`). ESM and CommonJS both supported.
14
+ While in beta, releases publish to the `@beta` dist-tag (npm reserves `latest` for the
15
+ eventual stable release). Node 20+ (uses the global `fetch`). ESM and CommonJS both supported.
15
16
 
16
17
  ### Scope & versioning
17
18
 
@@ -219,3 +220,29 @@ so the public-tier definition can't drift between the two repos. CI's
219
220
  `generated code matches spec` job verifies `src/generated` matches the committed spec;
220
221
  it cannot reach the private canonical swagger, so run `sync-spec` before cutting a
221
222
  release. (`npm test` stays hermetic.)
223
+
224
+ ### Releasing (maintainers)
225
+
226
+ Releases publish from CI with provenance — no manual `npm publish` or OTP. Bump the
227
+ version and push the tag; the `Release` workflow (`.github/workflows/release.yml`,
228
+ triggered on `v*` tags) runs the `prepublishOnly` gate and publishes:
229
+
230
+ ```bash
231
+ git checkout main && git pull # clean tree, on main
232
+ npm version prerelease --preid beta # 0.1.0-beta.N → N+1, commits + tags v0.1.0-beta.N+1
233
+ git push --follow-tags # pushes the commit + tag → CI publishes
234
+ ```
235
+
236
+ The workflow verifies the tag matches `package.json`, then publishes — prerelease
237
+ versions (e.g. `0.1.0-beta.N`) to the **`beta`** dist-tag (npm requires an explicit tag
238
+ for prereleases), stable versions to `latest`. For a stable release use
239
+ `npm version patch|minor|major` (no `--preid`).
240
+
241
+ **Auth is npm Trusted Publishing (OIDC) — no token to store.** npm exchanges the
242
+ workflow's GitHub OIDC token for a short-lived credential at publish time, and
243
+ provenance is generated automatically (verified-build badge on npmjs.com).
244
+
245
+ **One-time setup:** on npmjs.com, `@wefunder/sdk` → **Settings → Trusted Publishing →
246
+ GitHub Actions**, with org/user `Wefunder`, repository `wefunder-node`, workflow
247
+ `release.yml` (leave Environment blank). No repo secret needed. (Requires this public
248
+ repo + public package — both true.)
package/dist/index.cjs CHANGED
@@ -880,13 +880,6 @@ function backoffMs(attempt, opts, random) {
880
880
  const jitter = exp * 0.5 * random();
881
881
  return Math.min(exp + jitter, opts.maxDelayMs);
882
882
  }
883
- function withBearer(input, init, token) {
884
- const headers = new Headers(
885
- init?.headers ?? (input instanceof Request ? input.headers : void 0)
886
- );
887
- headers.set("Authorization", `Bearer ${token}`);
888
- return { ...init, headers };
889
- }
890
883
  function createFetch(deps) {
891
884
  const baseFetch = deps.fetch ?? fetch;
892
885
  const sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
@@ -900,21 +893,37 @@ function createFetch(deps) {
900
893
  return async function wrappedFetch(input, init) {
901
894
  const method = methodOf(input, init);
902
895
  const idempotent = IDEMPOTENT.has(method);
896
+ const isRequest = input instanceof Request;
903
897
  let refreshed = false;
904
898
  let attempt = 0;
899
+ let retryToken;
900
+ const dispatch = (authToken) => {
901
+ if (isRequest) {
902
+ const fresh = input.clone();
903
+ if (authToken === void 0) return baseFetch(fresh);
904
+ const headers = new Headers(fresh.headers);
905
+ headers.set("Authorization", `Bearer ${authToken}`);
906
+ return baseFetch(new Request(fresh, { headers }));
907
+ }
908
+ const nextInit = authToken === void 0 ? init : (() => {
909
+ const headers = new Headers(init?.headers);
910
+ headers.set("Authorization", `Bearer ${authToken}`);
911
+ return { ...init, headers };
912
+ })();
913
+ return baseFetch(input, nextInit);
914
+ };
905
915
  for (; ; ) {
906
916
  let response;
907
917
  let networkError;
908
918
  try {
909
- response = await baseFetch(input, init);
919
+ response = await dispatch(retryToken);
910
920
  } catch (err) {
911
921
  networkError = err;
912
922
  }
913
- const replayable = !(input instanceof Request && input.bodyUsed);
914
- if (response?.status === 401 && !refreshed && replayable && deps.tokenManager?.canRefresh) {
923
+ if (response?.status === 401 && !refreshed && deps.tokenManager?.canRefresh) {
915
924
  refreshed = true;
916
925
  const next = await deps.tokenManager.refresh();
917
- init = withBearer(input, init, next.accessToken);
926
+ retryToken = next.accessToken;
918
927
  continue;
919
928
  }
920
929
  if (response?.status === 429 && attempt < retry.maxRetries) {