chore: remove all old and un-needed files (#10584)

* chore: remove all old and un-needed files

* chore: fix missing file

* chore: fix ref error

* chore: add back missing file

* chore: incorrect folder location

* chore: ignore ts issues
This commit is contained in:
Jay 2026-03-30 20:15:15 +02:00 committed by GitHub
parent 2d14d8a300
commit a7f41f5bb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
124 changed files with 18 additions and 12316 deletions

View File

@ -6,7 +6,7 @@ on:
types:
- webhook
schedule:
- cron: "0 1 * * *"
- cron: '0 1 * * *'
permissions:
contents: write
@ -33,7 +33,7 @@ jobs:
run: npm ci
- name: Check if sponsors require updates
id: sponsors-requires-update
run: node ./scripts/sponsors/update-readme-sponsors.mjs
run: node ./scripts/update-readme-sponsors.mjs
- name: Check tracked README sponsor diff
id: readme-tracked-change
run: |
@ -58,8 +58,8 @@ jobs:
with:
branch: sponsors
delete-branch: true
commit-message: "chore(sponsor): update sponsor block"
title: "chore(docs): update sponsor block"
commit-message: 'chore(sponsor): update sponsor block'
title: 'chore(docs): update sponsor block'
body: |
**New sponsor block update:**
${{ env.CONTENT }}

View File

@ -1,157 +0,0 @@
import util from 'util';
import cp from 'child_process';
import { parseVersion } from './helpers/parser.js';
import githubAxios from './githubAxios.js';
import memoize from 'memoizee';
const exec = util.promisify(cp.exec);
export default class GithubAPI {
constructor(owner, repo) {
if (!owner) {
throw new Error('repo owner must be specified');
}
if (!repo) {
throw new Error('repo must be specified');
}
this.repo = repo;
this.owner = owner;
this.axios = githubAxios.create({
baseURL: `https://api.github.com/repos/${this.owner}/${this.repo}/`,
});
}
async createComment(issue, body) {
return (await this.axios.post(`/issues/${issue}/comments`, { body })).data;
}
async getComments(issue, { desc = false, per_page = 100, page = 1 } = {}) {
return (
await this.axios.get(`/issues/${issue}/comments`, {
params: { direction: desc ? 'desc' : 'asc', per_page, page },
})
).data;
}
async getComment(id) {
return (await this.axios.get(`/issues/comments/${id}`)).data;
}
async updateComment(id, body) {
return (await this.axios.patch(`/issues/comments/${id}`, { body })).data;
}
async appendLabels(issue, labels) {
return (await this.axios.post(`/issues/${issue}/labels`, { labels })).data;
}
async getUser(user) {
return (await githubAxios.get(`/users/${user}`)).data;
}
async isCollaborator(user) {
try {
return (await this.axios.get(`/collaborators/${user}`)).status === 204;
} catch (e) {
// Do nothing
}
}
async deleteLabel(issue, label) {
return (await this.axios.delete(`/issues/${issue}/labels/${label}`)).data;
}
async getIssue(issue) {
return (await this.axios.get(`/issues/${issue}`)).data;
}
async getPR(issue) {
return (await this.axios.get(`/pulls/${issue}`)).data;
}
async getIssues({
state = 'open',
labels,
sort = 'created',
desc = false,
per_page = 100,
page = 1,
}) {
return (
await this.axios.get(`/issues`, {
params: { state, labels, sort, direction: desc ? 'desc' : 'asc', per_page, page },
})
).data;
}
async updateIssue(issue, data) {
return (await this.axios.patch(`/issues/${issue}`, data)).data;
}
async closeIssue(issue) {
return this.updateIssue(issue, {
state: 'closed',
});
}
async getReleases({ per_page = 30, page = 1 } = {}) {
return (await this.axios.get(`/releases`, { params: { per_page, page } })).data;
}
async getRelease(release = 'latest') {
return (
await this.axios.get(
parseVersion(release) ? `/releases/tags/${release}` : `/releases/${release}`
)
).data;
}
async getTags({ per_page = 30, page = 1 } = {}) {
return (await this.axios.get(`/tags`, { params: { per_page, page } })).data;
}
async reopenIssue(issue) {
return this.updateIssue(issue, {
state: 'open',
});
}
static async getTagRef(tag) {
try {
return (await exec(`git show-ref --tags "refs/tags/${tag}"`)).stdout.split(' ')[0];
} catch (e) {
// Do nothing
}
}
static async getLatestTag() {
try {
const { stdout } = await exec(
`git for-each-ref refs/tags --sort=-taggerdate --format='%(refname)' --count=1`
);
return stdout.split('/').pop();
} catch (e) {
// Do nothing
}
}
static normalizeTag(tag) {
return tag ? 'v' + tag.replace(/^v/, '') : '';
}
}
const { prototype } = GithubAPI;
['getUser', 'isCollaborator'].forEach((methodName) => {
prototype[methodName] = memoize(prototype[methodName], { promise: true });
});
['get', 'post', 'put', 'delete', 'isAxiosError'].forEach(
(method) =>
(prototype[method] = function (...args) {
return this.axios[method](...args);
})
);

View File

@ -1,134 +0,0 @@
import GithubAPI from './GithubAPI.js';
import api from './api.js';
import Handlebars from 'handlebars';
import fs from 'fs/promises';
import { colorize } from './helpers/colorize.js';
import { getReleaseInfo } from './contributors.js';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const NOTIFY_PR_TEMPLATE = path.resolve(__dirname, '../templates/pr_published.hbs');
const normalizeTag = (tag) => (tag ? 'v' + tag.replace(/^v/, '') : '');
const GITHUB_BOT_LOGIN = 'github-actions[bot]';
const skipCollaboratorPRs = true;
class RepoBot {
constructor(options) {
const { owner, repo, templates } = options || {};
this.templates = {
published: NOTIFY_PR_TEMPLATE,
...templates,
};
this.github = api || new GithubAPI(owner, repo);
this.owner = this.github.owner;
this.repo = this.github.repo;
}
async addComment(targetId, message) {
return this.github.createComment(targetId, message);
}
async notifyPRPublished(id, tag) {
let pr;
try {
pr = await this.github.getPR(id);
} catch (err) {
if (err.response?.status === 404) {
throw new Error(`PR #${id} not found (404)`);
}
throw err;
}
tag = normalizeTag(tag);
const {
merged,
labels,
user: { login, type },
} = pr;
const isBot = type === 'Bot';
if (!merged) {
return false;
}
await this.github.appendLabels(id, [tag]);
if (
isBot ||
labels.find(({ name }) => name === 'automated pr') ||
(skipCollaboratorPRs && (await this.github.isCollaborator(login)))
) {
return false;
}
const comments = await this.github.getComments(id, { desc: true });
const comment = comments.find(
({ body, user }) => user.login === GITHUB_BOT_LOGIN && body.indexOf('published in') >= 0
);
if (comment) {
console.log(colorize()`Release comment [${comment.html_url}] already exists in #${pr.id}`);
return false;
}
const author = await this.github.getUser(login);
author.isBot = isBot;
const message = await this.constructor.renderTemplate(this.templates.published, {
id,
author,
release: {
tag,
url: `https://github.com/${this.owner}/${this.repo}/releases/tag/${tag}`,
},
});
return await this.addComment(id, message);
}
async notifyPublishedPRs(tag) {
tag = normalizeTag(tag);
const release = await getReleaseInfo(tag);
if (!release) {
throw Error(colorize()`Can't get release info for ${tag}`);
}
const { merges } = release;
console.log(colorize()`Found ${merges.length} PRs in ${tag}:`);
let i = 0;
for (const pr of merges) {
try {
console.log(colorize()`${i++}) Notify PR #${pr.id}`);
const result = await this.notifyPRPublished(pr.id, tag);
console.log('✔️', result ? 'Label, comment' : 'Label');
} catch (err) {
console.warn(colorize('green', 'red')`❌ Failed notify PR ${pr.id}: ${err.message}`);
}
}
}
static async renderTemplate(template, data) {
return Handlebars.compile(String(await fs.readFile(template)))(data);
}
}
export default RepoBot;

View File

@ -1,26 +0,0 @@
import minimist from 'minimist';
import RepoBot from '../RepoBot.js';
import fs from 'fs/promises';
const argv = minimist(process.argv.slice(2));
console.log(argv);
let { tag } = argv;
(async () => {
if (!tag || tag === true) {
const { version } = JSON.parse((await fs.readFile('./package.json')).toString());
tag = 'v' + version;
} else if (typeof tag !== 'string') {
throw new Error('tag must be a string');
}
const bot = new RepoBot();
try {
await bot.notifyPublishedPRs(tag);
} catch (err) {
console.warn('Error:', err.message);
}
})();

View File

@ -1,3 +0,0 @@
import GithubAPI from './GithubAPI.js';
export default new GithubAPI('axios', 'axios');

View File

@ -1,27 +0,0 @@
import fs from 'fs';
import assert from 'assert';
import axios from '../index.js';
import axiosBuild from '../dist/node/axios.cjs';
const { version } = JSON.parse(fs.readFileSync('./package.json'));
console.log('Checking versions...\n----------------------------');
console.log(`Package version: v${version}`);
console.log(`Axios version: v${axios.VERSION}`);
console.log(`Axios build version: v${axiosBuild.VERSION}`);
console.log(`----------------------------`);
assert.strictEqual(
version,
axios.VERSION,
`Version mismatch between package and Axios ${version} != ${axios.VERSION}`
);
assert.strictEqual(
version,
axiosBuild.VERSION,
`Version mismatch between package and build ${version} != ${axiosBuild.VERSION}`
);
console.log('✔️ PASSED\n');

View File

@ -1,247 +0,0 @@
import axios from './githubAxios.js';
import util from 'util';
import cp from 'child_process';
import Handlebars from 'handlebars';
import fs from 'fs/promises';
import { colorize } from './helpers/colorize.js';
const exec = util.promisify(cp.exec);
const ONE_MB = 1024 * 1024;
const removeExtraLineBreaks = (str) => str.replace(/(?:\r\n|\r|\n){3,}/gm, '\r\n\r\n');
const cleanTemplate = (template) =>
template
.replace(/\n +/g, '\n')
.replace(/^ +/, '')
.replace(/\n\n\n+/g, '\n\n')
.replace(/\n\n$/, '\n');
const getUserFromCommit = ((commitCache) => async (sha) => {
try {
if (commitCache[sha] !== undefined) {
return commitCache[sha];
}
console.log(colorize()`fetch github commit info (${sha})`);
const { data } = await axios.get(`https://api.github.com/repos/axios/axios/commits/${sha}`);
return (commitCache[sha] = {
...data.commit.author,
...data.author,
avatar_url_sm: data.author.avatar_url ? data.author.avatar_url + '&s=18' : '',
});
} catch (err) {
return (commitCache[sha] = null);
}
})({});
const getIssueById = ((cache) => async (id) => {
if (cache[id] !== undefined) {
return cache[id];
}
try {
const { data } = await axios.get(`https://api.github.com/repos/axios/axios/issues/${id}`);
return (cache[id] = data);
} catch (err) {
return null;
}
})({});
const getUserInfo = ((userCache) => async (userEntry) => {
const { email, commits } = userEntry;
if (userCache[email] !== undefined) {
return userCache[email];
}
console.log(colorize()`fetch github user info [${userEntry.name}]`);
return (userCache[email] = {
...userEntry,
...(await getUserFromCommit(commits[0].hash)),
});
})({});
const deduplicate = (authors) => {
const loginsMap = {};
const combined = {};
const assign = (a, b) => {
const { insertions, _deletions, _points, ...rest } = b;
Object.assign(a, rest);
a.insertions += insertions;
a.deletions += insertions;
a.insertions += insertions;
};
for (const [email, user] of Object.entries(authors)) {
const { login } = user;
let entry;
if (login && (entry = loginsMap[login])) {
assign(entry, user);
} else {
login && (loginsMap[login] = user);
combined[email] = user;
}
}
return combined;
};
const getReleaseInfo = ((releaseCache) => async (tag) => {
if (releaseCache[tag] !== undefined) {
return releaseCache[tag];
}
const isUnreleasedTag = !tag;
const version = 'v' + tag.replace(/^v/, '');
const command = isUnreleasedTag
? `npx auto-changelog --unreleased-only --stdout --commit-limit false --template json`
: `npx auto-changelog ${
version ? '--starting-version ' + version + ' --ending-version ' + version : ''
} --stdout --commit-limit false --template json`;
console.log(command);
const { stdout } = await exec(command, { maxBuffer: 10 * ONE_MB });
const release = JSON.parse(stdout)[0];
if (release) {
const authors = {};
const commits = [
...release.commits,
...release.fixes.map((fix) => fix.commit),
...release.merges.map((fix) => fix.commit),
].filter(Boolean);
const commitMergeMap = {};
for (const merge of release.merges) {
commitMergeMap[merge.commit.hash] = merge.id;
}
for (const { hash, author, email, insertions, deletions } of commits) {
const entry = (authors[email] = authors[email] || {
name: author,
prs: [],
email,
commits: [],
insertions: 0,
deletions: 0,
});
entry.commits.push({ hash });
let pr;
if ((pr = commitMergeMap[hash])) {
entry.prs.push(pr);
}
console.log(colorize()`Found commit [${hash}]`);
entry.displayName = entry.name || author || entry.login;
entry.github = entry.login ? `https://github.com/${encodeURIComponent(entry.login)}` : '';
entry.insertions += insertions;
entry.deletions += deletions;
entry.points = entry.insertions + entry.deletions;
}
for (const [email, author] of Object.entries(authors)) {
const entry = (authors[email] = await getUserInfo(author));
entry.isBot = entry.type === 'Bot';
}
release.authors = Object.values(deduplicate(authors)).sort((a, b) => b.points - a.points);
release.allCommits = commits;
}
releaseCache[tag] = release;
return release;
})({});
const renderContributorsList = async (tag, template) => {
const release = await getReleaseInfo(tag);
const compile = Handlebars.compile(String(await fs.readFile(template)));
const content = compile(release);
return removeExtraLineBreaks(cleanTemplate(content));
};
const renderPRsList = async (
tag,
template,
{ comments_threshold = 5, awesome_threshold = 5, label = 'add_to_changelog' } = {}
) => {
const release = await getReleaseInfo(tag);
const prs = {};
for (const merge of release.merges) {
const pr = await getIssueById(merge.id);
if (pr && pr.labels.find(({ name }) => name === label)) {
const { reactions, body } = pr;
prs[pr.number] = pr;
pr.isHot = pr.comments > comments_threshold;
const points =
reactions['+1'] +
reactions['hooray'] +
reactions['rocket'] +
reactions['heart'] +
reactions['laugh'] -
reactions['-1'];
pr.isAwesome = points > awesome_threshold;
let match;
pr.messages = [];
if (body) {
const reg = /```+changelog\n*(.+?)?\n*```/gms;
while ((match = reg.exec(body))) {
match[1] && pr.messages.push(match[1]);
}
}
}
}
release.prs = Object.values(prs);
const compile = Handlebars.compile(String(await fs.readFile(template)));
const content = compile(release);
return removeExtraLineBreaks(cleanTemplate(content));
};
const getTagRef = async (tag) => {
try {
return (await exec(`git show-ref --tags "refs/tags/${tag}"`)).stdout.split(' ')[0];
} catch (e) {
// Do nothing
}
};
export { renderContributorsList, getReleaseInfo, renderPRsList, getTagRef };

View File

@ -1,16 +0,0 @@
import chalk from 'chalk';
export const colorize = (...colors) => {
if (!colors.length) {
colors = ['green', 'cyan', 'magenta', 'blue', 'yellow', 'red'];
}
const colorsCount = colors.length;
return (strings, ...values) => {
const { length } = values;
return strings
.map((str, i) => (i < length ? str + chalk[colors[i % colorsCount]].bold(values[i]) : str))
.join('');
};
};

View File

@ -1,13 +0,0 @@
export const matchAll = (text, regexp, cb) => {
let match;
while ((match = regexp.exec(text))) {
cb(match);
}
};
export const parseSection = (body, name, cb) => {
matchAll(body, new RegExp(`^(#+)\\s+${name}?(.*?)^\\1\\s+\\w+`, 'gims'), cb);
};
export const parseVersion = (rawVersion) => /^v?(\d+).(\d+).(\d+)/.exec(rawVersion);

View File

@ -1,74 +0,0 @@
import fs from 'fs/promises';
import path from 'path';
import { renderContributorsList, getTagRef, renderPRsList } from './contributors.js';
import asyncReplace from 'string-replace-async';
import { fileURLToPath } from 'url';
import { colorize } from './helpers/colorize.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const CONTRIBUTORS_TEMPLATE = path.resolve(__dirname, '../templates/contributors.hbs');
const PRS_TEMPLATE = path.resolve(__dirname, '../templates/prs.hbs');
const injectSection = async (name, contributorsRE, injector, infile = '../CHANGELOG.md') => {
console.log(colorize()`Checking ${name} sections in ${infile}`);
infile = path.resolve(__dirname, infile);
const content = String(await fs.readFile(infile));
const headerRE = /^#+\s+\[([-_\d.\w]+)].+?$/gim;
let tag;
let index = 0;
let isFirstTag = true;
const newContent = await asyncReplace(content, headerRE, async (match, nextTag, offset) => {
const releaseContent = content.slice(index, offset);
const hasSection = contributorsRE.test(releaseContent);
const currentTag = tag;
tag = nextTag;
index = offset + match.length;
if (currentTag) {
if (hasSection) {
console.log(colorize()`[${currentTag}]: ✓ OK`);
} else {
const target = isFirstTag && !(await getTagRef(currentTag)) ? '' : currentTag;
console.log(colorize()`[${currentTag}]: ❌ MISSED` + (!target ? ' (UNRELEASED)' : ''));
isFirstTag = false;
console.log(`Generating section...`);
const section = await injector(target);
if (!section) {
return match;
}
console.log(colorize()`\nRENDERED SECTION [${name}] for [${currentTag}]:`);
console.log('-------------BEGIN--------------\n');
console.log(section);
console.log('--------------END---------------\n');
return section + '\n' + match;
}
}
return match;
});
await fs.writeFile(infile, newContent);
};
await injectSection('PRs', /^\s*### PRs/im, (tag) =>
tag ? '' : renderPRsList(tag, PRS_TEMPLATE, { awesome_threshold: 5, comments_threshold: 7 })
);
await injectSection('contributors', /^\s*### Contributors/im, (tag) =>
renderContributorsList(tag, CONTRIBUTORS_TEMPLATE)
);

139
bin/pr.js
View File

@ -1,139 +0,0 @@
import Handlebars from 'handlebars';
import fs from 'fs/promises';
import prettyBytes from 'pretty-bytes';
import { getBlobHistory } from './repo.js';
import pacote from 'pacote';
import zlib from 'zlib';
import tar from 'tar-stream';
import { Readable } from 'stream';
const FILE_SIZE_DIFF_THRESHOLD = 512; // 0.5KB
const readJSONFile = async (file) => JSON.parse(String(await fs.readFile(file)));
const { version } = await readJSONFile('./package.json');
const parseVersion = (tag) => {
const [, major, minor, patch] = /^v?(\d+)\.(\d+)\.(\d+)/.exec(tag) || [];
return [major, minor, patch];
};
const [MAJOR_NUMBER] = parseVersion(version);
async function getFilesFromNPM(pkg) {
const tgzData = await pacote.tarball(pkg); // Buffer з npm
const files = {};
return new Promise((resolve, reject) => {
const extract = tar.extract();
extract.on('entry', (header, stream, next) => {
const buffers = [];
stream.on('data', (buffer) => {
buffers.push(buffer);
});
stream.on('end', () => {
const content = Buffer.concat(buffers);
const gzipped = zlib.gzipSync(content);
files[header.name.replace(/^package\//, '')] = {
gzip: gzipped.length,
compressed: header.size ? gzipped.length / header.size : 1,
...header,
};
next();
});
});
Readable.from(tgzData)
.pipe(zlib.createGunzip())
.pipe(extract)
.on('error', reject)
.on('finish', () => resolve(files));
});
}
const generateFileReport = async (files, historyCount = 3) => {
const allFilesStat = {};
const commits = (await getBlobHistory('package.json', historyCount)).filter(({ tag }) => {
return MAJOR_NUMBER === parseVersion(tag)[0];
});
const warns = [];
const npmHistory = {};
await Promise.all(
commits.map(async ({ tag }) => {
npmHistory[tag] = await getFilesFromNPM(`axios@${tag.replace(/^v/, '')}`);
})
);
for (const [name, filename] of Object.entries(files)) {
const file = await fs.stat(filename).catch(console.warn);
const gzip = file ? zlib.gzipSync(await fs.readFile(filename)).length : 0;
const stat = (allFilesStat[filename] = file
? {
name,
size: file.size,
path: filename,
gzip,
compressed: file.size ? gzip / file.size : 1,
history: commits.map(({ tag }) => {
const files = npmHistory[tag];
const file = (files && files[filename]) || null;
return {
tag,
...file,
};
}),
}
: null);
if (stat.history[0]) {
const diff = stat.gzip - stat.history[0].gzip;
if (diff > FILE_SIZE_DIFF_THRESHOLD) {
warns.push({
filename,
sizeReport: true,
diff,
percent: stat.gzip ? diff / stat.gzip : 0,
});
}
}
}
return {
version,
files: allFilesStat,
warns,
};
};
const generateBody = async ({ files, template = './templates/pr.hbs' } = {}) => {
const data = await generateFileReport(files);
Handlebars.registerHelper('filesize', (bytes) =>
bytes != null ? prettyBytes(bytes) : '<unknown>'
);
Handlebars.registerHelper('percent', (value) =>
Number.isFinite(value) ? `${(value * 100).toFixed(1)}%` : `---`
);
return Handlebars.compile(String(await fs.readFile(template)))(data);
};
console.log(
await generateBody({
files: {
'Browser build (UMD)': 'dist/axios.min.js',
'Browser build (ESM)': 'dist/esm/axios.min.js',
},
})
);

View File

@ -1,40 +0,0 @@
import util from 'util';
import cp from 'child_process';
export const exec = util.promisify(cp.exec);
export const getBlobSize = async (filepath, sha = 'HEAD') => {
const size = (await exec(`git cat-file -s ${sha}:${filepath}`)).stdout;
return size ? +size : 0;
};
export const getBlobHistory = async (filepath, maxCount = 5) => {
const log = (
await exec(
`git log --max-count=${maxCount} --no-walk --tags=v* --oneline --format=%H%d -- ${filepath}`
)
).stdout;
const commits = [];
let match;
const regexp = /^(\w+) \(tag: (v?[.\d]+)\)$/gm;
while ((match = regexp.exec(log))) {
commits.push({
sha: match[1],
tag: match[2],
size: await getBlobSize(filepath, match[1]),
});
}
return commits;
};
export const getTags = async (pattern = 'v*', sort = '-v:refname') => {
const log = (await exec(`git tag -l ${pattern} --sort=${sort}`)).stdout;
return log.split(/\r?\n/);
};

View File

@ -1,20 +0,0 @@
import { exec, getTags } from './repo.js';
import fs from 'fs';
import { colorize } from './helpers/colorize.js';
const { version } = JSON.parse(fs.readFileSync('./package.json'));
const [major] = version.split('.');
const tags = await getTags();
const latestTag = (tags[0] || '').replace(/^v/, '');
const isBeta = !/^v?(\d+).(\d)+.(\d)+$/.test(version);
const isLatest = latestTag === version;
let tag = isBeta ? 'next' : isLatest ? 'latest' : `v${major}`;
console.log(
colorize()`Version [${version}] [${isBeta ? 'prerelease' : 'release'}] latest [${latestTag}]=> NPM Tag [${tag}]`
);
await exec(`echo "tag=${tag}" >> $GITHUB_OUTPUT`);

View File

@ -1,37 +0,0 @@
import { startTestServer, stopHTTPServer } from '../test/helpers/server.js';
import { spawn } from 'child_process';
import chalk from 'chalk';
let server;
async function run() {
console.log(chalk.red.bold(`[ Starting HTTP server... ]`));
server = await startTestServer(3000);
await new Promise((resolve, reject) => {
console.log('Starting karma runner...');
const karma = spawn('npx', ['karma', 'start', 'karma.conf.cjs', '--single-run'], {
stdio: 'inherit',
shell: true,
env: { ...process.env, LISTEN_ADDR: '0.0.0.0' },
});
karma.on('exit', (code) => {
code ? reject(new Error(`Karma tests failed with exit code ${code}`)) : resolve();
});
});
}
(async () => {
try {
await run();
} finally {
if (server) {
console.log(chalk.red.bold(`[ Terminating HTTP server... ]`));
await stopHTTPServer(server);
}
}
})();

View File

@ -1,24 +0,0 @@
import { spawn } from 'child_process';
const args = process.argv.slice(2);
console.log(`Running ${args.join(' ')} on ${process.version}\n`);
const match = /v(\d+)/.exec(process.version);
const isHotfixNeeded = match && match[1] > 16;
isHotfixNeeded && console.warn('Setting --openssl-legacy-provider as ssl hotfix');
const test = spawn(
'cross-env',
isHotfixNeeded ? ['NODE_OPTIONS=--openssl-legacy-provider', ...args] : args,
{
shell: true,
stdio: 'inherit',
}
);
test.on('exit', function (code) {
process.exit(code);
});

View File

@ -1,6 +1,6 @@
import gulp from 'gulp';
import fs from 'fs-extra';
import axios from './bin/githubAxios.js';
import axios from './scripts/axios-build-instance.js';
import minimist from 'minimist';
const argv = minimist(process.argv.slice(2));

View File

@ -1,5 +1,4 @@
import axios from '../index.js';
import { colorize } from './helpers/colorize.js';
const { GITHUB_TOKEN } = process.env;
@ -12,8 +11,9 @@ export default axios.create({
defaultTransform[0],
function (data) {
console.log(
colorize()`[${this.method.toUpperCase()}] Request [${new URL(axios.getUri(this)).pathname}]`
`[${this.method.toUpperCase()}] Request [${new URL(axios.getUri(this)).pathname}]`
);
return data;
},
],

View File

@ -1,5 +1,5 @@
import fs from 'fs/promises';
import _axios from '../../index.js';
import _axios from '../index.js';
const axios = _axios.create({
headers: {

View File

@ -1,13 +0,0 @@
{{#if authors}}
### Contributors to this release
{{#each authors}}
{{#unless isBot}}
{{#if login}}
- {{#if avatar_url}}<img src="{{avatar_url_sm}}" alt="avatar" width="18"/>{{/if}} [{{displayName}}]({{html_url}} "+{{insertions}}/-{{deletions}} ({{#each prs}}#{{this}} {{/each}})")
{{else}}
- {{displayName}}
{{/if}}
{{/unless}}
{{/each}}
{{/if}}

View File

@ -1,21 +0,0 @@
{{#if files}}
### Build info (v{{version}})
Client bundles:
{{#each files}}
- {{ name}} ({{ path }})
- **[ this ]** - {{ filesize size }} (**{{ filesize gzip }}** gzipped, {{percent compressed}})
{{#each history}}
- **[{{ tag }}]** - {{filesize size}} (**{{ filesize gzip }}** gzipped, {{percent compressed}})
{{/each}}
{{/each}}
{{/if}}
{{#if warns}}
#### Warnings
{{#each warns}}
{{#if sizeReport}}
- ⚠️ File `{{filename}}` has increased in size by `{{filesize diff}}` (`+{{percent percent}}`)
{{/if}}
{{/each}}
{{/if}}

View File

@ -1 +0,0 @@
Hi, @{{ author.login }}! This PR has been published in [{{ release.tag }}]({{ release.url }}) release. Thank you for your contribution ❤️!

View File

@ -1,13 +0,0 @@
{{#if prs}}
### PRs
{{#each prs}}
- {{title}} ( [#{{number}}]({{pull_request.url}}) ){{#if isHot}} 🔥{{/if}}{{#if isHot}} 🚀{{/if}}
{{#if messages}}
{{#each messages}}
```
{{this}}
```
{{/each}}
{{/if}}
{{/each}}
{{/if}}

View File

@ -1,20 +0,0 @@
export const retryNetwork = async (fn, retries = 3, delay = 1000) => {
let attempt = 0,
sleep;
do {
try {
return await fn();
} catch (err) {
if (err.code === 'ERR_NETWORK' && attempt++ < retries) {
sleep = attempt * attempt * delay;
console.warn(
`[ERR_NETWORK]: Attempt ${attempt}/${retries}${err.config ? ' [' + err.config.url + ']' : ''} sleep [${sleep}ms]`
);
await new Promise((resolve) => setTimeout(resolve, sleep));
} else {
throw err;
}
}
} while (true);
};

View File

@ -1,239 +0,0 @@
import http from 'http';
import http2 from 'http2';
import stream from 'stream';
import getStream, { getStreamAsBuffer } from 'get-stream';
import { Throttle } from 'stream-throttle';
import formidable from 'formidable';
import selfsigned from 'selfsigned';
export const LOCAL_SERVER_URL = 'http://localhost:4444';
export const SERVER_HANDLER_STREAM_ECHO = (req, res) => req.pipe(res);
export const setTimeoutAsync = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const certificatePromise = selfsigned.generate(null, { keySize: 2048 });
export const startHTTPServer = async (handlerOrOptions, options) => {
const certificate = await certificatePromise;
const {
handler,
useBuffering = false,
rate = undefined,
port = 4444,
keepAlive = 1000,
useHTTP2,
key = certificate.private,
cert = certificate.cert,
} = Object.assign(
typeof handlerOrOptions === 'function'
? {
handler: handlerOrOptions,
}
: handlerOrOptions || {},
options
);
return new Promise((resolve, reject) => {
const serverHandler =
handler ||
async function (req, res) {
try {
req.headers['content-length'] &&
res.setHeader('content-length', req.headers['content-length']);
let dataStream = req;
if (useBuffering) {
dataStream = stream.Readable.from(await getStream(req));
}
let streams = [dataStream];
if (rate) {
streams.push(new Throttle({ rate }));
}
streams.push(res);
stream.pipeline(streams, (err) => {
err && console.log('Server warning: ' + err.message);
});
} catch (err) {
console.warn('HTTP server error:', err);
}
};
const server = useHTTP2
? http2.createSecureServer({ key, cert }, serverHandler)
: http.createServer(serverHandler);
const sessions = new Set();
if (useHTTP2) {
server.on('session', (session) => {
sessions.add(session);
session.once('close', () => {
sessions.delete(session);
});
});
server.closeAllSessions = () => {
for (const session of sessions) {
session.destroy();
}
};
} else {
server.keepAliveTimeout = keepAlive;
}
server.listen(port, function (err) {
err ? reject(err) : resolve(this);
});
});
};
export const stopHTTPServer = async (server, timeout = 10000) => {
if (server) {
if (typeof server.closeAllConnections === 'function') {
server.closeAllConnections();
}
if (typeof server.closeAllSessions === 'function') {
server.closeAllSessions();
}
await Promise.race([new Promise((resolve) => server.close(resolve)), setTimeoutAsync(timeout)]);
}
};
export const handleFormData = (req) => {
return new Promise((resolve, reject) => {
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
if (err) {
return reject(err);
}
resolve({ fields, files });
});
});
};
export const nodeVersion = process.versions.node.split('.').map((v) => parseInt(v, 10));
export const generateReadable = (length = 1024 * 1024, chunkSize = 10 * 1024, sleep = 50) => {
return stream.Readable.from(
(async function* () {
let dataLength = 0;
while (dataLength < length) {
const leftBytes = length - dataLength;
const chunk = Buffer.alloc(leftBytes > chunkSize ? chunkSize : leftBytes);
dataLength += chunk.length;
yield chunk;
if (sleep) {
await setTimeoutAsync(sleep);
}
}
})()
);
};
export const makeReadableStream = (chunk = 'chunk', n = 10, timeout = 100) => {
return new ReadableStream(
{
async pull(controller) {
await setTimeoutAsync(timeout);
n-- ? controller.enqueue(chunk) : controller.close();
},
},
{
highWaterMark: 1,
}
);
};
export const makeEchoStream = (echo) =>
new WritableStream({
write(chunk) {
echo && console.log(`Echo chunk`, chunk);
},
});
export const startTestServer = async (port) => {
const handler = async (req) => {
const parsed = new URL(req.url, `http://localhost:${port}`);
const params = Object.fromEntries(parsed.searchParams);
let response = {
url: req.url,
pathname: parsed.pathname,
params,
method: req.method,
headers: req.headers,
};
const contentType = req.headers['content-type'] || '';
const { delay = 0 } = params;
if (+delay) {
await setTimeoutAsync(+delay);
}
switch (parsed.pathname.replace(/\/$/, '')) {
case '/echo/json':
default:
if (contentType.startsWith('multipart/')) {
let { fields, files } = await handleFormData(req);
response.form = fields;
response.files = files;
} else {
response.body = (await getStreamAsBuffer(req)).toString('hex');
}
return {
body: response,
};
}
};
return await startHTTPServer(
(req, res) => {
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', `*`); // Allows all origins, or specify a domain like 'http://example.com'
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); // Allowed HTTP methods
res.setHeader('Access-Control-Allow-Headers', '*'); // Allowed request headers
res.setHeader('Access-Control-Max-Age', '86400'); // Cache preflight requests for 24 hours
// Handle preflight requests (OPTIONS method)
if (req.method === 'OPTIONS') {
res.writeHead(204); // No content
res.end();
return;
}
Promise.resolve(handler(req, res)).then((response) => {
const { status = 200, headers = {}, body } = response || {};
res.statusCode = status;
Object.entries(headers).forEach((header, value) => {
res.setHeader(header, value);
});
res.end(JSON.stringify(body, null, 2));
});
},
{ port }
);
};

View File

@ -1,24 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
An alert should be shown with the <code>{"name":"axios"}</code>
<script src="promise.js"></script>
<script src="../../dist/axios.js"></script>
<script>
axios.get('./fixture.json').then(function (response) {
console.log(response);
alert(JSON.stringify(response.data));
alert('response headers:\n\n' + JSON.stringify(response.headers));
}, function (err) { console.log(err) });
</script>
</body>
</html>

View File

@ -1,23 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
An alert should be shown with <code>{"status":"ok"}</code>
<script src="promise.js"></script>
<script src="../../dist/axios.js"></script>
<script>
axios.get('http://cors-test.appspot.com/test').then(function (response) {
alert(JSON.stringify(response.data));
alert('response headers:\n\n' + JSON.stringify(response.headers));
}, function (err) { console.log(err) });
</script>
</body>
</html>

View File

@ -1,3 +0,0 @@
{
"name": "axios"
}

View File

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
See your console
<script src="../../dist/axios.js"></script>
<script>
const data = new Int8Array(10 * 1024 * 1024);
data.fill(123);
console.log('Starting...');
(async () => {
await axios.post('http://httpbin.org/post', data, {
adapter: 'xhr',
onUploadProgress: (e) => console.log('xhr upload', e),
onDownloadProgress: (e) => console.log('xhr download', e),
}).then(data => {
console.log(`Done: `, data);
}).catch(e => console.warn('xhr', e));
await axios.post('https://httpbin.org/post', data, {
adapter: 'fetch',
onUploadProgress: (e) => console.log('fetch upload', e),
onDownloadProgress: (e) => console.log('fetch download', e)
}).then(data => {
console.log(`Done: `, data);
}).catch(e => console.warn('fetch', e));
})();
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,11 +0,0 @@
const axios = require('axios');
const assert = require('assert');
const { CanceledError, AxiosError, AxiosHeaders } = axios;
assert.strictEqual(typeof axios, 'function');
assert.strictEqual(typeof CanceledError, 'function');
assert.strictEqual(typeof AxiosError, 'function');
assert.strictEqual(typeof AxiosHeaders, 'function');
console.log('CommonJS importing test passed');

View File

@ -1,15 +0,0 @@
{
"name": "cjs-entrypoint-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "npm i --no-save --no-package-lock && node index.js"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"axios": "file:../../.."
}
}

View File

@ -1,16 +0,0 @@
import assert from 'assert';
import axios, { CanceledError, AxiosError, AxiosHeaders } from 'axios';
import settle from 'axios/unsafe/core/settle.js';
assert.strictEqual(typeof axios, 'function');
assert.strictEqual(typeof CanceledError, 'function');
assert.strictEqual(typeof AxiosError, 'function');
assert.strictEqual(typeof AxiosHeaders, 'function');
assert.strictEqual(axios.CanceledError, CanceledError);
assert.strictEqual(axios.AxiosError, AxiosError);
assert.strictEqual(axios.AxiosHeaders, AxiosHeaders);
assert.strictEqual(typeof settle, 'function');
console.log('ESM importing test passed');

View File

@ -1,16 +0,0 @@
{
"name": "esm-entrypoint-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "npm i --no-save --no-package-lock && node index.js"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"axios": "file:../../.."
}
}

View File

@ -1,184 +0,0 @@
import assert from 'assert';
import * as axios from '../../index.js';
import axiosFactory from '../../lib/axios.js';
import utils from '../../lib/utils.js';
import { fileURLToPath } from 'url';
import path from 'path';
import util from 'util';
import cp from 'child_process';
import fs from 'fs-extra';
const BACKUP_PATH = './backup/';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const exec = util.promisify(cp.exec);
const spawn = (command, args) =>
new Promise((resolve, reject) => {
cp.spawn(command, args, {
shell: true,
stdio: 'inherit',
})
.once('error', reject)
.on('close', (code) => (code ? reject(new Error(`Exit code ${code}`)) : resolve()));
});
const { Axios } = axiosFactory;
const ignoreList = ['default'];
const instance = axiosFactory.create({});
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const remove = async (file) => {
console.log(`✓ Remove entry '${file}'...`);
try {
await sleep(1000);
await fs.remove(file);
} catch (err) {
console.warn(err.message);
}
};
describe('module', function () {
before(async () => {
console.log('✓ Creating build backup...');
await fs.copy('./dist/', BACKUP_PATH);
console.log('✓ Exec build script...');
await exec('npm run build');
console.log('✓ Running tests...');
});
after(async () => {
console.log('✓ Restore build from the backup...');
await fs.copy(BACKUP_PATH, './dist/');
await remove(BACKUP_PATH);
});
describe('export', function () {
it('should have consistent ESM export', function () {
const namedExport = {};
const factoryExport = {};
Object.entries(axiosFactory).forEach(([key, value]) => {
if (!utils.hasOwnProp(Axios, key) && !(key in instance) && ignoreList.indexOf(key) === -1) {
factoryExport[key] = value;
}
});
Object.entries(axios).forEach(([key, value]) => {
key !== 'default' && ignoreList.indexOf(key) === -1 && (namedExport[key] = value);
});
assert.deepStrictEqual(namedExport, factoryExport);
});
describe('CommonJS', () => {
const pkgPath = path.join(__dirname, './cjs');
after(async () => {
await remove(path.join(pkgPath, './node_modules'));
});
it('should be able to be loaded with require', async function () {
this.timeout(30000);
await exec(`npm test --prefix ${pkgPath}`);
});
});
describe('ESM', () => {
const pkgPath = path.join(__dirname, './esm');
after(async () => {
await remove(path.join(pkgPath, './node_modules'));
});
it('should be able to be loaded with import', async function () {
this.timeout(30000);
await exec(`npm test --prefix ${pkgPath}`);
});
});
describe('TS', () => {
const pkgPath = path.join(__dirname, './ts');
after(async () => {
await remove(path.join(pkgPath, './node_modules'));
});
it('should be able to be loaded with import', async function () {
this.timeout(30000);
await exec(`npm test --prefix ${pkgPath}`, {});
});
});
describe("TS require('axios')", () => {
const pkgPath = path.join(__dirname, './ts-require');
after(async () => {
await remove(path.join(pkgPath, './node_modules'));
});
it('should be able to be loaded with require', async function () {
this.timeout(30000);
await exec(`npm test --prefix ${pkgPath}`, {});
});
});
describe("TS require('axios').default", () => {
const pkgPath = path.join(__dirname, './ts-require-default');
after(async () => {
await remove(path.join(pkgPath, './node_modules'));
});
it('should be able to be loaded with require', async function () {
this.timeout(30000);
await exec(`npm test --prefix ${pkgPath}`, {});
});
});
});
describe('typings', () => {
describe('ESM', () => {
const pkgPath = path.join(__dirname, './typings/esm');
after(async () => {
await remove(path.join(pkgPath, './node_modules'));
});
it('should pass types check', async function () {
this.timeout(30000);
await spawn(`npm test --prefix ${pkgPath}`, [], {
shell: true,
stdio: 'pipe',
});
});
});
describe('CommonJS', () => {
const pkgPath = path.join(__dirname, './typings/cjs');
after(async () => {
await remove(path.join(pkgPath, './node_modules'));
});
it('should pass types check', async function () {
this.timeout(30000);
await spawn(`npm test --prefix ${pkgPath}`, [], {
shell: true,
stdio: 'pipe',
});
});
});
});
});

View File

@ -1,23 +0,0 @@
"use strict";
const assert = require('assert');
const axios = require('axios').default;
const { CanceledError, AxiosError, AxiosHeaders, formToJSON, spread, isAxiosError, isCancel, all, toFormData, } = axios;
assert.strictEqual(typeof axios, 'function');
assert.strictEqual(typeof CanceledError, 'function');
assert.strictEqual(typeof AxiosError, 'function');
assert.strictEqual(typeof AxiosHeaders, 'function');
assert.strictEqual(typeof formToJSON, 'function');
assert.strictEqual(typeof spread, 'function');
assert.strictEqual(typeof isAxiosError, 'function');
assert.strictEqual(typeof isCancel, 'function');
assert.strictEqual(typeof all, 'function');
assert.strictEqual(typeof toFormData, 'function');
assert.strictEqual(typeof axios.CanceledError, 'function');
assert.strictEqual(typeof axios.AxiosError, 'function');
assert.strictEqual(typeof axios.AxiosHeaders, 'function');
assert.strictEqual(typeof axios.formToJSON, 'function');
assert.strictEqual(typeof axios.spread, 'function');
assert.strictEqual(typeof axios.isAxiosError, 'function');
assert.strictEqual(typeof axios.isCancel, 'function');
assert.strictEqual(typeof axios.all, 'function');
assert.strictEqual(typeof axios.toFormData, 'function');

View File

@ -1,20 +0,0 @@
{
"name": "ts-entrypoint-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "npm i --no-save --no-package-lock && npm run build && node index.js",
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@types/node": "^18.11.3",
"axios": "file:../../.."
},
"devDependencies": {
"typescript": "^5.9.3"
}
}

View File

@ -1,103 +0,0 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View File

@ -1,23 +0,0 @@
"use strict";
const assert = require('assert');
const axios = require('axios');
const { CanceledError, AxiosError, AxiosHeaders, formToJSON, spread, isAxiosError, isCancel, all, toFormData, } = axios;
assert.strictEqual(typeof axios, 'function');
assert.strictEqual(typeof CanceledError, 'function');
assert.strictEqual(typeof AxiosError, 'function');
assert.strictEqual(typeof AxiosHeaders, 'function');
assert.strictEqual(typeof formToJSON, 'function');
assert.strictEqual(typeof spread, 'function');
assert.strictEqual(typeof isAxiosError, 'function');
assert.strictEqual(typeof isCancel, 'function');
assert.strictEqual(typeof all, 'function');
assert.strictEqual(typeof toFormData, 'function');
assert.strictEqual(typeof axios.CanceledError, 'function');
assert.strictEqual(typeof axios.AxiosError, 'function');
assert.strictEqual(typeof axios.AxiosHeaders, 'function');
assert.strictEqual(typeof axios.formToJSON, 'function');
assert.strictEqual(typeof axios.spread, 'function');
assert.strictEqual(typeof axios.isAxiosError, 'function');
assert.strictEqual(typeof axios.isCancel, 'function');
assert.strictEqual(typeof axios.all, 'function');
assert.strictEqual(typeof axios.toFormData, 'function');

View File

@ -1,20 +0,0 @@
{
"name": "ts-entrypoint-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "npm i --no-save --no-package-lock && npm run build && node index.js",
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@types/node": "^18.11.3",
"axios": "file:../../.."
},
"devDependencies": {
"typescript": "^5.9.3"
}
}

View File

@ -1,103 +0,0 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View File

@ -1,59 +0,0 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const axios_1 = __importStar(require("axios"));
assert_1.default.strictEqual(typeof axios_1.default, 'function');
assert_1.default.strictEqual(typeof axios_1.CanceledError, 'function');
assert_1.default.strictEqual(typeof axios_1.AxiosError, 'function');
assert_1.default.strictEqual(typeof axios_1.AxiosHeaders, 'function');
assert_1.default.strictEqual(typeof axios_1.formToJSON, 'function');
assert_1.default.strictEqual(typeof axios_1.spread, 'function');
assert_1.default.strictEqual(typeof axios_1.isAxiosError, 'function');
assert_1.default.strictEqual(typeof axios_1.isCancel, 'function');
assert_1.default.strictEqual(typeof axios_1.all, 'function');
assert_1.default.strictEqual(typeof axios_1.toFormData, 'function');
assert_1.default.strictEqual(typeof axios_1.default.CanceledError, 'function');
assert_1.default.strictEqual(typeof axios_1.default.AxiosError, 'function');
assert_1.default.strictEqual(typeof axios_1.default.AxiosHeaders, 'function');
assert_1.default.strictEqual(typeof axios_1.default.formToJSON, 'function');
assert_1.default.strictEqual(typeof axios_1.default.spread, 'function');
assert_1.default.strictEqual(typeof axios_1.default.isAxiosError, 'function');
assert_1.default.strictEqual(typeof axios_1.default.isCancel, 'function');
assert_1.default.strictEqual(typeof axios_1.default.all, 'function');
assert_1.default.strictEqual(typeof axios_1.default.toFormData, 'function');

View File

@ -1,20 +0,0 @@
{
"name": "ts-entrypoint-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "npm i --no-save --no-package-lock && npm run build && node index.js",
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@types/node": "^18.11.3",
"axios": "file:../../.."
},
"devDependencies": {
"typescript": "^5.9.3"
}
}

View File

@ -1,103 +0,0 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View File

@ -1,20 +0,0 @@
{
"name": "commonjs-typings-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "npm i --no-save --no-package-lock && tsc -v && npm run test:types",
"test:types": "tsc --noEmit"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@types/node": "^18.11.3",
"axios": "file:../../../.."
},
"devDependencies": {
"typescript": "^5.9.3"
}
}

View File

@ -1,6 +0,0 @@
{
"compilerOptions": {
"checkJs": true,
"module": "node16"
}
}

View File

@ -1,21 +0,0 @@
{
"name": "esm-typings-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test:types": "tsc --noEmit",
"test": "npm i --no-save --no-package-lock && tsc -v && npm run test:types"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@types/node": "^18.11.3",
"axios": "file:../../../.."
},
"devDependencies": {
"typescript": "^5.9.3"
}
}

View File

@ -1,6 +0,0 @@
{
"compilerOptions": {
"checkJs": true,
"module": "node16"
}
}

View File

@ -1,45 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
import _axios from '../../index.js';
window.axios = _axios;
// Jasmine config
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;
jasmine.getEnv().defaultTimeoutInterval = 60000;
window.TEST_SERVER_URL = 'http://localhost:3000';
// Get Ajax request using an increasing timeout to retry
window.getAjaxRequest = (function () {
let attempts = 0;
const MAX_ATTEMPTS = 5;
const ATTEMPT_DELAY_FACTOR = 5;
function getAjaxRequest() {
return new Promise(function (resolve, reject) {
attempts = 0;
attemptGettingAjaxRequest(resolve, reject);
});
}
function attemptGettingAjaxRequest(resolve, reject) {
const delay = attempts * attempts * ATTEMPT_DELAY_FACTOR;
if (attempts++ > MAX_ATTEMPTS) {
reject(new Error('No request was found'));
return;
}
setTimeout(function () {
const request = jasmine.Ajax.requests.mostRecent();
if (request) {
resolve(request);
} else {
attemptGettingAjaxRequest(resolve, reject);
}
}, delay);
}
return getAjaxRequest;
})();

View File

@ -1,98 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
describe('adapter', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should support custom adapter', function (done) {
axios('/foo', {
adapter: function barAdapter(config) {
return new Promise(function dispatchXhrRequest(resolve) {
const request = new XMLHttpRequest();
request.open('GET', '/bar');
request.onreadystatechange = function () {
resolve({
config: config,
request: request,
});
};
request.send(null);
});
},
}).catch(done);
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/bar');
done();
});
});
it('should execute adapter code synchronously', function (done) {
let asyncFlag = false;
axios('/foo', {
adapter: function barAdapter(config) {
return new Promise(function dispatchXhrRequest(resolve) {
const request = new XMLHttpRequest();
request.open('GET', '/bar');
request.onreadystatechange = function () {
resolve({
config: config,
request: request,
});
};
expect(asyncFlag).toBe(false);
request.send(null);
});
},
}).catch(done);
asyncFlag = true;
getAjaxRequest().then(function () {
done();
});
});
it('should execute adapter code asynchronously when interceptor is present', function (done) {
let asyncFlag = false;
axios.interceptors.request.use(function (config) {
config.headers.async = 'async it!';
return config;
});
axios('/foo', {
adapter: function barAdapter(config) {
return new Promise(function dispatchXhrRequest(resolve) {
const request = new XMLHttpRequest();
request.open('GET', '/bar');
request.onreadystatechange = function () {
resolve({
config: config,
request: request,
});
};
expect(asyncFlag).toBe(true);
request.send(null);
});
},
}).catch(done);
asyncFlag = true;
getAjaxRequest().then(function () {
done();
});
});
});

View File

@ -1,81 +0,0 @@
/* eslint-env mocha */
describe('static api', function () {
it('should have request method helpers', function () {
expect(typeof axios.request).toEqual('function');
expect(typeof axios.get).toEqual('function');
expect(typeof axios.head).toEqual('function');
expect(typeof axios.options).toEqual('function');
expect(typeof axios.delete).toEqual('function');
expect(typeof axios.post).toEqual('function');
expect(typeof axios.put).toEqual('function');
expect(typeof axios.patch).toEqual('function');
});
it('should have promise method helpers', function () {
const promise = axios('/test');
expect(typeof promise.then).toEqual('function');
expect(typeof promise.catch).toEqual('function');
});
it('should have defaults', function () {
expect(typeof axios.defaults).toEqual('object');
expect(typeof axios.defaults.headers).toEqual('object');
});
it('should have interceptors', function () {
expect(typeof axios.interceptors.request).toEqual('object');
expect(typeof axios.interceptors.response).toEqual('object');
});
it('should have all/spread helpers', function () {
expect(typeof axios.all).toEqual('function');
expect(typeof axios.spread).toEqual('function');
});
it('should have factory method', function () {
expect(typeof axios.create).toEqual('function');
});
it('should have CanceledError, CancelToken, and isCancel properties', function () {
expect(typeof axios.Cancel).toEqual('function');
expect(typeof axios.CancelToken).toEqual('function');
expect(typeof axios.isCancel).toEqual('function');
});
it('should have getUri method', function () {
expect(typeof axios.getUri).toEqual('function');
});
it('should have isAxiosError properties', function () {
expect(typeof axios.isAxiosError).toEqual('function');
});
it('should have mergeConfig properties', function () {
expect(typeof axios.mergeConfig).toEqual('function');
});
it('should have getAdapter properties', function () {
expect(typeof axios.getAdapter).toEqual('function');
});
});
describe('instance api', function () {
const instance = axios.create();
it('should have request methods', function () {
expect(typeof instance.request).toEqual('function');
expect(typeof instance.get).toEqual('function');
expect(typeof instance.options).toEqual('function');
expect(typeof instance.head).toEqual('function');
expect(typeof instance.delete).toEqual('function');
expect(typeof instance.post).toEqual('function');
expect(typeof instance.put).toEqual('function');
expect(typeof instance.patch).toEqual('function');
});
it('should have interceptors', function () {
expect(typeof instance.interceptors.request).toEqual('object');
expect(typeof instance.interceptors.response).toEqual('object');
});
});

View File

@ -1,87 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
import axios from '../../index';
function validateInvalidCharacterError(error) {
expect(/character/i.test(error.message)).toEqual(true);
}
describe('basicAuth', function () {
// Validate an invalid character error
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should accept HTTP Basic auth with username/password', function (done) {
axios('/foo', {
auth: {
username: 'Aladdin',
password: 'open sesame',
},
});
setTimeout(function () {
const request = jasmine.Ajax.requests.mostRecent();
expect(request.requestHeaders['Authorization']).toEqual('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==');
done();
}, 100);
});
it('should accept HTTP Basic auth credentials without the password parameter', function (done) {
axios('/foo', {
auth: {
username: 'Aladdin',
},
});
setTimeout(function () {
const request = jasmine.Ajax.requests.mostRecent();
expect(request.requestHeaders['Authorization']).toEqual('Basic QWxhZGRpbjo=');
done();
}, 100);
});
it('should accept HTTP Basic auth credentials with non-Latin1 characters in password', function (done) {
axios('/foo', {
auth: {
username: 'Aladdin',
password: 'open ßç£☃sesame',
},
});
setTimeout(function () {
const request = jasmine.Ajax.requests.mostRecent();
expect(request.requestHeaders['Authorization']).toEqual(
'Basic QWxhZGRpbjpvcGVuIMOfw6fCo+KYg3Nlc2FtZQ=='
);
done();
}, 100);
});
it('should fail to encode HTTP Basic auth credentials with non-Latin1 characters in username', function (done) {
axios('/foo', {
auth: {
username: 'Aladßç£☃din',
password: 'open sesame',
},
})
.then(function (response) {
done(
new Error(
'Should not succeed to make a HTTP Basic auth request with non-latin1 chars in credentials.'
)
);
})
.catch(function (error) {
validateInvalidCharacterError(error);
done();
});
});
});

View File

@ -1,130 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
const Cancel = axios.Cancel;
const CancelToken = axios.CancelToken;
import { AbortController as _AbortController } from 'abortcontroller-polyfill/dist/cjs-ponyfill.js';
const envAbortController =
typeof AbortController === 'function' ? AbortController : _AbortController;
describe('cancel', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
describe('when called before sending request', function () {
it('rejects Promise with a CanceledError object', function (done) {
const source = CancelToken.source();
source.cancel('Operation has been canceled.');
axios
.get('/foo', {
cancelToken: source.token,
})
.catch(function (thrown) {
expect(thrown).toEqual(jasmine.any(Cancel));
expect(thrown.message).toBe('Operation has been canceled.');
done();
});
});
});
describe('when called after request has been sent', function () {
it('rejects Promise with a CanceledError object', function (done) {
const source = CancelToken.source();
axios
.get('/foo/bar', {
cancelToken: source.token,
})
.catch(function (thrown) {
expect(thrown).toEqual(jasmine.any(Cancel));
expect(thrown.message).toBe('Operation has been canceled.');
done();
});
getAjaxRequest().then(function (request) {
// call cancel() when the request has been sent, but a response has not been received
source.cancel('Operation has been canceled.');
request.respondWith({
status: 200,
responseText: 'OK',
});
});
});
it('calls abort on request object', function (done) {
const source = CancelToken.source();
let request;
axios
.get('/foo/bar', {
cancelToken: source.token,
})
.catch(function () {
// jasmine-ajax sets statusText to 'abort' when request.abort() is called
expect(request.statusText).toBe('abort');
done();
});
getAjaxRequest().then(function (req) {
// call cancel() when the request has been sent, but a response has not been received
source.cancel();
request = req;
});
});
});
// describe('when called after response has been received', function() {
// // https://github.com/axios/axios/issues/482
// it('does not cause unhandled rejection', function(done) {
// var source = CancelToken.source();
// axios.get('/foo', {
// cancelToken: source.token
// }).then(function() {
// window.addEventListener('unhandledrejection', function() {
// done.fail('Unhandled rejection.');
// });
// source.cancel();
// setTimeout(done, 100);
// });
// getAjaxRequest().then(function(request) {
// request.respondWith({
// status: 200,
// responseText: 'OK'
// });
// });
// });
// });
it('it should support cancellation using AbortController signal', function (done) {
const controller = new envAbortController();
axios
.get('/foo/bar', {
signal: controller.signal,
})
.then(
function () {
done.fail('Has not been canceled');
},
function (thrown) {
expect(thrown).toEqual(jasmine.any(Cancel));
done();
}
);
getAjaxRequest().then(function (request) {
// call cancel() when the request has been sent, but a response has not been received
controller.abort();
setTimeout(function () {
request.respondWith({
status: 200,
responseText: 'OK',
});
}, 0);
});
});
});

View File

@ -1,88 +0,0 @@
/* eslint-env mocha */
import CancelToken from '../../../lib/cancel/CancelToken';
import CanceledError from '../../../lib/cancel/CanceledError';
describe('CancelToken', function () {
describe('constructor', function () {
it('throws when executor is not specified', function () {
expect(function () {
new CancelToken();
}).toThrowError(TypeError, 'executor must be a function.');
});
it('throws when executor is not a function', function () {
expect(function () {
new CancelToken(123);
}).toThrowError(TypeError, 'executor must be a function.');
});
});
describe('reason', function () {
it('returns a CanceledError if cancellation has been requested', function () {
let cancel;
const token = new CancelToken(function (c) {
cancel = c;
});
cancel('Operation has been canceled.');
expect(token.reason).toEqual(jasmine.any(CanceledError));
expect(token.reason.message).toBe('Operation has been canceled.');
});
it('returns undefined if cancellation has not been requested', function () {
const token = new CancelToken(function () {});
expect(token.reason).toBeUndefined();
});
});
describe('promise', function () {
it('returns a Promise that resolves when cancellation is requested', function (done) {
let cancel;
const token = new CancelToken(function (c) {
cancel = c;
});
token.promise.then(function onFulfilled(value) {
expect(value).toEqual(jasmine.any(CanceledError));
expect(value.message).toBe('Operation has been canceled.');
done();
});
cancel('Operation has been canceled.');
});
});
describe('throwIfRequested', function () {
it('throws if cancellation has been requested', function () {
// Note: we cannot use expect.toThrowError here as CanceledError does not inherit from Error
let cancel;
const token = new CancelToken(function (c) {
cancel = c;
});
cancel('Operation has been canceled.');
try {
token.throwIfRequested();
fail('Expected throwIfRequested to throw.');
} catch (thrown) {
if (!(thrown instanceof CanceledError)) {
fail('Expected throwIfRequested to throw a CanceledError, but it threw ' + thrown + '.');
}
expect(thrown.message).toBe('Operation has been canceled.');
}
});
it('does not throw if cancellation has not been requested', function () {
const token = new CancelToken(function () {});
token.throwIfRequested();
});
});
describe('source', function () {
it('returns an object containing token and cancel function', function () {
const source = CancelToken.source();
expect(source.token).toEqual(jasmine.any(CancelToken));
expect(source.cancel).toEqual(jasmine.any(Function));
expect(source.token.reason).toBeUndefined();
source.cancel('Operation has been canceled.');
expect(source.token.reason).toEqual(jasmine.any(CanceledError));
expect(source.token.reason.message).toBe('Operation has been canceled.');
});
});
});

View File

@ -1,22 +0,0 @@
/* eslint-env mocha */
import CanceledError from '../../../lib/cancel/CanceledError';
describe('Cancel', function () {
describe('toString', function () {
it('returns correct result when message is not specified', function () {
const cancel = new CanceledError();
expect(cancel.toString()).toBe('CanceledError: canceled');
});
it('returns correct result when message is specified', function () {
const cancel = new CanceledError('Operation has been canceled.');
expect(cancel.toString()).toBe('CanceledError: Operation has been canceled.');
});
});
it('should be a native error as checked by the NodeJS `isNativeError` function', function () {
if (typeof process !== 'undefined' && process.release.name === 'node') {
let { isNativeError } = require('node:util/types');
expect(isNativeError(new CanceledError('My Canceled Error'))).toBeTruthy();
}
});
});

View File

@ -1,13 +0,0 @@
/* eslint-env mocha */
import isCancel from '../../../lib/cancel/isCancel';
import CanceledError from '../../../lib/cancel/CanceledError';
describe('isCancel', function () {
it('returns true if value is a CanceledError', function () {
expect(isCancel(new CanceledError())).toBe(true);
});
it('returns false if value is not a CanceledError', function () {
expect(isCancel({ foo: 'bar' })).toBe(false);
});
});

View File

@ -1,110 +0,0 @@
/* eslint-env mocha */
import AxiosError from '../../../lib/core/AxiosError';
describe('core::AxiosError', function () {
it('should create an Error with message, config, code, request, response, stack and isAxiosError', function () {
const request = { path: '/foo' };
const response = { status: 200, data: { foo: 'bar' } };
const error = new AxiosError('Boom!', 'ESOMETHING', { foo: 'bar' }, request, response);
expect(error instanceof Error).toBe(true);
expect(error.message).toBe('Boom!');
expect(error.config).toEqual({ foo: 'bar' });
expect(error.code).toBe('ESOMETHING');
expect(error.request).toBe(request);
expect(error.response).toBe(response);
expect(error.isAxiosError).toBe(true);
expect(error.stack).toBeDefined();
});
it('should create an Error that can be serialized to JSON', function () {
// Attempting to serialize request and response results in
// TypeError: Converting circular structure to JSON
const request = { path: '/foo' };
const response = { status: 200, data: { foo: 'bar' } };
const error = new AxiosError('Boom!', 'ESOMETHING', { foo: 'bar' }, request, response);
const json = error.toJSON();
expect(json.message).toBe('Boom!');
expect(json.config).toEqual({ foo: 'bar' });
expect(json.code).toBe('ESOMETHING');
expect(json.status).toBe(200);
expect(json.request).toBe(undefined);
expect(json.response).toBe(undefined);
});
describe('core::createError.from', function () {
it('should add config, config, request and response to error', function () {
const error = new Error('Boom!');
const request = { path: '/foo' };
const response = { status: 200, data: { foo: 'bar' } };
const axiosError = AxiosError.from(error, 'ESOMETHING', { foo: 'bar' }, request, response);
expect(axiosError.config).toEqual({ foo: 'bar' });
expect(axiosError.code).toBe('ESOMETHING');
expect(axiosError.request).toBe(request);
expect(axiosError.response).toBe(response);
expect(axiosError.isAxiosError).toBe(true);
});
it('should return error', function () {
const error = new Error('Boom!');
expect(
AxiosError.from(error, 'ESOMETHING', { foo: 'bar' }) instanceof AxiosError
).toBeTruthy();
});
it('should preserve status property from original error when response is not provided', function () {
const error = new Error('Network Error');
error.status = 404;
const axiosError = AxiosError.from(error, 'ERR_NETWORK', { foo: 'bar' });
expect(axiosError.status).toBe(404);
});
it('should use response.status over error.status when response is provided', function () {
const error = new Error('Error');
error.status = 500;
const response = { status: 404 };
const axiosError = AxiosError.from(error, 'ERR_BAD_REQUEST', {}, null, response);
expect(axiosError.status).toBe(404);
});
});
it('should be a native error as checked by the NodeJS `isNativeError` function', function () {
if (typeof process !== 'undefined' && process.release.name === 'node') {
let { isNativeError } = require('node:util/types');
expect(isNativeError(new AxiosError('My Axios Error'))).toBeTruthy();
}
});
it('should create an error using one of the static class properties as an error code', function () {
const myError = new AxiosError('My Axios Error', AxiosError.ECONNABORTED);
expect(myError.code).toEqual(AxiosError.ECONNABORTED);
});
it('should have status property when response was passed to the constructor', () => {
const err = new AxiosError('test', 'foo', {}, {}, { status: 400 });
expect(err.status).toBe(400);
});
it('should have message property as enumerable for backward compatibility', () => {
const err = new AxiosError('Test error message', 'ERR_TEST', { foo: 'bar' });
// Test Object.keys() includes message
const keys = Object.keys(err);
expect(keys).toContain('message');
// Test Object.entries() includes message
const entries = Object.entries(err);
const messageEntry = entries.find(([key]) => key === 'message');
expect(messageEntry).toBeDefined();
expect(messageEntry[1]).toBe('Test error message');
// Test spread operator includes message
const spread = { ...err };
expect(spread.message).toBe('Test error message');
// Verify message descriptor is enumerable
const descriptor = Object.getOwnPropertyDescriptor(err, 'message');
expect(descriptor.enumerable).toBe(true);
});
});

View File

@ -1,34 +0,0 @@
/* eslint-env mocha */
import buildFullPath from '../../../lib/core/buildFullPath';
describe('helpers::buildFullPath', function () {
it('should combine URLs when the requestedURL is relative', function () {
expect(buildFullPath('https://api.github.com', '/users')).toBe('https://api.github.com/users');
});
it('should not combine the URLs when the requestedURL is absolute', function () {
expect(buildFullPath('https://api.github.com', 'https://api.example.com/users')).toBe(
'https://api.example.com/users'
);
});
it('should combine the URLs when the requestedURL is absolute and allowAbsoluteUrls is false', function () {
expect(buildFullPath('https://api.github.com', 'https://api.example.com/users', false)).toBe(
'https://api.github.com/https://api.example.com/users'
);
});
it('should not combine the URLs when the requestedURL is absolute, allowAbsoluteUrls is false, and the baseURL is not configured', function () {
expect(buildFullPath(undefined, 'https://api.example.com/users', false)).toBe(
'https://api.example.com/users'
);
});
it('should not combine URLs when the baseURL is not configured', function () {
expect(buildFullPath(undefined, '/users')).toBe('/users');
});
it('should combine URLs when the baseURL and requestedURL are relative', function () {
expect(buildFullPath('/api', '/users')).toBe('/api/users');
});
});

View File

@ -1,348 +0,0 @@
/* eslint-env mocha */
import defaults from '../../../lib/defaults';
import mergeConfig from '../../../lib/core/mergeConfig';
import { AxiosHeaders } from '../../../index.js';
describe('core::mergeConfig', function () {
it('should accept undefined for second argument', function () {
expect(mergeConfig(defaults, undefined)).toEqual(defaults);
});
it('should accept an object for second argument', function () {
expect(mergeConfig(defaults, {})).toEqual(defaults);
});
it('should not leave references', function () {
const merged = mergeConfig(defaults, {});
expect(merged).not.toBe(defaults);
expect(merged.headers).not.toBe(defaults.headers);
});
it('should allow setting request options', function () {
const config = {
url: '__sample url__',
method: '__sample method__',
params: '__sample params__',
data: { foo: true },
};
const merged = mergeConfig(defaults, config);
expect(merged.url).toEqual(config.url);
expect(merged.method).toEqual(config.method);
expect(merged.params).toEqual(config.params);
expect(merged.data).toEqual(config.data);
});
it('should not inherit request options', function () {
const localDefaults = {
method: '__sample method__',
data: { foo: true },
};
const merged = mergeConfig(localDefaults, {});
expect(merged.method).toEqual(undefined);
expect(merged.data).toEqual(undefined);
});
['auth', 'headers', 'params', 'proxy'].forEach(function (key) {
it('should set new config for' + key + ' without default', function () {
const a = {},
b = {},
c = {};
a[key] = undefined;
b[key] = { user: 'foo', pass: 'test' };
c[key] = { user: 'foo', pass: 'test' };
expect(mergeConfig(a, b)).toEqual(c);
});
it('should merge ' + key + ' with defaults', function () {
const a = {},
b = {},
c = {};
a[key] = { user: 'foo', pass: 'bar' };
b[key] = { pass: 'test' };
c[key] = { user: 'foo', pass: 'test' };
expect(mergeConfig(a, b)).toEqual(c);
});
it('should overwrite default ' + key + ' with a non-object value', function () {
[false, null, 123].forEach(function (value) {
const a = {},
b = {},
c = {};
a[key] = { user: 'foo', pass: 'test' };
b[key] = value;
c[key] = value;
expect(mergeConfig(a, b)).toEqual(c);
});
});
});
it('should allow setting other options', function () {
const merged = mergeConfig(defaults, { timeout: 123 });
expect(merged.timeout).toEqual(123);
});
it('should allow setting custom options', function () {
const merged = mergeConfig(defaults, { foo: 'bar' });
expect(merged.foo).toEqual('bar');
});
it('should allow setting custom default options', function () {
const merged = mergeConfig({ foo: 'bar' }, {});
expect(merged.foo).toEqual('bar');
});
it('should allow merging custom objects in the config', function () {
const merged = mergeConfig(
{
nestedConfig: {
propertyOnDefaultConfig: true,
},
},
{
nestedConfig: {
propertyOnRequestConfig: true,
},
}
);
expect(merged.nestedConfig.propertyOnDefaultConfig).toEqual(true);
expect(merged.nestedConfig.propertyOnRequestConfig).toEqual(true);
});
describe('headers', () => {
it('should allow merging with AxiosHeaders instances', () => {
const merged = mergeConfig(
{
headers: new AxiosHeaders({
x: 1,
y: 2,
}),
},
{
headers: new AxiosHeaders({
X: 1,
Y: 2,
}),
}
);
expect(merged.headers).toEqual({
x: '1',
y: '2',
});
});
});
describe('valueFromConfig2Keys', function () {
const config1 = { url: '/foo', method: 'post', data: { a: 3 } };
it('should skip if config2 is undefined', function () {
expect(mergeConfig(config1, {})).toEqual({});
});
it('should clone config2 if is plain object', function () {
const data = { a: 1, b: 2 };
const merged = mergeConfig(config1, { data: data });
expect(merged.data).toEqual(data);
expect(merged.data).not.toBe(data);
});
it('should clone config2 if is array', function () {
const data = [1, 2, 3];
const merged = mergeConfig(config1, { data: data });
expect(merged.data).toEqual(data);
expect(merged.data).not.toBe(data);
});
it('should set as config2 in other cases', function () {
const obj = Object.create({});
expect(mergeConfig(config1, { data: 1 }).data).toBe(1);
expect(mergeConfig(config1, { data: 'str' }).data).toBe('str');
expect(mergeConfig(config1, { data: obj }).data).toBe(obj);
expect(mergeConfig(config1, { data: null }).data).toBe(null);
});
});
describe('mergeDeepPropertiesKeys', function () {
it('should skip if both config1 and config2 are undefined', function () {
expect(mergeConfig({ headers: undefined }, { headers: undefined })).toEqual({});
});
it('should merge if both config1 and config2 are plain object', function () {
expect(mergeConfig({ headers: { a: 1, b: 1 } }, { headers: { b: 2, c: 2 } })).toEqual({
headers: { a: 1, b: 2, c: 2 },
});
});
it('should clone config2 if is plain object', function () {
const config1 = { headers: [1, 2, 3] };
const config2 = { headers: { a: 1, b: 2 } };
const merged = mergeConfig(config1, config2);
expect(merged.headers).toEqual(config2.headers);
expect(merged.headers).not.toBe(config2.headers);
});
it('should clone config2 if is array', function () {
const config1 = { headers: { a: 1, b: 1 } };
const config2 = { headers: [1, 2, 3] };
const merged = mergeConfig(config1, config2);
expect(merged.headers).toEqual(config2.headers);
expect(merged.headers).not.toBe(config2.headers);
});
it('should set as config2 in other cases', function () {
const config1 = { headers: { a: 1, b: 1 } };
const obj = Object.create({});
expect(mergeConfig(config1, { headers: 1 }).headers).toBe(1);
expect(mergeConfig(config1, { headers: 'str' }).headers).toBe('str');
expect(mergeConfig(config1, { headers: obj }).headers).toBe(obj);
expect(mergeConfig(config1, { headers: null }).headers).toBe(null);
});
it('should clone config1 if is plain object', function () {
const config1 = { headers: { a: 1, b: 2 } };
const config2 = {};
const merged = mergeConfig(config1, config2);
expect(merged.headers).toEqual(config1.headers);
expect(merged.headers).not.toBe(config1.headers);
});
it('should clone config1 if is array', function () {
const config1 = { headers: [1, 2, 3] };
const config2 = {};
const merged = mergeConfig(config1, config2);
expect(merged.headers).toEqual(config1.headers);
expect(merged.headers).not.toBe(config1.headers);
});
it('should set as config1 in other cases', function () {
const config2 = {};
const obj = Object.create({});
expect(mergeConfig({ headers: 1 }, config2).headers).toBe(1);
expect(mergeConfig({ headers: 'str' }, config2).headers).toBe('str');
expect(mergeConfig({ headers: obj }, config2).headers).toBe(obj);
expect(mergeConfig({ headers: null }, config2).headers).toBe(null);
});
});
describe('defaultToConfig2Keys', function () {
it('should skip if both config1 and config2 are undefined', function () {
expect(mergeConfig({ transformRequest: undefined }, { transformRequest: undefined })).toEqual(
{}
);
});
it('should clone config2 if both config1 and config2 are plain object', function () {
const config1 = { transformRequest: { a: 1, b: 1 } };
const config2 = { transformRequest: { b: 2, c: 2 } };
const merged = mergeConfig(config1, config2);
expect(merged.transformRequest).toEqual(config2.transformRequest);
expect(merged.transformRequest).not.toBe(config2.transformRequest);
});
it('should clone config2 if is array', function () {
const config1 = { transformRequest: { a: 1, b: 1 } };
const config2 = { transformRequest: [1, 2, 3] };
const merged = mergeConfig(config1, config2);
expect(merged.transformRequest).toEqual(config2.transformRequest);
expect(merged.transformRequest).not.toBe(config2.transformRequest);
});
it('should set as config2 in other cases', function () {
const config1 = { transformRequest: { a: 1, b: 1 } };
const obj = Object.create({});
expect(mergeConfig(config1, { transformRequest: 1 }).transformRequest).toBe(1);
expect(mergeConfig(config1, { transformRequest: 'str' }).transformRequest).toBe('str');
expect(mergeConfig(config1, { transformRequest: obj }).transformRequest).toBe(obj);
expect(mergeConfig(config1, { transformRequest: null }).transformRequest).toBe(null);
});
it('should clone config1 if is plain object', function () {
const config1 = { transformRequest: { a: 1, b: 2 } };
const config2 = {};
const merged = mergeConfig(config1, config2);
expect(merged.transformRequest).toEqual(config1.transformRequest);
expect(merged.transformRequest).not.toBe(config1.transformRequest);
});
it('should clone config1 if is array', function () {
const config1 = { transformRequest: [1, 2, 3] };
const config2 = {};
const merged = mergeConfig(config1, config2);
expect(merged.transformRequest).toEqual(config1.transformRequest);
expect(merged.transformRequest).not.toBe(config1.transformRequest);
});
it('should set as config1 in other cases', function () {
const config2 = {};
const obj = Object.create({});
expect(mergeConfig({ transformRequest: 1 }, config2).transformRequest).toBe(1);
expect(mergeConfig({ transformRequest: 'str' }, config2).transformRequest).toBe('str');
expect(mergeConfig({ transformRequest: obj }, config2).transformRequest).toBe(obj);
expect(mergeConfig({ transformRequest: null }, config2).transformRequest).toBe(null);
});
});
describe('directMergeKeys', function () {
it('should merge if config2 in keys', function () {
expect(mergeConfig({}, { validateStatus: undefined })).toEqual({ validateStatus: undefined });
});
it('should merge if both config1 and config2 are plain object', function () {
expect(
mergeConfig({ validateStatus: { a: 1, b: 1 } }, { validateStatus: { b: 2, c: 2 } })
).toEqual({ validateStatus: { a: 1, b: 2, c: 2 } });
});
it('should clone config2 if is plain object', function () {
const config1 = { validateStatus: [1, 2, 3] };
const config2 = { validateStatus: { a: 1, b: 2 } };
const merged = mergeConfig(config1, config2);
expect(merged.validateStatus).toEqual(config2.validateStatus);
expect(merged.validateStatus).not.toBe(config2.validateStatus);
});
it('should clone config2 if is array', function () {
const config1 = { validateStatus: { a: 1, b: 2 } };
const config2 = { validateStatus: [1, 2, 3] };
const merged = mergeConfig(config1, config2);
expect(merged.validateStatus).toEqual(config2.validateStatus);
expect(merged.validateStatus).not.toBe(config2.validateStatus);
});
it('should set as config2 in other cases', function () {
const config1 = { validateStatus: { a: 1, b: 2 } };
const obj = Object.create({});
expect(mergeConfig(config1, { validateStatus: 1 }).validateStatus).toBe(1);
expect(mergeConfig(config1, { validateStatus: 'str' }).validateStatus).toBe('str');
expect(mergeConfig(config1, { validateStatus: obj }).validateStatus).toBe(obj);
expect(mergeConfig(config1, { validateStatus: null }).validateStatus).toBe(null);
});
it('should clone config1 if is plain object', function () {
const config1 = { validateStatus: { a: 1, b: 2 } };
const config2 = {};
const merged = mergeConfig(config1, config2);
expect(merged.validateStatus).toEqual(config1.validateStatus);
expect(merged.validateStatus).not.toBe(config1.validateStatus);
});
it('should clone config1 if is array', function () {
const config1 = { validateStatus: [1, 2, 3] };
const config2 = {};
const merged = mergeConfig(config1, config2);
expect(merged.validateStatus).toEqual(config1.validateStatus);
expect(merged.validateStatus).not.toBe(config1.validateStatus);
});
it('should set as config1 in other cases', function () {
const config2 = {};
const obj = Object.create({});
expect(mergeConfig({ validateStatus: 1 }, config2).validateStatus).toBe(1);
expect(mergeConfig({ validateStatus: 'str' }, config2).validateStatus).toBe('str');
expect(mergeConfig({ validateStatus: obj }, config2).validateStatus).toBe(obj);
expect(mergeConfig({ validateStatus: null }, config2).validateStatus).toBe(null);
});
});
});

View File

@ -1,85 +0,0 @@
/* eslint-env mocha */
import settle from '../../../lib/core/settle';
describe('core::settle', function () {
let resolve;
let reject;
beforeEach(function () {
resolve = jasmine.createSpy('resolve');
reject = jasmine.createSpy('reject');
});
it('should resolve promise if status is not set', function () {
const response = {
config: {
validateStatus: function () {
return true;
},
},
};
settle(resolve, reject, response);
expect(resolve).toHaveBeenCalledWith(response);
expect(reject).not.toHaveBeenCalled();
});
it('should resolve promise if validateStatus is not set', function () {
const response = {
status: 500,
config: {},
};
settle(resolve, reject, response);
expect(resolve).toHaveBeenCalledWith(response);
expect(reject).not.toHaveBeenCalled();
});
it('should resolve promise if validateStatus returns true', function () {
const response = {
status: 500,
config: {
validateStatus: function () {
return true;
},
},
};
settle(resolve, reject, response);
expect(resolve).toHaveBeenCalledWith(response);
expect(reject).not.toHaveBeenCalled();
});
it('should reject promise if validateStatus returns false', function () {
const req = {
path: '/foo',
};
const response = {
status: 500,
config: {
validateStatus: function () {
return false;
},
},
request: req,
};
settle(resolve, reject, response);
expect(resolve).not.toHaveBeenCalled();
expect(reject).toHaveBeenCalled();
const reason = reject.calls.first().args[0];
expect(reason instanceof Error).toBe(true);
expect(reason.message).toBe('Request failed with status code 500');
expect(reason.config).toBe(response.config);
expect(reason.request).toBe(req);
expect(reason.response).toBe(response);
});
it('should pass status to validateStatus', function () {
const validateStatus = jasmine.createSpy('validateStatus');
const response = {
status: 500,
config: {
validateStatus: validateStatus,
},
};
settle(resolve, reject, response);
expect(validateStatus).toHaveBeenCalledWith(500);
});
});

View File

@ -1,66 +0,0 @@
/* eslint-env mocha */
import transformData from '../../../lib/core/transformData';
describe('core::transformData', function () {
it('should support a single transformer', function () {
let data;
data = transformData.call({}, function (data) {
data = 'foo';
return data;
});
expect(data).toEqual('foo');
});
it('should support an array of transformers', function () {
let data = '';
data = transformData.call({ data }, [
function (data) {
data += 'f';
return data;
},
function (data) {
data += 'o';
return data;
},
function (data) {
data += 'o';
return data;
},
]);
expect(data).toEqual('foo');
});
it('should support reference headers in transformData', function () {
const headers = {
'content-type': 'foo/bar',
};
let data = '';
data = transformData.call({ data, headers }, [
function (data, headers) {
data += headers['content-type'];
return data;
},
]);
expect(data).toEqual('foo/bar');
});
it('should support reference status code in transformData', function () {
let data = '';
data = transformData.call(
{},
[
function (data, headers, status) {
data += status;
return data;
},
],
{ data, status: 200 }
);
expect(data).toEqual('200');
});
});

View File

@ -1,209 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
import defaults from '../../lib/defaults';
import AxiosHeaders from '../../lib/core/AxiosHeaders';
describe('defaults', function () {
const XSRF_COOKIE_NAME = 'CUSTOM-XSRF-TOKEN';
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
delete axios.defaults.baseURL;
delete axios.defaults.headers.get['X-CUSTOM-HEADER'];
delete axios.defaults.headers.post['X-CUSTOM-HEADER'];
document.cookie =
XSRF_COOKIE_NAME + '=;expires=' + new Date(Date.now() - 86400000).toGMTString();
});
it('should transform request json', function () {
expect(defaults.transformRequest[0]({ foo: 'bar' }, new AxiosHeaders())).toEqual(
'{"foo":"bar"}'
);
});
it("should also transform request json when 'Content-Type' is 'application/json'", function () {
const headers = new AxiosHeaders({
'Content-Type': 'application/json',
});
expect(defaults.transformRequest[0](JSON.stringify({ foo: 'bar' }), headers)).toEqual(
'{"foo":"bar"}'
);
expect(defaults.transformRequest[0]([42, 43], headers)).toEqual('[42,43]');
expect(defaults.transformRequest[0]('foo', headers)).toEqual('"foo"');
expect(defaults.transformRequest[0](42, headers)).toEqual('42');
expect(defaults.transformRequest[0](true, headers)).toEqual('true');
expect(defaults.transformRequest[0](false, headers)).toEqual('false');
expect(defaults.transformRequest[0](null, headers)).toEqual('null');
});
it("should transform the plain data object to a FormData instance 'Content-Type' if header is 'multipart/form-data'", function () {
const headers = new AxiosHeaders({
'Content-Type': 'multipart/form-data',
});
const payload = { x: 1 };
const transformed = defaults.transformRequest[0](payload, headers);
expect(transformed).toEqual(jasmine.any(FormData));
});
it('should do nothing to request string', function () {
expect(defaults.transformRequest[0]('foo=bar', new AxiosHeaders())).toEqual('foo=bar');
});
it('should transform response json', function () {
const data = defaults.transformResponse[0].call(defaults, '{"foo":"bar"}');
expect(typeof data).toEqual('object');
expect(data.foo).toEqual('bar');
});
it('should do nothing to response string', function () {
expect(defaults.transformResponse[0]('foo=bar')).toEqual('foo=bar');
});
it('should use global defaults config', function (done) {
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo');
done();
});
});
it('should use modified defaults config', function (done) {
axios.defaults.baseURL = 'http://example.com/';
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('http://example.com/foo');
done();
});
});
it('should use request config', function (done) {
axios('/foo', {
baseURL: 'http://www.example.com',
});
getAjaxRequest().then(function (request) {
expect(request.url).toBe('http://www.example.com/foo');
done();
});
});
it('should use default config for custom instance', function (done) {
const instance = axios.create({
xsrfCookieName: XSRF_COOKIE_NAME,
xsrfHeaderName: 'X-CUSTOM-XSRF-TOKEN',
});
document.cookie = instance.defaults.xsrfCookieName + '=foobarbaz';
instance.get('/foo');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[instance.defaults.xsrfHeaderName]).toEqual('foobarbaz');
done();
});
});
it('should use GET headers', function (done) {
axios.defaults.headers.get['X-CUSTOM-HEADER'] = 'foo';
axios.get('/foo');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders['X-CUSTOM-HEADER']).toBe('foo');
done();
});
});
it('should use POST headers', function (done) {
axios.defaults.headers.post['X-CUSTOM-HEADER'] = 'foo';
axios.post('/foo', {});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders['X-CUSTOM-HEADER']).toBe('foo');
done();
});
});
it('should use header config', function (done) {
const instance = axios.create({
headers: {
common: {
'X-COMMON-HEADER': 'commonHeaderValue',
},
get: {
'X-GET-HEADER': 'getHeaderValue',
},
post: {
'X-POST-HEADER': 'postHeaderValue',
},
},
});
instance.get('/foo', {
headers: {
'X-FOO-HEADER': 'fooHeaderValue',
'X-BAR-HEADER': 'barHeaderValue',
},
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders).toEqual(
AxiosHeaders.concat(defaults.headers.common, defaults.headers.get, {
'X-COMMON-HEADER': 'commonHeaderValue',
'X-GET-HEADER': 'getHeaderValue',
'X-FOO-HEADER': 'fooHeaderValue',
'X-BAR-HEADER': 'barHeaderValue',
}).toJSON()
);
done();
});
});
it('should be used by custom instance if set before instance created', function (done) {
axios.defaults.baseURL = 'http://example.org/';
const instance = axios.create();
instance.get('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('http://example.org/foo');
done();
});
});
it('should not be used by custom instance if set after instance created', function (done) {
const instance = axios.create();
axios.defaults.baseURL = 'http://example.org/';
instance.get('/foo/users');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo/users');
done();
});
});
it('should resistant to ReDoS attack', function (done) {
const instance = axios.create();
const start = performance.now();
const slashes = '/'.repeat(100000);
instance.defaults.baseURL = '/' + slashes + 'bar/';
instance.get('/foo');
getAjaxRequest().then(function (request) {
const elapsedTimeMs = performance.now() - start;
expect(elapsedTimeMs).toBeLessThan(20);
expect(request.url).toBe('/' + slashes + 'bar/foo');
done();
});
});
});

View File

@ -1,20 +0,0 @@
/* eslint-env mocha */
import { retryNetwork } from '../helpers/retry.js';
describe('FormData', function () {
it('should allow FormData posting', async () => {
await retryNetwork(() => {
return axios
.postForm(TEST_SERVER_URL, {
a: 'foo',
b: 'bar',
})
.then(({ data }) => {
expect(data.form).toEqual({
a: 'foo',
b: 'bar',
});
});
});
});
});

View File

@ -1,169 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
const { AxiosHeaders } = axios;
function testHeaderValue(headers, key, val) {
let found = false;
for (const k in headers) {
if (k.toLowerCase() === key.toLowerCase()) {
found = true;
expect(headers[k]).toEqual(val);
break;
}
}
if (!found) {
if (typeof val === 'undefined') {
expect(headers.hasOwnProperty(key)).toEqual(false);
} else {
throw new Error(key + ' was not found in headers');
}
}
}
describe('headers', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should default common headers', function (done) {
const headers = axios.defaults.headers.common;
axios('/foo');
getAjaxRequest().then(function (request) {
for (const key in headers) {
if (headers.hasOwnProperty(key)) {
expect(request.requestHeaders[key]).toEqual(headers[key]);
}
}
done();
});
});
it('should respect common Content-Type header', function () {
const instance = axios.create();
instance.defaults.headers.common['Content-Type'] = 'application/custom';
instance.patch('/foo', '');
const expectedHeaders = {
'Content-Type': 'application/custom',
};
return getAjaxRequest().then(function (request) {
for (const key in expectedHeaders) {
if (expectedHeaders.hasOwnProperty(key)) {
expect(request.requestHeaders[key]).toEqual(expectedHeaders[key]);
}
}
});
});
it('should add extra headers for post', function () {
const headers = AxiosHeaders.from(axios.defaults.headers.common).toJSON();
axios.post('/foo', 'fizz=buzz');
return getAjaxRequest().then(function (request) {
for (const key in headers) {
expect(request.requestHeaders[key]).toEqual(headers[key]);
}
});
});
it('should reset headers by null or explicit undefined', function (done) {
axios
.create({
headers: {
common: {
'x-header-a': 'a',
'x-header-b': 'b',
'x-header-c': 'c',
},
},
})
.post(
'/foo',
{ fizz: 'buzz' },
{
headers: {
'Content-Type': null,
'x-header-a': null,
'x-header-b': undefined,
},
}
)
.catch(function (err) {
done(err);
});
getAjaxRequest()
.then(function (request) {
testHeaderValue(request.requestHeaders, 'Content-Type', undefined);
testHeaderValue(request.requestHeaders, 'x-header-a', undefined);
testHeaderValue(request.requestHeaders, 'x-header-b', undefined);
testHeaderValue(request.requestHeaders, 'x-header-c', 'c');
done();
})
.catch(done);
});
it('should use application/json when posting an object', function (done) {
axios.post('/foo/bar', {
firstName: 'foo',
lastName: 'bar',
});
getAjaxRequest().then(function (request) {
testHeaderValue(request.requestHeaders, 'Content-Type', 'application/json');
done();
});
});
it('should remove content-type if data is empty', function (done) {
axios.post('/foo');
getAjaxRequest().then(function (request) {
testHeaderValue(request.requestHeaders, 'Content-Type', undefined);
done();
});
});
it('should preserve content-type if data is false', async function () {
axios.post('/foo', false);
await getAjaxRequest().then(function (request) {
testHeaderValue(request.requestHeaders, 'Content-Type', 'application/x-www-form-urlencoded');
});
});
it('should allow an AxiosHeaders instance to be used as the value of the headers option', async () => {
const instance = axios.create({
headers: new AxiosHeaders({
xFoo: 'foo',
xBar: 'bar',
}),
});
instance.get('/foo', {
headers: {
XFOO: 'foo2',
xBaz: 'baz',
},
});
await getAjaxRequest().then(function (request) {
expect(request.requestHeaders.xFoo).toEqual('foo2');
expect(request.requestHeaders.xBar).toEqual('bar');
expect(request.requestHeaders.xBaz).toEqual('baz');
expect(request.requestHeaders.XFOO).toEqual(undefined);
});
});
});

