mirror of
https://github.com/tenrok/axios.git
synced 2026-06-20 20:00:40 +03:00
revert: transformrequest typing 10745 (#10810)
* Revert "chore: added clarifying docs for the type change (#10804)" This reverts commit25387ae1ce. * Revert "fix: transformRequest input typing (#10745)" This reverts commit694f1eca8c.
This commit is contained in:
+5
-30
@@ -320,39 +320,14 @@ declare namespace axios {
|
|||||||
|
|
||||||
type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders;
|
type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders;
|
||||||
|
|
||||||
/**
|
interface AxiosRequestTransformer {
|
||||||
* `transformRequest` is invoked as a left-fold pipeline: each function's return
|
(this: InternalAxiosRequestConfig, data: any, headers: AxiosRequestHeaders): any;
|
||||||
* value becomes the next function's `data` argument (see `lib/core/transformData.js`).
|
|
||||||
*
|
|
||||||
* The `D` generic describes the type of `data` entering the *first* transformer
|
|
||||||
* in the chain. Subsequent transformers in an array — and any user transformer
|
|
||||||
* that runs after axios's default `transformRequest` (which serializes objects
|
|
||||||
* to JSON, FormData, URLSearchParams, etc.) — may receive a serialized form
|
|
||||||
* (`string`, `Buffer`, `ArrayBuffer`, `FormData`, `URLSearchParams`,
|
|
||||||
* `Stream`, ...) rather than `D`. The final transformer in the chain is
|
|
||||||
* expected to return one of those serialized forms.
|
|
||||||
*
|
|
||||||
* For best results, type `D` only when supplying a single transformer that
|
|
||||||
* runs first, or accept that intermediate stages may need a runtime check.
|
|
||||||
*/
|
|
||||||
interface AxiosRequestTransformer<D = any> {
|
|
||||||
(this: InternalAxiosRequestConfig<D>, data: D, headers: AxiosRequestHeaders): any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
interface AxiosResponseTransformer {
|
||||||
* `transformResponse` is invoked as a left-fold pipeline: each function's
|
|
||||||
* return value becomes the next function's `data` argument.
|
|
||||||
*
|
|
||||||
* The `T` generic describes the type of `data` entering the *first* transformer
|
|
||||||
* in the chain — typically the raw response body (`string`, `ArrayBuffer`,
|
|
||||||
* `Buffer`, or `Stream` depending on `responseType`). Later transformers
|
|
||||||
* receive whatever the previous stage returned, so `T` is only accurate for
|
|
||||||
* the first call.
|
|
||||||
*/
|
|
||||||
interface AxiosResponseTransformer<T = any> {
|
|
||||||
(
|
(
|
||||||
this: InternalAxiosRequestConfig,
|
this: InternalAxiosRequestConfig,
|
||||||
data: T,
|
data: any,
|
||||||
headers: AxiosResponseHeaders,
|
headers: AxiosResponseHeaders,
|
||||||
status?: number
|
status?: number
|
||||||
): any;
|
): any;
|
||||||
@@ -496,7 +471,7 @@ declare namespace axios {
|
|||||||
method?: Method | string;
|
method?: Method | string;
|
||||||
baseURL?: string;
|
baseURL?: string;
|
||||||
allowAbsoluteUrls?: boolean;
|
allowAbsoluteUrls?: boolean;
|
||||||
transformRequest?: AxiosRequestTransformer<D> | AxiosRequestTransformer<D>[];
|
transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
|
||||||
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
|
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
|
||||||
headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;
|
headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;
|
||||||
params?: any;
|
params?: any;
|
||||||
|
|||||||
Vendored
+5
-30
@@ -138,39 +138,14 @@ export type RawAxiosResponseHeaders = Partial<RawAxiosHeaders & RawCommonRespons
|
|||||||
|
|
||||||
export type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders;
|
export type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders;
|
||||||
|
|
||||||
/**
|
export interface AxiosRequestTransformer {
|
||||||
* `transformRequest` is invoked as a left-fold pipeline: each function's return
|
(this: InternalAxiosRequestConfig, data: any, headers: AxiosRequestHeaders): any;
|
||||||
* value becomes the next function's `data` argument (see `lib/core/transformData.js`).
|
|
||||||
*
|
|
||||||
* The `D` generic describes the type of `data` entering the *first* transformer
|
|
||||||
* in the chain. Subsequent transformers in an array — and any user transformer
|
|
||||||
* that runs after axios's default `transformRequest` (which serializes objects
|
|
||||||
* to JSON, FormData, URLSearchParams, etc.) — may receive a serialized form
|
|
||||||
* (`string`, `Buffer`, `ArrayBuffer`, `FormData`, `URLSearchParams`,
|
|
||||||
* `Stream`, ...) rather than `D`. The final transformer in the chain is
|
|
||||||
* expected to return one of those serialized forms.
|
|
||||||
*
|
|
||||||
* For best results, type `D` only when supplying a single transformer that
|
|
||||||
* runs first, or accept that intermediate stages may need a runtime check.
|
|
||||||
*/
|
|
||||||
export interface AxiosRequestTransformer<D = any> {
|
|
||||||
(this: InternalAxiosRequestConfig<D>, data: D, headers: AxiosRequestHeaders): any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export interface AxiosResponseTransformer {
|
||||||
* `transformResponse` is invoked as a left-fold pipeline: each function's
|
|
||||||
* return value becomes the next function's `data` argument.
|
|
||||||
*
|
|
||||||
* The `T` generic describes the type of `data` entering the *first* transformer
|
|
||||||
* in the chain — typically the raw response body (`string`, `ArrayBuffer`,
|
|
||||||
* `Buffer`, or `Stream` depending on `responseType`). Later transformers
|
|
||||||
* receive whatever the previous stage returned, so `T` is only accurate for
|
|
||||||
* the first call.
|
|
||||||
*/
|
|
||||||
export interface AxiosResponseTransformer<T = any> {
|
|
||||||
(
|
(
|
||||||
this: InternalAxiosRequestConfig,
|
this: InternalAxiosRequestConfig,
|
||||||
data: T,
|
data: any,
|
||||||
headers: AxiosResponseHeaders,
|
headers: AxiosResponseHeaders,
|
||||||
status?: number
|
status?: number
|
||||||
): any;
|
): any;
|
||||||
@@ -392,7 +367,7 @@ export interface AxiosRequestConfig<D = any> {
|
|||||||
method?: StringLiteralsOrString<Method>;
|
method?: StringLiteralsOrString<Method>;
|
||||||
baseURL?: string;
|
baseURL?: string;
|
||||||
allowAbsoluteUrls?: boolean;
|
allowAbsoluteUrls?: boolean;
|
||||||
transformRequest?: AxiosRequestTransformer<D> | AxiosRequestTransformer<D>[];
|
transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
|
||||||
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
|
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
|
||||||
headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;
|
headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;
|
||||||
params?: any;
|
params?: any;
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const createTempFixture = (suiteRoot, repoRoot, name, sourcePath, tsconfig, packageJson) => {
|
const createTempFixture = (suiteRoot, name, sourcePath, tsconfig, packageJson) => {
|
||||||
const tempRoot = fs.mkdtempSync(path.join(suiteRoot, `.tmp-module-${name}-`));
|
const tempRoot = fs.mkdtempSync(path.join(suiteRoot, `.tmp-module-${name}-`));
|
||||||
const source = fs.readFileSync(sourcePath, 'utf8');
|
const source = fs.readFileSync(sourcePath, 'utf8');
|
||||||
|
|
||||||
fs.writeFileSync(path.join(tempRoot, 'index.ts'), source);
|
fs.writeFileSync(path.join(tempRoot, 'index.ts'), source);
|
||||||
fs.writeFileSync(path.join(tempRoot, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2));
|
fs.writeFileSync(path.join(tempRoot, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2));
|
||||||
|
|
||||||
if (repoRoot) {
|
|
||||||
const axiosFixturePath = path.join(tempRoot, 'node_modules', 'axios');
|
|
||||||
fs.mkdirSync(path.dirname(axiosFixturePath), { recursive: true });
|
|
||||||
fs.symlinkSync(repoRoot, axiosFixturePath, 'junction');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packageJson) {
|
if (packageJson) {
|
||||||
fs.writeFileSync(path.join(tempRoot, 'package.json'), JSON.stringify(packageJson, null, 2));
|
fs.writeFileSync(path.join(tempRoot, 'package.json'), JSON.stringify(packageJson, null, 2));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
import axios = require('axios');
|
|
||||||
|
|
||||||
type Payload = {
|
|
||||||
foo: string;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type OtherPayload = {
|
|
||||||
other: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
const transformer: axios.AxiosRequestTransformer<Payload> = function (data, headers) {
|
|
||||||
headers.setContentType('application/json');
|
|
||||||
data.foo.toUpperCase();
|
|
||||||
data.count.toFixed();
|
|
||||||
|
|
||||||
// `this` is narrowed to InternalAxiosRequestConfig<Payload>, so this.data is Payload
|
|
||||||
this.data?.foo.toUpperCase();
|
|
||||||
this.data?.count.toFixed();
|
|
||||||
// @ts-expect-error this.data is Payload, not OtherPayload
|
|
||||||
this.data?.other;
|
|
||||||
|
|
||||||
// @ts-expect-error property does not exist on Payload
|
|
||||||
data.bar;
|
|
||||||
|
|
||||||
return JSON.stringify(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrongTransformer: axios.AxiosRequestTransformer<OtherPayload> = (data) => JSON.stringify(data);
|
|
||||||
|
|
||||||
const config: axios.AxiosRequestConfig<Payload> = {
|
|
||||||
data: {
|
|
||||||
foo: 'hello',
|
|
||||||
count: 1,
|
|
||||||
},
|
|
||||||
transformRequest: [
|
|
||||||
transformer,
|
|
||||||
(data) => {
|
|
||||||
data.foo.toUpperCase();
|
|
||||||
data.count.toFixed();
|
|
||||||
|
|
||||||
// @ts-expect-error property does not exist on Payload
|
|
||||||
data.bar;
|
|
||||||
|
|
||||||
return JSON.stringify(data);
|
|
||||||
},
|
|
||||||
// @ts-expect-error transformer payload type does not match config D
|
|
||||||
wrongTransformer,
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
void axios.request(config);
|
|
||||||
@@ -21,13 +21,7 @@ const tsconfig = {
|
|||||||
describe('module ts-require-default compatibility', () => {
|
describe('module ts-require-default compatibility', () => {
|
||||||
it('compiles and executes require("axios").default imports', () => {
|
it('compiles and executes require("axios").default imports', () => {
|
||||||
const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/ts-require-default.ts');
|
const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/ts-require-default.ts');
|
||||||
const fixturePath = createTempFixture(
|
const fixturePath = createTempFixture(suiteRoot, 'ts-require-default', sourcePath, tsconfig);
|
||||||
suiteRoot,
|
|
||||||
null,
|
|
||||||
'ts-require-default',
|
|
||||||
sourcePath,
|
|
||||||
tsconfig
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runCommand('node', [tscBin, '-p', 'tsconfig.json'], { cwd: fixturePath });
|
runCommand('node', [tscBin, '-p', 'tsconfig.json'], { cwd: fixturePath });
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const tsconfig = {
|
|||||||
describe('module ts-require compatibility', () => {
|
describe('module ts-require compatibility', () => {
|
||||||
it('compiles and executes require("axios") imports', () => {
|
it('compiles and executes require("axios") imports', () => {
|
||||||
const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/ts-require.ts');
|
const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/ts-require.ts');
|
||||||
const fixturePath = createTempFixture(suiteRoot, null, 'ts-require', sourcePath, tsconfig);
|
const fixturePath = createTempFixture(suiteRoot, 'ts-require', sourcePath, tsconfig);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runCommand('node', [tscBin, '-p', 'tsconfig.json'], { cwd: fixturePath });
|
runCommand('node', [tscBin, '-p', 'tsconfig.json'], { cwd: fixturePath });
|
||||||
|
|||||||
@@ -17,27 +17,7 @@ const tsconfig = {
|
|||||||
describe('module cjs typings compatibility', () => {
|
describe('module cjs typings compatibility', () => {
|
||||||
it('type-checks commonjs axios typings', () => {
|
it('type-checks commonjs axios typings', () => {
|
||||||
const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/cjs-typing.ts');
|
const sourcePath = path.join(repoRoot, 'tests/module/cjs/tests/helpers/cjs-typing.ts');
|
||||||
const fixturePath = createTempFixture(suiteRoot, repoRoot, 'typings-cjs', sourcePath, tsconfig);
|
const fixturePath = createTempFixture(suiteRoot, 'typings-cjs', sourcePath, tsconfig);
|
||||||
|
|
||||||
try {
|
|
||||||
runCommand('node', [tscBin, '--noEmit', '-p', 'tsconfig.json'], { cwd: fixturePath });
|
|
||||||
} finally {
|
|
||||||
cleanupTempFixture(fixturePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('type-checks generic commonjs request transformer typings', () => {
|
|
||||||
const sourcePath = path.join(
|
|
||||||
repoRoot,
|
|
||||||
'tests/module/cjs/tests/helpers/transform-request-typing.ts'
|
|
||||||
);
|
|
||||||
const fixturePath = createTempFixture(
|
|
||||||
suiteRoot,
|
|
||||||
repoRoot,
|
|
||||||
'typings-cjs-transform-request',
|
|
||||||
sourcePath,
|
|
||||||
tsconfig
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runCommand('node', [tscBin, '--noEmit', '-p', 'tsconfig.json'], { cwd: fixturePath });
|
runCommand('node', [tscBin, '--noEmit', '-p', 'tsconfig.json'], { cwd: fixturePath });
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
export const createTempFixture = (suiteRoot, repoRoot, name, sourcePath, tsconfig, packageJson) => {
|
export const createTempFixture = (suiteRoot, name, sourcePath, tsconfig, packageJson) => {
|
||||||
const tempRoot = fs.mkdtempSync(path.join(suiteRoot, `.tmp-module-${name}-`));
|
const tempRoot = fs.mkdtempSync(path.join(suiteRoot, `.tmp-module-${name}-`));
|
||||||
const source = fs.readFileSync(sourcePath, 'utf8');
|
const source = fs.readFileSync(sourcePath, 'utf8');
|
||||||
|
|
||||||
fs.writeFileSync(path.join(tempRoot, 'index.ts'), source);
|
fs.writeFileSync(path.join(tempRoot, 'index.ts'), source);
|
||||||
fs.writeFileSync(path.join(tempRoot, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2));
|
fs.writeFileSync(path.join(tempRoot, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2));
|
||||||
|
|
||||||
if (repoRoot) {
|
|
||||||
const axiosFixturePath = path.join(tempRoot, 'node_modules', 'axios');
|
|
||||||
fs.mkdirSync(path.dirname(axiosFixturePath), { recursive: true });
|
|
||||||
fs.symlinkSync(repoRoot, axiosFixturePath, 'junction');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packageJson) {
|
if (packageJson) {
|
||||||
fs.writeFileSync(path.join(tempRoot, 'package.json'), JSON.stringify(packageJson, null, 2));
|
fs.writeFileSync(path.join(tempRoot, 'package.json'), JSON.stringify(packageJson, null, 2));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
import axios, { AxiosRequestConfig, AxiosRequestTransformer } from 'axios';
|
|
||||||
|
|
||||||
type Payload = {
|
|
||||||
foo: string;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type OtherPayload = {
|
|
||||||
other: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
const transformer: AxiosRequestTransformer<Payload> = function (data, headers) {
|
|
||||||
headers.setContentType('application/json');
|
|
||||||
data.foo.toUpperCase();
|
|
||||||
data.count.toFixed();
|
|
||||||
|
|
||||||
// `this` is narrowed to InternalAxiosRequestConfig<Payload>, so this.data is Payload
|
|
||||||
this.data?.foo.toUpperCase();
|
|
||||||
this.data?.count.toFixed();
|
|
||||||
// @ts-expect-error this.data is Payload, not OtherPayload
|
|
||||||
this.data?.other;
|
|
||||||
|
|
||||||
// @ts-expect-error property does not exist on Payload
|
|
||||||
data.bar;
|
|
||||||
|
|
||||||
return JSON.stringify(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrongTransformer: AxiosRequestTransformer<OtherPayload> = (data) => JSON.stringify(data);
|
|
||||||
|
|
||||||
const config: AxiosRequestConfig<Payload> = {
|
|
||||||
data: {
|
|
||||||
foo: 'hello',
|
|
||||||
count: 1,
|
|
||||||
},
|
|
||||||
transformRequest: [
|
|
||||||
transformer,
|
|
||||||
(data) => {
|
|
||||||
data.foo.toUpperCase();
|
|
||||||
data.count.toFixed();
|
|
||||||
|
|
||||||
// @ts-expect-error property does not exist on Payload
|
|
||||||
data.bar;
|
|
||||||
|
|
||||||
return JSON.stringify(data);
|
|
||||||
},
|
|
||||||
// @ts-expect-error transformer payload type does not match config D
|
|
||||||
wrongTransformer,
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
void axios.request(config);
|
|
||||||
@@ -22,7 +22,7 @@ const tsconfig = {
|
|||||||
describe('module ts compatibility', () => {
|
describe('module ts compatibility', () => {
|
||||||
it('compiles and executes import axios syntax', () => {
|
it('compiles and executes import axios syntax', () => {
|
||||||
const sourcePath = path.join(repoRoot, 'tests/module/esm/tests/helpers/esm-functions.ts');
|
const sourcePath = path.join(repoRoot, 'tests/module/esm/tests/helpers/esm-functions.ts');
|
||||||
const fixturePath = createTempFixture(suiteRoot, null, 'ts', sourcePath, tsconfig, {
|
const fixturePath = createTempFixture(suiteRoot, 'ts', sourcePath, tsconfig, {
|
||||||
type: 'commonjs',
|
type: 'commonjs',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -16,41 +16,11 @@ const tsconfig = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe('module esm typings compatibility', () => {
|
describe('module esm typings compatibility', () => {
|
||||||
it('type-checks esm axios typings', { timeout: 20000 }, () => {
|
it('type-checks esm axios typings', () => {
|
||||||
const sourcePath = path.join(repoRoot, 'tests/module/esm/tests/helpers/esm-index.ts');
|
const sourcePath = path.join(repoRoot, 'tests/module/esm/tests/helpers/esm-index.ts');
|
||||||
const fixturePath = createTempFixture(
|
const fixturePath = createTempFixture(suiteRoot, 'typings-esm', sourcePath, tsconfig, {
|
||||||
suiteRoot,
|
type: 'module',
|
||||||
repoRoot,
|
});
|
||||||
'typings-esm',
|
|
||||||
sourcePath,
|
|
||||||
tsconfig,
|
|
||||||
{
|
|
||||||
type: 'module',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
runCommand('node', [tscBin, '--noEmit', '-p', 'tsconfig.json'], { cwd: fixturePath });
|
|
||||||
} finally {
|
|
||||||
cleanupTempFixture(fixturePath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('type-checks generic request transformer typings', { timeout: 20000 }, () => {
|
|
||||||
const sourcePath = path.join(
|
|
||||||
repoRoot,
|
|
||||||
'tests/module/esm/tests/helpers/transform-request-typing.ts'
|
|
||||||
);
|
|
||||||
const fixturePath = createTempFixture(
|
|
||||||
suiteRoot,
|
|
||||||
repoRoot,
|
|
||||||
'typings-esm-transform-request',
|
|
||||||
sourcePath,
|
|
||||||
tsconfig,
|
|
||||||
{
|
|
||||||
type: 'module',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runCommand('node', [tscBin, '--noEmit', '-p', 'tsconfig.json'], { cwd: fixturePath });
|
runCommand('node', [tscBin, '--noEmit', '-p', 'tsconfig.json'], { cwd: fixturePath });
|
||||||
|
|||||||
Reference in New Issue
Block a user