Skip to content

Commit 7ad2b0a

Browse files
authored
Fix fetch implementation (#1390)
* Enforce maxRedirects and maxContentLength on the no-axios fetch path * Fix no-axios/minimal and browser builds to embed version via __PACKAGE_VERSION__ * Add shared HttpClient test suite covering axios and no-axios paths * Migrate Horizon fetchTimebounds tests from axios-mock-adapter to MSW for cross-build coverage
1 parent 8db146e commit 7ad2b0a

15 files changed

Lines changed: 1453 additions & 82 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ A breaking change will get clearly marked in this log.
2626
* `AssembledTransaction.simulate` did not clear `this.built` before re-simulating after a state restoration rebuild, causing it to assemble stale transaction data ([#1372](https://github.com/stellar/js-stellar-sdk/pull/1372)).
2727
* `AssembledTransaction.signAndSend` mutated the shared `this.options.submit` flag to prevent double submission. Replaced with a wrapper around `signTransaction` that injects `submit: false` without mutating shared state ([#1372](https://github.com/stellar/js-stellar-sdk/pull/1372)).
2828
* Fetch HTTP client: async request interceptors were not awaited — the synchronous `try/catch` loop passed unresolved promise objects as the config. Replaced with a proper `.then()` chain matching Axios interceptor semantics ([#1372](https://github.com/stellar/js-stellar-sdk/pull/1372)).
29+
* Fetch HTTP client: `maxRedirects` and `maxContentLength` were silently ignored on the no-axios / minimal builds, turning SDK-set SSRF and DoS guards (`StellarToml.Resolver.resolve`, `FederationServer`) into no-ops. A new bounded adapter activates when either option is set, refusing redirects past `maxRedirects` and streaming the response body with a running-total check so oversized responses abort mid-stream ([#1390](https://github.com/stellar/js-stellar-sdk/pull/1390)).
30+
* `src/bindings/config.ts` imported `../../package.json` with a relative path that resolved incorrectly for the `lib/no-axios/` and `lib/minimal/` build outputs, making those libs unloadable. Replaced with the `__PACKAGE_VERSION__` compile-time define ([#1390](https://github.com/stellar/js-stellar-sdk/pull/1390)).
2931

3032
### Added
3133
* `AccountResponse` constructor now uses explicit field-by-field assignment instead of `Object.entries` dynamic assignment for type safety ([#1373](https://github.com/stellar/js-stellar-sdk/pull/1373)).
@@ -34,6 +36,8 @@ A breaking change will get clearly marked in this log.
3436
* `rpc.Server.getLatestLedger()` now includes `closeTime`, `headerXdr`, and `metadataXdr` in the typed response, with `headerXdr`/`metadataXdr` parsed into XDR objects instead of raw base64 strings ([#1389
3537
](https://github.com/stellar/js-stellar-sdk/pull/1389)).
3638

39+
40+
3741
### Deprecated
3842
* `BalanceResponse.revocable` is deprecated in favor of `authorizedToMaintainLiabilities`, which correctly reflects the trustline flag semantics ([#1372](https://github.com/stellar/js-stellar-sdk/pull/1372)).
3943

config/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
"target": "es6"
1313
},
1414
"include": ["../src"]
15-
}
15+
}

config/vitest.config.browser.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ export default defineConfig({
2727
},
2828
// Run all unit tests in browser
2929
include: ["test/unit/**/*.test.ts"],
30-
exclude: ["test/unit/call_builders.test.ts"],
30+
exclude: [
31+
"test/unit/call_builders.test.ts",
32+
"test/unit/server/horizon/server.test.ts",
33+
],
3134
// Setup files to load the browser bundle
3235
setupFiles: [resolve(__dirname, "../test/setup-browser.ts")],
3336
},

config/vitest.config.no-axios.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { defineConfig } from "vitest/config";
2+
import { resolve } from "path";
3+
4+
export default defineConfig({
5+
test: {
6+
globals: true,
7+
environment: "node",
8+
coverage: {
9+
provider: "v8",
10+
reporter: ["text", "html", "lcov"],
11+
// This config runs tests against lib/no-axios (USE_AXIOS=false routes
12+
// the test harness there). Scope coverage to that build so the report
13+
// reflects what's actually under test; the default axios build is
14+
// covered by vitest.config.ts.
15+
include: ["lib/no-axios/**/*.js"],
16+
exclude: [
17+
"test/**",
18+
"dist/**",
19+
"coverage/**",
20+
"**/*.d.ts",
21+
"lib/**/*.d.ts",
22+
"**/*/browser.js",
23+
],
24+
},
25+
testTimeout: 20000,
26+
include: ["test/unit/**/*.test.ts"],
27+
exclude: ["**/browser.test.ts"],
28+
},
29+
resolve: {
30+
alias: {
31+
"@": resolve(__dirname, "../src"),
32+
},
33+
extensions: [".ts", ".tsx", ".js", ".jsx", ".json"],
34+
},
35+
36+
define: {
37+
__USE_AXIOS__: false,
38+
__USE_EVENTSOURCE__: true,
39+
__PACKAGE_VERSION__: JSON.stringify(process.env.npm_package_version),
40+
},
41+
});

config/webpack.config.browser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ const config = {
104104
new webpack.DefinePlugin({
105105
__USE_AXIOS__: JSON.stringify(buildConfig.useAxios),
106106
__USE_EVENTSOURCE__: JSON.stringify(buildConfig.useEventSource),
107-
__PACKAGE_VERSION__: version,
107+
__PACKAGE_VERSION__: JSON.stringify(version),
108108
})
109109
],
110110
watchOptions: {

eslint.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ const typescriptConfig = [
3434
files: ["**/*.ts", "**/*.tsx"],
3535
rules: {
3636
"@typescript-eslint/require-await": "error",
37+
"@typescript-eslint/no-unused-vars": [
38+
"error",
39+
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
40+
],
3741
"no-fallthrough": "off",
3842
},
3943
},

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,11 @@
100100
"build:docs": "cross-env NODE_ENV=docs yarn _babel",
101101
"clean": "rm -rf lib/ dist/ coverage/ .nyc_output/ jsdoc/ test/e2e/.soroban",
102102
"docs": "yarn build:docs && jsdoc -c ./config/.jsdoc.json",
103-
"test": "yarn test:node && yarn test:integration && yarn test:browser",
104-
"test:all": "yarn test:node && yarn test:integration && yarn test:browser && yarn test:e2e",
103+
"test": "yarn test:node && yarn test:node:no-axios && yarn test:integration && yarn test:browser",
104+
"test:all": "yarn test:node && yarn test:node:no-axios && yarn test:integration && yarn test:browser && yarn test:e2e",
105105
"test:e2e": "./test/e2e/initialize.sh && vitest run --config config/vitest.config.e2e.ts --coverage",
106106
"test:node": "vitest run test/unit --config config/vitest.config.ts --coverage",
107+
"test:node:no-axios": "cross-env USE_AXIOS=false vitest run test/unit --config config/vitest.config.no-axios.ts",
107108
"test:e2e:noeval": "NODE_OPTIONS=--disallow-code-generation-from-strings yarn test:e2e",
108109
"test:integration": "vitest run test/integration --config config/vitest.config.ts --coverage",
109110
"test:browser": "yarn build:browser && vitest run --config config/vitest.config.browser.ts test/unit --coverage",
@@ -161,7 +162,6 @@
161162
"@vitest/coverage-istanbul": "4.1.2",
162163
"@vitest/coverage-v8": "^4.1.2",
163164
"@vitest/ui": "^4.1.2",
164-
"axios-mock-adapter": "^1.22.0",
165165
"babel-loader": "^9.1.3",
166166
"babel-plugin-istanbul": "^7.0.1",
167167
"babel-plugin-transform-define": "^2.1.4",
@@ -183,6 +183,7 @@
183183
"jsdom": "^27.0.0",
184184
"lint-staged": "^15.5.1",
185185
"lodash": "^4.17.21",
186+
"msw": "^2.13.4",
186187
"node-polyfill-webpack-plugin": "^3.0.0",
187188
"null-loader": "^4.0.1",
188189
"nyc": "^17.0.0",

src/bindings/config.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import packageJson from "../../package.json";
1+
// The SDK version is baked in at build time via babel-plugin-transform-define.
2+
// Previously this was `import packageJson from "../../package.json"`, which
3+
// failed at runtime in deeper build outputs (lib/no-axios, lib/minimal) because
4+
// the relative path `../../package.json` resolved into the output tree rather
5+
// than the project root.
6+
// eslint-disable-next-line @typescript-eslint/naming-convention
7+
declare const __PACKAGE_VERSION__: string;
28

39
export interface ConfigGenerateOptions {
410
contractName: string;
@@ -45,7 +51,7 @@ export class ConfigGenerator {
4551
build: "tsc",
4652
},
4753
dependencies: {
48-
"@stellar/stellar-sdk": `^${packageJson.version}`,
54+
"@stellar/stellar-sdk": `^${__PACKAGE_VERSION__}`,
4955
buffer: "6.0.3",
5056
},
5157
devDependencies: {

0 commit comments

Comments
 (0)