View File

@ -1,13 +0,0 @@
/* eslint-env mocha */
import bind from '../../../lib/helpers/bind';
describe('bind', function () {
it('should bind an object to a function', function () {
const o = { val: 123 };
const f = bind(function (num) {
return this.val * num;
}, o);
expect(f(2)).toEqual(246);
});
});

View File

@ -1,126 +0,0 @@
/* eslint-env mocha */
import buildURL from '../../../lib/helpers/buildURL';
describe('helpers::buildURL', function () {
it('should support null params', function () {
expect(buildURL('/foo')).toEqual('/foo');
});
it('should support params', function () {
expect(
buildURL('/foo', {
foo: 'bar',
isUndefined: undefined,
isNull: null,
})
).toEqual('/foo?foo=bar');
});
it('should support sending raw params to custom serializer func', function () {
const serializer = sinon.stub();
const params = { foo: 'bar' };
serializer.returns('foo=bar');
expect(
buildURL(
'/foo',
{
foo: 'bar',
},
{
serialize: serializer,
}
)
).toEqual('/foo?foo=bar');
expect(serializer.calledOnce).toBe(true);
expect(serializer.calledWith(params)).toBe(true);
});
it('should support object params', function () {
expect(
buildURL('/foo', {
foo: {
bar: 'baz',
},
})
).toEqual('/foo?foo%5Bbar%5D=baz');
});
it('should support date params', function () {
const date = new Date();
expect(
buildURL('/foo', {
date: date,
})
).toEqual('/foo?date=' + date.toISOString());
});
it('should support array params with encode', function () {
expect(
buildURL('/foo', {
foo: ['bar', 'baz'],
})
).toEqual('/foo?foo%5B%5D=bar&foo%5B%5D=baz');
});
it('should support special char params', function () {
expect(
buildURL('/foo', {
foo: ':$, ',
})
).toEqual('/foo?foo=:$,+');
});
it('should support existing params', function () {
expect(
buildURL('/foo?foo=bar', {
bar: 'baz',
})
).toEqual('/foo?foo=bar&bar=baz');
});
it('should support "length" parameter', function () {
expect(
buildURL('/foo', {
query: 'bar',
start: 0,
length: 5,
})
).toEqual('/foo?query=bar&start=0&length=5');
});
it('should correct discard url hash mark', function () {
expect(
buildURL('/foo?foo=bar#hash', {
query: 'baz',
})
).toEqual('/foo?foo=bar&query=baz');
});
it('should support URLSearchParams', function () {
expect(buildURL('/foo', new URLSearchParams('bar=baz'))).toEqual('/foo?bar=baz');
});
it('should support custom serialize function', function () {
const params = {
x: 1,
};
const options = {
serialize: (thisParams, thisOptions) => {
expect(thisParams).toEqual(params);
expect(thisOptions).toEqual(options);
return 'rendered';
},
};
expect(buildURL('/foo', params, options)).toEqual('/foo?rendered');
const customSerializer = (thisParams) => {
expect(thisParams).toEqual(params);
return 'rendered';
};
expect(buildURL('/foo', params, customSerializer)).toEqual('/foo?rendered');
});
});

