{"_id":"fetch-fun","_rev":"27-da9e4922e270b1210e86f64ae44b88e5","name":"fetch-fun","dist-tags":{"latest":"0.15.0"},"versions":{"0.1.0":{"name":"fetch-fun","version":"0.1.0","keywords":["fetch","function","fp"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.1.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"8a37cb61f67b30d27fb52fc048fd7d34dd666d74","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.1.0.tgz","fileCount":27,"integrity":"sha512-4QzlmifahguwJAebSaRfDHiA0s+dc1YCK3s9bgiR7DvZ9CFxeJursxEE20bX/XnFUdqxG+KUpOq4k54XmqHcJg==","signatures":[{"sig":"MEUCIB/rHDGr60qlvvXTLd7AtMUvn5A3vbNsJzUyqbKHgDSPAiEAlRs+MP35l6WxsYUxQjlajoTf7kj1ZWNO5hBOr7owj8E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":93455,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdjYRWCRA9TVsSAnZWagAAhHkP/0xwl4OreroSAiz7eVgj\nNGL1JjlzAYSBrZzdzVdQfoEMzUljViCpJdVcI9382qXPBMH4dA7qTSTSI3J4\nUhSjqlfK2noe7NDKQvm4U+t+Pyo4Bj0U2UbGJn8+3x0jjLYP0RjWnbN0pBoU\ndhSnnXv5uUTehpSRY2/RLI0+1cPeXmHDZVQpAMn74lINuw1U5TQ+nS4gkJf7\nwf1uYT+GwQz3VvWigMPJqNM4A5vvMhXLUrBDRb2hT1lHJ+c5Q72/aW/T6xUH\nX+g25YjdoZFN77zVGsz+qwNMPCYrJX9wOngVWz+J8ZPDnSBXMEvccK7OTTCp\nvO/giEVAneUGmPjH9d5M+DT5ii4cYS2Yo7YDCL0N+23Jzrbtw+5tLr9TIejv\nSNz80EK5qIlAnoNTRDjip9R9Ym4QFJVSdTH6t8dEq7s+aBVdEUoVj7PVx2PD\nLvjquhxG1w9EhiyGi3poTjZkao4db+4SfduLtYCd666NJM8xZb7fYIH0BLKS\nHfJL6r+QYdWgfnDkqjtVQ580ytloL3N5s1eu2n80kBsJSinwYBaNLq6CXJ9q\nxeGDrWK2Q0IHr7imfI4AXXM5XrLn+oCcmQFnEPBOFUm9Caun1X/Q2kgxD/Ya\ntEMRSpwMyZp7OVHHU1QCLbaNd+ZjOyE67R2Pd3fsGjvUk2j2+3stJgrwm4gZ\n3UOd\r\n=29Lb\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/fetch-fun.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"unpkg":"dist/fetch-fun.umd.min.js","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/fetch-fun.esm.js","browser":"dist/fetch-fun.umd.js","gitHead":"94d33cd61610ca5138ceddb4501e5efb7e8c6b73","scripts":{"lint":"eslint --fix src test","test":"cross-env NODE_ENV=test nyc mocha --recursive --exclude mock --exclude fixtures -r @babel/register -r should -r should-sinon","build":"rollup -c","start":"npm test -- --watch","commit":"lint-staged && git-cz -n","coverage":"nyc report --reporter=text-lcov | coveralls","prepublish":"rimraf dist && npm run build"},"_npmUser":{"name":"wmzy","email":"1256573276@qq.com"},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"6.9.0","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"10.13.0","dependencies":{"lodash":"^4.17.11"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^13.2.0","husky":"^1.3.1","mocha":"^5.2.0","sinon":"^7.2.3","eslint":"^5.12.0","rimraf":"^3.0.0","rollup":"^1.1.2","should":"^13.2.3","prettier":"^1.16.4","coveralls":"^3.0.2","cross-env":"^5.2.0","commitizen":"^3.0.5","fetch-mock":"^7.3.0","node-fetch":"^2.3.0","@babel/core":"^7.2.2","lint-staged":"^8.1.3","babel-eslint":"^10.0.1","should-sinon":"0.0.6","@babel/register":"^7.0.0","@babel/preset-env":"^7.2.3","eslint-plugin-babel":"^5.3.0","eslint-plugin-mocha":"^5.2.1","rollup-plugin-babel":"^4.3.2","eslint-plugin-import":"^2.16.0","rollup-plugin-terser":"^5.1.2","eslint-config-prettier":"^4.0.0","eslint-plugin-prettier":"^3.1.1","rollup-plugin-commonjs":"^9.2.0","rollup-plugin-by-output":"^1.0.0","cz-conventional-changelog":"^2.1.0","eslint-config-airbnb-base":"^13.1.0","rollup-plugin-node-resolve":"^4.0.0","eslint-plugin-builtin-compat":"0.0.2","@babel/plugin-proposal-pipeline-operator":"^7.3.2"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.1.0_1569555541513_0.34701156404898903","host":"s3://npm-registry-packages"}},"0.2.0":{"name":"fetch-fun","version":"0.2.0","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.2.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"5db3555112018fdac79cd7d901061f0f09e413f5","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.2.0.tgz","fileCount":14,"integrity":"sha512-l5TVdl9TvtbI90Ze5B+0Zu1EAo8M4C9OCHRd/iOETZZwFki4HJvJCmf1A7fJKmzH8I+dg4LRjEVaTTZPvcEOZg==","signatures":[{"sig":"MEYCIQDWzYrG3r5c3CMRyNikXk/Jjei4Kf3LSxcRWMcSaeuWRQIhAPbsvTq08OPlHZReDa0tLMYrhCe4p9mGEg+xGGA7kqau","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32126},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"src/index.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./src/index.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"d1a6456c2e51921676b804065af442165ba21faf","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage","prepublish":"rimraf dist && npm run build && npm run build:types","build:types":"tsc --emitDeclarationOnly"},"_npmUser":{"name":"wmzy","email":"1256573276@qq.com"},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"10.9.0","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.12.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.1.0","husky":"^9.1.7","eslint":"^9.20.0","vitest":"^3.0.5","cross-env":"^7.0.3","commitizen":"^4.3.1","typescript":"^5.7.3","lint-staged":"^15.4.3","tools-config":"^0.2.0","@vitest/coverage-v8":"^3.0.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.2.0_1739365996258_0.44062012016950947","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"fetch-fun","version":"0.2.1","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.2.1","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"9172950e04dca76d05672f5d4bb3d8c5e6d54979","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.2.1.tgz","fileCount":14,"integrity":"sha512-uliHM5K/leDeOAGUOujiuyeL3Yqmj+qHQdscD7oX4i+qWHCInEdJR4J8kLwAOw1D84Th5Z2ADLnJbsQQIrb2Ag==","signatures":[{"sig":"MEUCIQCqAW8joM4fAzehwSPV2mBBMwqa4O3KzcPDc4U9ohc6twIgfQBNNsExocn9Zxjhp8e1mwDYfKO0qtAAM9FgaGEKPSs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32956},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"src/index.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./src/index.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"a34b51385600ba066ad8b879e717ec8affc13f40","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage","prepublishOnly":"npm run build -- --emptyOutDir"},"_npmUser":{"name":"wmzy","email":"1256573276@qq.com"},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"10.9.0","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.12.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.1.0","husky":"^9.1.7","eslint":"^9.20.0","vitest":"^3.0.5","cross-env":"^7.0.3","commitizen":"^4.3.1","typescript":"^5.7.3","lint-staged":"^15.4.3","tools-config":"^0.2.0","@vitest/coverage-v8":"^3.0.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.2.1_1739366328214_0.7307012548831691","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"fetch-fun","version":"0.3.0","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.3.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"27232d5485fe9e7cae7e29c444306a7d862be1ab","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.3.0.tgz","fileCount":14,"integrity":"sha512-LIZvPbcGmjDgOb3PIVbba8R+d3taAo6AFCemDY58rI8BBFBHjGx9XwyPyjZtclRC9vlPGw5LW299gdVGcDywqw==","signatures":[{"sig":"MEQCIBzglDJz282Flbs4HJhpNMjRAONwXI3ni8cOwX2CuSLEAiA7BVMvmXZfcKpbYlies6ZzwCg2bojAdFqH9ZdMWclv/Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34766},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"src/index.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./src/index.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"d2ebd6abaf9bbc0dbe299258710ef0d56e61a3c5","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage","prepublishOnly":"npm run build -- --emptyOutDir"},"_npmUser":{"name":"wmzy","email":"1256573276@qq.com"},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"10.9.0","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.12.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.1.0","husky":"^9.1.7","eslint":"^9.20.0","vitest":"^3.0.5","cross-env":"^7.0.3","commitizen":"^4.3.1","typescript":"^5.7.3","lint-staged":"^15.4.3","tools-config":"^0.2.0","@vitest/coverage-v8":"^3.0.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.3.0_1739521934610_0.015377275457391537","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"fetch-fun","version":"0.3.1","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.3.1","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"f4a1cac479c55252fb2bb6e5b234e3ed20cb36d5","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.3.1.tgz","fileCount":22,"integrity":"sha512-KnvZHhxuShtIEYad7Owc4gd2QRoAxbQxXDbWChEhWrD/Zdwtdyg3DT1JjwU5Ymx35nd3bnu/xhv1gleuiUqblQ==","signatures":[{"sig":"MEYCIQCInHGZuLsDei5DLNwyoZZ5/eHoiRku/Xq1W4a1uqyYdgIhAI2c/ma1kIBgAJIr9QDe1F7pPeDBxs80QJdiJHk4H7PK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39331},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./dist/types/index.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"011fbf1844fdcbe76aa818f5de97b7bc066de131","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage","build:types":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build -- --emptyOutDir"},"_npmUser":{"name":"wmzy","email":"1256573276@qq.com"},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"10.9.0","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.12.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.1.0","husky":"^9.1.7","eslint":"^9.20.0","vitest":"^3.0.5","cross-env":"^7.0.3","commitizen":"^4.3.1","typescript":"^5.7.3","lint-staged":"^15.4.3","tools-config":"^0.2.1","@vitest/coverage-v8":"^3.0.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.3.1_1739844855807_0.8823179659498688","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"fetch-fun","version":"0.3.2","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.3.2","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"2af2d42a1d8207aa94849c0903945c2be0ed8c24","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.3.2.tgz","fileCount":22,"integrity":"sha512-Kko99JdA8wgMTf4B0gGKSMU30MaBldBsfv1FDZEgiXHJt4YbSOuBTaoVRzNl1i2QFtTedW5US7730nKJy9WeCQ==","signatures":[{"sig":"MEUCIQCST0SIKc22Iq55mepF8OzFAkzv+BnXWx59xzUYkHtaYQIgci/TApgpYALeiX6M/Az6a0qjW12kM102BBnqrGIC/nw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39496},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./dist/types/index.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"da5b34e374f8b96e5c1a8118da4002e89b85c6d2","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage","build:types":"tsc -p tsconfig.build.json","postpublish":"git push --follow-tags","prepublishOnly":"npm run build -- --emptyOutDir"},"_npmUser":{"name":"wmzy","email":"1256573276@qq.com"},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"10.9.0","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"23.1.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.1.0","husky":"^9.1.7","eslint":"^9.20.0","vitest":"^3.0.5","cross-env":"^7.0.3","commitizen":"^4.3.1","typescript":"^5.7.3","lint-staged":"^15.4.3","tools-config":"^0.2.1","@vitest/coverage-v8":"^3.0.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.3.2_1740653421884_0.9331867283851656","host":"s3://npm-registry-packages-npm-production"}},"0.3.3":{"name":"fetch-fun","version":"0.3.3","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.3.3","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"8076cfad8e1be1458b904e976e86a115b975df59","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.3.3.tgz","fileCount":22,"integrity":"sha512-2KMIiizK548dM1kSawbuxF8/ad07OOstqo595h3P2x6gToyNyxT7QKR4NaQVhzw8U8+tRL4q5Q6eq0gtaNyJ6w==","signatures":[{"sig":"MEYCIQC8d/cku3Avvll2khFn/+t5a5C800WpmSQnAhb8Miv7SwIhAIUdiTKTLJ3eeP+W624r0LV0E3escyjLz8wm18zBaXYG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39500},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"c881d74db18448ad1747e0802d53c8362e356445","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage","build:types":"tsc -p tsconfig.build.json","postpublish":"git push --follow-tags","prepublishOnly":"npm run build -- --emptyOutDir"},"_npmUser":{"name":"wmzy","email":"1256573276@qq.com"},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"10.9.0","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"23.1.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.1.0","husky":"^9.1.7","eslint":"^9.20.0","vitest":"^3.0.5","cross-env":"^7.0.3","commitizen":"^4.3.1","typescript":"^5.7.3","lint-staged":"^15.4.3","tools-config":"^0.2.1","@vitest/coverage-v8":"^3.0.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.3.3_1740659866365_0.42112499128026615","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"fetch-fun","version":"0.4.0","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.4.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"b7e2a9b1434b343225296fefa673ccc62228cb63","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.4.0.tgz","fileCount":22,"integrity":"sha512-GZmJ+T0O7x1W4s9cMIfd9rmdGzM3WKd5xYw/c+cN3aisljm8+mQlgxcZMlgPZg0MKMyeT2pa9y7fgli460syHg==","signatures":[{"sig":"MEUCIFjcK9FLMoOyr/2OEhhu2KSw3rKpQL31tY7v2SZ2TjD9AiEAkGBWgPYqkmFux4/VwaH0NS6D2x+DnzqWPjtqlC+es3o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":230357},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"6aba589d6ddf4dc001e7c2d68448ec7c6a223d30","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage","build:types":"tsc -p tsconfig.build.json","postpublish":"git push --follow-tags","prepublishOnly":"npm run build -- --emptyOutDir"},"_npmUser":{"name":"wmzy","email":"1256573276@qq.com"},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"11.6.2","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.0","husky":"^9.1.7","eslint":"^9.39.2","vitest":"^4.0.16","cross-env":"^10.1.0","commitizen":"^4.3.1","typescript":"^5.9.3","lint-staged":"^16.2.7","tools-config":"^0.2.3","@vitest/coverage-v8":"^4.0.16","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.4.0_1773074118061_0.9271050335966944","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"fetch-fun","version":"0.4.1","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.4.1","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"4ed0dc8c190e168402d4dd0bf6d962f82c57efcd","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.4.1.tgz","fileCount":22,"integrity":"sha512-xMnzVhGo7PfMbWy6heiO1jZVfRQj9A+imdP0K0lpPl43ehXIN2a7vR7vj4W3HijTFBVtqh49Q/xr9LWMQuZb6g==","signatures":[{"sig":"MEUCIFksXI2/7d4F1zfKIX8dSutHhrknBCHEoAnopdOSbCzZAiEAhg2i2UqO7FFYvfQu1cQPsTuD3ih3aW3wTdKzHd2WBtU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":230382},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"502585b4d164d36fb829c1acfa233efc644b8b20","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","build:types":"tsc -p tsconfig.build.json","postpublish":"git push --follow-tags","prepublishOnly":"npm run build -- --emptyOutDir"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"11.12.1","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.22.1","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","husky":"^9.1.7","eslint":"^10.0.3","vitest":"^4.0.18","cross-env":"^10.1.0","commitizen":"^4.3.1","typescript":"^5.9.3","lint-staged":"^16.3.2","tools-config":"^0.2.3","@vitest/coverage-v8":"^4.0.18","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.4.1_1774623996733_0.6985438153882195","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"fetch-fun","version":"0.4.2","keywords":["fetch","http"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.4.2","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"0c5b3a89bc7e4a87e85481ada8ddba87dde30349","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.4.2.tgz","fileCount":22,"integrity":"sha512-dtQw9gfLpZgy6nwZ8j3QOxIahOH0+w4U5AQ0sYQqT713R2jUwF8mrdPvbC1LNfwTV998unu/zCwhHErn5dyijw==","signatures":[{"sig":"MEUCIQDaefWWEduaTgDCgu9fZYcZyH9YZqrjYgIyrIOnbyNAUAIgF24KssZezSVI0wCIU4Vb59RzXO4ocE5/l+EU/N7gMmk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":230281},"main":"dist/index.cjs.js","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.es.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/index.es.js","require":"./dist/index.cjs.js"}},"gitHead":"9b46d17b9af66c45f0789425a4d697ac5f313f1d","scripts":{"dev":"vite","lint":"eslint --fix src test","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","build:types":"tsc -p tsconfig.build.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"11.12.1","description":"fetch functions","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.22.1","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","husky":"^9.1.7","eslint":"^10.0.3","vitest":"^4.0.18","cross-env":"^10.1.0","commitizen":"^4.3.1","typescript":"^5.9.3","lint-staged":"^16.3.2","tools-config":"^0.2.3","@vitest/coverage-v8":"^4.0.18","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.4.2_1774667575246_0.9155371071284872","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"fetch-fun","version":"0.5.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.5.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"e57336119adbf8b18434b4d47575e3c1d4bd3be5","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.5.0.tgz","fileCount":33,"integrity":"sha512-2sJuBl+3mR8YB/F7QCm6N4DKoDtWvT1xJ2058kqUqp1NiS/14cMtRTqcd00WoUUlqzf2xJ5cnPVYlJif3Nlypw==","signatures":[{"sig":"MEUCIQCwlZafJcC1rywKv6HXTP7DUx2RFa8IFpORprWYduO5fAIgPWQ2iMbMocBnR817O7/P0aGL3Mg7dfoI06W5dV8/+OM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":564950},"main":"dist/index.cjs","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"04abc376c7ab2f81a45c6e6502fb11843ce70319","scripts":{"dev":"vite","attw":"attw --pack .","lint":"eslint --fix src test","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"_npmVersion":"11.19.0","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","husky":"^9.1.7","eslint":"^10.0.3","vitest":"^4.0.18","publint":"^0.3.24","cross-env":"^10.1.0","commitizen":"^4.3.1","typescript":"^5.9.3","lint-staged":"^16.3.2","tools-config":"^0.2.3","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^4.0.18","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.5.0_1787243519114_0.776396514608982","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"fetch-fun","version":"0.6.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.6.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"444fdcec2932e29363599169347254a94e8d81e0","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.6.0.tgz","fileCount":33,"integrity":"sha512-kErhhnOr7K9DsF4LKpY2o4I/wsudVK/cxk8LSNts/ptdiYE+3sQNxwSM4si6jgU1bUnBK7MoAWIRcIHLxIPcSg==","signatures":[{"sig":"MEUCIQCHy3ZielMJdKW6lBdaatJgdNB6tdJx7yi6YvJRpTluhAIgHDYKE2lqmo4UhFkGTn5uzcESPSOW7yc/21osr8PGj0w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":599094},"main":"dist/index.cjs","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"ead9b2df99f09e2b3772cbf8c397c08ee492f2be","scripts":{"dev":"vite","attw":"attw --pack .","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full bundle (dist/index.mjs, min+gz)","path":"dist/index.mjs","limit":"20 KB","disablePlugins":["@size-limit/esbuild"]},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"10 KB","import":"{ create, url, fetchJSON, json }"}],"_npmVersion":"11.19.0","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","husky":"^9.1.7","eslint":"^10.0.3","vitest":"^4.0.18","publint":"^0.3.24","cross-env":"^10.1.0","commitizen":"^4.3.1","size-limit":"^13.0.3","typescript":"^5.9.3","lint-staged":"^16.3.2","tools-config":"^0.2.3","@size-limit/file":"^13.0.3","typescript-eslint":"^8.56.1","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.0.18","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.6.0_1787248503918_0.07988066947268391","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"fetch-fun","version":"0.7.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.7.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"d20d655702a6dc1ee6740c25f36dcfe8c0e56df2","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.7.0.tgz","fileCount":33,"integrity":"sha512-bknZWPgqucbqbQfoCim/ecP4rrFalzy53jqoos41bEKxpwR5zirv8n751LVgc0rK6a/LVdMfeqMssBbGfQSIhg==","signatures":[{"sig":"MEQCIGACxMlTh91FNoLL8tJ2V3CDwjrqnk0FwTfPPKnI9km+AiAtGKW5Tsqaqjgnyt9drq4WzFaooUqiSEiqnsLY8IBCBQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":650857},"main":"dist/index.cjs","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"573deb513b3e9f564b73ca82c13ec8896a0f3e1e","scripts":{"dev":"vite","attw":"attw --pack .","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full bundle (dist/index.mjs, min+gz)","path":"dist/index.mjs","limit":"20 KB","disablePlugins":["@size-limit/esbuild"]},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"10 KB","import":"{ create, url, fetchJSON, json }"}],"_npmVersion":"11.19.0","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","husky":"^9.1.7","eslint":"^10.0.3","vitest":"^4.0.18","publint":"^0.3.24","cross-env":"^10.1.0","commitizen":"^4.3.1","size-limit":"^13.0.3","typescript":"^5.9.3","lint-staged":"^16.3.2","tools-config":"^0.2.3","@size-limit/file":"^13.0.3","typescript-eslint":"^8.56.1","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.0.18","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.7.0_1787312299541_0.6383175442820981","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"fetch-fun","version":"0.8.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.8.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"3f3d0f75d436e307691e39c64bc76c6321b10d5c","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.8.0.tgz","fileCount":36,"integrity":"sha512-Pd0Gn20TY7Kop7KgPkeBltzrS3uMnyAmYHHCUHMYXLHX/3QjACtx0FmgJI548ksNSK1bmUMLVKBugl/9OastEQ==","signatures":[{"sig":"MEQCIAMeQ9laTmVTBR62rNfwPUgegjEQz/bY4QTQtfKHzKvEAiBe9AxHILKJtbJrY3nM4Xv08kZUjginPQpWZJYQPoR0Jw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":707551},"main":"dist/index.cjs","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"c73aa9f8b986b4acc0532b30cf494b062d317ab5","scripts":{"dev":"vite","attw":"attw --pack .","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full bundle (dist/index.mjs, min+gz)","path":"dist/index.mjs","limit":"8 KB","disablePlugins":["@size-limit/esbuild"]},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"}],"_npmVersion":"11.19.0","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","husky":"^9.1.7","eslint":"^10.0.3","vitest":"^4.0.18","publint":"^0.3.24","cross-env":"^10.1.0","commitizen":"^4.3.1","size-limit":"^13.0.3","typescript":"^5.9.3","lint-staged":"^16.3.2","tools-config":"^0.2.3","@size-limit/file":"^13.0.3","typescript-eslint":"^8.56.1","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.0.18","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.8.0_1787387079434_0.5295702346854589","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"fetch-fun","version":"0.8.1","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.8.1","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"3b4029645311cc887c81b0bcf67927376fd8c903","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.8.1.tgz","fileCount":36,"integrity":"sha512-iomBf39zjvmBTbaXYw/fwSdOgO3btSkFAl7x1UPQQiYcq3j+8jABmnmsUylnjQ3n2ln274yIhYRRgv34+jl2lQ==","signatures":[{"sig":"MEUCIQCfzaGmTCEoJLfI2fCWozeJEoUFiaPS7oPimbCr+qj92AIgMfX7vtW5aXiP1ggxrD6vaLbo7Gr/KIFIV2whDYsdq8g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.8.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":707551},"main":"dist/index.cjs","husky":{"hooks":{"pre-commit":"lint-staged"}},"types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"777f89defaf2cb16a364bbb9c4f7e5e5091bee78","scripts":{"dev":"vite","attw":"attw --pack .","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full bundle (dist/index.mjs, min+gz)","path":"dist/index.mjs","limit":"8 KB","disablePlugins":["@size-limit/esbuild"]},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"}],"_npmVersion":"11.19.0","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.js":["cross-env NODE_ENV=production eslint --fix","git add"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","husky":"^9.1.7","eslint":"^10.0.3","vitest":"^4.0.18","publint":"^0.3.24","cross-env":"^10.1.0","commitizen":"^4.3.1","size-limit":"^13.0.3","typescript":"^5.9.3","lint-staged":"^16.3.2","tools-config":"^0.2.3","@size-limit/file":"^13.0.3","typescript-eslint":"^8.56.1","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.0.18","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.8.1_1787418484669_0.3446383773797692","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"fetch-fun","version":"0.9.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.9.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"3150e72c9c35a4265e45e152893f9a70ef58067d","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.9.0.tgz","fileCount":36,"integrity":"sha512-BCF8qBDAKWpGo6MXaa8DhHLBfp1UEHnFvl2k+6u1U1FHd1lpN8DlUkfnr97/qRaoMwCZjHc/63BSQoMTSN+UBA==","signatures":[{"sig":"MEUCIQDCAfuHQkRBpAe04f5Rxxr7VUX8A78RkaVbLn3pzHCgNAIgAcbaH+IyhN5T/YtJDGuFbEY3T8MvfnYakUgSTXfUfLk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":706486},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"c1bccb0c7230fffc57afe3de917361a754c2f289","scripts":{"dev":"vite","attw":"attw --pack .","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full bundle (dist/index.mjs, min+gz)","path":"dist/index.mjs","limit":"8 KB","disablePlugins":["@size-limit/esbuild"]},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"}],"_npmVersion":"11.19.0","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.9.0","vitest":"^4.1.11","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.3.0","tools-config":"^0.3.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.67.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.9.0_1787539591923_0.3748586078337439","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"fetch-fun","version":"0.10.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.10.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"8abe5d6c69a86e6f71c8c7f1749df8be8d5fcaff","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.10.0.tgz","fileCount":36,"integrity":"sha512-Dg/gx7jWJxqtQfPxzVlVulYpTdsho4rLHXjsHtIR/oappxw58rhX4qlgotzRIN6mlRxHPEbwtN1VlMElZVRg+Q==","signatures":[{"sig":"MEUCIElmsdfWw5nCP4MuFDCtkM3PRgxVGu4uQM2q9E2Mti+2AiEAu+bdsAZRvlEZLSciKPhw/BWp63pg3F/NveN2AklVbZs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.10.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":728325},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}}},"gitHead":"52672cd6210dfe14a9a3ef5b15c69234ef924cee","scripts":{"dev":"vite","attw":"attw --pack .","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full bundle (dist/index.mjs, min+gz)","path":"dist/index.mjs","limit":"8 KB","disablePlugins":["@size-limit/esbuild"]},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"}],"_npmVersion":"11.19.0","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.9.0","vitest":"^4.1.11","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.3.0","tools-config":"^0.3.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.67.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.10.0_1787714553729_0.32292250335383144","host":"s3://npm-registry-packages-npm-production"}},"0.11.0":{"name":"fetch-fun","version":"0.11.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.11.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"6e9a620793c6df8b4863da2efce76aef8e260d0a","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.11.0.tgz","fileCount":47,"integrity":"sha512-wHDebRB08gLnzKAgezMlA9y/4hXXqcTagsx6wNr67jKCVIVLPD0dG5F63ydKp5Qq47MEVEl7TNXQYcTBY0765Q==","signatures":[{"sig":"MEUCIQCKr5KATgz7b5x0+PWl/cGJnPoSdglKEU+PEb6RbER3IAIgDvipgjQnxchqGsp3VbhdsIriAY4ptTwVroTzmUVo2LA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.11.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":761838},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"gitHead":"2c229d186125b24c6d9c6141c749c0f0be6fe257","scripts":{"dev":"vite","attw":"attw --pack . --profile node16","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","limit":"6 KB"},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"},{"gzip":true,"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","limit":"2 KB","import":"{ createOpenapi }"}],"_npmVersion":"11.19.1","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.9.0","vitest":"^4.1.11","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.3.0","tools-config":"^0.3.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.67.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.11.0_1788145121580_0.9864354063559737","host":"s3://npm-registry-packages-npm-production"}},"0.11.1":{"name":"fetch-fun","version":"0.11.1","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.11.1","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"e861d8aee2feaf7d11deb832683f6da47e6e13df","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.11.1.tgz","fileCount":47,"integrity":"sha512-djv/8uJonK5BO9r8gjo84SGZbp+0rpgrTS2AJYvMAbZCBREtTZwuXBWTplH5dEYIdWLB4qG2ee3IUHXzwvXBOg==","signatures":[{"sig":"MEYCIQD2ADQu0EdcEtS89A8uHpRFEbznddHbdGMRaPCkhfiocAIhAJHx1+Xf6u1KpPj7UyNrUhBBro1gmIzsBj4TFh92c8c6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.11.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":770127},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"gitHead":"0f77a9a450563296f070738ead4630fb31696b5e","scripts":{"dev":"vite","attw":"attw --pack . --profile node16","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","limit":"6 KB"},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"},{"gzip":true,"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","limit":"2 KB","import":"{ createOpenapi }"}],"_npmVersion":"11.19.1","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.9.0","vitest":"^4.1.11","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.3.0","tools-config":"^0.3.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.67.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.11.1_1788343927599_0.07133503012865527","host":"s3://npm-registry-packages-npm-production"}},"0.12.0":{"name":"fetch-fun","version":"0.12.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.12.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"1f33a8327701df703309a4dba310633e8e7276db","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.12.0.tgz","fileCount":47,"integrity":"sha512-EQNka0Xq3Af3/gykQxMuqmHqZpOQCzkagWAz5fqii++6XTmm0GsvN/Z1x8QvCgrmPpXitV80Eub17EAkFNLEig==","signatures":[{"sig":"MEUCIQCjHxYqXOyFcZZLfEB1Jn2vyYy38z3imnvYCUS4a9RrMgIgaK0FSlZT02CYFyDsT0HNboMU9vUqgljtLrCMmQTpH3k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.12.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":850725},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"gitHead":"4bd66cd56fbbcfc3124ffc42f329553addf9f350","scripts":{"dev":"vite","attw":"attw --pack . --profile node16","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","limit":"6 KB"},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"},{"gzip":true,"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","limit":"2 KB","import":"{ createOpenapi }"}],"_npmVersion":"11.19.1","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.9.0","vitest":"^4.1.11","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.3.0","tools-config":"^0.3.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.67.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.12.0_1788461576248_0.3061820249194729","host":"s3://npm-registry-packages-npm-production"}},"0.12.1":{"name":"fetch-fun","version":"0.12.1","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.12.1","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"eca5d06b1d40926a905126d6d7b4625b702316ab","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.12.1.tgz","fileCount":47,"integrity":"sha512-koRtGSpH+drogny0/OTX3LRwvIqumH35ClnxvdzkmfM2DIfsKS1kN+1IeybNnJNIO12pjiuFJ03XhdOd4FTC+g==","signatures":[{"sig":"MEYCIQC7cVTJgfT709I1LyhAOD5ihIgxMS/KXjgoPeaK4DU2CQIhAKCCjr8oJDk30AJviOjFZBYpkfZ4KR+wZOCVcEaB1pJU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.12.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":851790},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"gitHead":"583d280ed9558ffb3538d0f966c7bc74243ab452","scripts":{"dev":"vite","attw":"attw --pack . --profile node16","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","limit":"6 KB"},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"},{"gzip":true,"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","limit":"2 KB","import":"{ createOpenapi }"}],"_npmVersion":"11.19.1","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.9.0","vitest":"^4.1.11","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.3.0","tools-config":"^0.3.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.67.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.12.1_1788462067515_0.4879268513620818","host":"s3://npm-registry-packages-npm-production"}},"0.12.2":{"name":"fetch-fun","version":"0.12.2","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.12.2","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"52c9617198e11fdf2dacde51442a9b6c105c499c","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.12.2.tgz","fileCount":47,"integrity":"sha512-ymk/+rWMaDVvd3om7uC5/vEEkZ8uO1Jzkcigq2qupTtEFl5WFZ56tReGyRfbV11D/ms57NzwThZRqFT9NKikOw==","signatures":[{"sig":"MEUCIQCrkkmMqQXFtbPcMKxheUTziIRhGxhnzVzgduB5BR+APAIgROnYGOBg3nMYupNpp2pvtsUIDaUmbAl08WWVEs46LNA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.12.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":858422},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"gitHead":"035d99e8db6b47fada3167494130efc69c79167f","scripts":{"dev":"vite","attw":"attw --pack . --profile node16","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","limit":"6 KB"},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"},{"gzip":true,"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","limit":"2 KB","import":"{ createOpenapi }"}],"_npmVersion":"11.19.1","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.9.0","vitest":"^4.1.11","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.3.0","tools-config":"^0.3.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.67.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.12.2_1788665627741_0.8699798723341554","host":"s3://npm-registry-packages-npm-production"}},"0.13.0":{"name":"fetch-fun","version":"0.13.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.13.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"d6f611ee36d52cd54a7753009df0a539c203f754","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.13.0.tgz","fileCount":47,"integrity":"sha512-24d6DH9STAbGAV5YUC8hjU78ONMF1GdQi+mfAq0gUFfmjjiYBnGLlhMPzG4W/PtDvc2oDfWR2604rlxy3ADiUQ==","signatures":[{"sig":"MEYCIQCKPzGL8TgWkfyWzLrj/nSDKKm/PYOelw2B0+kdj/8TwgIhAK1bIxRho44vtimydIFJLhUMyiAvGEXU3S5Rbfkm3yi9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.13.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":871660},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"gitHead":"0f12b2f8ab0d431182606376943504a118008cd1","scripts":{"dev":"vite","attw":"attw --pack . --profile node16","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","limit":"6 KB"},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"},{"gzip":true,"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","limit":"2 KB","import":"{ createOpenapi }"}],"_npmVersion":"11.19.1","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.9.0","vitest":"^4.1.11","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.3.0","tools-config":"^0.3.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.67.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^4.1.11","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.13.0_1788786882359_0.07979020029001371","host":"s3://npm-registry-packages-npm-production"}},"0.14.0":{"name":"fetch-fun","version":"0.14.0","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.14.0","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"ab80947cff7ef24a8ff29c4a21d9adc9c10691f9","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.14.0.tgz","fileCount":47,"integrity":"sha512-c49hsind4DhUP/cc6Rdbov1uo54Y/zddSx73Ry86c7xup3qbLDskZBtVwoFXBpyszvZ17ktMeUowDZuRohWPIw==","signatures":[{"sig":"MEQCIA5cG9Oq3wTfgKEHxNSSNVcDupH1XIFtQprpQmOeLfpPAiA+UH91MHIy4fq5dZsX25JGjxMbU/uNQrGUpym8ytQPbA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.14.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":878854},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"gitHead":"bc8e3d2d245548a3d41bd024071703ff8e06cd88","scripts":{"dev":"vite","attw":"attw --pack . --profile node16","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","limit":"6 KB"},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"},{"gzip":true,"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","limit":"2 KB","import":"{ createOpenapi }"}],"_npmVersion":"11.19.1","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.10.0","vitest":"^5.0.0","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.5.0","tools-config":"^0.4.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.69.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^5.0.0","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.14.0_1788866920098_0.07581155148918639","host":"s3://npm-registry-packages-npm-production"}},"0.14.1":{"name":"fetch-fun","version":"0.14.1","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","_id":"fetch-fun@0.14.1","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"homepage":"https://github.com/wmzy/fetch-fun#readme","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"dist":{"shasum":"b6cf9e207f5f434b0afcdab209ac1560cffb8df1","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.14.1.tgz","fileCount":47,"integrity":"sha512-SlRmFQ21KnyIfHn0k8kN7Sp/Lmv6K1hYlk01+my+/CIvhkvfNJ94pU+WW/G3nJ6CyzGUz1nS3xu0mQB1LNrgow==","signatures":[{"sig":"MEUCIAa0dx6rg3KVriUFfjqjRk6qm6UZnzsl+xkLpbThd6EFAiEAhp196F7xVRzH9Q09Gd3+zMd1AToto0dKr5jAmJxZuHY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.14.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":880561},"main":"dist/index.cjs","types":"dist/types/index.d.ts","config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"module":"dist/index.mjs","engines":{"node":">=20.3"},"exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"gitHead":"ec1fd04160a66d7ce73aa44e4ec6f8e9f47e8cfc","scripts":{"dev":"vite","attw":"attw --pack . --profile node16","lint":"eslint --fix src test","size":"size-limit","test":"vitest","build":"vite build && npm run build:types","start":"vitest watch","commit":"lint-staged && git-cz -n","prepare":"husky","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint:pkg":"publint --strict","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"repository":{"url":"git+https://github.com/wmzy/fetch-fun.git","type":"git"},"size-limit":[{"gzip":true,"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","limit":"6 KB"},{"gzip":true,"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","limit":"4 KB","import":"{ create, url, fetchJSON, json }"},{"gzip":true,"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","limit":"2 KB","import":"{ createOpenapi }"}],"_npmVersion":"11.19.1","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","directories":{},"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"sideEffects":false,"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"vite":"^8.2.2","husky":"^9.1.7","eslint":"^10.10.0","vitest":"^5.0.0","publint":"^0.3.24","commitizen":"^4.3.2","size-limit":"^13.0.3","typescript":"~6.0.3","lint-staged":"^17.5.0","tools-config":"^0.4.0","@size-limit/file":"^13.0.3","typescript-eslint":"^8.69.0","@size-limit/esbuild":"^13.0.3","@vitest/coverage-v8":"^5.0.0","@arethetypeswrong/cli":"^0.18.5","cz-conventional-changelog":"^3.3.0"},"_npmOperationalInternal":{"tmp":"tmp/fetch-fun_0.14.1_1788881297989_0.991242491899073","host":"s3://npm-registry-packages-npm-production"}},"0.15.0":{"name":"fetch-fun","version":"0.15.0","description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","main":"dist/index.cjs","module":"dist/index.mjs","types":"dist/types/index.d.ts","exports":{".":{"import":{"types":"./dist/types/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/types/index.d.ts","default":"./dist/index.cjs"}},"./openapi":{"import":{"types":"./dist/types/openapi.d.mts","default":"./dist/openapi.mjs"},"require":{"types":"./dist/types/openapi.d.ts","default":"./dist/openapi.cjs"}}},"sideEffects":false,"engines":{"node":">=20.3"},"scripts":{"commit":"lint-staged && git-cz -n","prepare":"husky","build":"vite build && npm run build:types","build:types":"tsc -p tsconfig.build.json && node scripts/gen-dmts.mjs","dev":"vite","preview":"vite preview","coverage":"vitest run --coverage --coverage.reporter=lcov","lint":"eslint --fix src test","lint:pkg":"publint --strict","attw":"attw --pack . --profile node16","size":"size-limit","verify:tree-shaking":"node scripts/verify-tree-shaking.mjs","test":"vitest","start":"vitest watch"},"repository":{"type":"git","url":"git+https://github.com/wmzy/fetch-fun.git"},"keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"author":{"name":"wmzy"},"license":"MIT","bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"homepage":"https://github.com/wmzy/fetch-fun#readme","size-limit":[{"name":"full library: dist/index.mjs entry + shared chunk (min+gz)","path":"dist/index.mjs","gzip":true,"limit":"6 KB"},{"name":"minimal usage: create/url/fetchJSON/json (min+gz)","path":"src/index.ts","import":"{ create, url, fetchJSON, json }","gzip":true,"limit":"4 KB"},{"name":"openapi usage: createOpenapi (min+gz)","path":"src/openapi.ts","import":"{ createOpenapi }","gzip":true,"limit":"2 KB"}],"lint-staged":{"*.{js,mjs,cjs,ts}":["eslint --fix"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"devDependencies":{"@arethetypeswrong/cli":"^0.18.5","@size-limit/esbuild":"^13.0.3","@size-limit/file":"^13.0.3","@vitest/coverage-v8":"^5.0.0","commitizen":"^4.3.2","cz-conventional-changelog":"^3.3.0","eslint":"^10.10.0","husky":"^9.1.7","lint-staged":"^17.5.0","publint":"^0.3.24","size-limit":"^13.0.3","tools-config":"^0.4.0","typescript":"~6.0.3","typescript-eslint":"^8.69.0","vite":"^8.2.2","vitest":"^5.0.0"},"gitHead":"2045b7e2ccc45fe952a4c4ecf954ec5f80c9f6fa","_id":"fetch-fun@0.15.0","_nodeVersion":"22.23.2","_npmVersion":"11.19.1","dist":{"integrity":"sha512-CDoGdJJVGBbuGYRSwd1ao//uTF56DasOA7zlTFcGbY6OAjmnlbgSfiGrszuBsxaH55BtzaxHf6HtBWAlJmqNAA==","shasum":"99b34570128b257d4039dfa125b60e0a116d3abc","tarball":"https://registry.npmjs.org/fetch-fun/-/fetch-fun-0.15.0.tgz","fileCount":47,"unpackedSize":884060,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/fetch-fun@0.15.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDkQovK6aPJyRaSQzqvHVQ90p6cbD6G0dc5IHkRxOUrXgIgeFWH/ABl3hEOQaNfQH7UNKSc067ZkQhYMBUmwIqQMvs="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c800e07e-8ca3-4dc3-b556-9554e8d3aff3"}},"directories":{},"maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/fetch-fun_0.15.0_1788881860298_0.30266157147772454"},"_hasShrinkwrap":false}},"time":{"created":"2019-09-27T03:39:01.512Z","modified":"2026-09-08T15:37:40.897Z","0.1.0":"2019-09-27T03:39:01.659Z","0.2.0":"2025-02-12T13:13:16.503Z","0.2.1":"2025-02-12T13:18:48.386Z","0.3.0":"2025-02-14T08:32:14.798Z","0.3.1":"2025-02-18T02:14:15.997Z","0.3.2":"2025-02-27T10:50:22.116Z","0.3.3":"2025-02-27T12:37:46.543Z","0.4.0":"2026-03-09T16:35:18.231Z","0.4.1":"2026-03-27T15:06:36.882Z","0.4.2":"2026-03-28T03:12:55.451Z","0.5.0":"2026-08-20T16:31:59.249Z","0.6.0":"2026-08-20T17:55:04.105Z","0.7.0":"2026-08-21T11:38:19.699Z","0.8.0":"2026-08-22T08:24:39.600Z","0.8.1":"2026-08-22T17:08:04.821Z","0.9.0":"2026-08-24T02:46:32.066Z","0.10.0":"2026-08-26T03:22:33.870Z","0.11.0":"2026-08-31T02:58:41.742Z","0.11.1":"2026-09-02T10:12:07.724Z","0.12.0":"2026-09-03T18:52:56.454Z","0.12.1":"2026-09-03T19:01:07.907Z","0.12.2":"2026-09-06T03:33:47.887Z","0.13.0":"2026-09-07T13:14:42.518Z","0.14.0":"2026-09-08T11:28:40.240Z","0.14.1":"2026-09-08T15:28:18.149Z","0.15.0":"2026-09-08T15:37:40.440Z"},"bugs":{"url":"https://github.com/wmzy/fetch-fun/issues"},"author":{"name":"wmzy"},"license":"MIT","homepage":"https://github.com/wmzy/fetch-fun#readme","keywords":["fetch","http","http-client","functional","pipe","middleware","typed","standard-schema","retry","timeout"],"repository":{"type":"git","url":"git+https://github.com/wmzy/fetch-fun.git"},"description":"Functional fetch toolkit: pipeable config functions over a plain options object, typed data flow, Standard Schema validation, smart retry and per-attempt timeout. Zero dependencies.","maintainers":[{"name":"wmzy","email":"1256573276@qq.com"}],"readme":"# Fetch Fun\n\n[![npm version](https://badge.fury.io/js/fetch-fun.svg)](https://badge.fury.io/js/fetch-fun)\n[![Build Status](https://github.com/wmzy/fetch-fun/actions/workflows/ci.yml/badge.svg)](https://github.com/wmzy/fetch-fun/actions)\n[![Coverage Status](https://coveralls.io/repos/github/wmzy/fetch-fun/badge.svg?branch=main)](https://coveralls.io/repos/github/wmzy/fetch-fun?branch=main)\n\nA functional fetch toolkit built on one composition protocol: **any function of the shape `(o, ...args) => o'` is an extension point**. Config functions, middlewares, executors, and your own helpers are all just pipeable functions over a plain options object — no class hierarchy, no hidden state, zero runtime dependencies. The small footprint is enforced, not estimated: CI runs size-limit budgets plus a tree-shaking verification, so a typical `create` + `url` + `fetchJSON` + `json` app stays ≈2 kB min+gzip and the full client ≈5 kB.\n\n## Why fetch-fun (vs ky / ofetch / wretch / up-fetch)\n\n| Dimension | fetch-fun | ky / ofetch / wretch / up-fetch |\n| --- | --- | --- |\n| Composition model | Everything is a plain pipeable function `(o, ...args) => o'` — config functions, executors, and your own helpers alike; middlewares order declaratively (`outer` / `inner` / `NORMAL`) | Instance options + hooks (ky), wrapper fn + interceptors (ofetch), fluent chain + addons (wretch), one builder fn + lifecycle hooks (up-fetch) |\n| Tree-shaking | 0 deps, `sideEffects: false`, independent named exports — **enforced by CI** (size-limit + tree-shaking checks): ≈2 kB min+gzip for a typical app, ≈5 kB for the full client | Mostly single-entry units — ky ships retry/hooks/progress with every import, ofetch and up-fetch (~1.6 kB) bundle as one unit; only wretch keeps unused addons out |\n| Errors | `fetch` never throws on status; typed `HTTPError` / `NetworkError` / `TimeoutError` / `ValidationError`, all JSON-serializable via `toJSON()`; `mapError` last-hop transformation | The others throw on non-2xx by default with varying escape hatches; typed classes, serialization, and transformation differ per library |\n| Type inference | The reader's return type flows into `fetchData`; `validate` converges to the schema's Standard Schema output; query keys tracked at type level | Generics at call sites; schema-output typing in ky and up-fetch |\n| Retry & timeouts | Method/status-aware retry with capped `Retry-After` and jittered backoff, lazy per-attempt `timeout`, whole-request `totalTimeout` | Retry with backoff in ky/ofetch/up-fetch (bring-your-own in wretch); total-over-retries timeouts only in ky |\n| Built-in extras | SSE reader (`events` + per-frame `onEvent`), upload/download `withProgress`, dynamic auth suppliers (`withAuth(() => token)`) — each opt-in and tree-shaking-isolated | ofetch v2 (alpha) auto-detects event streams; up-fetch has streaming hooks; ky ships progress but no SSE; wretch covers both via addons |\n\nThat table is the short version. The full 19-dimension matrix — error serialization, dynamic auth, query serialization, progress models, Node.js baselines, against exact competitor versions (ky 2.0.2, ofetch 1.5.1 / v2 alpha, wretch 3.0.9, up-fetch 2.6.0) — lives in [COMPARISON.md](COMPARISON.md).\n\n## Table of Contents\n\n- [Why fetch-fun](#why-fetch-fun-vs-ky--ofetch--wretch--up-fetch)\n  - [Full comparison matrix](COMPARISON.md)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Core Concept: the pipe protocol](#core-concept-the-pipe-protocol)\n- [Config Functions Reference](#config-functions-reference)\n  - [path — typed placeholder interpolation](#path--typed-placeholder-interpolation)\n  - [timeout — lazy, per-attempt budget](#timeout--lazy-per-attempt-budget)\n  - [totalTimeout — whole-request budget](#totaltimeout--whole-request-budget)\n  - [retry — decision matrix](#retry--decision-matrix)\n  - [validate — Standard Schema validation](#validate--standard-schema-validation)\n- [Executors: fetch / fetchData / fetchJSON](#executors-fetch--fetchdata--fetchjson)\n- [Errors](#errors)\n  - [Serializable errors (toJSON)](#serializable-errors-tojson)\n  - [mapError — last-hop error transformation](#maperror--last-hop-error-transformation)\n- [Middleware and the Positioning System](#middleware-and-the-positioning-system)\n- [Type Inference](#type-inference)\n- [OpenAPI-typed clients](docs/openapi.md)\n- [Recipes: data libraries, auth, testing](docs/recipes.md)\n- [Utilities and Advanced API](#utilities-and-advanced-api)\n- [Versioning](#versioning)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Requirements\n\n- Node.js >= 18 (native `fetch`), or any modern browser. `AbortSignal.any`/`AbortSignal.timeout` (Node.js >= 20.3) are used when present and gracefully fall back to an equivalent manual `AbortController` composition on older runtimes.\n- Native `fetch`.\n\n## Installation\n\n```bash\nnpm install fetch-fun\n```\n\nor\n\n```bash\npnpm add fetch-fun\n```\n\n## Quick Start\n\n```typescript\nimport * as ff from 'fetch-fun';\n\n// A client is just a plain options object with a pipe method.\nconst client = ff\n  .create({ baseUrl: 'https://api.example.com' })\n  .pipe(ff.accept, 'application/json');\n\n// GET: describe the request, then execute it.\nconst users = await client\n  .pipe(ff.url, '/users')\n  .pipe(ff.querySet, 'page', '1')\n  .pipe(ff.timeout, 5000)\n  .pipe(ff.retry, 2)\n  .pipe(ff.fetchJSON<User[]>);\n\n// POST with a JSON body (jsonBody sets body AND Content-Type).\nconst created = await client\n  .pipe(ff.url, '/users')\n  .pipe(ff.method, 'POST')\n  .pipe(ff.jsonBody, { name: 'John', email: 'john@example.com' })\n  .pipe(ff.fetchJSON);\n```\n\nNon-2xx responses reject `fetchJSON`/`fetchData` with an `HTTPError`:\n\n```typescript\nimport * as ff from 'fetch-fun';\n\ntry {\n  const user = await client.pipe(ff.url, '/users/42').pipe(ff.fetchJSON);\n} catch (e) {\n  if (e instanceof ff.HTTPError) {\n    console.log(e.response.status); // e.g. 404\n    console.log(e.data); // parsed error body, e.g. { message: 'Not Found' }\n    console.log(e.request?.url); // best-effort reconstructed Request\n  }\n}\n```\n\nOne naming caveat — three different things are called `fetch` here:\n\n- `ff.fetch(o)` is the **executor**: it consumes the options object and returns `Promise<Response>`.\n- the `fetch` option in `create({ fetch })` is the **injected implementation**: a custom `typeof globalThis.fetch` used under the hood.\n- `globalThis.fetch` is the **native** fetch API the other two build on.\n\nSame name, three roles — when mixing them, make sure you know which one you are holding.\n\n`json` is overloaded the same way, across the request/response divide:\n\n- the third argument of the method sugar — `post(o, path, json)` — is the **request body**: stringified and sent with a `Content-Type` (`jsonBody` semantics).\n- `ff.json(o)` is the **response reader**: it parses the body that comes back.\n- `ff.fetchJSON(o)` is the **executor**: it adds the `json` reader itself and resolves the parsed value.\n\n`client.pipe(ff.post, '/users', { name: 'Ada' })` sends JSON; `client.pipe(ff.json)` reads it back. One word, both directions — check which side you are holding.\n\n## Core Concept: the pipe protocol\n\n`create()` returns `Options & Pipe`. `pipe`, `add`, and `with` are three aliases for the same operation:\n\n```typescript\nconst piped = client.pipe(ff.url, '/users');   // calls url(client, '/users')\nconst added = client.add(ff.url, '/users');    // identical\nconst with_ = client.with(ff.url, '/users');   // identical\n```\n\nEvery config function has the shape `(o, ...args) => o'` — it takes the current options object and returns a new one. That is the entire framework:\n\n- Built-in config functions (`url`, `jsonBody`, `timeout`, ...) are just functions you can call directly: `url({ url: '/a' }, '/b')`.\n- Your own helpers compose with zero registration: `const page = (o: Options, n: string) => querySet(o, 'page', n);`\n- Middlewares are functions `(fetchFn, instance) => fetchFn`, added through `use`.\n- Executors terminate the chain and return a `Promise`.\n\n## Config Functions Reference\n\n| Function | Purpose | Key parameters |\n| --- | --- | --- |\n| `url(o, path)` | Set the request path (joined with `baseUrl` at fetch time) | `path: string` |\n| `baseUrl(o, base)` | Set the base prefix for all requests; slash-normalized join, absolute `url` bypasses it | `base: string` |\n| `appendUrl(o, path)` | Append a segment to the existing `url` (typed template concat) | `path: string` |\n| `path(o, template, params)` | Set the request path by filling `{name}` placeholders in a template — each value `encodeURIComponent`-ed; the template's placeholders become the **required** keys of `params` at the type level | `template: string`, `params: Record<string, string \\| number>` |\n| `query(o, params)` | **Replace** query params | `params`: string / record / tuple array / `URLSearchParams` — values `string \\| number \\| boolean` |\n| `mergeQuery(o, params)` | Merge into existing query params | same input as `query` |\n| `querySet(o, name, value)` | Set one param (replaces existing value); key and value tracked at type level (`querySet(o, 'page', 1)` → `{ page: '1' }`) | `name`, `value: string \\| number \\| boolean` |\n| `queryAppend(o, name, value)` | Append one param (duplicates allowed); repeated keys become arrays at type level | `name`, `value: string \\| number \\| boolean` |\n| `method(o, m)` | Set the HTTP method | `'GET' \\| 'POST' \\| ... \\| string` |\n| `get(o, path?, json?)` | Method sugar: set method `GET`, optionally the path and a JSON body (`jsonBody` semantics) in one step | `path?: string`, `json?: unknown` |\n| `post(o, path?, json?)` | Same sugar for `POST` | same |\n| `put(o, path?, json?)` | Same sugar for `PUT` | same |\n| `patch(o, path?, json?)` | Same sugar for `PATCH` | same |\n| `del(o, path?, json?)` | Same sugar for `DELETE` (named `del` — `delete` is a reserved word) | same |\n| `head(o, path?, json?)` | Same sugar for `HEAD` | same |\n| `headers(o, h)` | **Replace** all headers (`Headers` instances and tuple arrays are normalized into a plain record) | `h: Record<string, string> \\| Headers \\| [string, string][]` |\n| `header(o, name, value)` | Set one header (merges) | `name`, `value: string` |\n| `auth(o, type, credentials)` | Set `Authorization: ${type} ${credentials}` | `'Basic' \\| 'Bearer' \\| 'Digest' \\| string` |\n| `accept(o, mime)` | Set the `Accept` header | `mime: string` |\n| `contentType(o, type)` | Set the `Content-Type` header | `type: string` |\n| `body(o, data)` | Set a raw request body of any kind | `data: BodyInit \\| null` |\n| `jsonBody(o, data)` | `JSON.stringify` the body and set `Content-Type: application/json` | `data: unknown` |\n| `signal(o, s)` | Set an `AbortSignal` for cancellation | `s: AbortSignal` |\n| `timeout(o, ms)` | Set a **lazy** per-attempt timeout budget (`timeoutMs`) | `ms: number` |\n| `totalTimeout(o, ms)` | Set a **lazy** whole-request timeout budget (`totalTimeoutMs`) covering the first attempt, all retries, and backoff waits | `ms: number` |\n| `retry(o, maxRetries, opts?)` | Add the smart retry middleware | `maxRetries`, [`RetryOptions`](#retry--decision-matrix) |\n| `mapResponse(o, mapper)` | Add a middleware mapping `(res, options) => Response` | `mapper` |\n| `checkError(o, check)` | Add a middleware that inspects `res` and may throw | `check: (res) => void \\| Promise<void>` |\n| `mapError(o, mapper)` | Add a last-hop error mapper — its return value is what `fetchData`/`fetchJSON` throw (see [Errors](#maperror--last-hop-error-transformation)) | `mapper: (e: unknown, ctx: MapErrorContext) => unknown` |\n| `data(o, reader)` | Add a response reader; its return value becomes the request's data | `reader: (res) => unknown` |\n| `json(o, parseJson?)` | Reader: parse the response body as JSON (does **not** touch request headers); an empty body (`204`/`205`/`HEAD`, …) resolves `undefined` — `parseJson` is never called for empty bodies | `parseJson?: (raw: string) => unknown` — custom parser, e.g. `JSON.parse` with a reviver to revive `Date`s; its return type flows into `fetchData`'s inference |\n| `text(o)` | Reader: read the body as text | — |\n| `blob(o)` | Reader: read the body as a `Blob` | — |\n| `arrayBuffer(o)` | Reader: read the body as an `ArrayBuffer` | — |\n| `formData(o)` | Reader: read the body as a `FormData` | — |\n| `events(o, onEvent?)` | Reader: parse the body as a Server-Sent Events stream — each frame is passed to `onEvent` the moment its terminating blank line arrives, and `fetchData` resolves to the complete `SSEEvent[]` once the stream ends. Full wire-format framing: leading BOM, `\\r\\n`/`\\r`/`\\n` line endings, `:` comments, multi-line `data:` (joined with `\\n`), `id:`, numeric `retry:`, and a trailing frame missing its blank line. Non-2xx responses still throw `HTTPError`; reconnection policy stays with you (see [docs/recipes.md](docs/recipes.md) for the Last-Event-ID loop) | `onEvent?: (e: SSEEvent) => void` — annotate the parameter (`(e: SSEEvent) => …`), as with `json`'s parser, so the generic pipe overload applies |\n| `validate(o, schema \\| factory)` | Attach a Standard Schema v1 schema — or a `(client) => schema` factory resolved per request with the merged client; parsed data is validated and replaced by its output | `schema: StandardSchema \\| (client: T) => StandardSchema \\| undefined` |\n| `use(o, mw)` | Add one middleware (function or `{ name, outer, inner, middleware }` config) | `mw: MiddlewareInput` |\n| `middlewares(o, list)` | **Replace** the middleware list | `list: MiddlewareInput[]` |\n| `context(o, ctx)` | Set the business-data slot carried on the client (replaces a previous one); stripped from `RequestInit`, readable in middleware / mappers / a `validate` factory / `mapError` (`ctx.context`) | `ctx: const C` — the literal type flows through: `T & { context: C }` on the default unknown slot (assignable back to `T`), `Omit` replacement when `T` declared a narrow context |\n\nNotes:\n\n- URL building: `baseUrl` trailing slashes and `url` leading slashes collapse into a single `/`; an absolute `url` (own protocol) bypasses `baseUrl` entirely, and so does a protocol-relative `url` (`//cdn.example.com/x`) — it inherits the caller's protocol and is passed through untouched. `../` segments are kept verbatim in the join: there is no client-side URL resolution, the server sees and resolves them. `searchParams` are appended with `?` or `&` as needed. A `baseUrl` carrying its own query string is not supported — use `query`/`mergeQuery`.\n- `query` accepts anything the `URLSearchParams` constructor accepts, with `number`/`boolean` values stringified along the way (`{ page: 1 }` → `?page=1`). For nested/array serialization, serialize first with your preferred library (`qs`, `query-string`) and pass the string.\n- `json()` only configures **response** parsing; it no longer sets a request `Content-Type`. To send JSON use `jsonBody`, or set headers explicitly with `contentType`/`header`.\n\n### path — typed placeholder interpolation\n\n`path(o, template, params)` is `url` for templated routes: it fills every `{name}` placeholder in the template with `encodeURIComponent(params[name])` and sets the result as the `url` — replacing any previous one and joining with `baseUrl` at fetch time exactly like a plain `url` call. Because values are encoded, a param can never inject `/`, `?`, or `#` and escape its path segment.\n\nThe template is checked at compile time: its placeholders become the **required** keys of `params` — a missing key is a compile error, and an object literal with extra keys is rejected by excess property checking — so `'/articles/{slug}'` accepts exactly `{ slug }` and nothing else.\n\n```typescript\nconst article = await client\n  .pipe(ff.path, '/articles/{slug}', { slug }) // '/articles/hello-world'\n  .pipe(ff.fetchJSON<Article>);\n\n// values are URL-encoded, so they stay inside their segment\nclient.pipe(ff.path, '/files/{name}', { name: 'my report.pdf' });\n// url becomes '/files/my%20report.pdf'\n```\n\nAt runtime a missing or `undefined` param throws a `TypeError` naming the template and the missing parameter(s). Like every config function, the fill happens at pipe time — the error surfaces before any request is attempted.\n\n`path` composes with the rest of the URL toolkit: `baseUrl` joins underneath, `appendUrl` appends segments after the fill, and the query functions append after that:\n\n```typescript\nconst posts = await client // baseUrl: 'https://api.example.com'\n  .pipe(ff.path, '/users/{id}', { id: userId })\n  .pipe(ff.appendUrl, '/posts')\n  .pipe(ff.querySet, 'page', 2)\n  .pipe(ff.fetchJSON<Post[]>);\n// GET https://api.example.com/users/42/posts?page=2\n```\n\nThe standalone helper `fillPath(template, params): string` performs the same fill outside a pipe — handy for cache keys, router paths, or pre-building a `url()`:\n\n```typescript\nfillPath('/articles/{slug}', { slug: '你好 世界' });\n// '/articles/%E4%BD%A0%E5%A5%BD%20%E4%B8%96%E7%95%8C'\n```\n\n### timeout — lazy, per-attempt budget\n\n`timeout(o, ms)` only stores `timeoutMs` on the options — no timer starts until the request executes. Each attempt (including every retry attempt) then gets a **fresh** timeout signal, combined with your `signal` via `AbortSignal.any` (or an equivalent manual composition on runtimes predating it). Piping `timeout` is side-effect free, so a reused client always gets a full budget; a later `timeout` pipe overwrites an earlier one.\n\n```typescript\n// Each attempt of each request gets 5 seconds, counted from its own start\nconst res = await client\n  .pipe(ff.url, '/slow')\n  .pipe(ff.timeout, 5000)\n  .pipe(ff.retry, 2)\n  .pipe(ff.fetch);\n```\n\nA timeout abort is rethrown as `ff.TimeoutError` with the underlying `DOMException` as `cause`; user-initiated aborts (`AbortError`) propagate unchanged.\n\n### totalTimeout — whole-request budget\n\n`totalTimeout(o, ms)` stores `totalTimeoutMs` — lazily again: no timer starts until the request executes, and a later `totalTimeout` pipe overwrites an earlier one. At execution time a single `AbortSignal.timeout(ms)` wraps the fully applied middleware chain, outside retry, so the one budget covers the first attempt, every retry, and the backoff waits in between. When it elapses, the in-flight attempt is aborted and the request rejects with `ff.TimeoutError` carrying the budget (`Request timed out after 10000ms`); aborting through your own `signal` still propagates as the native `AbortError`.\n\n`totalTimeout` and per-attempt `timeout` compose independently — the outer total bounds the whole sequence, the inner budget bounds each attempt:\n\n```typescript\n// The whole request — 3 attempts and the backoff between them — must\n// finish within 10s; any single attempt that stalls for 3s fails faster\n// and lets retry start sooner.\nconst res = await client\n  .pipe(ff.url, '/flaky')\n  .pipe(ff.timeout, 3000)       // per-attempt: a fresh 3s budget on every try\n  .pipe(ff.retry, 2)            // up to 3 attempts with backoff in between\n  .pipe(ff.totalTimeout, 10000) // whole-request: one 10s budget over it all\n  .pipe(ff.fetch);\n```\n\nThis mirrors ky's `totalTimeout` option — a deadline over retries rather than per attempt — except here it is one more pipeable config function rather than an option flag.\n\n### retry — decision matrix\n\n`retry(o, maxRetries, opts?)` retries up to `maxRetries` times (the initial attempt is not counted), gated by method and failure kind:\n\n| Attempt outcome | Retried? |\n| --- | --- |\n| Resolved, status in `statuses` (default `408 425 429 500 502 503 504`), retryable method | ✅ Yes |\n| Resolved, other status (e.g. 404) | ❌ No — response returned as-is |\n| Rejected: `NetworkError` (transport failure) / `TimeoutError` / unknown error | ✅ Yes (retryable methods only) |\n| Rejected: `HTTPError` (from your `checkError`) with status in `statuses` | ✅ Yes |\n| Rejected: `HTTPError` with status **not** in `statuses` | ❌ No |\n| Rejected: `ValidationError` | ❌ No — deterministic, retrying cannot fix it |\n| Any outcome, method not in `methods` (default `GET HEAD OPTIONS TRACE PUT DELETE`) | ❌ Never |\n| Retries exhausted (`attempt >= maxRetries`) | ❌ Rethrows / returns |\n\nWhen `opts.shouldRetry` is provided, it **replaces** the two built-in decisions above — status-set membership for resolved responses and error classification for rejections — with your own predicate. Hard rules always win regardless of its answer: the method gate and the `maxRetries` budget are checked first, and `ValidationError` rejections are never retried.\n\n`RetryOptions`:\n\n| Option | Default | Meaning |\n| --- | --- | --- |\n| `statuses` | `[408, 425, 429, 500, 502, 503, 504]` | Statuses worth retrying; compared case-insensitively on resolved responses and thrown `HTTPError`s |\n| `methods` | `['GET', 'HEAD', 'OPTIONS', 'TRACE', 'PUT', 'DELETE']` | Idempotent allowlist; non-listed methods never retry (avoids duplicating side effects) |\n| `respectRetryAfter` | `true` | A parseable, non-past `Retry-After` header (integer seconds or HTTP-date) overrides backoff — consulted on the discarded response and on a thrown `HTTPError`'s response (e.g. from your `checkError`) alike |\n| `maxRetryAfter` | `30000` | Upper bound (ms) for waits honored from `Retry-After`; a server demanding more is clamped down to it — the retry still happens, just sooner. Only relevant when `respectRetryAfter` is true |\n| `shouldRetry` | — (built-in decisions) | Custom predicate `(attempt, { response? \\| error? }) => boolean \\| Promise<boolean>` that fully replaces the built-in retry decisions (see note above); `attempt` is 0-indexed |\n| `beforeRetry` | — (none) | Hook `({ attempt, error?, request?, response? }) => RequestInit \\| false \\| void \\| Promise<...>` run right before each retry attempt — after the gates decided a retry is worth it, before the backoff wait. Return a `RequestInit` patch to rewrite the next attempt (`headers` merge per name with the patch winning, other fields replace), `false` to give up and surface the failed outcome as-is, or nothing to retry unchanged. Async hooks are awaited. `error` is the rejection when the attempt threw; `response` is the failed response when one exists (the resolved retryable response, or a thrown `HTTPError`'s response — body still readable); `request` is a best-effort reconstructed `Request` |\n| `delay` | `{ initial: 1000, max: 10000, multiplier: 2 }` | Exponential backoff tuning; delays carry ±25% jitter |\n\n```typescript\n// Default policy on an idempotent request\nawait client.pipe(ff.url, '/flaky').pipe(ff.retry, 3).pipe(ff.fetchJSON);\n\n// Custom policy: also retry POST, only on 503, 5s initial delay\nawait client.pipe(ff.url, '/jobs').pipe(ff.method, 'POST')\n  .pipe(ff.retry, 3, {\n    methods: ['GET', 'POST'],\n    statuses: [503],\n    delay: { initial: 5000 },\n  })\n  .pipe(ff.fetchJSON);\n\n// Response/error-driven: consult the response body before retrying\nawait client.pipe(ff.url, '/report').pipe(ff.retry, 2, {\n  shouldRetry: async (attempt, { response, error }) => {\n    if (response)\n      return response.status === 503 &&\n        (await response.clone().json()).retryable === true;\n    return error instanceof ff.NetworkError; // transport failures, not timeouts\n  },\n});\n```\n\n**401 → refresh the token → replay** is one `beforeRetry` hook — no custom middleware. The hook runs after retry decided the 401 is worth another attempt, awaits your async refresh, and its returned `RequestInit` patch becomes the replayed request (headers merge per name, so swapping `Authorization` keeps `Content-Type` and friends):\n\n```typescript\nimport * as ff from 'fetch-fun';\n\nlet accessToken = await signIn(); // e.g. 'Bearer eyJhbGci...'\n\nconst api = ff\n  .create({ baseUrl: 'https://api.example.com' })\n  .pipe(ff.header, 'Authorization', `Bearer ${accessToken}`) // whatever signIn gave\n  .pipe(ff.retry, 1, {\n    statuses: [401, 429, 503], // the token-expiry 401 is retryable\n    delay: { initial: 250 },\n    beforeRetry: async ({ attempt, error, request, response }) => {\n      // Only the token-expiry path needs new credentials; everything else\n      // (429/503) just retries with the original request untouched.\n      if (response?.status !== 401) return; // void → retry unchanged\n      accessToken = await refreshAccessToken(); // POST /oauth/token, awaited\n      // The patch is merged into the next attempt: the replay goes out\n      // with the fresh token while the rest of the headers survive.\n      return { headers: { Authorization: `Bearer ${accessToken}` } };\n      // return false;  // ← instead: give up, surface the 401 as-is\n    },\n  });\n\n// First try: 401 → beforeRetry refreshes → replay: 200\nconst me = await api.pipe(ff.url, '/me').pipe(ff.fetchJSON);\n```\n\nThe hook also fires for rejections (a `checkError` that threw `HTTPError`) — then `error` is the thrown error and `response` the `HTTPError`'s response. Returning `false` stops the loop: the failed response is returned with its body intact, or the original error rethrown — exactly as an exhausted budget would surface it. The hook is never consulted when no retry would happen anyway (non-retryable method/status, `ValidationError`, exhausted `maxRetries`).\n\nBackoff waits are interruptible by the client's `signal`, and discarded retry responses have their bodies cancelled before the wait. An honored `Retry-After` never waits longer than `maxRetryAfter` (default 30s) — the value is clamped, not skipped.\n\n### validate — Standard Schema validation\n\n`validate(o, schema)` accepts any [Standard Schema v1](https://standardschema.dev) object — detected by duck typing (`~standard: { version: 1, validate }`), so Zod, Valibot, ArkType, and friends work with zero adapters and zero runtime dependencies. Validation runs after the data reader regardless of pipe order; it is skipped for non-2xx responses so `HTTPError` semantics stay intact.\n\n```typescript\nimport { z } from 'zod';\n\nconst UserSchema = z.object({\n  id: z.number(),\n  name: z.string(),\n});\n\nconst user = await client\n  .pipe(ff.url, '/users/1')\n  .pipe(ff.json)\n  .pipe(ff.validate, UserSchema)\n  .pipe(ff.fetchData); // Promise<{ id: number; name: string }>\n\n// A failing schema rejects with ff.ValidationError (e.issues, e.data)\n```\n\nOn success a transformed/defaulted schema output replaces the stored data; on failure `fetchData`/`fetchJSON` reject with a `ValidationError`. Passing anything that is not a Standard Schema v1 object throws a `TypeError` immediately.\n\n**Schema factories for client-dependent schemas.** When the schema depends on client state — an API version, a tenant, anything carried on the client — pass `(client) => schema` instead of a fixed object. The factory runs once per request at validation time with the *fully merged* client, so it sees options attached anywhere in the chain, including after `validate`:\n\n```typescript\nconst schemaFor = (v: 'v1' | 'v2') =>\n  v === 'v2'\n    ? z.object({ id: z.number(), nickname: z.string() })\n    : z.object({ id: z.number() });\n\nconst api = ff\n  .create({ baseUrl: 'https://api.example.com', context: { apiVersion: 'v2' } as const })\n  .pipe(ff.json)\n  .pipe(ff.validate, (c) => schemaFor(c.context.apiVersion)) // `c.context` is typed\n  .pipe(ff.url, '/users/1');\n\nawait api.pipe(ff.fetchData); // Promise<{ id: number; nickname: string }>\n```\n\nA factory returning `undefined` (or `null`) skips validation for that request — the opt-out for schema-less endpoints on a shared validated chain. Any other non-schema return throws a `TypeError` when it runs — at fetch time, since its result only exists then.\n\n**Business data via `context`.** The client doubles as a plain options object; `context` is its sanctioned slot for per-request business data (tenant ids, trace ids, feature flags). Attach it via `create({ context })` or the `context(o, ctx)` config function:\n\n```typescript\nconst api = ff\n  .create({ baseUrl: 'https://api.example.com' })\n  .pipe(ff.context, { tenantId: 't-42' }) // replaces any previous context\n  .pipe(ff.json);\n```\n\nIt is a fetch-fun option, not a `RequestInit` field: `toFetchParams` strips it before calling fetch — it never reaches fetch and never trips the dev-mode unknown-option warning. After the request it stays readable in middleware factories, `mapResponse` mappers, a `validate` factory, and `mapError` mappers (`ctx.context`).\n\n## Executors: fetch / fetchData / fetchJSON\n\n| | `fetch(o)` | `fetchData<T>(o)` | `fetchJSON<T>(o)` |\n| --- | --- | --- | --- |\n| Non-2xx status | Resolves the `Response` — **never throws on status** | Throws `HTTPError` | Throws `HTTPError` |\n| Returns | `Promise<Response>` | `Promise<T>` (parsed data) | `Promise<T>` (parsed JSON) |\n| Reader needed | No | Yes — configure `json` / `text` / `blob` / `events` / `data` first | No — `fetchJSON` adds the `json` reader itself |\n| Transport / timeout / validation errors | Can still throw `NetworkError` / `TimeoutError`; `ValidationError` on 2xx | Same + `HTTPError` | Same + `HTTPError` |\n\n```typescript\n// fetch: the raw escape hatch — inspect statuses yourself\nconst res = await client.pipe(ff.url, '/maybe-missing').pipe(ff.fetch);\nif (res.ok) { /* ... */ }\n\n// fetchData: parse-then-throw semantics, with the parsed error body attached\ntry {\n  const list = await client.pipe(ff.url, '/users').pipe(ff.json).pipe(ff.fetchData);\n} catch (e) {\n  if (e instanceof ff.HTTPError) console.log(e.data); // parsed error body, if any\n}\n```\n\nAll executors require `url` to be set (`Fetchable`). A custom `fetch` implementation can be injected via the `fetch` option (`create({ fetch: myFetch })`).\n\nOne `no-cors` caveat: such requests resolve to opaque responses (`type: 'opaque'`, `status: 0`, `ok: false`). `fetchData`/`fetchJSON` deliberately do **not** throw `HTTPError` for them (matching ky 2.0) — the response is handed to your reader, and any failure to read the by-design-unreadable opaque body surfaces naturally from the reader instead. For `no-cors` requests, consider the raw `fetch()` escape hatch and inspect the response yourself.\n\n## Errors\n\nAll four classes extend `Error` and are exported from the package root.\n\n| Class | Thrown by | Fields |\n| --- | --- | --- |\n| `HTTPError` | `fetchData` / `fetchJSON` on `!res.ok` | `response: Response` — the failed response; `status: number` — shorthand for `response.status`; `request?: Request` — best-effort reconstructed request; `data?: unknown` — parsed error body when a reader (e.g. `json`) already ran; a non-2xx body the reader cannot parse (an HTML error page under `json`) resolves to `undefined`, so the `HTTPError` is still what you catch — never the reader's `SyntaxError`; `withMessage(msg)` — clone with the message replaced: created with the original as its prototype, so it inherits every field — `response`/`request`/`data`/`cause` plus anything a subclass or caller attached later — and keeps the `HTTPError` identity; the clone shares the original's `stack` instead of capturing a fresh one |\n| `NetworkError` | The innermost wrapper around the base fetch, when fetch itself rejects with a `TypeError` (DNS failure, connection refused, TLS error, offline) | `url?: string` — best-effort URL of the failed request; `cause` — the original `TypeError`; message reads like `GET https://api.example.com/x failed: network error` |\n| `TimeoutError` | The timeout layers — per-attempt `timeout` or whole-request `totalTimeout` — when the budget elapses | `cause` — the underlying `DOMException`; message includes the budget (`Request timed out after 5000ms`) |\n| `ValidationError` | `validate` on failing schema | `issues: readonly unknown[]` — the schema's issues (Zod/Valibot/ArkType objects); `data?: unknown` — the unvalidated data that was rejected |\n\n`NetworkError` wrapping sits directly around the base fetch — inside every middleware — so only the transport's own `TypeError`s are relabeled, and only when the signal hasn't aborted: errors thrown by user middlewares and user-initiated aborts keep their identity. `retry` still treats `NetworkError` as retryable.\n\n```typescript\nimport * as ff from 'fetch-fun';\n\ntry {\n  await client.pipe(ff.url, '/users/1').pipe(ff.validate, UserSchema).pipe(ff.fetchJSON);\n} catch (e) {\n  if (e instanceof ff.HTTPError) { /* 4xx/5xx: e.response.status, e.data */ }\n  else if (e instanceof ff.NetworkError) { /* transport failed: e.url, e.cause */ }\n  else if (e instanceof ff.TimeoutError) { /* budget elapsed: e.cause */ }\n  else if (e instanceof ff.ValidationError) { /* schema failed: e.issues, e.data */ }\n}\n```\n\n### Serializable errors (toJSON)\n\nAll four error classes implement `toJSON()`, so `JSON.stringify(err)` emits a plain, meaningful object instead of `{}` — the shape survives any JSON boundary: SSR → client hydration, web worker → main thread, `postMessage`, test snapshots. No live `Response`/`Request` reference is carried across:\n\n```typescript\n// catch (e) — any of the four classes\nJSON.stringify(e);\n// HTTPError       → { name, message, status, url, data }\n// NetworkError    → { name, message, url?, cause?: { name, message } }\n// TimeoutError    → { name, message, cause?: { name, message } }\n// ValidationError → { name, message, issues, data }\n```\n\nOn the receiving side, branch on the `name` field (`'HTTPError'` | `'NetworkError'` | `'TimeoutError'` | `'ValidationError'`). An `Error` cause is reduced to `{ name, message }`; anything else is dropped (`undefined`) so the object always serializes.\n\n### mapError — last-hop error transformation\n\n`mapError(o, mapper)` attaches an error mapper that runs as the very last hop before `fetchData`/`fetchJSON` throw to your code — the counterpart of ky's `beforeError` and up-fetch's `parseRejected`:\n\n```typescript\nclass NotFoundError extends Error {\n  constructor(readonly response: Response, cause: unknown) {\n    super(`Not found: ${response.url}`, { cause });\n  }\n}\n\nconst user = await client\n  .pipe(ff.url, '/users/42')\n  .pipe(ff.mapError, (e, ctx) =>\n    ctx.response?.status === 404 ? new NotFoundError(ctx.response, e) : e,\n  )\n  .pipe(ff.fetchJSON);\n```\n\nThe mapper has the shape `(e: unknown, ctx: MapErrorContext) => unknown`, where `MapErrorContext` (`{ response?: Response; request?: Request; context?: unknown }`) carries the failed `response` plus the best-effort reconstructed `request` only when the error is an `HTTPError`; `ctx.context` mirrors the client's business-data slot for **every** error type.\n\nThe most common mapping — rewrite the message from the parsed error body — is one line with `HTTPError.withMessage`: the clone is created with the original as its prototype — it inherits every field (`response`, `request`, `data`, `cause`, and anything a subclass or middleware attached after construction) and keeps the `HTTPError` identity, so downstream `instanceof` checks, `.status`, and `.data` all keep working (a global 401 → logout handler can still branch on `e.status`); the clone shares the original's `stack` rather than capturing a fresh one:\n\n```typescript\nconst user = await client\n  .pipe(ff.url, '/users/42')\n  .pipe(ff.mapError, (e) =>\n    e instanceof ff.HTTPError ? e.withMessage(errorText(e.data)) : e,\n  )\n  .pipe(ff.fetchJSON);\n```\n\nKey semantics:\n\n- **Every error type passes through** — `HTTPError`, `NetworkError`, `TimeoutError`, `ValidationError`, and errors thrown by user middlewares alike. The mapper's return value is thrown as-is; async mappers are awaited.\n- **`undefined` passes the original through** — a mapper that returns `undefined` (e.g. a branch that found nothing to map) rejects with the original error, never with `undefined` itself.\n- **A failing mapper never swallows the original** — if the mapper itself throws, its own error surfaces with the original attached as `cause` (an `Error` without one gains it; a non-`Error` thrown value is wrapped in an `Error` whose `cause` carries both).\n- **`retry` sees the original error** — the mapper runs after the whole middleware chain (including retry) has settled, so retry decisions are made on the unmapped error; only the finally thrown value is mapped.\n- **Piping `mapError` again replaces** the previous mapper — the same overwrite semantics as `timeout`.\n- **Only `fetchData`/`fetchJSON` map** — the raw `fetch()` escape hatch bypasses the mapper entirely and rejects with the original error.\n\n## Middleware and the Positioning System\n\nA middleware wraps the fetch function — the classic onion model:\n\n```typescript\nimport type { MiddlewareFn } from 'fetch-fun';\n\nconst timing: MiddlewareFn = (f, o) => async (...params) => {\n  const start = Date.now();\n  try {\n    return await f(...params);\n  } finally {\n    console.log(`${o.url} took ${Date.now() - start}ms`);\n  }\n};\n```\n\nAdd middlewares as a bare function or as a config object with declarative positioning:\n\n```typescript\nclient.pipe(ff.use, timing); // anonymous, lands in the NORMAL group\n\nclient.pipe(ff.use, {\n  name: 'trace',          // unique name others can position against\n  outer: ff.NORMAL,       // wraps everything positioned NORMAL (the default group)\n  middleware: timing,\n});\n```\n\n- `outer: X` — this middleware wraps `X` (runs before `X` on the way out, after `X` on the way back).\n- `inner: X` — this middleware is wrapped by `X`.\n- `NORMAL` — a virtual node anchoring the default position: anonymous middlewares keep pipe order inside it, `outer: NORMAL` middlewares precede it, `inner: NORMAL` middlewares follow it.\n\nBuilt-in middleware factories ship with reserved `builtin:*` names and positions:\n\n| Factory | Name | Position |\n| --- | --- | --- |\n| `withRetry(maxRetries, opts?)` | `builtin:retry` | — |\n| `withTimeout(ms)` | `builtin:timeout` | `inner` of `builtin:retry` — every retry attempt gets a fresh budget |\n| `withAuth(credentials, type?)` | `builtin:auth` | `inner` of `builtin:retry` — each attempt (re)applies the `Authorization` header; `credentials` may be a string or a supplier `() => string \\| null \\| undefined \\| Promise<...>` re-evaluated on every attempt; empty results (`''` / `null` / `undefined` / whitespace) skip the header and drop any inherited `Authorization` |\n| `withLogging(logger?)` | `builtin:logging` | `outer` of `NORMAL` — logs request/response/error with duration |\n| `withProgress(opts?)` | `builtin:progress` | `inner` of `NORMAL` — inside the default group (and therefore inside retry): every (re)try reports its own progress from zero |\n\n```typescript\nconst res = await client\n  .pipe(ff.use, ff.withLogging())     // outermost of the NORMAL group\n  .pipe(ff.use, ff.withRetry(3))      // 'builtin:retry'\n  .pipe(ff.use, ff.withTimeout(5000)) // inner of retry → per-attempt budget\n  .pipe(ff.use, ff.withAuth(() => tokenStore.get())) // inner of retry → token re-read per attempt\n  .pipe(ff.url, '/flaky')\n  .pipe(ff.fetch);\n```\n\n`withAuth` also accepts a **token supplier** in place of a static string: `withAuth(() => store.getToken())`, or an async `withAuth(async () => await refreshJwt())`. The supplier is awaited once per request — and again on every retry attempt — so rotated or refreshed tokens are picked up without writing a custom middleware. As with the config-side `auth(o, type, credentials)`, the header value is the literal `${type} ${credentials}` with no extra encoding (pass pre-encoded base64 for `Basic`). A supplier that returns an empty value (`''`, `null`, `undefined`, or whitespace) sends no `Authorization` header at all — an inherited default (e.g. a stale token set via `header()` on a shared client) is deleted, so a logged-out supplier can simply `return token ?? undefined`.\n\n`withProgress` reports progress while bodies stream. Downloads are observed by piping `response.body` through a counting `TransformStream`; callbacks fire per chunk — after `fetch` has already resolved, so consume the body to drive them:\n\n```typescript\n// percent ∈ [0, 1], total from Content-Length; without Content-Length,\n// total stays 0 and percent stays 0 while transferred still counts bytes\nconst res = await client\n  .pipe(ff.use, ff.withProgress({\n    onDownloadProgress: ({ percent, transferred, total }) =>\n      console.log(`${transferred}/${total || '?'} bytes (${(percent * 100).toFixed(1)}%)`),\n  }))\n  .pipe(ff.url, '/assets/report.zip')\n  .pipe(ff.fetch);\n\nawait res.blob(); // reading the body drives the callbacks\n```\n\nNull-body responses (`204`/`205`/`HEAD`, …) are returned untouched and produce no callbacks. `onUploadProgress` fires out of the box only when the request `init.body` is a `ReadableStream` — every other body shape passes through uncounted rather than being serialized just to count it; a stream's length is unknown, so `total` is `0` there. Opt in with `wrapBody: true` to observe the other shapes too: `string`, `Blob`, `ArrayBuffer`, `ArrayBufferView`, and `URLSearchParams` bodies are wrapped into a counting stream, so `total` becomes the body's real byte size and `percent` turns meaningful. Because a stream body loses the implicit `Content-Type` that native `fetch` would have set, the defaults for `string` (`text/plain;charset=UTF-8`) and `URLSearchParams` (`application/x-www-form-urlencoded;charset=UTF-8`) are restored — only when the request headers set no `Content-Type` explicitly — and `duplex: 'half'` is set automatically, never overriding a caller-provided value. `FormData` is never wrapped (it cannot be sized without serializing it), and a bare `ReadableStream` keeps the counting path above with `total: 0` — for it, native `fetch` requires `duplex: 'half'`, which callers set themselves.\n\nOrdering rules (applied by `sortMiddlewares`, a topological sort):\n\n- **Duplicate names throw at composition time** — piping a middleware whose explicit name is already on the chain throws immediately in `use` / `middlewares` (`Duplicate middleware name \"...\"`), including a second `builtin:retry`; use `pipe(retry, n)` / bare functions, which generate unique anonymous names, when you need several of a kind.\n- **Cycles throw** — `Middleware dependency cycle detected: a -> b -> a` (resolved at execution time).\n- **Dangling constraints are ignored** — an `outer`/`inner` referencing an unregistered name (other than `NORMAL`) orders nothing and never creates a cycle.\n\nChains are **append-only**: every `use` adds a layer, derived clients inherit the parent's chain unchanged, and nothing replaces a middleware by name. To vary a layer's policy per client — say, retry 5 times instead of 3 — factor the shared construction rather than overriding on a derived client:\n\n```typescript\nconst makeClient = (retries: number) =>\n  create().pipe(use, withRetry(retries)).pipe(use, withAuth(token));\nconst normal = makeClient(3), aggressive = makeClient(5);\n```\n\nPositioning is resolved at execution time from the final middleware list, so it holds no matter the order middlewares were added in.\n\n## Type Inference\n\nData types travel through the pipe as phantom types — no casts needed at the call site.\n\n**The reader's return type flows into `fetchData`.** `data(o, reader)` brands the options with a `ReaderData` phantom type, and `fetchData` resolves `Promise<Awaited<R>>`:\n\n```typescript\nconst feed = await client\n  .pipe(ff.url, '/feed.xml')\n  .pipe(ff.data, async (res) => parseXML(await res.text()) as Feed)\n  .pipe(ff.fetchData); // Promise<Feed> — inferred from the reader\n```\n\n**Explicit type parameters** go on the executors:\n\n```typescript\nconst users = await client\n  .pipe(ff.url, '/users')\n  .pipe(ff.fetchJSON<User[]>); // Promise<User[]>\n```\n\n**`validate` converges the type to the schema's output.** After `pipe(json).pipe(validate, schema)`, `fetchData` returns the schema's Standard Schema `Output` type — works with any Standard Schema v1 vendor (Zod, Valibot, ArkType):\n\n```typescript\nconst UserSchema = z.object({ id: z.number(), name: z.string() });\n\nconst user = await client\n  .pipe(ff.url, '/users/1')\n  .pipe(ff.json)\n  .pipe(ff.validate, UserSchema)\n  .pipe(ff.fetchData); // Promise<{ id: number; name: string }>\n```\n\n**Query keys are tracked at the type level.** `querySet`/`queryAppend` accumulate `{ key: value }` (repeated keys become tuple types) on the `searchParams` phantom, and `createQuery` builds a typed `URLSearchParams` for IDE hints:\n\n```typescript\nconst q = ff.createQuery({ page: '1', limit: '10' } as const);\n// q._type is { page: '1', limit: '10' } — visible in IDE hover\n```\n\n## OpenAPI-typed clients\n\nGrafting `openapi-typescript`'s generated `paths` types onto the pipe — typed paths (with `{param}` template substitution), methods, request bodies, and success-response shapes via the `fetch-fun/openapi` sub-entry (`createOpenapi<paths>()` binding `typedUrl`/`typedPath`/`typedMethod`/`typedJsonBody`/`typedJson`, ~1 KB gzip) — now lives in [docs/openapi.md](docs/openapi.md), including the comparison with `openapi-fetch`.\n\n## Recipes: data libraries, auth, testing\n\nShort, focused recipes — TanStack Query / SWR, 401 → refresh → retry, Nuxt / Vue, Next.js RSC, msw / vitest testing, Zod 4 / Valibot validation, and streaming responses / Server-Sent Events — now live in [docs/recipes.md](docs/recipes.md).\n\n### The SPA default: timeout + retry + auth\n\nEvery SPA wants the same three protections, and they are two pipes away — no aggregate `spa()` factory needed, the defaults are already right:\n\n```typescript\nconst client = ff\n  .create({ baseUrl })\n  .pipe(ff.use, ff.withTimeout(10000)) // per-attempt budget; each retry gets a fresh one\n  .pipe(ff.use, ff.withRetry(2));      // default retries idempotent methods on transient statuses (408/425/429/500/502/503/504)\n```\n\nWhy these defaults fit a browser app:\n\n- **`withTimeout`** — without a budget a request on a flaky network hangs forever; with a blocking router loader that is a frozen page whose only escape is canceling the navigation. `withTimeout(10000)` rejects with `ff.TimeoutError` after 10 s, every attempt.\n- **`withRetry(2)`** — retries at most twice, and only what is safe: idempotent methods (`GET`/`HEAD`/`PUT`/`DELETE`/`OPTIONS`/`TRACE`) failing transiently (`408`/`425`/`429`/`500`/`502`/`503`/`504`, network errors, `TimeoutError`). A `POST` or a `404` never replays. Tune with `ff.withRetry(2, { methods: ['GET', 'HEAD'], ... })`.\n- **`withAuth`** — add it on the same client for token injection: `ff.withAuth(() => tokenStore.token, 'Bearer')`. The supplier re-runs on every attempt, and an empty token sends no `Authorization` header at all (logged-out requests stay anonymous).\n- **Cancellation stays yours** — `Options` is a `RequestInit` superset, so a per-call `signal` goes straight through: `client.pipe(ff.get, '/x').pipe(ff.signal, abortController.signal)`. Timeout, retry, and your signal compose via `AbortSignal.any`.\n\n## Utilities and Advanced API\n\n| Export | Purpose |\n| --- | --- |\n| `create(o?)` | Create a client (`Options & Pipe`) from initial options |\n| `toFetchParams(o)` | Convert a `Fetchable` to `[url, RequestInit]` (performs the baseUrl join); keys that are neither fetch-fun options nor `RequestInit` fields pass through to fetch silently — in development each one logs a `console.warn` naming it (silent in production) |\n| `applyMiddlewares(f, o)` | Sort and apply a configuration's middlewares to a fetch function |\n| `sortMiddlewares(entries)` | Topological sort of middleware entries (outer → inner); throws on duplicate names (also rejected eagerly by `use` / `middlewares`) and on cycles |\n| `normalizeMiddleware(input)` | Normalize a function or config object into a `MiddlewareEntry` |\n| `createRetry(maxRetries, opts?)` | Build the smart retry middleware as a bare `MiddlewareFn` |\n| `createRetryBase(beforeRetry)` | Build a retry middleware from a fully custom `(attempt, error, o) => Promise<void>` callback (reject to stop) |\n| `withRetry` / `withTimeout` / `withAuth` / `withLogging` / `withProgress` | Named + positioned built-in middleware factories (see above) |\n| `createQuery(input)` | Typed `URLSearchParams` factory (object / tuple array / string) |\n| `fillPath(template, params)` | Fill `{name}` placeholders in a path template, `encodeURIComponent`-ing each value; throws `TypeError` on missing/`undefined` params. `path()` uses it internally; params are typed via `PlaceholderParams<T>` |\n| `NORMAL` | Symbol anchoring the default middleware position |\n\nCommonly used types: `Options`, `Fetchable`, `Client`, `Method`, `Pipe`, `MiddlewareFn`, `MiddlewareInput`, `MiddlewareConfig`, `MiddlewareName`, `QueryType`, `TypedURLSearchParams`, `PlaceholderParams`, `StandardSchema`, `RetryOptions`, `MapErrorContext`, `ProgressOptions`, `ProgressState`, `NetworkError`, `SSEEvent` (a parsed SSE frame: `{ event, data, id?, retry? }`).\n\n## Versioning\n\nThis package follows [semantic versioning](https://semver.org/). Releases and their changelogs are generated automatically by [semantic-release](https://github.com/semantic-release/semantic-release) from [Conventional Commits](https://www.conventionalcommits.org/) — see the [GitHub releases page](https://github.com/wmzy/fetch-fun/releases) for the generated notes.\n\n## Contributing\n\nWe welcome contributions to Fetch Fun! If you have any ideas, suggestions, or bug reports, please open an issue on our [GitHub repository](https://github.com/wmzy/fetch-fun/issues).\n\nTo contribute code, please follow these steps:\n\n1. Fork the repository.\n2. Create a new branch (`git checkout -b feature-branch`).\n3. Make your changes and commit them (`git commit -m 'Add new feature'`).\n4. Push to the branch (`git push origin feature-branch`).\n5. Open a pull request.\n\nPlease ensure your code adheres to our coding standards and includes appropriate tests.\n\n## License\n\nThis project is licensed under the MIT License.\n","readmeFilename":"README.md"}