View File

@ -1,24 +0,0 @@
/* eslint-env mocha */
import combineURLs from '../../../lib/helpers/combineURLs';
describe('helpers::combineURLs', function () {
it('should combine URLs', function () {
expect(combineURLs('https://api.github.com', '/users')).toBe('https://api.github.com/users');
});
it('should remove duplicate slashes', function () {
expect(combineURLs('https://api.github.com/', '/users')).toBe('https://api.github.com/users');
});
it('should insert missing slash', function () {
expect(combineURLs('https://api.github.com', 'users')).toBe('https://api.github.com/users');
});
it('should not insert slash when relative url missing/empty', function () {
expect(combineURLs('https://api.github.com/users', '')).toBe('https://api.github.com/users');
});
it('should allow a single slash for relative url', function () {
expect(combineURLs('https://api.github.com/users', '/')).toBe('https://api.github.com/users/');
});
});

View File

@ -1,40 +0,0 @@
/* eslint-env mocha */
import cookies from '../../../lib/helpers/cookies';
describe('helpers::cookies', function () {
afterEach(function () {
// Remove all the cookies
const expires = Date.now() - 60 * 60 * 24 * 7;
document.cookie
.split(';')
.map(function (cookie) {
return cookie.split('=')[0];
})
.forEach(function (name) {
document.cookie = name + '=; expires=' + new Date(expires).toGMTString();
});
});
it('should write cookies', function () {
cookies.write('foo', 'baz');
expect(document.cookie).toEqual('foo=baz');
});
it('should read cookies', function () {
cookies.write('foo', 'abc');
cookies.write('bar', 'def');
expect(cookies.read('foo')).toEqual('abc');
expect(cookies.read('bar')).toEqual('def');
});
it('should remove cookies', function () {
cookies.write('foo', 'bar');
cookies.remove('foo');
expect(cookies.read('foo')).toEqual(null);
});
it('should uri encode values', function () {
cookies.write('foo', 'bar baz%');
expect(document.cookie).toEqual('foo=bar%20baz%25');
});
});

View File

@ -1,72 +0,0 @@
/* eslint-env mocha */
import formDataToJSON from '../../../lib/helpers/formDataToJSON';
describe('formDataToJSON', function () {
it('should convert a FormData Object to JSON Object', function () {
const formData = new FormData();
formData.append('foo[bar][baz]', '123');
expect(formDataToJSON(formData)).toEqual({
foo: {
bar: {
baz: '123',
},
},
});
});
it('should convert repeatable values as an array', function () {
const formData = new FormData();
formData.append('foo', '1');
formData.append('foo', '2');
expect(formDataToJSON(formData)).toEqual({
foo: ['1', '2'],
});
});
it('should convert props with empty brackets to arrays', function () {
const formData = new FormData();
formData.append('foo[]', '1');
formData.append('foo[]', '2');
expect(formDataToJSON(formData)).toEqual({
foo: ['1', '2'],
});
});
it('should supported indexed arrays', function () {
const formData = new FormData();
formData.append('foo[0]', '1');
formData.append('foo[1]', '2');
expect(formDataToJSON(formData)).toEqual({
foo: ['1', '2'],
});
});
it('should resist prototype pollution CVE', () => {
const formData = new FormData();
formData.append('foo[0]', '1');
formData.append('foo[1]', '2');
formData.append('__proto__.x', 'hack');
formData.append('constructor.prototype.y', 'value');
expect(formDataToJSON(formData)).toEqual({
foo: ['1', '2'],
constructor: {
prototype: {
y: 'value',
},
},
});
expect({}.x).toEqual(undefined);
expect({}.y).toEqual(undefined);
});
});

View File

@ -1,24 +0,0 @@
/* eslint-env mocha */
import isAbsoluteURL from '../../../lib/helpers/isAbsoluteURL';
describe('helpers::isAbsoluteURL', function () {
it('should return true if URL begins with valid scheme name', function () {
expect(isAbsoluteURL('https://api.github.com/users')).toBe(true);
expect(isAbsoluteURL('custom-scheme-v1.0://example.com/')).toBe(true);
expect(isAbsoluteURL('HTTP://example.com/')).toBe(true);
});
it('should return false if URL begins with invalid scheme name', function () {
expect(isAbsoluteURL('123://example.com/')).toBe(false);
expect(isAbsoluteURL('!valid://example.com/')).toBe(false);
});
it('should return true if URL is protocol-relative', function () {
expect(isAbsoluteURL('//example.com/')).toBe(true);
});
it('should return false if URL is relative', function () {
expect(isAbsoluteURL('/foo')).toBe(false);
expect(isAbsoluteURL('foo')).toBe(false);
});
});

View File

@ -1,21 +0,0 @@
/* eslint-env mocha */
import AxiosError from '../../../lib/core/AxiosError';
import isAxiosError from '../../../lib/helpers/isAxiosError';
describe('helpers::isAxiosError', function () {
it('should return true if the error is created by core::createError', function () {
expect(isAxiosError(new AxiosError('Boom!', null, { foo: 'bar' }))).toBe(true);
});
it('should return true if the error is enhanced by core::enhanceError', function () {
expect(isAxiosError(AxiosError.from(new Error('Boom!'), null, { foo: 'bar' }))).toBe(true);
});
it('should return false if the error is a normal Error instance', function () {
expect(isAxiosError(new Error('Boom!'))).toBe(false);
});
it('should return false if the error is null', function () {
expect(isAxiosError(null)).toBe(false);
});
});

View File

@ -1,12 +0,0 @@
/* eslint-env mocha */
import isURLSameOrigin from '../../../lib/helpers/isURLSameOrigin';
describe('helpers::isURLSameOrigin', function () {
it('should detect same origin', function () {
expect(isURLSameOrigin(window.location.href)).toEqual(true);
});
it('should detect different origin', function () {
expect(isURLSameOrigin('https://github.com/axios/axios')).toEqual(false);
});
});

View File

@ -1,43 +0,0 @@
/* eslint-env mocha */
import parseHeaders from '../../../lib/helpers/parseHeaders';
describe('helpers::parseHeaders', function () {
it('should parse headers', function () {
const date = new Date();
const parsed = parseHeaders(
'Date: ' +
date.toISOString() +
'\n' +
'Content-Type: application/json\n' +
'Connection: keep-alive\n' +
'Transfer-Encoding: chunked'
);
expect(parsed['date']).toEqual(date.toISOString());
expect(parsed['content-type']).toEqual('application/json');
expect(parsed['connection']).toEqual('keep-alive');
expect(parsed['transfer-encoding']).toEqual('chunked');
});
it('should use array for set-cookie', function () {
const parsedZero = parseHeaders('');
const parsedSingle = parseHeaders('Set-Cookie: key=val;');
const parsedMulti = parseHeaders('Set-Cookie: key=val;\n' + 'Set-Cookie: key2=val2;\n');
expect(parsedZero['set-cookie']).toBeUndefined();
expect(parsedSingle['set-cookie']).toEqual(['key=val;']);
expect(parsedMulti['set-cookie']).toEqual(['key=val;', 'key2=val2;']);
});
it('should handle duplicates', function () {
const parsed = parseHeaders(
'Age: age-a\n' + // age is in ignore duplicates blocklist
'Age: age-b\n' +
'Foo: foo-a\n' +
'Foo: foo-b\n'
);
expect(parsed['age']).toEqual('age-a');
expect(parsed['foo']).toEqual('foo-a, foo-b');
});
});

View File

@ -1,21 +0,0 @@
/* eslint-env mocha */
import spread from '../../../lib/helpers/spread';
describe('helpers::spread', function () {
it('should spread array to arguments', function () {
let value = 0;
spread(function (a, b) {
value = a * b;
})([5, 10]);
expect(value).toEqual(50);
});
it('should return callback result', function () {
const value = spread(function (a, b) {
return a * b;
})([5, 10]);
expect(value).toEqual(50);
});
});

View File

@ -1,126 +0,0 @@
/* eslint-env mocha */
import toFormData from '../../../lib/helpers/toFormData';
describe('toFormData', function () {
it('should convert nested data object to FormData with dots option enabled', function () {
const o = {
val: 123,
nested: {
arr: ['hello', 'world'],
},
};
const form = toFormData(o, null, { dots: true });
expect(form instanceof FormData).toEqual(true);
expect(Array.from(form.keys()).length).toEqual(3);
expect(form.get('val')).toEqual('123');
expect(form.get('nested.arr.0')).toEqual('hello');
});
it('should respect metaTokens option', function () {
const data = {
'obj{}': { x: 1, y: 2 },
};
const str = JSON.stringify(data['obj{}']);
const form = toFormData(data, null, { metaTokens: false });
expect(Array.from(form.keys()).length).toEqual(1);
expect(form.getAll('obj')).toEqual([str]);
});
describe('Flat arrays serialization', function () {
it('should include full indexes when the `indexes` option is set to true', function () {
const data = {
arr: [1, 2, 3],
arr2: [1, [2], 3],
};
const form = toFormData(data, null, { indexes: true });
expect(Array.from(form.keys()).length).toEqual(6);
expect(form.get('arr[0]')).toEqual('1');
expect(form.get('arr[1]')).toEqual('2');
expect(form.get('arr[2]')).toEqual('3');
expect(form.get('arr2[0]')).toEqual('1');
expect(form.get('arr2[1][0]')).toEqual('2');
expect(form.get('arr2[2]')).toEqual('3');
});
it('should include brackets only when the `indexes` option is set to false', function () {
const data = {
arr: [1, 2, 3],
arr2: [1, [2], 3],
};
const form = toFormData(data, null, { indexes: false });
expect(Array.from(form.keys()).length).toEqual(6);
expect(form.getAll('arr[]')).toEqual(['1', '2', '3']);
expect(form.get('arr2[0]')).toEqual('1');
expect(form.get('arr2[1][0]')).toEqual('2');
expect(form.get('arr2[2]')).toEqual('3');
});
it('should omit brackets when the `indexes` option is set to null', function () {
const data = {
arr: [1, 2, 3],
arr2: [1, [2], 3],
};
const form = toFormData(data, null, { indexes: null });
expect(Array.from(form.keys()).length).toEqual(6);
expect(form.getAll('arr')).toEqual(['1', '2', '3']);
expect(form.get('arr2[0]')).toEqual('1');
expect(form.get('arr2[1][0]')).toEqual('2');
expect(form.get('arr2[2]')).toEqual('3');
});
});
it('should convert nested data object to FormData', function () {
const o = {
val: 123,
nested: {
arr: ['hello', 'world'],
},
};
const form = toFormData(o);
expect(form instanceof FormData).toEqual(true);
expect(Array.from(form.keys()).length).toEqual(3);
expect(form.get('val')).toEqual('123');
expect(form.get('nested[arr][0]')).toEqual('hello');
});
it('should append value whose key ends with [] as separate values with the same key', function () {
const data = {
'arr[]': [1, 2, 3],
};
const form = toFormData(data);
expect(Array.from(form.keys()).length).toEqual(3);
expect(form.getAll('arr[]')).toEqual(['1', '2', '3']);
});
it('should append value whose key ends with {} as a JSON string', function () {
const data = {
'obj{}': { x: 1, y: 2 },
};
const str = JSON.stringify(data['obj{}']);
const form = toFormData(data);
expect(Array.from(form.keys()).length).toEqual(1);
expect(form.getAll('obj{}')).toEqual([str]);
});
});

View File

@ -1,56 +0,0 @@
/* eslint-env mocha */
'use strict';
import validator from '../../../lib/helpers/validator';
describe('validator::assertOptions', function () {
it('should throw only if unknown an option was passed', function () {
expect(function () {
validator.assertOptions(
{
x: true,
},
{
y: validator.validators.boolean,
}
);
}).toThrow(new Error('Unknown option x'));
expect(function () {
validator.assertOptions(
{
x: true,
},
{
x: validator.validators.boolean,
y: validator.validators.boolean,
}
);
}).not.toThrow(new Error('Unknown option x'));
});
it("should throw TypeError only if option type doesn't match", function () {
expect(function () {
validator.assertOptions(
{
x: 123,
},
{
x: validator.validators.boolean,
}
);
}).toThrow(new TypeError('option x must be a boolean'));
expect(function () {
validator.assertOptions(
{
x: true,
},
{
x: validator.validators.boolean,
y: validator.validators.boolean,
}
);
}).not.toThrow();
});
});

View File

@ -1,165 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
describe('instance', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should have the same methods as default instance', function () {
const instance = axios.create();
for (const prop in axios) {
if (
[
'Axios',
'AxiosError',
'create',
'Cancel',
'CanceledError',
'CancelToken',
'isCancel',
'all',
'spread',
'getUri',
'isAxiosError',
'mergeConfig',
'getAdapter',
'VERSION',
'default',
'toFormData',
'formToJSON',
'AxiosHeaders',
'HttpStatusCode',
].indexOf(prop) > -1
) {
continue;
}
expect(typeof instance[prop]).toBe(typeof axios[prop]);
}
});
it('should make an http request without verb helper', function (done) {
const instance = axios.create();
instance('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo');
done();
});
});
it('should make an http request with url instead of baseURL', function (done) {
const instance = axios.create({
url: 'https://api.example.com',
});
instance('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo');
done();
});
});
it('should make an http request', function (done) {
const instance = axios.create();
instance.get('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo');
done();
});
});
it('should use instance options', function (done) {
const instance = axios.create({ timeout: 1000 });
instance.get('/foo');
getAjaxRequest().then(function (request) {
expect(request.timeout).toBe(1000);
done();
});
});
it('should have defaults.headers', function () {
const instance = axios.create({
baseURL: 'https://api.example.com',
});
expect(typeof instance.defaults.headers, 'object');
expect(typeof instance.defaults.headers.common, 'object');
});
it('should have interceptors on the instance', function (done) {
axios.interceptors.request.use(function (config) {
config.foo = true;
return config;
});
const instance = axios.create();
instance.interceptors.request.use(function (config) {
config.bar = true;
return config;
});
let response;
instance.get('/foo').then(function (res) {
response = res;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
});
setTimeout(function () {
expect(response.config.foo).toEqual(undefined);
expect(response.config.bar).toEqual(true);
done();
}, 100);
});
});
it('should have getUri on the instance', function () {
const instance = axios.create({
baseURL: 'https://api.example.com',
});
const options = {
url: 'foo/bar',
params: {
name: 'axios',
},
};
expect(instance.getUri(options)).toBe('https://api.example.com/foo/bar?name=axios');
});
it('should correctly build url without baseURL', function () {
const instance = axios.create();
const options = {
url: 'foo/bar?foo=bar',
params: {
name: 'axios',
},
};
expect(instance.getUri(options)).toBe('foo/bar?foo=bar&name=axios');
});
it('should correctly discard url hash mark', function () {
const instance = axios.create();
const options = {
baseURL: 'https://api.example.com',
url: 'foo/bar?foo=bar#hash',
params: {
name: 'axios',
},
};
expect(instance.getUri(options)).toBe('https://api.example.com/foo/bar?foo=bar&name=axios');
});
});

View File

@ -1,697 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
describe('interceptors', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
axios.interceptors.request.handlers = [];
axios.interceptors.response.handlers = [];
});
it('should add a request interceptor (asynchronous by default)', function (done) {
let asyncFlag = false;
axios.interceptors.request.use(function (config) {
config.headers.test = 'added by interceptor';
expect(asyncFlag).toBe(true);
return config;
});
axios('/foo');
asyncFlag = true;
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.test).toBe('added by interceptor');
done();
});
});
it('should add a request interceptor (explicitly flagged as asynchronous)', function (done) {
let asyncFlag = false;
axios.interceptors.request.use(
function (config) {
config.headers.test = 'added by interceptor';
expect(asyncFlag).toBe(true);
return config;
},
null,
{ synchronous: false }
);
axios('/foo');
asyncFlag = true;
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.test).toBe('added by interceptor');
done();
});
});
it('should add a request interceptor that is executed synchronously when flag is provided', function (done) {
let asyncFlag = false;
axios.interceptors.request.use(
function (config) {
config.headers.test = 'added by synchronous interceptor';
expect(asyncFlag).toBe(false);
return config;
},
null,
{ synchronous: true }
);
axios('/foo');
asyncFlag = true;
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.test).toBe('added by synchronous interceptor');
done();
});
});
it('should execute asynchronously when not all interceptors are explicitly flagged as synchronous', function (done) {
let asyncFlag = false;
axios.interceptors.request.use(function (config) {
config.headers.foo = 'uh oh, async';
expect(asyncFlag).toBe(true);
return config;
});
axios.interceptors.request.use(
function (config) {
config.headers.test = 'added by synchronous interceptor';
expect(asyncFlag).toBe(true);
return config;
},
null,
{ synchronous: true }
);
axios.interceptors.request.use(function (config) {
config.headers.test = 'added by the async interceptor';
expect(asyncFlag).toBe(true);
return config;
});
axios('/foo');
asyncFlag = true;
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.foo).toBe('uh oh, async');
/* request interceptors have a reversed execution order */
expect(request.requestHeaders.test).toBe('added by synchronous interceptor');
done();
});
});
it('should execute request interceptor in legacy order', function (done) {
let sequence = '';
axios.interceptors.request.use(function (config) {
sequence += '1';
return config;
});
axios.interceptors.request.use(function (config) {
sequence += '2';
return config;
});
axios.interceptors.request.use(function (config) {
sequence += '3';
return config;
});
axios({
url: '/foo',
});
getAjaxRequest().then(function (request) {
expect(sequence).toBe('321');
done();
});
});
it('should execute request interceptor in order', function (done) {
let sequence = '';
axios.interceptors.request.use(function (config) {
sequence += '1';
return config;
});
axios.interceptors.request.use(function (config) {
sequence += '2';
return config;
});
axios.interceptors.request.use(function (config) {
sequence += '3';
return config;
});
axios({
url: '/foo',
transitional: {
legacyInterceptorReqResOrdering: false,
},
});
getAjaxRequest().then(function (request) {
expect(sequence).toBe('123');
done();
});
});
it('runs the interceptor if runWhen function is provided and resolves to true', function (done) {
function onGetCall(config) {
return config.method === 'get';
}
axios.interceptors.request.use(
function (config) {
config.headers.test = 'special get headers';
return config;
},
null,
{ runWhen: onGetCall }
);
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.test).toBe('special get headers');
done();
});
});
it('does not run the interceptor if runWhen function is provided and resolves to false', function (done) {
function onPostCall(config) {
return config.method === 'post';
}
axios.interceptors.request.use(
function (config) {
config.headers.test = 'special get headers';
return config;
},
null,
{ runWhen: onPostCall }
);
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.test).toBeUndefined();
done();
});
});
it('does not run async interceptor if runWhen function is provided and resolves to false (and run synchronously)', function (done) {
let asyncFlag = false;
function onPostCall(config) {
return config.method === 'post';
}
axios.interceptors.request.use(
function (config) {
config.headers.test = 'special get headers';
return config;
},
null,
{ synchronous: false, runWhen: onPostCall }
);
axios.interceptors.request.use(
function (config) {
config.headers.sync = 'hello world';
expect(asyncFlag).toBe(false);
return config;
},
null,
{ synchronous: true }
);
axios('/foo');
asyncFlag = true;
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.test).toBeUndefined();
expect(request.requestHeaders.sync).toBe('hello world');
done();
});
});
it('should add a request interceptor with an onRejected block that is called if interceptor code fails', function (done) {
const rejectedSpy = jasmine.createSpy('rejectedSpy');
const error = new Error('deadly error');
axios.interceptors.request.use(
function () {
throw error;
},
rejectedSpy,
{ synchronous: true }
);
axios('/foo').catch(done);
getAjaxRequest().then(function () {
expect(rejectedSpy).toHaveBeenCalledWith(error);
done();
});
});
it('should add a request interceptor that returns a new config object', function (done) {
axios.interceptors.request.use(function () {
return {
url: '/bar',
method: 'post',
};
});
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.method).toBe('POST');
expect(request.url).toBe('/bar');
done();
});
});
it('should add a request interceptor that returns a promise', function (done) {
axios.interceptors.request.use(function (config) {
return new Promise(function (resolve) {
// do something async
setTimeout(function () {
config.headers.async = 'promise';
resolve(config);
}, 100);
});
});
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.async).toBe('promise');
done();
});
});
it('should add multiple request interceptors', function (done) {
axios.interceptors.request.use(function (config) {
config.headers.test1 = '1';
return config;
});
axios.interceptors.request.use(function (config) {
config.headers.test2 = '2';
return config;
});
axios.interceptors.request.use(function (config) {
config.headers.test3 = '3';
return config;
});
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.test1).toBe('1');
expect(request.requestHeaders.test2).toBe('2');
expect(request.requestHeaders.test3).toBe('3');
done();
});
});
it('should add a response interceptor', function (done) {
let response;
axios.interceptors.response.use(function (data) {
data.data = data.data + ' - modified by interceptor';
return data;
});
axios('/foo').then(function (data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK',
});
setTimeout(function () {
expect(response.data).toBe('OK - modified by interceptor');
done();
}, 100);
});
});
it('should add a response interceptor when request interceptor is defined', function (done) {
let response;
axios.interceptors.request.use(function (data) {
return data;
});
axios.interceptors.response.use(function (data) {
data.data = data.data + ' - modified by interceptor';
return data;
});
axios('/foo').then(function (data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK',
});
setTimeout(function () {
expect(response.data).toBe('OK - modified by interceptor');
done();
}, 100);
});
});
it('should add a response interceptor that returns a new data object', function (done) {
let response;
axios.interceptors.response.use(function () {
return {
data: 'stuff',
};
});
axios('/foo').then(function (data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK',
});
setTimeout(function () {
expect(response.data).toBe('stuff');
done();
}, 100);
});
});
it('should add a response interceptor that returns a promise', function (done) {
let response;
axios.interceptors.response.use(function (data) {
return new Promise(function (resolve) {
// do something async
setTimeout(function () {
data.data = 'you have been promised!';
resolve(data);
}, 10);
});
});
axios('/foo').then(function (data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK',
});
setTimeout(function () {
expect(response.data).toBe('you have been promised!');
done();
}, 100);
});
});
describe('given you add multiple response interceptors', function () {
describe('and when the response was fulfilled', function () {
function fireRequestAndExpect(expectation) {
let response;
axios('/foo').then(function (data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK',
});
setTimeout(function () {
expectation(response);
}, 100);
});
}
it('then each interceptor is executed', function (done) {
const interceptor1 = jasmine.createSpy('interceptor1');
const interceptor2 = jasmine.createSpy('interceptor2');
axios.interceptors.response.use(interceptor1);
axios.interceptors.response.use(interceptor2);
fireRequestAndExpect(function () {
expect(interceptor1).toHaveBeenCalled();
expect(interceptor2).toHaveBeenCalled();
done();
});
});
it('then they are executed in the order they were added', function (done) {
const interceptor1 = jasmine.createSpy('interceptor1');
const interceptor2 = jasmine.createSpy('interceptor2');
axios.interceptors.response.use(interceptor1);
axios.interceptors.response.use(interceptor2);
fireRequestAndExpect(function () {
expect(interceptor1).toHaveBeenCalledBefore(interceptor2);
done();
});
});
it("then only the last interceptor's result is returned", function (done) {
axios.interceptors.response.use(function () {
return 'response 1';
});
axios.interceptors.response.use(function () {
return 'response 2';
});
fireRequestAndExpect(function (response) {
expect(response).toBe('response 2');
done();
});
});
it("then every interceptor receives the result of it's predecessor", function (done) {
axios.interceptors.response.use(function () {
return 'response 1';
});
axios.interceptors.response.use(function (response) {
return [response, 'response 2'];
});
fireRequestAndExpect(function (response) {
expect(response).toEqual(['response 1', 'response 2']);
done();
});
});
describe('and when the fulfillment-interceptor throws', function () {
function fireRequestCatchAndExpect(expectation) {
axios('/foo').catch(function (data) {
// dont handle result
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK',
});
setTimeout(function () {
expectation();
}, 100);
});
}
it('then the following fulfillment-interceptor is not called', function (done) {
axios.interceptors.response.use(function () {
throw Error('throwing interceptor');
});
const interceptor2 = jasmine.createSpy('interceptor2');
axios.interceptors.response.use(interceptor2);
fireRequestCatchAndExpect(function () {
expect(interceptor2).not.toHaveBeenCalled();
done();
});
});
it('then the following rejection-interceptor is called', function (done) {
axios.interceptors.response.use(function () {
throw Error('throwing interceptor');
});
const unusedFulfillInterceptor = function () {};
const rejectIntercept = jasmine.createSpy('rejectIntercept');
axios.interceptors.response.use(unusedFulfillInterceptor, rejectIntercept);
fireRequestCatchAndExpect(function () {
expect(rejectIntercept).toHaveBeenCalled();
done();
});
});
it('once caught, another following fulfill-interceptor is called again (just like in a promise chain)', function (done) {
axios.interceptors.response.use(function () {
throw Error('throwing interceptor');
});
const unusedFulfillInterceptor = function () {};
const catchingThrowingInterceptor = function () {};
axios.interceptors.response.use(unusedFulfillInterceptor, catchingThrowingInterceptor);
const interceptor3 = jasmine.createSpy('interceptor3');
axios.interceptors.response.use(interceptor3);
fireRequestCatchAndExpect(function () {
expect(interceptor3).toHaveBeenCalled();
done();
});
});
});
});
});
it('should allow removing interceptors', function (done) {
let response, intercept;
axios.interceptors.response.use(function (data) {
data.data = data.data + '1';
return data;
});
intercept = axios.interceptors.response.use(function (data) {
data.data = data.data + '2';
return data;
});
axios.interceptors.response.use(function (data) {
data.data = data.data + '3';
return data;
});
axios.interceptors.response.eject(intercept);
axios('/foo').then(function (data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK',
});
setTimeout(function () {
expect(response.data).toBe('OK13');
done();
}, 100);
});
});
it('should remove async interceptor before making request and execute synchronously', function (done) {
let asyncFlag = false;
const asyncIntercept = axios.interceptors.request.use(
function (config) {
config.headers.async = 'async it!';
return config;
},
null,
{ synchronous: false }
);
axios.interceptors.request.use(
function (config) {
config.headers.sync = 'hello world';
expect(asyncFlag).toBe(false);
return config;
},
null,
{ synchronous: true }
);
axios.interceptors.request.eject(asyncIntercept);
axios('/foo');
asyncFlag = true;
getAjaxRequest().then(function (request) {
expect(request.requestHeaders.async).toBeUndefined();
expect(request.requestHeaders.sync).toBe('hello world');
done();
});
});
it('should execute interceptors before transformers', function (done) {
axios.interceptors.request.use(function (config) {
config.data.baz = 'qux';
return config;
});
axios.post('/foo', {
foo: 'bar',
});
getAjaxRequest().then(function (request) {
expect(request.params).toEqual('{"foo":"bar","baz":"qux"}');
done();
});
});
it('should modify base URL in request interceptor', function (done) {
const instance = axios.create({
baseURL: 'http://test.com/',
});
instance.interceptors.request.use(function (config) {
config.baseURL = 'http://rebase.com/';
return config;
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('http://rebase.com/foo');
done();
});
});
it('should clear all request interceptors', function () {
const instance = axios.create({
baseURL: 'http://test.com/',
});
instance.interceptors.request.use(function (config) {
return config;
});
instance.interceptors.request.clear();
expect(instance.interceptors.request.handlers.length).toBe(0);
});
it('should clear all response interceptors', function () {
const instance = axios.create({
baseURL: 'http://test.com/',
});
instance.interceptors.response.use(function (config) {
return config;
});
instance.interceptors.response.clear();
expect(instance.interceptors.response.handlers.length).toBe(0);
});
});

View File

@ -1,151 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
// import AxiosHeaders from "../../lib/core/AxiosHeaders.js";
// import isAbsoluteURL from '../../lib/helpers/isAbsoluteURL.js';
describe('options', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should default method to get', function (done) {
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.method).toBe('GET');
done();
});
});
it('should accept headers', function (done) {
axios('/foo', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
},
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders['X-Requested-With']).toEqual('XMLHttpRequest');
done();
});
});
it('should accept params', function (done) {
axios('/foo', {
params: {
foo: 123,
bar: 456,
},
});
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo?foo=123&bar=456');
done();
});
});
it('should allow overriding default headers', function (done) {
axios('/foo', {
headers: {
Accept: 'foo/bar',
},
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders['Accept']).toEqual('foo/bar');
done();
});
});
it('should accept base URL', function (done) {
const instance = axios.create({
baseURL: 'http://test.com/',
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('http://test.com/foo');
done();
});
});
it('should warn about baseUrl', function (done) {
spyOn(window.console, 'warn');
const instance = axios.create({
baseUrl: 'http://example.com/',
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
expect(window.console.warn).toHaveBeenCalledWith(
'baseUrl is likely a misspelling of baseURL'
);
expect(request.url).toBe('/foo');
done();
});
});
it('should ignore base URL if request URL is absolute', function (done) {
const instance = axios.create({
baseURL: 'http://someurl.com/',
});
instance.get('http://someotherurl.com/');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('http://someotherurl.com/');
done();
});
});
it('should combine the URLs if base url and request url exist and allowAbsoluteUrls is false', function (done) {
const instance = axios.create({
baseURL: 'http://someurl.com/',
allowAbsoluteUrls: false,
});
instance.get('http://someotherurl.com/');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('http://someurl.com/http://someotherurl.com/');
done();
});
});
it('should change only the baseURL of the specified instance', function () {
const instance1 = axios.create();
const instance2 = axios.create();
instance1.defaults.baseURL = 'http://instance1.example.com/';
expect(instance2.defaults.baseURL).not.toBe('http://instance1.example.com/');
});
it('should change only the headers of the specified instance', function () {
const instance1 = axios.create();
const instance2 = axios.create();
instance1.defaults.headers.common.Authorization = 'faketoken';
instance2.defaults.headers.common.Authorization = 'differentfaketoken';
instance1.defaults.headers.common['Content-Type'] = 'application/xml';
instance2.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
expect(axios.defaults.headers.common.Authorization).toBe(undefined);
expect(instance1.defaults.headers.common.Authorization).toBe('faketoken');
expect(instance2.defaults.headers.common.Authorization).toBe('differentfaketoken');
expect(axios.defaults.headers.common['Content-Type']).toBe(undefined);
expect(instance1.defaults.headers.common['Content-Type']).toBe('application/xml');
expect(instance2.defaults.headers.common['Content-Type']).toBe(
'application/x-www-form-urlencoded'
);
});
});

View File

@ -1,113 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
describe('progress events', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should add a download progress handler', function (done) {
const progressSpy = jasmine.createSpy('progress');
axios('/foo', { onDownloadProgress: progressSpy });
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}',
});
expect(progressSpy).toHaveBeenCalled();
done();
});
});
it('should add a upload progress handler', function (done) {
const progressSpy = jasmine.createSpy('progress');
axios('/foo', { onUploadProgress: progressSpy });
getAjaxRequest().then(function (request) {
// Jasmine AJAX doesn't trigger upload events. Waiting for upstream fix
// expect(progressSpy).toHaveBeenCalled();
done();
});
});
it('should add both upload and download progress handlers', function (done) {
const downloadProgressSpy = jasmine.createSpy('downloadProgress');
const uploadProgressSpy = jasmine.createSpy('uploadProgress');
axios('/foo', { onDownloadProgress: downloadProgressSpy, onUploadProgress: uploadProgressSpy });
getAjaxRequest().then(function (request) {
// expect(uploadProgressSpy).toHaveBeenCalled();
expect(downloadProgressSpy).not.toHaveBeenCalled();
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}',
});
expect(downloadProgressSpy).toHaveBeenCalled();
done();
});
});
it('should add a download progress handler from instance config', function (done) {
const progressSpy = jasmine.createSpy('progress');
const instance = axios.create({
onDownloadProgress: progressSpy,
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}',
});
expect(progressSpy).toHaveBeenCalled();
done();
});
});
it('should add a upload progress handler from instance config', function (done) {
const progressSpy = jasmine.createSpy('progress');
const instance = axios.create({
onUploadProgress: progressSpy,
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
// expect(progressSpy).toHaveBeenCalled();
done();
});
});
it('should add upload and download progress handlers from instance config', function (done) {
const downloadProgressSpy = jasmine.createSpy('downloadProgress');
const uploadProgressSpy = jasmine.createSpy('uploadProgress');
const instance = axios.create({
onDownloadProgress: downloadProgressSpy,
onUploadProgress: uploadProgressSpy,
});
instance.get('/foo');
getAjaxRequest().then(function (request) {
// expect(uploadProgressSpy).toHaveBeenCalled();
expect(downloadProgressSpy).not.toHaveBeenCalled();
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}',
});
expect(downloadProgressSpy).toHaveBeenCalled();
done();
});
});
});

View File

@ -1,75 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
describe('promise', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should provide succinct object to then', function (done) {
let response;
axios('/foo').then(function (r) {
response = r;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '{"hello":"world"}',
});
setTimeout(function () {
expect(typeof response).toEqual('object');
expect(response.data.hello).toEqual('world');
expect(response.status).toEqual(200);
expect(response.headers['content-type']).toEqual('application/json');
expect(response.config.url).toEqual('/foo');
done();
}, 100);
});
});
it('should support all', function (done) {
let fulfilled = false;
axios.all([true, 123]).then(function () {
fulfilled = true;
});
setTimeout(function () {
expect(fulfilled).toEqual(true);
done();
}, 100);
});
it('should support spread', function (done) {
let sum = 0;
let fulfilled = false;
let result;
axios
.all([123, 456])
.then(
axios.spread(function (a, b) {
sum = a + b;
fulfilled = true;
return 'hello world';
})
)
.then(function (res) {
result = res;
})
.catch(done);
setTimeout(function () {
expect(fulfilled).toEqual(true);
expect(sum).toEqual(123 + 456);
expect(result).toEqual('hello world');
done();
}, 100);
});
});

View File

@ -1,547 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
describe('requests', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should treat single string arg as url', function (done) {
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo');
expect(request.method).toBe('GET');
done();
});
});
it('should treat method value as lowercase string', function (done) {
axios({
url: '/foo',
method: 'POST',
}).then(function (response) {
expect(response.config.method).toBe('post');
done();
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
});
});
});
it('should allow string arg as url, and config arg', function (done) {
axios.post('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo');
expect(request.method).toBe('POST');
done();
});
});
it('should allow data', function (done) {
axios.delete('/foo', {
data: { foo: 'bar' },
});
getAjaxRequest().then(function (request) {
expect(request.params).toBe(JSON.stringify({ foo: 'bar' }));
done();
});
});
it('should make an http request', function (done) {
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.url).toBe('/foo');
done();
});
});
describe('timeouts', function () {
beforeEach(function () {
jasmine.clock().install();
});
afterEach(function () {
jasmine.clock().uninstall();
});
it('should handle timeouts', function (done) {
axios({
url: '/foo',
timeout: 100,
}).then(
function () {
fail(new Error('timeout error not caught'));
},
function (err) {
expect(err instanceof Error).toBe(true);
expect(err.code).toEqual('ECONNABORTED');
done();
}
);
jasmine.Ajax.requests.mostRecent().responseTimeout();
});
describe('transitional.clarifyTimeoutError', function () {
it('should activate throwing ETIMEDOUT instead of ECONNABORTED on request timeouts', function (done) {
axios({
url: '/foo',
timeout: 100,
transitional: {
clarifyTimeoutError: true,
},
}).then(
function () {
fail(new Error('timeout error not caught'));
},
function (err) {
expect(err instanceof Error).toBe(true);
expect(err.code).toEqual('ETIMEDOUT');
done();
}
);
jasmine.Ajax.requests.mostRecent().responseTimeout();
});
});
});
it('should reject on network errors', function (done) {
// disable jasmine.Ajax since we're hitting a non-existent server anyway
jasmine.Ajax.uninstall();
const resolveSpy = jasmine.createSpy('resolve');
const rejectSpy = jasmine.createSpy('reject');
const finish = function () {
expect(resolveSpy).not.toHaveBeenCalled();
expect(rejectSpy).toHaveBeenCalled();
const reason = rejectSpy.calls.first().args[0];
expect(reason instanceof Error).toBe(true);
expect(reason.config.method).toBe('get');
expect(reason.config.url).toBe('http://thisisnotaserver/foo');
expect(reason.request).toEqual(jasmine.any(XMLHttpRequest));
// re-enable jasmine.Ajax
jasmine.Ajax.install();
done();
};
axios('http://thisisnotaserver/foo').then(resolveSpy, rejectSpy).then(finish, finish);
});
it('should reject on abort', function (done) {
const resolveSpy = jasmine.createSpy('resolve');
const rejectSpy = jasmine.createSpy('reject');
const finish = function () {
expect(resolveSpy).not.toHaveBeenCalled();
expect(rejectSpy).toHaveBeenCalled();
const reason = rejectSpy.calls.first().args[0];
expect(reason instanceof Error).toBe(true);
expect(reason.config.method).toBe('get');
expect(reason.config.url).toBe('/foo');
expect(reason.request).toEqual(jasmine.any(XMLHttpRequest));
done();
};
axios('/foo').then(resolveSpy, rejectSpy).then(finish, finish);
getAjaxRequest().then(function (request) {
request.abort();
});
});
it('should reject when validateStatus returns false', function (done) {
const resolveSpy = jasmine.createSpy('resolve');
const rejectSpy = jasmine.createSpy('reject');
axios('/foo', {
validateStatus: function (status) {
return status !== 500;
},
})
.then(resolveSpy)
.catch(rejectSpy)
.then(function () {
expect(resolveSpy).not.toHaveBeenCalled();
expect(rejectSpy).toHaveBeenCalled();
const reason = rejectSpy.calls.first().args[0];
expect(reason instanceof Error).toBe(true);
expect(reason.message).toBe('Request failed with status code 500');
expect(reason.config.method).toBe('get');
expect(reason.config.url).toBe('/foo');
expect(reason.response.status).toBe(500);
done();
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 500,
});
});
});
it('should resolve when validateStatus returns true', function (done) {
const resolveSpy = jasmine.createSpy('resolve');
const rejectSpy = jasmine.createSpy('reject');
axios('/foo', {
validateStatus: function (status) {
return status === 500;
},
})
.then(resolveSpy)
.catch(rejectSpy)
.then(function () {
expect(resolveSpy).toHaveBeenCalled();
expect(rejectSpy).not.toHaveBeenCalled();
done();
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 500,
});
});
});
it('should resolve when the response status is 0 (i.e. requesting with file protocol)', function (done) {
const resolveSpy = jasmine.createSpy('resolve');
const rejectSpy = jasmine.createSpy('reject');
axios('file:///xxx')
.then(resolveSpy)
.catch(rejectSpy)
.then(function () {
expect(resolveSpy).toHaveBeenCalled();
expect(rejectSpy).not.toHaveBeenCalled();
done();
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 0,
responseURL: 'file:///xxx',
});
});
});
it('should resolve when validateStatus is null', function (done) {
const resolveSpy = jasmine.createSpy('resolve');
const rejectSpy = jasmine.createSpy('reject');
axios('/foo', {
validateStatus: null,
})
.then(resolveSpy)
.catch(rejectSpy)
.then(function () {
expect(resolveSpy).toHaveBeenCalled();
expect(rejectSpy).not.toHaveBeenCalled();
done();
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 500,
});
});
});
it('should resolve when validateStatus is undefined', function (done) {
const resolveSpy = jasmine.createSpy('resolve');
const rejectSpy = jasmine.createSpy('reject');
axios('/foo', {
validateStatus: undefined,
})
.then(resolveSpy)
.catch(rejectSpy)
.then(function () {
expect(resolveSpy).toHaveBeenCalled();
expect(rejectSpy).not.toHaveBeenCalled();
done();
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 500,
});
});
});
// https://github.com/axios/axios/issues/378
it('should return JSON when rejecting', function (done) {
let response;
axios(
'/api/account/signup',
{
username: null,
password: null,
},
{
method: 'post',
headers: {
Accept: 'application/json',
},
}
).catch(function (error) {
response = error.response;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 400,
statusText: 'Bad Request',
responseText: '{"error": "BAD USERNAME", "code": 1}',
});
setTimeout(function () {
expect(typeof response.data).toEqual('object');
expect(response.data.error).toEqual('BAD USERNAME');
expect(response.data.code).toEqual(1);
done();
}, 100);
});
});
it('should make cross domain http request', function (done) {
let response;
axios.post('www.someurl.com/foo').then(function (res) {
response = res;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
statusText: 'OK',
responseText: '{"foo": "bar"}',
headers: {
'Content-Type': 'application/json',
},
});
setTimeout(function () {
expect(response.data.foo).toEqual('bar');
expect(response.status).toEqual(200);
expect(response.statusText).toEqual('OK');
expect(response.headers['content-type']).toEqual('application/json');
done();
}, 100);
});
});
it('should supply correct response', function (done) {
let response;
axios.post('/foo').then(function (res) {
response = res;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
statusText: 'OK',
responseText: '{"foo": "bar"}',
headers: {
'Content-Type': 'application/json',
},
});
setTimeout(function () {
expect(response.data.foo).toEqual('bar');
expect(response.status).toEqual(200);
expect(response.statusText).toEqual('OK');
expect(response.headers['content-type']).toEqual('application/json');
done();
}, 100);
});
});
it('should not modify the config url with relative baseURL', function (done) {
let config;
axios
.get('/foo', {
baseURL: '/api',
})
.catch(function (error) {
config = error.config;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 404,
statusText: 'NOT FOUND',
responseText: 'Resource not found',
});
setTimeout(function () {
expect(config.baseURL).toEqual('/api');
expect(config.url).toEqual('/foo');
done();
}, 100);
});
});
it('should allow overriding Content-Type header case-insensitive', function (done) {
let response;
const contentType = 'application/vnd.myapp.type+json';
axios
.post(
'/foo',
{ prop: 'value' },
{
headers: {
'Content-Type': contentType,
},
}
)
.then(function (res) {
response = res;
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders['Content-Type']).toEqual(contentType);
done();
});
});
it('should support binary data as array buffer', function (done) {
const input = new Int8Array(2);
input[0] = 1;
input[1] = 2;
axios.post('/foo', input.buffer);
getAjaxRequest().then(function (request) {
const output = new Int8Array(request.params);
expect(output.length).toEqual(2);
expect(output[0]).toEqual(1);
expect(output[1]).toEqual(2);
done();
});
});
it('should support binary data as array buffer view', function (done) {
const input = new Int8Array(2);
input[0] = 1;
input[1] = 2;
axios.post('/foo', input);
getAjaxRequest().then(function (request) {
const output = new Int8Array(request.params);
expect(output.length).toEqual(2);
expect(output[0]).toEqual(1);
expect(output[1]).toEqual(2);
done();
});
});
it('should support array buffer response', function (done) {
let response;
function str2ab(str) {
const buff = new ArrayBuffer(str.length * 2);
const view = new Uint16Array(buff);
for (let i = 0, l = str.length; i < l; i++) {
view[i] = str.charCodeAt(i);
}
return buff;
}
axios('/foo', {
responseType: 'arraybuffer',
}).then(function (data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
response: str2ab('Hello world'),
});
setTimeout(function () {
expect(response.data.byteLength).toBe(22);
done();
}, 100);
});
});
it('should support URLSearchParams', function (done) {
const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);
getAjaxRequest().then(function (request) {
expect(request.requestHeaders['Content-Type']).toBe(
'application/x-www-form-urlencoded;charset=utf-8'
);
expect(request.params).toBe('param1=value1&param2=value2');
done();
});
});
it('should support HTTP protocol', function (done) {
let response;
axios.get('/foo').then(function (res) {
response = res;
});
getAjaxRequest().then(function (request) {
expect(request.method).toBe('GET');
request.respondWith({
status: 200,
});
done();
});
});
it('should support HTTPS protocol', function (done) {
let response;
axios.get('https://www.google.com').then(function (res) {
response = res;
});
getAjaxRequest().then(function (request) {
expect(request.method).toBe('GET');
request.respondWith({
status: 200,
});
done();
});
});
it('should return unsupported protocol error message', function () {
return axios.get('ftp:localhost').then(
function () {
fail('Does not throw');
},
function (error) {
expect(error.message).toEqual('Unsupported protocol ftp:');
}
);
});
});

View File

@ -1,238 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
import AxiosError from '../../lib/core/AxiosError';
describe('transform', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should transform JSON to string', function (done) {
const data = {
foo: 'bar',
};
axios.post('/foo', data);
getAjaxRequest().then(function (request) {
expect(request.params).toEqual('{"foo":"bar"}');
done();
});
});
it('should transform string to JSON', function (done) {
let response;
axios('/foo').then(function (data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '{"foo": "bar"}',
});
setTimeout(function () {
expect(typeof response.data).toEqual('object');
expect(response.data.foo).toEqual('bar');
done();
}, 100);
});
});
it('should throw a SyntaxError if JSON parsing failed and responseType is "json" if silentJSONParsing is false', function (done) {
let thrown;
axios({
url: '/foo',
responseType: 'json',
transitional: { silentJSONParsing: false },
}).then(
function () {
done(new Error('should fail'));
},
function (err) {
thrown = err;
}
);
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '{foo": "bar"}', // JSON SyntaxError
});
setTimeout(function () {
expect(thrown).toBeTruthy();
expect(thrown.name).toContain('SyntaxError');
expect(thrown.code).toEqual(AxiosError.ERR_BAD_RESPONSE);
done();
}, 100);
});
});
it('should send data as JSON if request content-type is application/json', function (done) {
let response;
axios.post('/foo', 123, { headers: { 'Content-Type': 'application/json' } }).then(
function (_response) {
response = _response;
},
function (err) {
done(err);
}
);
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '',
});
setTimeout(function () {
expect(response).toBeTruthy();
expect(request.requestHeaders['Content-Type']).toBe('application/json');
expect(JSON.parse(request.params)).toBe(123);
done();
}, 100);
});
});
it('should not assume JSON if responseType is not `json`', function (done) {
let response;
axios
.get('/foo', {
responseType: 'text',
transitional: {
forcedJSONParsing: false,
},
})
.then(
function (_response) {
response = _response;
},
function (err) {
done(err);
}
);
const rawData = '{"x":1}';
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: rawData,
});
setTimeout(function () {
expect(response).toBeTruthy();
expect(response.data).toBe(rawData);
done();
}, 100);
});
});
it('should override default transform', function (done) {
const data = {
foo: 'bar',
};
axios.post('/foo', data, {
transformRequest: function (data) {
return data;
},
});
getAjaxRequest().then(function (request) {
expect(typeof request.params).toEqual('object');
done();
});
});
it('should allow an Array of transformers', function (done) {
const data = {
foo: 'bar',
};
axios.post('/foo', data, {
transformRequest: axios.defaults.transformRequest.concat(function (data) {
return data.replace('bar', 'baz');
}),
});
getAjaxRequest().then(function (request) {
expect(request.params).toEqual('{"foo":"baz"}');
done();
});
});
it('should allowing mutating headers', function (done) {
const token = Math.floor(Math.random() * Math.pow(2, 64)).toString(36);
axios('/foo', {
transformRequest: function (data, headers) {
headers['X-Authorization'] = token;
},
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders['X-Authorization']).toEqual(token);
done();
});
});
it("should normalize 'content-type' header when using a custom transformRequest", function (done) {
const data = {
foo: 'bar',
};
axios.post('/foo', data, {
headers: { 'content-type': 'application/x-www-form-urlencoded' },
transformRequest: [
function () {
return 'aa=44';
},
],
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders['Content-Type']).toEqual('application/x-www-form-urlencoded');
done();
});
});
it('should return response.data as parsed JSON object when responseType is json', function (done) {
const instance = axios.create({
baseURL: '/api',
transformResponse: [
function (data) {
return data;
},
],
responseType: 'json',
});
instance
.get('my/endpoint', { responseType: 'json' })
.then((response) => {
expect(typeof response).toBe('object');
done();
})
.catch((err) => {
done(err);
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: '{"key1": "value1"}',
});
});
});
});

View File

@ -1,13 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
const { kindOf } = utils;
describe('utils::kindOf', function () {
it('should return object tag', function () {
expect(kindOf({})).toEqual('object');
// cached result
expect(kindOf({})).toEqual('object');
expect(kindOf([])).toEqual('array');
});
});

View File

@ -1,40 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
const { extend } = utils;
describe('utils::extend', function () {
it('should be mutable', function () {
const a = {};
const b = { foo: 123 };
extend(a, b);
expect(a.foo).toEqual(b.foo);
});
it('should extend properties', function () {
let a = { foo: 123, bar: 456 };
const b = { bar: 789 };
a = extend(a, b);
expect(a.foo).toEqual(123);
expect(a.bar).toEqual(789);
});
it('should bind to thisArg', function () {
const a = {};
const b = {
getFoo: function getFoo() {
return this.foo;
},
};
const thisArg = { foo: 'barbaz' };
extend(a, b, thisArg);
expect(typeof a.getFoo).toEqual('function');
expect(a.getFoo()).toEqual(thisArg.foo);
});
});

View File

@ -1,69 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
const { forEach } = utils;
describe('utils::forEach', function () {
it('should loop over an array', function () {
let sum = 0;
forEach([1, 2, 3, 4, 5], function (val) {
sum += val;
});
expect(sum).toEqual(15);
});
it('should loop over object keys', function () {
let keys = '';
let vals = 0;
const obj = {
b: 1,
a: 2,
r: 3,
};
forEach(obj, function (v, k) {
keys += k;
vals += v;
});
expect(keys).toEqual('bar');
expect(vals).toEqual(6);
});
it('should handle undefined gracefully', function () {
let count = 0;
forEach(undefined, function () {
count++;
});
expect(count).toEqual(0);
});
it('should make an array out of non-array argument', function () {
let count = 0;
forEach(
function () {},
function () {
count++;
}
);
expect(count).toEqual(1);
});
it('should handle non object prototype gracefully', function () {
let count = 0;
const data = Object.create(null);
data.foo = 'bar';
forEach(data, function () {
count++;
});
expect(count).toEqual(1);
});
});

View File

@ -1,80 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
describe('utils::isX', function () {
it('should validate Array', function () {
expect(utils.isArray([])).toEqual(true);
expect(utils.isArray({ length: 5 })).toEqual(false);
});
it('should validate ArrayBuffer', function () {
expect(utils.isArrayBuffer(new ArrayBuffer(2))).toEqual(true);
expect(utils.isArrayBuffer({})).toEqual(false);
});
it('should validate ArrayBufferView', function () {
expect(utils.isArrayBufferView(new DataView(new ArrayBuffer(2)))).toEqual(true);
});
it('should validate FormData', function () {
expect(utils.isFormData(new FormData())).toEqual(true);
});
it('should validate Blob', function () {
expect(utils.isBlob(new Blob())).toEqual(true);
});
it('should validate String', function () {
expect(utils.isString('')).toEqual(true);
expect(
utils.isString({
toString: function () {
return '';
},
})
).toEqual(false);
});
it('should validate Number', function () {
expect(utils.isNumber(123)).toEqual(true);
expect(utils.isNumber('123')).toEqual(false);
});
it('should validate Undefined', function () {
expect(utils.isUndefined()).toEqual(true);
expect(utils.isUndefined(null)).toEqual(false);
});
it('should validate Object', function () {
expect(utils.isObject({})).toEqual(true);
expect(utils.isObject([])).toEqual(true);
expect(utils.isObject(null)).toEqual(false);
});
it('should validate plain Object', function () {
expect(utils.isPlainObject({})).toEqual(true);
expect(utils.isPlainObject([])).toEqual(false);
expect(utils.isPlainObject(null)).toEqual(false);
expect(utils.isPlainObject(Object.create({}))).toEqual(false);
});
it('should validate Date', function () {
expect(utils.isDate(new Date())).toEqual(true);
expect(utils.isDate(Date.now())).toEqual(false);
});
it('should validate Function', function () {
expect(utils.isFunction(function () {})).toEqual(true);
expect(utils.isFunction('function')).toEqual(false);
});
it('should validate URLSearchParams', function () {
expect(utils.isURLSearchParams(new URLSearchParams())).toEqual(true);
expect(utils.isURLSearchParams('foo=1&bar=2')).toEqual(false);
});
it('should validate TypedArray instance', function () {
expect(utils.isTypedArray(new Uint8Array([1, 2, 3]))).toEqual(true);
expect(utils.isTypedArray([1, 2, 3])).toEqual(false);
});
});

View File

@ -1,13 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
const { kindOf } = utils;
describe('utils::kindOf', function () {
it('should return object tag', function () {
expect(kindOf({})).toEqual('object');
// cached result
expect(kindOf({})).toEqual('object');
expect(kindOf([])).toEqual('array');
});
});

View File

@ -1,11 +0,0 @@
/* eslint-env mocha */
import { kindOfTest } from '../../../lib/utils';
describe('utils::kindOfTest', function () {
it('should return true if the type is matched', function () {
const test = kindOfTest('number');
expect(test(123)).toEqual(true);
expect(test('123')).toEqual(false);
});
});

View File

@ -1,97 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
const { merge } = utils;
describe('utils::merge', function () {
it('should be immutable', function () {
const a = {};
const b = { foo: 123 };
const c = { bar: 456 };
merge(a, b, c);
expect(typeof a.foo).toEqual('undefined');
expect(typeof a.bar).toEqual('undefined');
expect(typeof b.bar).toEqual('undefined');
expect(typeof c.foo).toEqual('undefined');
});
it('should merge properties', function () {
const a = { foo: 123 };
const b = { bar: 456 };
const c = { foo: 789 };
const d = merge(a, b, c);
expect(d.foo).toEqual(789);
expect(d.bar).toEqual(456);
});
it('should merge recursively', function () {
const a = { foo: { bar: 123 } };
const b = { foo: { baz: 456 }, bar: { qux: 789 } };
expect(merge(a, b)).toEqual({
foo: {
bar: 123,
baz: 456,
},
bar: {
qux: 789,
},
});
});
it('should remove all references from nested objects', function () {
const a = { foo: { bar: 123 } };
const b = {};
const d = merge(a, b);
expect(d).toEqual({
foo: {
bar: 123,
},
});
expect(d.foo).not.toBe(a.foo);
});
it('handles null and undefined arguments', function () {
expect(merge(undefined, undefined)).toEqual({});
expect(merge(undefined, { foo: 123 })).toEqual({ foo: 123 });
expect(merge({ foo: 123 }, undefined)).toEqual({ foo: 123 });
expect(merge(null, null)).toEqual({});
expect(merge(null, { foo: 123 })).toEqual({ foo: 123 });
expect(merge({ foo: 123 }, null)).toEqual({ foo: 123 });
});
it('should replace properties with null', function () {
expect(merge({}, { a: null })).toEqual({ a: null });
expect(merge({ a: null }, {})).toEqual({ a: null });
});
it('should replace properties with arrays', function () {
expect(merge({}, { a: [1, 2, 3] })).toEqual({ a: [1, 2, 3] });
expect(merge({ a: 2 }, { a: [1, 2, 3] })).toEqual({ a: [1, 2, 3] });
expect(merge({ a: { b: 2 } }, { a: [1, 2, 3] })).toEqual({ a: [1, 2, 3] });
});
it('should replace properties with cloned arrays', function () {
const a = [1, 2, 3];
const d = merge({}, { a: a });
expect(d).toEqual({ a: [1, 2, 3] });
expect(d.a).not.toBe(a);
});
it('should support caseless option', () => {
const a = { x: 1 };
const b = { X: 2 };
const merged = merge.call({ caseless: true }, a, b);
expect(merged).toEqual({
x: 2,
});
});
});

View File

@ -1,13 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
const { toArray } = utils;
describe('utils::kindOf', function () {
it('should return object tag', function () {
expect(toArray()).toEqual(null);
expect(toArray([])).toEqual([]);
expect(toArray([1])).toEqual([1]);
expect(toArray([1, 2, 3])).toEqual([1, 2, 3]);
});
});

View File

@ -1,13 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
const { toFlatObject } = utils;
describe('utils::toFlatObject', function () {
it('should resolve object proto chain to a flat object representation', function () {
const a = { x: 1 };
const b = Object.create(a, { y: { value: 2 } });
const c = Object.create(b, { z: { value: 3 } });
expect(toFlatObject(c)).toEqual({ x: 1, y: 2, z: 3 });
});
});

View File

@ -1,12 +0,0 @@
/* eslint-env mocha */
import utils from '../../../lib/utils';
describe('utils::trim', function () {
it('should trim spaces', function () {
expect(utils.trim(' foo ')).toEqual('foo');
});
it('should trim tabs', function () {
expect(utils.trim('\tfoo\t')).toEqual('foo');
});
});

View File

@ -1,148 +0,0 @@
/* eslint-env mocha */
/* global jasmine */
import cookies from '../../lib/helpers/cookies';
describe('xsrf', function () {
beforeEach(function () {
jasmine.Ajax.install();
});
afterEach(function () {
document.cookie =
axios.defaults.xsrfCookieName + '=;expires=' + new Date(Date.now() - 86400000).toGMTString();
jasmine.Ajax.uninstall();
});
it('should not set xsrf header if cookie is null', function (done) {
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual(undefined);
done();
});
});
it('should set xsrf header if cookie is set', function (done) {
document.cookie = axios.defaults.xsrfCookieName + '=12345';
axios('/foo');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual('12345');
done();
});
});
it('should not set xsrf header if xsrfCookieName is null', function (done) {
document.cookie = axios.defaults.xsrfCookieName + '=12345';
axios('/foo', {
xsrfCookieName: null,
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual(undefined);
done();
});
});
it('should not read cookies at all if xsrfCookieName is null', function (done) {
spyOn(cookies, 'read');
axios('/foo', {
xsrfCookieName: null,
});
getAjaxRequest().then(function (request) {
expect(cookies.read).not.toHaveBeenCalled();
done();
});
});
it('should not set xsrf header for cross origin', function (done) {
document.cookie = axios.defaults.xsrfCookieName + '=12345';
axios('http://example.com/');
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual(undefined);
done();
});
});
it('should not set xsrf header for cross origin when using withCredentials', function (done) {
document.cookie = axios.defaults.xsrfCookieName + '=12345';
axios('http://example.com/', {
withCredentials: true,
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual(undefined);
done();
});
});
describe('withXSRFToken option', function () {
it('should set xsrf header for cross origin when withXSRFToken = true', function (done) {
const token = '12345';
document.cookie = axios.defaults.xsrfCookieName + '=' + token;
axios('http://example.com/', {
withXSRFToken: true,
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual(token);
done();
});
});
it('should not set xsrf header for the same origin when withXSRFToken = false', function (done) {
const token = '12345';
document.cookie = axios.defaults.xsrfCookieName + '=' + token;
axios('/foo', {
withXSRFToken: false,
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual(undefined);
done();
});
});
it('should not set xsrf header for the same origin when withXSRFToken = false', function (done) {
const token = '12345';
document.cookie = axios.defaults.xsrfCookieName + '=' + token;
axios('/foo', {
withXSRFToken: false,
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual(undefined);
done();
});
});
it('should support function resolver', (done) => {
const token = '12345';
document.cookie = axios.defaults.xsrfCookieName + '=' + token;
axios('/foo', {
withXSRFToken: (config) => config.userFlag === 'yes',
userFlag: 'yes',
});
getAjaxRequest().then(function (request) {
expect(request.requestHeaders[axios.defaults.xsrfHeaderName]).toEqual(token);
done();
});
});
});
});

View File

@ -1,48 +0,0 @@
/* eslint-env mocha */
import adapters from '../../../lib/adapters/adapters.js';
import assert from 'assert';
describe('adapters', function () {
const store = { ...adapters.adapters };
beforeEach(() => {
Object.keys(adapters.adapters).forEach((name) => {
delete adapters.adapters[name];
});
Object.assign(adapters.adapters, store);
});
it('should support loading by fn handle', function () {
const adapter = () => {};
assert.strictEqual(adapters.getAdapter(adapter), adapter);
});
it('should support loading by name', function () {
const adapter = () => {};
adapters.adapters['testadapter'] = adapter;
assert.strictEqual(adapters.getAdapter('testAdapter'), adapter);
});
it('should detect adapter unavailable status', function () {
adapters.adapters['testadapter'] = null;
assert.throws(() => adapters.getAdapter('testAdapter'), /is not available in the build/);
});
it('should detect adapter unsupported status', function () {
adapters.adapters['testadapter'] = false;
assert.throws(() => adapters.getAdapter('testAdapter'), /is not supported by the environment/);
});
it('should pick suitable adapter from the list', function () {
const adapter = () => {};
Object.assign(adapters.adapters, {
foo: false,
bar: null,
baz: adapter,
});
assert.strictEqual(adapters.getAdapter(['foo', 'bar', 'baz']), adapter);
});
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,17 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICpDCCAYwCCQDbqELLwgbPdDANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMjAwNjI2MjIxMTQ3WhcNNDcxMTExMjIxMTQ3WjAUMRIwEAYD
VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD6
Ogt99/dZ0UgbCuVV1RZ9n28Ov3DzrJCkjperQoXomIq3Fr4RUI1a2rwe3mtl3UzE
1IVZVvWPGdEsEQHwXfAsP/jFGTwI3HDyOhcqzFQSKsjvqJWYkOOb+2r3SBrFlRZW
09k/3lC+hx2XtuuG68u4Xgn3AlUvm2vplgCN7eiYcGeNwVuf2eHdOqTRTqiYCZLi
T8GtdYMDXOrwsGZs/jUKd9U0ar/lqwMhmw07yzlVDM2MWM2tyq/asQ7Sf7vuoMFu
oAtDJ3E+bK1k/7SNhdyP4RonhyUCkWG+mzoKDS1qgXroTiQSDUksAvOCTcj8BNIT
ee+Lcn9FaTKNJiKiU9q/AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAFi5ZpaUj+mU
dsgOka+j2/njgNXux3cOjhm7z/N7LeTuDENAOrYa5b+j5JX/YM7RKHrkbXHsQbfs
GB3ufH6QhSiCd/AdsXp/TbCE/8gdq8ykkjwVP1bvBle9oPH7x1aO/WP/odsepYUv
o9aOZW4iNQVmwamU62ezglf3QD7HPeE4LnZueaFtuzRoC+aWT9v0MIeUPJLe3WDQ
FEySwUuthMDJEv92/TeK0YOiunmseCu2mvdiDj6E3C9xa5q2DWgl+msu7+bPgvYO
GuWaoNeQQGk7ebBO3Hk3IyaGx6Cbd8ty+YaZW7dUT+m7KCs1VkxdcDMjZJVWiJy4
4HcEcKboG4Y=
-----END CERTIFICATE-----

View File

@ -1,90 +0,0 @@
/* eslint-env mocha */
import assert from 'assert';
import https from 'https';
import net from 'net';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import axios from '../../../index.js';
/** __dirname replacement for ESM */
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/** Get a port that will refuse connections: bind to a random port and close it. */
async function getClosedPort() {
return await new Promise((resolve) => {
const srv = net.createServer();
srv.listen(0, '127.0.0.1', () => {
const { port } = srv.address();
srv.close(() => resolve(port));
});
});
}
describe('adapters network-error details', function () {
this.timeout(5000);
it('should expose ECONNREFUSED and set error.cause on connection refusal', async function () {
const port = await getClosedPort();
try {
await axios.get(`http://127.0.0.1:${port}`, { timeout: 500 });
assert.fail('request unexpectedly succeeded');
} catch (err) {
assert.ok(err instanceof Error, 'should be an Error');
assert.strictEqual(err.isAxiosError, true, 'isAxiosError should be true');
// New behavior: Node error code is surfaced and original error is linked via cause
assert.strictEqual(err.code, 'ECONNREFUSED');
assert.ok('cause' in err, 'error.cause should exist');
assert.ok(err.cause instanceof Error, 'cause should be an Error');
assert.strictEqual(err.cause && err.cause.code, 'ECONNREFUSED');
// Message remains a string (content may include the code prefix)
assert.strictEqual(typeof err.message, 'string');
}
});
it('should expose self-signed TLS error and set error.cause', async function () {
// Use the same certs already present for adapter tests in this folder
const keyPath = path.join(__dirname, 'key.pem');
const certPath = path.join(__dirname, 'cert.pem');
const key = fs.readFileSync(keyPath);
const cert = fs.readFileSync(certPath);
const httpsServer = https.createServer({ key, cert }, (req, res) => res.end('ok'));
await new Promise((resolve) => httpsServer.listen(0, '127.0.0.1', resolve));
const { port } = httpsServer.address();
try {
await axios.get(`https://127.0.0.1:${port}`, {
timeout: 500,
httpsAgent: new https.Agent({ rejectUnauthorized: true }), // Explicit: reject self-signed
});
assert.fail('request unexpectedly succeeded');
} catch (err) {
const codeStr = String(err.code);
// OpenSSL/Node variants: SELF_SIGNED_CERT_IN_CHAIN, DEPTH_ZERO_SELF_SIGNED_CERT, UNABLE_TO_VERIFY_LEAF_SIGNATURE
assert.ok(
/SELF_SIGNED|UNABLE_TO_VERIFY_LEAF_SIGNATURE|DEPTH_ZERO/.test(codeStr),
'unexpected TLS code: ' + codeStr
);
assert.ok('cause' in err, 'error.cause should exist');
assert.ok(err.cause instanceof Error, 'cause should be an Error');
const causeCode = String(err.cause && err.cause.code);
assert.ok(
/SELF_SIGNED|UNABLE_TO_VERIFY_LEAF_SIGNATURE|DEPTH_ZERO/.test(causeCode),
'unexpected cause code: ' + causeCode
);
assert.strictEqual(typeof err.message, 'string');
} finally {
await new Promise((resolve) => httpsServer.close(resolve));
}
});
});

View File

@ -1,541 +0,0 @@
/* eslint-env mocha */
import assert from 'assert';
import {
startHTTPServer,
stopHTTPServer,
LOCAL_SERVER_URL,
setTimeoutAsync,
makeReadableStream,
generateReadable,
makeEchoStream,
} from '../../helpers/server.js';
import axios from '../../../index.js';
import stream from 'stream';
import { AbortController } from 'abortcontroller-polyfill/dist/cjs-ponyfill.js';
import util from 'util';
const pipelineAsync = util.promisify(stream.pipeline);
const fetchAxios = axios.create({
baseURL: LOCAL_SERVER_URL,
adapter: 'fetch',
});
let server;
describe('supports fetch with nodejs', function () {
before(function () {
if (typeof fetch !== 'function') {
this.skip();
}
});
afterEach(async function () {
await stopHTTPServer(server);
server = null;
});
describe('responses', async () => {
it(`should support text response type`, async () => {
const originalData = 'my data';
server = await startHTTPServer((req, res) => res.end(originalData));
const { data } = await fetchAxios.get('/', {
responseType: 'text',
});
assert.deepStrictEqual(data, originalData);
});
it(`should support arraybuffer response type`, async () => {
const originalData = 'my data';
server = await startHTTPServer((req, res) => res.end(originalData));
const { data } = await fetchAxios.get('/', {
responseType: 'arraybuffer',
});
assert.deepStrictEqual(
data,
Uint8Array.from(await new TextEncoder().encode(originalData)).buffer
);
});
it(`should support blob response type`, async () => {
const originalData = 'my data';
server = await startHTTPServer((req, res) => res.end(originalData));
const { data } = await fetchAxios.get('/', {
responseType: 'blob',
});
assert.deepStrictEqual(data, new Blob([originalData]));
});
it(`should support stream response type`, async () => {
const originalData = 'my data';
server = await startHTTPServer((req, res) => res.end(originalData));
const { data } = await fetchAxios.get('/', {
responseType: 'stream',
});
assert.ok(data instanceof ReadableStream, 'data is not instanceof ReadableStream');
let response = new Response(data);
assert.deepStrictEqual(await response.text(), originalData);
});
it(`should support formData response type`, async function () {
this.timeout(5000);
const originalData = new FormData();
originalData.append('x', '123');
server = await startHTTPServer(async (req, res) => {
const response = await new Response(originalData);
res.setHeader('Content-Type', response.headers.get('Content-Type'));
res.end(await response.text());
});
const { data } = await fetchAxios.get('/', {
responseType: 'formdata',
});
assert.ok(data instanceof FormData, 'data is not instanceof FormData');
assert.deepStrictEqual(
Object.fromEntries(data.entries()),
Object.fromEntries(originalData.entries())
);
});
it(`should support json response type`, async () => {
const originalData = { x: 'my data' };
server = await startHTTPServer((req, res) => res.end(JSON.stringify(originalData)));
const { data } = await fetchAxios.get('/', {
responseType: 'json',
});
assert.deepStrictEqual(data, originalData);
});
});
describe('progress', () => {
describe('upload', function () {
it('should support upload progress capturing', async function () {
this.timeout(15000);
server = await startHTTPServer({
rate: 100 * 1024,
});
let content = '';
const count = 10;
const chunk = 'test';
const chunkLength = Buffer.byteLength(chunk);
const contentLength = count * chunkLength;
const readable = stream.Readable.from(
(async function* () {
let i = count;
while (i-- > 0) {
await setTimeoutAsync(1100);
content += chunk;
yield chunk;
}
})()
);
const samples = [];
const { data } = await fetchAxios.post('/', readable, {
onUploadProgress: ({ loaded, total, progress, bytes, upload }) => {
console.log(
`Upload Progress ${loaded} from ${total} bytes (${(progress * 100).toFixed(1)}%)`
);
samples.push({
loaded,
total,
progress,
bytes,
upload,
});
},
headers: {
'Content-Length': contentLength,
},
responseType: 'text',
});
await setTimeoutAsync(500);
assert.strictEqual(data, content);
assert.deepStrictEqual(
samples,
Array.from(
(function* () {
for (let i = 1; i <= 10; i++) {
yield {
loaded: chunkLength * i,
total: contentLength,
progress: (chunkLength * i) / contentLength,
bytes: 4,
upload: true,
};
}
})()
)
);
});
it('should not fail with get method', async () => {
server = await startHTTPServer((req, res) => res.end('OK'));
const { data } = await fetchAxios.get('/', {
onUploadProgress() {},
});
assert.strictEqual(data, 'OK');
});
});
describe('download', function () {
it('should support download progress capturing', async function () {
this.timeout(15000);
server = await startHTTPServer({
rate: 100 * 1024,
});
let content = '';
const count = 10;
const chunk = 'test';
const chunkLength = Buffer.byteLength(chunk);
const contentLength = count * chunkLength;
const readable = stream.Readable.from(
(async function* () {
let i = count;
while (i-- > 0) {
await setTimeoutAsync(1100);
content += chunk;
yield chunk;
}
})()
);
const samples = [];
const { data } = await fetchAxios.post('/', readable, {
onDownloadProgress: ({ loaded, total, progress, bytes, download }) => {
console.log(
`Download Progress ${loaded} from ${total} bytes (${(progress * 100).toFixed(1)}%)`
);
samples.push({
loaded,
total,
progress,
bytes,
download,
});
},
headers: {
'Content-Length': contentLength,
},
responseType: 'text',
maxRedirects: 0,
});
await setTimeoutAsync(500);
assert.strictEqual(data, content);
assert.deepStrictEqual(
samples,
Array.from(
(function* () {
for (let i = 1; i <= 10; i++) {
yield {
loaded: chunkLength * i,
total: contentLength,
progress: (chunkLength * i) / contentLength,
bytes: 4,
download: true,
};
}
})()
)
);
});
});
});
it('should support basic auth', async () => {
server = await startHTTPServer((req, res) => res.end(req.headers.authorization));
const user = 'foo';
const headers = { Authorization: 'Bearer 1234' };
const res = await axios.get('http://' + user + '@localhost:4444/', { headers: headers });
const base64 = Buffer.from(user + ':', 'utf8').toString('base64');
assert.equal(res.data, 'Basic ' + base64);
});
it('should support stream.Readable as a payload', async () => {
server = await startHTTPServer();
const { data } = await fetchAxios.post('/', stream.Readable.from('OK'));
assert.strictEqual(data, 'OK');
});
describe('request aborting', function () {
it('should be able to abort the request stream', async function () {
server = await startHTTPServer({
rate: 100000,
useBuffering: true,
});
const controller = new AbortController();
setTimeout(() => {
controller.abort();
}, 500);
await assert.rejects(async () => {
await fetchAxios.post('/', makeReadableStream(), {
responseType: 'stream',
signal: controller.signal,
});
}, /CanceledError/);
});
it('should be able to abort the response stream', async function () {
server = await startHTTPServer((req, res) => {
pipelineAsync(generateReadable(10000, 10), res);
});
const controller = new AbortController();
setTimeout(() => {
controller.abort(new Error('test'));
}, 800);
const { data } = await fetchAxios.get('/', {
responseType: 'stream',
signal: controller.signal,
});
await assert.rejects(async () => {
await data.pipeTo(makeEchoStream());
}, /^(AbortError|CanceledError):/);
});
});
it('should support a timeout', async () => {
server = await startHTTPServer(async (req, res) => {
await setTimeoutAsync(1000);
res.end('OK');
});
const timeout = 500;
const ts = Date.now();
await assert.rejects(async () => {
await fetchAxios('/', {
timeout,
});
}, /timeout/);
const passed = Date.now() - ts;
assert.ok(passed >= timeout - 5, `early cancellation detected (${passed} ms)`);
});
it('should combine baseURL and url', async () => {
server = await startHTTPServer();
const res = await fetchAxios('/foo');
assert.equal(res.config.baseURL, LOCAL_SERVER_URL);
assert.equal(res.config.url, '/foo');
});
it('should support params', async () => {
server = await startHTTPServer((req, res) => res.end(req.url));
const { data } = await fetchAxios.get('/?test=1', {
params: {
foo: 1,
bar: 2,
},
});
assert.strictEqual(data, '/?test=1&foo=1&bar=2');
});
it('should handle fetch failed error as an AxiosError with ERR_NETWORK code', async () => {
try {
await fetchAxios('http://notExistsUrl.in.nowhere');
assert.fail('should fail');
} catch (err) {
assert.strictEqual(String(err), 'AxiosError: Network Error');
assert.strictEqual(err.cause && err.cause.code, 'ENOTFOUND');
}
});
it('should get response headers', async () => {
server = await startHTTPServer((req, res) => {
res.setHeader('foo', 'bar');
res.end(req.url);
});
const { headers } = await fetchAxios.get('/', {
responseType: 'stream',
});
assert.strictEqual(headers.get('foo'), 'bar');
});
describe('fetch adapter - Content-Type handling', function () {
it('should set correct Content-Type for FormData automatically', async function () {
const FormData = (await import('form-data')).default; // Node FormData
const form = new FormData();
form.append('foo', 'bar');
server = await startHTTPServer((req, res) => {
const contentType = req.headers['content-type'];
assert.match(contentType, /^multipart\/form-data; boundary=/i);
res.end('OK');
});
await fetchAxios.post('/form', form);
});
});
describe('env config', () => {
it('should respect env fetch API configuration', async () => {
const { data, headers } = await fetchAxios.get('/', {
env: {
fetch() {
return {
headers: {
foo: '1',
},
text: async () => 'test',
};
},
},
});
assert.strictEqual(headers.get('foo'), '1');
assert.strictEqual(data, 'test');
});
it('should be able to request with lack of Request object', async () => {
const form = new FormData();
form.append('x', '1');
const { data, headers } = await fetchAxios.post('/', form, {
onUploadProgress() {
// dummy listener to activate streaming
},
env: {
Request: null,
fetch() {
return {
headers: {
foo: '1',
},
text: async () => 'test',
};
},
},
});
assert.strictEqual(headers.get('foo'), '1');
assert.strictEqual(data, 'test');
});
it('should be able to handle response with lack of Response object', async () => {
const { data, headers } = await fetchAxios.get('/', {
onDownloadProgress() {
// dummy listener to activate streaming
},
env: {
Request: null,
Response: null,
fetch() {
return {
headers: {
foo: '1',
},
text: async () => 'test',
};
},
},
});
assert.strictEqual(headers.get('foo'), '1');
assert.strictEqual(data, 'test');
});
it('should fallback to the global on undefined env value', async () => {
server = await startHTTPServer((req, res) => res.end('OK'));
const { data } = await fetchAxios.get('/', {
env: {
fetch: undefined,
},
});
assert.strictEqual(data, 'OK');
});
it('should use current global fetch when env fetch is not specified', async () => {
const globalFetch = fetch;
fetch = async () => {
return {
headers: {
foo: '1',
},
text: async () => 'global',
};
};
try {
server = await startHTTPServer((req, res) => res.end('OK'));
const { data } = await fetchAxios.get('/', {
env: {
fetch: undefined,
},
});
assert.strictEqual(data, 'global');
} finally {
fetch = globalFetch;
}
});
});
});

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA+joLfff3WdFIGwrlVdUWfZ9vDr9w86yQpI6Xq0KF6JiKtxa+
EVCNWtq8Ht5rZd1MxNSFWVb1jxnRLBEB8F3wLD/4xRk8CNxw8joXKsxUEirI76iV
mJDjm/tq90gaxZUWVtPZP95Qvocdl7brhuvLuF4J9wJVL5tr6ZYAje3omHBnjcFb
n9nh3Tqk0U6omAmS4k/BrXWDA1zq8LBmbP41CnfVNGq/5asDIZsNO8s5VQzNjFjN
rcqv2rEO0n+77qDBbqALQydxPmytZP+0jYXcj+EaJ4clApFhvps6Cg0taoF66E4k
Eg1JLALzgk3I/ATSE3nvi3J/RWkyjSYiolPavwIDAQABAoIBAEbMi5ndwjfAlkVI
hPEPNKjgpnymwB/CEL7utY04akkQeBcrsSWXBBfT0exuBDczMVhzxTMs/pe5t0xf
l4vaGG18wDeMV0cukCqJMyrh21u0jVv5+DHNtQjaTz6eQSzsbQCuOkbu8SuncUEO
+X8YUnDc8rbYCyBIOnVCAvAlg201uW0G5G9NEwJOu6cAKMKkogdHqv+FRX96C5hm
gtbGEzpGV2vVClgMwMcX49ucluZvqLvit/yehNVd0VOtW/kuLup4R6q0abHRapDd
95rJAhPvar4mzP+UgJrGQ9hozqhizDthBjnsmGeMBUiBCkay7OXIZpvLoCpQkti1
WIWuikkCgYEA/oZqq71RT1nPuI7rlcjx3AeWe2EUQtKhQMJBiPx5eLLP6gII8+v2
pD1qlmJM2eyIK0lzuskLIulTAA5Z+ejORDbvmn/DdT0CSvdrUFrcvnrRQnt2M5M2
9VDRp6nvPE0H4kRZJrtITyLn0dv5ABf2L32i4dPCMePjKjSUygJSHrsCgYEA+61A
cIqch/lrQTk8hG7Y6p0EJzSInFVaKuZoMYpLhlDQcVvSDIQbGgRAN6BKTdxeQ+tK
hSxBSm2mze11aHig8GBGgdBFLaJOZRo6G+2fl+s1t1FCHfsaFhHwheZJONHMpKKd
Qm/7L/V35QV9YG0lPZ01TM6d5lXuKsmUNvBJTc0CgYASYajAgGqn3WeX/5JZ/eoh
ptaiUG+DJ+0HXUAYYYtwQRGs57q3yvnEAL963tyH/IIVBjf6bFyGh+07ms26s6p5
2LHTKZj3FZHd0iKI6hb5FquYLoxpyx7z9oM9pZMmerWwDJmXp3zgYjf1uvovnItm
AJ/LyVxD+B5GxQdd028U0wKBgG4OllZglxDzJk7wa6FyI9N89Fr8oxzSSkrmVPwN
APfskSpxP8qPXpai8z4gDz47NtG2q/DOqIKWrtHwnF4iGibjwxFzdTz+dA/MR0r9
P8QcbHIMy7/2lbK/B5JWYQDC5h28qs5pz8tqKZLyMqCfOiDWhX9f/zbBrxPw8KqR
q0ylAoGAL/0kemA/Tmxpwmp0S0oCqnA4gbCgS7qnApxB09xTewc/tuvraXc3Mzea
EvqDXLXK0R7O4E3vo0Mr23SodRVlFPevsmUUJLPJMJcxdfnSJgX+qE/UC8Ux+UMi
eYufYRDYSslfL2rt9D7abnnbqSfsHymJKukWpElIgJTklQUru4k=
-----END RSA PRIVATE KEY-----

Some files were not shown because too many files have changed in this diff Show More