MOOver 2.0
Slashcommands added hehehehehe
This commit is contained in:
parent
ec216e2d2f
commit
d2a87e6f10
1241 changed files with 237709 additions and 198 deletions
347
commands/birthday.js
Normal file
347
commands/birthday.js
Normal file
|
@ -0,0 +1,347 @@
|
||||||
|
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||||
|
let birthdayJSON = require('../database/birthdays.json');
|
||||||
|
const { MessageEmbed } = require('discord.js');
|
||||||
|
const help = require('../helpFunctions.js');
|
||||||
|
const PATH = './database/birthdays.json';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('birthday')
|
||||||
|
.setDescription('shows birthday')
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('check')
|
||||||
|
.setDescription('Checks who\'s birthday is the closest'))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('add')
|
||||||
|
.setDescription('Adds new birthday entry to database')
|
||||||
|
.addUserOption(option => option.setName('user')
|
||||||
|
.setDescription('Select a user')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('day')
|
||||||
|
.setDescription('Day of birth')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('month')
|
||||||
|
.setDescription('Month of birth')
|
||||||
|
.setRequired(true))
|
||||||
|
.addStringOption(option =>
|
||||||
|
option.setName('nickname')
|
||||||
|
.setDescription('Nickname of birthday person')))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('delete')
|
||||||
|
.setDescription('Deletes birthday entry')
|
||||||
|
.addUserOption(option => option.setName('user')
|
||||||
|
.setDescription('Select a user')
|
||||||
|
.setRequired(true)))
|
||||||
|
.addSubcommandGroup(subcommandGroup =>
|
||||||
|
subcommandGroup
|
||||||
|
.setName('change')
|
||||||
|
.setDescription('Change the birthday entry')
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('date')
|
||||||
|
.setDescription('Change date of a person')
|
||||||
|
.addUserOption(option => option.setName('user')
|
||||||
|
.setDescription('Select a user')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('day')
|
||||||
|
.setDescription('Day of birth')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('month')
|
||||||
|
.setDescription('Month of birth')
|
||||||
|
.setRequired(true)))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('nickname')
|
||||||
|
.setDescription('Change nickname of a person')
|
||||||
|
.addUserOption(option => option.setName('user')
|
||||||
|
.setDescription('Select a user')
|
||||||
|
.setRequired(true))
|
||||||
|
.addStringOption(option =>
|
||||||
|
option.setName('nickname')
|
||||||
|
.setDescription('Nickname of birthday person (can be empty to remove)')))),
|
||||||
|
async execute(interaction) {
|
||||||
|
const error = catchErrors(interaction.options);
|
||||||
|
if (error != null) {
|
||||||
|
await interaction.reply(error);
|
||||||
|
}
|
||||||
|
let subcommandGroup;
|
||||||
|
try {
|
||||||
|
subcommandGroup = interaction.options.getSubcommandGroup();
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
subcommandGroup = undefined;
|
||||||
|
}
|
||||||
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
if (subcommandGroup == undefined) {
|
||||||
|
switch (subcommand) {
|
||||||
|
case 'add':
|
||||||
|
await interaction.reply(addBirthday(interaction.options));
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
await interaction.reply(deleteBirthday(interaction.options));
|
||||||
|
break;
|
||||||
|
case 'check':
|
||||||
|
await interaction.reply({ embeds: [checkBirthday(interaction)] });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (subcommand) {
|
||||||
|
case 'date':
|
||||||
|
await interaction.reply(changeDate(interaction.options));
|
||||||
|
break;
|
||||||
|
case 'nickname':
|
||||||
|
await interaction.reply(changeNickname(interaction.options));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function addBirthday(options) {
|
||||||
|
const userId = options.getUser('user').id;
|
||||||
|
const newDay = options.getInteger('day');
|
||||||
|
const newMonth = options.getInteger('month');
|
||||||
|
|
||||||
|
let nickname;
|
||||||
|
try {
|
||||||
|
nickname = options.getString('nickname');
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
nickname = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < birthdayJSON.length; i++) {
|
||||||
|
const currDay = birthdayJSON[i].day;
|
||||||
|
const currMonth = birthdayJSON[i].month;
|
||||||
|
if (birthdayJSON[i].id == userId) {
|
||||||
|
return 'This user already exists in database';
|
||||||
|
}
|
||||||
|
if ((currMonth == newMonth && currDay >= newDay) || currMonth > newMonth) {
|
||||||
|
const fstPart = birthdayJSON.slice(0, i);
|
||||||
|
const sndPart = birthdayJSON.slice(i);
|
||||||
|
fstPart.push({ id: userId, day: newDay, month: newMonth, nickname: nickname });
|
||||||
|
birthdayJSON = fstPart.concat(sndPart);
|
||||||
|
const error = help.writeToFile(birthdayJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating the birthday list';
|
||||||
|
}
|
||||||
|
return `Successfuly added <@${userId}> to the birthday list`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
birthdayJSON.push({ id: userId, day: newDay, month: newMonth, nickname: nickname });
|
||||||
|
const error = help.writeToFile(birthdayJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating the birthday list';
|
||||||
|
}
|
||||||
|
return `Successfuly added <@${userId}> to the birthday list`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkBirthday(interaction) {
|
||||||
|
const guildMembers = interaction.guild.members;
|
||||||
|
const currentDay = new Date().getDate();
|
||||||
|
const currentMonth = new Date().getMonth() + 1;
|
||||||
|
|
||||||
|
const closest = [];
|
||||||
|
let closestD;
|
||||||
|
let closestM;
|
||||||
|
let isFirst = true;
|
||||||
|
|
||||||
|
const rng = help.RNG(6);
|
||||||
|
let probably = '';
|
||||||
|
if (rng == 1) {
|
||||||
|
probably = '(probably)';
|
||||||
|
}
|
||||||
|
else if (rng == 2) {
|
||||||
|
probably = '(or will they?)';
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the person with day closest to today date
|
||||||
|
for (let i = 0; i < birthdayJSON.length; i++) {
|
||||||
|
const birthDay = birthdayJSON[i].day;
|
||||||
|
const birthMonth = birthdayJSON[i].month;
|
||||||
|
const userId = birthdayJSON[i].id;
|
||||||
|
const nick = birthdayJSON[i].nickname;
|
||||||
|
// first date that is bigger or equal is the closest
|
||||||
|
if ((currentMonth == birthMonth && currentDay <= birthDay) || currentMonth < birthMonth) {
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
closestD = birthDay;
|
||||||
|
closestM = birthMonth;
|
||||||
|
}
|
||||||
|
if (!isFirst) {
|
||||||
|
if (closestD == birthDay && closestM == birthMonth) {
|
||||||
|
const result = isInGuild(guildMembers, userId);
|
||||||
|
if (result != undefined) {
|
||||||
|
closest.push(`<@${userId}> ${nick}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
closest.join('\n');
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.setTitle(`Closest birthday is ${closestD}. ${closestM}.`)
|
||||||
|
.setDescription(`${closest} \n will celebrate ${probably}`)
|
||||||
|
.setColor(help.randomColor());
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ? if the closest is in next year -> closest is the first in list
|
||||||
|
closestD = birthdayJSON[0].day;
|
||||||
|
closestM = birthdayJSON[0].month;
|
||||||
|
// check if there are others with the same date just to be sure
|
||||||
|
for (let i = 0; i < birthdayJSON.length; i++) {
|
||||||
|
const birthDay = birthdayJSON[i].day;
|
||||||
|
const birthMonth = birthdayJSON[i].month;
|
||||||
|
const userId = birthdayJSON[i].id;
|
||||||
|
const nick = birthdayJSON[i].nickname;
|
||||||
|
|
||||||
|
if (closestD == birthDay && closestM == birthMonth) {
|
||||||
|
closest.push(`<@${userId}> ${nick}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
closest.join('\n');
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.setTitle(`Closest birthday is ${birthDay}. ${birthMonth}.`)
|
||||||
|
.setDescription(`${closest} \n will celebrate ${probably}`)
|
||||||
|
.setColor(help.randomColor());
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if noone from server is in the birthday list (and maybe something else)
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.setTitle('Oh no...')
|
||||||
|
.setDescription('There was an error');
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteBirthday(options) {
|
||||||
|
const userId = options.getUser('user').id;
|
||||||
|
|
||||||
|
for (let i = 0; i < birthdayJSON.length; i++) {
|
||||||
|
if (birthdayJSON[i].id == userId) {
|
||||||
|
const fstPart = birthdayJSON.slice(0, i);
|
||||||
|
const sndPart = birthdayJSON.slice(i + 1);
|
||||||
|
birthdayJSON = fstPart.concat(sndPart);
|
||||||
|
const error = help.writeToFile(birthdayJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating birthday list';
|
||||||
|
}
|
||||||
|
return `Successfuly deleted <@${userId}> from birthday list`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'There was a problem :c';
|
||||||
|
}
|
||||||
|
|
||||||
|
function catchErrors(options) {
|
||||||
|
const month = options.getInteger('month');
|
||||||
|
const day = options.getInteger('day');
|
||||||
|
if (month == null || day == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (month > 12 || month < 1) {
|
||||||
|
return 'Bruh, "month" kinda poopy';
|
||||||
|
}
|
||||||
|
if (day > checkMonth(month) || day < 1) {
|
||||||
|
return 'Bruh, "day" kinda poopy';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeDate(options) {
|
||||||
|
const userId = options.getUser('user').id;
|
||||||
|
|
||||||
|
for (let i = 0; i < birthdayJSON.length; i++) {
|
||||||
|
const id = birthdayJSON[i].id;
|
||||||
|
if (birthdayJSON[i].id == userId) {
|
||||||
|
const day = options.getInteger('day');
|
||||||
|
const month = options.getInteger('month');
|
||||||
|
const nick = birthdayJSON[i].nickname;
|
||||||
|
const prevD = birthdayJSON[i].day;
|
||||||
|
const prevM = birthdayJSON[i].month;
|
||||||
|
let fstPart = birthdayJSON.slice(0, i);
|
||||||
|
let sndPart = birthdayJSON.slice(i + 1);
|
||||||
|
birthdayJSON = fstPart.concat(sndPart);
|
||||||
|
|
||||||
|
for (let j = 0; j < birthdayJSON.length; j++) {
|
||||||
|
const currDay = birthdayJSON[j].day;
|
||||||
|
const currMonth = birthdayJSON[j].month;
|
||||||
|
if ((currMonth == month && currDay >= day) || currMonth > month) {
|
||||||
|
fstPart = birthdayJSON.slice(0, j);
|
||||||
|
sndPart = birthdayJSON.slice(j);
|
||||||
|
fstPart.push({ id: id, day: day, month: month, nickname: nick });
|
||||||
|
birthdayJSON = fstPart.concat(sndPart);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const error = help.writeToFile(birthdayJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating the birthday list';
|
||||||
|
}
|
||||||
|
return `Successfuly changed birthday date of <@${userId}> from ${prevD}. ${prevM}. to ${day}. ${month}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'There was an error (this user probably isn\'t on birthday list)';
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeNickname(options) {
|
||||||
|
|
||||||
|
const userId = options.getUser('user').id;
|
||||||
|
for (let i = 0; i < birthdayJSON.length; i++) {
|
||||||
|
if (birthdayJSON[i].id == userId) {
|
||||||
|
const prevNick = birthdayJSON[i].nickname;
|
||||||
|
const newNick = options.getString('nickname');
|
||||||
|
birthdayJSON[i].nickname = newNick;
|
||||||
|
|
||||||
|
const error = help.writeToFile(birthdayJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating the birthday list';
|
||||||
|
}
|
||||||
|
return `Succesfully change nickname of <@${userId}> from ${prevNick} to ${newNick}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkMonth(month) {
|
||||||
|
switch (month) {
|
||||||
|
case 1:
|
||||||
|
return 31;
|
||||||
|
case 2:
|
||||||
|
return 28;
|
||||||
|
case 3:
|
||||||
|
return 31;
|
||||||
|
case 4:
|
||||||
|
return 30;
|
||||||
|
case 5:
|
||||||
|
return 31;
|
||||||
|
case 6:
|
||||||
|
return 30;
|
||||||
|
case 7:
|
||||||
|
return 31;
|
||||||
|
case 8:
|
||||||
|
return 31;
|
||||||
|
case 9:
|
||||||
|
return 30;
|
||||||
|
case 10:
|
||||||
|
return 31;
|
||||||
|
case 11:
|
||||||
|
return 30;
|
||||||
|
case 12:
|
||||||
|
return 31;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function isInGuild(guildMembers, userId) {
|
||||||
|
(await guildMembers.fetch()).find(user => user.id == userId);
|
||||||
|
}
|
597
commands/events.js
Normal file
597
commands/events.js
Normal file
|
@ -0,0 +1,597 @@
|
||||||
|
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||||
|
const { MessageEmbed } = require('discord.js');
|
||||||
|
const help = require('../helpFunctions.js');
|
||||||
|
const PATH = './database/events.json';
|
||||||
|
const eventsJSON = require('../database/events.json');
|
||||||
|
const { writeToFile } = require('../helpFunctions.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('event')
|
||||||
|
.setDescription('Adds events to celebrate!')
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand.setName('add')
|
||||||
|
.setDescription('Adds new event to the database')
|
||||||
|
.addStringOption(option => option.setName('name')
|
||||||
|
.setDescription('Name of the event you want to add')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('day')
|
||||||
|
.setDescription('Day of event')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('month')
|
||||||
|
.setDescription('Month of event')
|
||||||
|
.setRequired(true))
|
||||||
|
.addBooleanOption(option =>
|
||||||
|
option.setName('global')
|
||||||
|
.setDescription('Should this event display on all servers?')))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand.setName('delete')
|
||||||
|
.setDescription('Deletes event from database')
|
||||||
|
.addStringOption(option => option.setName('name')
|
||||||
|
.setDescription('Name of the event you want to delete'))
|
||||||
|
.addIntegerOption(option => option.setName('id')
|
||||||
|
.setDescription('Id of the even you want to change')))
|
||||||
|
.addSubcommandGroup(subcommandGroup =>
|
||||||
|
subcommandGroup.setName('change')
|
||||||
|
.setDescription('Change the event entry')
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand.setName('date')
|
||||||
|
.setDescription('Change date of an event')
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('day')
|
||||||
|
.setDescription('New event day')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('month')
|
||||||
|
.setDescription('New event month')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option => option.setName('id')
|
||||||
|
.setDescription('Id of the even you want to change'))
|
||||||
|
.addStringOption(option => option.setName('name')
|
||||||
|
.setDescription('Name of the event you want to change')))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand.setName('name')
|
||||||
|
.setDescription('Change name of an event')
|
||||||
|
.addStringOption(option =>
|
||||||
|
option.setName('new-name')
|
||||||
|
.setDescription('New name of the event')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option => option.setName('id')
|
||||||
|
.setDescription('Id of the even you want to change'))
|
||||||
|
.addStringOption(option => option.setName('name')
|
||||||
|
.setDescription('Name of the event you want to change'))))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand.setName('list')
|
||||||
|
.setDescription('List all events')),
|
||||||
|
async execute(interaction) {
|
||||||
|
// make this help function you basically copy it evrytime (in birthday.js aswell)
|
||||||
|
const error = catchErrors(interaction.options);
|
||||||
|
if (error != null) {
|
||||||
|
await interaction.reply(error);
|
||||||
|
}
|
||||||
|
let subcommandGroup;
|
||||||
|
try {
|
||||||
|
subcommandGroup = interaction.options.getSubcommandGroup();
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
subcommandGroup = undefined;
|
||||||
|
}
|
||||||
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
const key = idOrName(interaction.options);
|
||||||
|
if (subcommandGroup == undefined) {
|
||||||
|
switch (subcommand) {
|
||||||
|
case 'list':
|
||||||
|
await interaction.reply({ embeds: [listEvents(interaction)] });
|
||||||
|
break;
|
||||||
|
case 'add':
|
||||||
|
await interaction.reply(addEvent(interaction));
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
await interaction.reply(deleteEvent(interaction, key));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (subcommand) {
|
||||||
|
case 'date':
|
||||||
|
await interaction.reply(changeEventDate(interaction, key));
|
||||||
|
break;
|
||||||
|
case 'name':
|
||||||
|
await interaction.reply(changeEventName(interaction, key));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO add event GLOBAL
|
||||||
|
// TODO add event local
|
||||||
|
// if the guild isnt there add it
|
||||||
|
|
||||||
|
|
||||||
|
function changeEventDate(interaction, key) {
|
||||||
|
if (key == null) {
|
||||||
|
return 'I need id or name of the event you want to edit';
|
||||||
|
}
|
||||||
|
const newDay = interaction.options.getInteger('day');
|
||||||
|
const newMonth = interaction.options.getInteger('month');
|
||||||
|
// TODO deduplicate
|
||||||
|
if (!isNaN(key)) {
|
||||||
|
const id = parseFloat(key);
|
||||||
|
if (id % 10 == 0) {
|
||||||
|
let globalEvents = eventsJSON.global;
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
const name = globalEvents[i].name;
|
||||||
|
if (globalEvents[i].id == id) {
|
||||||
|
const prevDay = globalEvents[i].day;
|
||||||
|
const prevMonth = globalEvents[i].month;
|
||||||
|
let fstPart = globalEvents.slice(0, i);
|
||||||
|
let sndPart = globalEvents.slice(i + 1);
|
||||||
|
globalEvents = fstPart.concat(sndPart);
|
||||||
|
|
||||||
|
for (let j = 0; j < globalEvents.length; j++) {
|
||||||
|
if ((newMonth == globalEvents[i].month && newDay >= globalEvents.day)
|
||||||
|
|| newMonth < globalEvents[i].month) {
|
||||||
|
fstPart = globalEvents.slice(0, j);
|
||||||
|
fstPart.push({ id: id, name: name, day: newDay, month: newMonth });
|
||||||
|
sndPart = globalEvents.slice(j + 1);
|
||||||
|
eventsJSON.global = fstPart.concat(sndPart);
|
||||||
|
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly changed global event ${name} date ` +
|
||||||
|
`from ${prevDay}. ${prevMonth}. ` +
|
||||||
|
`to ${newDay}. ${newMonth}.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globalEvents.push({ id: id, name: name, day: newDay, month: newMonth });
|
||||||
|
eventsJSON.global = globalEvents;
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly changed global event ${name} date ` +
|
||||||
|
`from ${prevDay}. ${prevMonth}. ` +
|
||||||
|
`to ${newDay}. ${newMonth}.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const guildEvents = eventsJSON[interaction.guild.id];
|
||||||
|
for (let i = 0; i < guildEvents.length; i++) {
|
||||||
|
const name = guildEvents[i].name;
|
||||||
|
if (guildEvents[i].id == id) {
|
||||||
|
const prevDay = guildEvents[i].day;
|
||||||
|
const prevMonth = guildEvents[i].month;
|
||||||
|
let fstPart = guildEvents.slice(0, i);
|
||||||
|
let sndPart = guildEvents.slice(i + 1);
|
||||||
|
for (let j = 0; j < guildEvents.length; j++) {
|
||||||
|
if ((newMonth == guildEvents[i].month &&
|
||||||
|
newDay >= guildEvents.day) ||
|
||||||
|
newMonth < guildEvents[i].month) {
|
||||||
|
fstPart = guildEvents.slice(0, j);
|
||||||
|
fstPart.push({ id: id, name: name, day: newDay, month: newMonth });
|
||||||
|
sndPart = guildEvents.slice(j + 1);
|
||||||
|
eventsJSON[interaction.guild.id] = fstPart.concat(sndPart);
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly changed guild event ${name} date ` +
|
||||||
|
`from ${prevDay}. ${prevMonth}. ` +
|
||||||
|
`to ${newDay}. ${newMonth}.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guildEvents.push({ id: id, name: name, day: newDay, month: newMonth });
|
||||||
|
eventsJSON.global = guildEvents;
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly changed guild event ${name} date ` +
|
||||||
|
`from ${prevDay}. ${prevMonth}. ` +
|
||||||
|
`to ${newDay}. ${newMonth}.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let globalEvents = eventsJSON.global;
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
const name = globalEvents[i].name;
|
||||||
|
const id = globalEvents[i].id;
|
||||||
|
if (globalEvents[i].name == name) {
|
||||||
|
const prevDay = globalEvents[i].day;
|
||||||
|
const prevMonth = globalEvents[i].month;
|
||||||
|
let fstPart = globalEvents.slice(0, i);
|
||||||
|
let sndPart = globalEvents.slice(i + 1);
|
||||||
|
globalEvents = fstPart.concat(sndPart);
|
||||||
|
|
||||||
|
for (let j = 0; j < globalEvents.length; j++) {
|
||||||
|
if ((newMonth == globalEvents[i].month && newDay >= globalEvents.day)
|
||||||
|
|| newMonth < globalEvents[i].month) {
|
||||||
|
fstPart = globalEvents.slice(0, j);
|
||||||
|
fstPart.push({ id: id, name: name, day: newDay, month: newMonth });
|
||||||
|
sndPart = globalEvents.slice(j);
|
||||||
|
eventsJSON.global = fstPart.concat(sndPart);
|
||||||
|
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly changed global event ${name}` +
|
||||||
|
` date from ${prevDay}. ${prevMonth}.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const guildEvents = eventsJSON[interaction.guild.id];
|
||||||
|
for (let i = 0; i < guildEvents.length; i++) {
|
||||||
|
const name = guildEvents[i].name;
|
||||||
|
const id = globalEvents[i].id;
|
||||||
|
if (guildEvents[i].name == name) {
|
||||||
|
const prevDay = guildEvents[i].day;
|
||||||
|
const prevMonth = guildEvents[i].month;
|
||||||
|
let fstPart = guildEvents.slice(0, i);
|
||||||
|
let sndPart = guildEvents.slice(i + 1);
|
||||||
|
for (let j = 0; j < guildEvents.length; j++) {
|
||||||
|
if ((newMonth == guildEvents[i].month &&
|
||||||
|
newDay >= guildEvents.day) ||
|
||||||
|
newMonth < guildEvents[i].month) {
|
||||||
|
fstPart = guildEvents.slice(0, j);
|
||||||
|
fstPart.push({ id: id, name: name, day: newDay, month: newMonth });
|
||||||
|
sndPart = guildEvents.slice(j);
|
||||||
|
eventsJSON.global = fstPart.concat(sndPart);
|
||||||
|
eventsJSON[interaction.guild.id] = fstPart.concat(sndPart);
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly changed guild event ${name} date` +
|
||||||
|
` from ${prevDay}. ${prevMonth}.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'There was an error (probably entered wrong id/name)';
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeEventName(interaction, key) {
|
||||||
|
if (key == null) {
|
||||||
|
return 'I need id or name of the event you want to edit';
|
||||||
|
}
|
||||||
|
// TODO deduplicate
|
||||||
|
if (!isNaN(key)) {
|
||||||
|
const id = parseFloat(key);
|
||||||
|
if (id % 10 == 0) {
|
||||||
|
const globalEvents = eventsJSON.global;
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
const name = globalEvents[i].name;
|
||||||
|
if (globalEvents[i].id == id) {
|
||||||
|
globalEvents[i].name = interaction.options.getString('name');
|
||||||
|
eventsJSON.global = globalEvents;
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return 'Successfuly changed name of global event' +
|
||||||
|
`${name} to ${interaction.options.getString('name')}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const guildEvents = eventsJSON[interaction.guild.id];
|
||||||
|
for (let i = 0; i < guildEvents.length; i++) {
|
||||||
|
const name = guildEvents[i].name;
|
||||||
|
if (guildEvents[i].id == id) {
|
||||||
|
guildEvents[i].name = interaction.options.getString('name');
|
||||||
|
eventsJSON[interaction.guild.id] = guildEvents;
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return 'Successfuly changed name of guild event' +
|
||||||
|
`${name} to ${interaction.options.getString('name')}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const globalEvents = eventsJSON.global;
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
const name = globalEvents[i].name;
|
||||||
|
if (name == key) {
|
||||||
|
globalEvents[i].name = interaction.options.getString('name');
|
||||||
|
eventsJSON.global = globalEvents;
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return 'Successfuly changed name of global event' +
|
||||||
|
`${name} to ${interaction.options.getString('name')}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const guildEvents = eventsJSON[interaction.guild.id];
|
||||||
|
for (let i = 0; i < guildEvents.length; i++) {
|
||||||
|
const name = guildEvents[i].name;
|
||||||
|
if (name == key) {
|
||||||
|
guildEvents[i].name = interaction.options.getString('name');
|
||||||
|
eventsJSON[interaction.guild.id] = guildEvents;
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return 'Successfuly changed name of guild event' +
|
||||||
|
`${name} to ${interaction.options.getString('name')}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'There was an error (probably entered wrong id/name)';
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteEvent(interaction, key) {
|
||||||
|
if (key == null) {
|
||||||
|
return 'I need id or name of the event you want to delete';
|
||||||
|
}
|
||||||
|
// TODO deduplicate
|
||||||
|
if (!isNaN(key)) {
|
||||||
|
const id = parseFloat(key);
|
||||||
|
if (id % 10 == 0) {
|
||||||
|
const globalEvents = eventsJSON.global;
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
const name = globalEvents[i].name;
|
||||||
|
if (globalEvents[i].id == id) {
|
||||||
|
const fstPart = globalEvents.slice(0, i);
|
||||||
|
const sndPart = globalEvents.slice(i + 1);
|
||||||
|
eventsJSON.global = fstPart.concat(sndPart);
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly deleted global event ${name} from database`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const guildEvents = eventsJSON[interaction.guild.id];
|
||||||
|
for (let i = 0; i < guildEvents.length; i++) {
|
||||||
|
const name = guildEvents[i].name;
|
||||||
|
if (guildEvents[i].id == id) {
|
||||||
|
const fstPart = guildEvents.slice(0, i);
|
||||||
|
const sndPart = guildEvents.slice(i + 1);
|
||||||
|
eventsJSON[interaction.guild.id] = fstPart.concat(sndPart);
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly deleted guild event ${name} from database`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const guildEvents = eventsJSON[interaction.guild.id];
|
||||||
|
for (let i = 0; i < guildEvents.length; i++) {
|
||||||
|
const name = guildEvents[i].name;
|
||||||
|
if (name == key) {
|
||||||
|
const fstPart = guildEvents.slice(0, i);
|
||||||
|
const sndPart = guildEvents.slice(i + 1);
|
||||||
|
eventsJSON[interaction.guild.id] = fstPart.concat(sndPart);
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly deleted guild event ${name} from database`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const globalEvents = eventsJSON.global;
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
const name = globalEvents[i].name;
|
||||||
|
if (name == key) {
|
||||||
|
const fstPart = globalEvents.slice(0, i);
|
||||||
|
const sndPart = globalEvents.slice(i + 1);
|
||||||
|
eventsJSON.global = fstPart.concat(sndPart);
|
||||||
|
const error = writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
return `Successfuly deleted global event ${name} from database`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'There was an error (probably entered wrong id/name)';
|
||||||
|
}
|
||||||
|
|
||||||
|
function addEvent(interaction) {
|
||||||
|
const name = interaction.options.getString('name');
|
||||||
|
const day = interaction.options.getInteger('day');
|
||||||
|
const month = interaction.options.getInteger('month');
|
||||||
|
|
||||||
|
let isGlobal;
|
||||||
|
try {
|
||||||
|
isGlobal = interaction.options.getBoolean('global');
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
isGlobal = false;
|
||||||
|
}
|
||||||
|
// TODO if duplicate send if they want to add it anyway and 2 buttons yes/no
|
||||||
|
|
||||||
|
const ms = new Date().getMilliseconds();
|
||||||
|
let id = (100000 * day) + (100 * (ms % 1000)) + (month * 10);
|
||||||
|
|
||||||
|
if (isGlobal) {
|
||||||
|
const globalEvents = eventsJSON.global;
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
// TODO make this help function you basically copy it evrytime (in birthday.js aswell)
|
||||||
|
if ((globalEvents[i].month == month && globalEvents[i].day >= day) || globalEvents[i].month > month) {
|
||||||
|
const fstPart = globalEvents.slice(0, i);
|
||||||
|
const sndPart = globalEvents.slice(i);
|
||||||
|
fstPart.push({ id: id, name: name, day: day, month: month });
|
||||||
|
eventsJSON.global = fstPart.concat(sndPart);
|
||||||
|
const error = help.writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating event list';
|
||||||
|
}
|
||||||
|
return `Successfuly added global event ${name} to event list`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globalEvents.push({ id: id, name: name, day: day, month: month });
|
||||||
|
eventsJSON.global = globalEvents;
|
||||||
|
const error = help.writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating event list';
|
||||||
|
}
|
||||||
|
return `Successfuly added guild event ${name} to event list`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const guildEvents = eventsJSON[interaction.guild.id];
|
||||||
|
id++;
|
||||||
|
if (guildEvents == undefined) {
|
||||||
|
eventsJSON[interaction.guild.id] = [{ id: id, name: name, day: day, month: month }];
|
||||||
|
const error = help.writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating event list';
|
||||||
|
}
|
||||||
|
return `Successfuly added guild event ${name} to event list`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (let i = 0; i < guildEvents.length; i++) {
|
||||||
|
if ((guildEvents[i].month == month && guildEvents[i].day >= day) || guildEvents[i].month > month) {
|
||||||
|
const fstPart = guildEvents.slice(0, i);
|
||||||
|
const sndPart = guildEvents.slice(i);
|
||||||
|
fstPart.push({ id: id, name: name, day: day, month: month });
|
||||||
|
eventsJSON[interaction.guild.id] = fstPart.concat(sndPart);
|
||||||
|
const error = help.writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating event list';
|
||||||
|
}
|
||||||
|
return `Successfuly added guild event ${name} to event list`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guildEvents.push({ id: id, name: name, day: day, month: month });
|
||||||
|
eventsJSON[interaction.guild.id] = guildEvents;
|
||||||
|
const error = help.writeToFile(eventsJSON, PATH);
|
||||||
|
if (error != null) {
|
||||||
|
return 'There was an error while updating event list';
|
||||||
|
}
|
||||||
|
return `Successfuly added guild event ${name} to event list`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function listEvents(interaction) {
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.setColor(help.randomColor())
|
||||||
|
.setTitle('Literally nothing here');
|
||||||
|
|
||||||
|
let eventIds = [];
|
||||||
|
let eventNames = [];
|
||||||
|
let eventDates = [];
|
||||||
|
const globalEvents = eventsJSON.global;
|
||||||
|
// TODO deduplicate
|
||||||
|
if (globalEvents != undefined && globalEvents.length > 0) {
|
||||||
|
embed.addField('Global events:', '\u200b')
|
||||||
|
.setTitle('');
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
eventIds.push(globalEvents[i].id);
|
||||||
|
eventNames.push(globalEvents[i].name);
|
||||||
|
eventDates.push(`${globalEvents[i].day}. ${globalEvents[i].month}.`);
|
||||||
|
}
|
||||||
|
embed.addField('Id: ', eventIds.join('\n'), true);
|
||||||
|
embed.addField('Name: ', eventNames.join('\n'), true);
|
||||||
|
embed.addField('Date: ', eventDates.join('\n'), true);
|
||||||
|
embed.addField('\u200b', '\u200b');
|
||||||
|
}
|
||||||
|
|
||||||
|
const guildEvents = eventsJSON[interaction.guild.id];
|
||||||
|
if (guildEvents != undefined && guildEvents.length > 0) {
|
||||||
|
eventIds = [];
|
||||||
|
eventNames = [];
|
||||||
|
eventDates = [];
|
||||||
|
embed.addField('Guild events:', '\u200b')
|
||||||
|
.setTitle('');
|
||||||
|
for (let i = 0; i < guildEvents.length; i++) {
|
||||||
|
eventIds.push(guildEvents[i].id);
|
||||||
|
eventNames.push(guildEvents[i].name);
|
||||||
|
eventDates.push(`${guildEvents[i].day}. ${guildEvents[i].month}.`);
|
||||||
|
}
|
||||||
|
embed.addField('Id: ', eventIds.join('\n'), true);
|
||||||
|
embed.addField('Name: ', eventNames.join('\n'), true);
|
||||||
|
embed.addField('Date: ', eventDates.join('\n'), true);
|
||||||
|
}
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
|
||||||
|
function idOrName(options) {
|
||||||
|
let id;
|
||||||
|
try {
|
||||||
|
id = options.getInteger('id');
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
id = undefined;
|
||||||
|
}
|
||||||
|
if (id == undefined) {
|
||||||
|
let name;
|
||||||
|
try {
|
||||||
|
name = options.getString('name');
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
name = undefined;
|
||||||
|
}
|
||||||
|
if (name == undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function catchErrors(options) {
|
||||||
|
const month = options.getInteger('month');
|
||||||
|
const day = options.getInteger('day');
|
||||||
|
if (month == null || day == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (month > 12 || month < 1) {
|
||||||
|
return 'Bruh, "month" kinda poopy';
|
||||||
|
}
|
||||||
|
if (day > checkMonth(month) || day < 1) {
|
||||||
|
return 'Bruh, "day" kinda poopy';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkMonth(month) {
|
||||||
|
switch (month) {
|
||||||
|
case 1:
|
||||||
|
return 31;
|
||||||
|
case 2:
|
||||||
|
return 29;
|
||||||
|
case 3:
|
||||||
|
return 31;
|
||||||
|
case 4:
|
||||||
|
return 30;
|
||||||
|
case 5:
|
||||||
|
return 31;
|
||||||
|
case 6:
|
||||||
|
return 30;
|
||||||
|
case 7:
|
||||||
|
return 31;
|
||||||
|
case 8:
|
||||||
|
return 31;
|
||||||
|
case 9:
|
||||||
|
return 30;
|
||||||
|
case 10:
|
||||||
|
return 31;
|
||||||
|
case 11:
|
||||||
|
return 30;
|
||||||
|
case 12:
|
||||||
|
return 31;
|
||||||
|
}
|
||||||
|
}
|
45
commands/gif.js
Normal file
45
commands/gif.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||||
|
const help = require('../helpFunctions.js');
|
||||||
|
const gifAmount = 50;
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('gif')
|
||||||
|
.setDescription('Sends gif')
|
||||||
|
.addStringOption(option =>
|
||||||
|
option.setName('what')
|
||||||
|
.setDescription('What should I search for? (If this is empty I will give you something random!)'))
|
||||||
|
.addBooleanOption(option => option.setName('r-rated').setDescription('Should the gif be R-rated')),
|
||||||
|
async execute(interaction) {
|
||||||
|
const embed = await getGifEmbed(interaction.options);
|
||||||
|
await interaction.reply({ embeds: [embed] });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async function getGifEmbed(options) {
|
||||||
|
let rating = 'low';
|
||||||
|
try {
|
||||||
|
if (options.getBoolean('r-rated')) {
|
||||||
|
rating = 'off';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
rating = 'low';
|
||||||
|
}
|
||||||
|
|
||||||
|
let search;
|
||||||
|
try {
|
||||||
|
search = options.getString('what').trim();
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
const gifs = `https://g.tenor.com/v1/random?key=${process.env.TENOR}&limit=${gifAmount}&contentfilter=${rating}`;
|
||||||
|
return help.getGif(gifs, gifAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchSplits = search.split(/[ ]+/);
|
||||||
|
const searchKey = searchSplits.join('-');
|
||||||
|
|
||||||
|
const gifs = `https://g.tenor.com/v1/search?q=${searchKey}&key=${process.env.TENOR}&limit=${gifAmount}&contentfilter=${rating}`;
|
||||||
|
return help.getGif(gifs, gifAmount);
|
||||||
|
}
|
32
commands/headpat.js
Normal file
32
commands/headpat.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||||
|
const help = require('../helpFunctions.js');
|
||||||
|
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('headpat')
|
||||||
|
.setDescription('Headpat someone!')
|
||||||
|
.addMentionableOption(options =>
|
||||||
|
options.setName('who')
|
||||||
|
.setDescription('Is for me? c:')),
|
||||||
|
async execute(interaction) {
|
||||||
|
const resultTuple = await headpat(interaction);
|
||||||
|
const embed = resultTuple[1];
|
||||||
|
if (resultTuple[0] == null) {
|
||||||
|
interaction.reply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const msgContent = resultTuple[0];
|
||||||
|
interaction.reply({ content: msgContent, embeds: [embed] });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async function headpat(interaction) {
|
||||||
|
const searchKey = 'headpat-anime';
|
||||||
|
const gifAmount = 16;
|
||||||
|
const gifs = `https://g.tenor.com/v1/search?q=${searchKey}&key=${process.env.TENOR}&limit=${gifAmount}`;
|
||||||
|
|
||||||
|
return help.getGifWithMessage(interaction, gifs, gifAmount);
|
||||||
|
}
|
15
commands/helpWIP.js
Normal file
15
commands/helpWIP.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||||
|
const { MessageEmbed } = require('discord.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('help')
|
||||||
|
.setDescription('sheeeee')
|
||||||
|
.addMentionableOption(option => option.setName('aaaa').setDescription('aaaaaaa')),
|
||||||
|
// .addBooleanOption(option => option.setName('naco').setDescription('Select a boolean')),
|
||||||
|
async execute(interaction) {
|
||||||
|
const embed = new MessageEmbed()
|
||||||
|
.addField('Battle', 'Field');
|
||||||
|
interaction.reply({ embeds: [embed] });
|
||||||
|
},
|
||||||
|
};
|
32
commands/hug.js
Normal file
32
commands/hug.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||||
|
const help = require('../helpFunctions.js');
|
||||||
|
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('hug')
|
||||||
|
.setDescription('Hug all your friends!')
|
||||||
|
.addMentionableOption(options =>
|
||||||
|
options.setName('who')
|
||||||
|
.setDescription('It\'s not me.. is it? :c')),
|
||||||
|
async execute(interaction) {
|
||||||
|
const resultTuple = await hug(interaction);
|
||||||
|
const embed = resultTuple[1];
|
||||||
|
if (resultTuple[0] == null) {
|
||||||
|
interaction.reply({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const msgContent = resultTuple[0];
|
||||||
|
interaction.reply({ content: msgContent, embeds: [embed] });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async function hug(interaction) {
|
||||||
|
const searchKey = 'hug-anime';
|
||||||
|
const gifAmount = 16;
|
||||||
|
const gifs = `https://g.tenor.com/v1/search?q=${searchKey}&key=${process.env.TENOR}&limit=${gifAmount}`;
|
||||||
|
|
||||||
|
return help.getGifWithMessage(interaction, gifs, gifAmount);
|
||||||
|
}
|
21
commands/say.js
Normal file
21
commands/say.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
const { SlashCommandBuilder } = require('@discordjs/builders');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('say')
|
||||||
|
.setDescription('Make me say something!')
|
||||||
|
.addStringOption(options =>
|
||||||
|
options.setName('what')
|
||||||
|
.setDescription('What will you make me say this time? 🙃')
|
||||||
|
.setRequired(true)),
|
||||||
|
async execute(interaction) {
|
||||||
|
await say(interaction);
|
||||||
|
await interaction.reply({ content: 'Said and done', ephemeral: true });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function say(interaction) {
|
||||||
|
const message = interaction.options.getString('what');
|
||||||
|
message.trim();
|
||||||
|
interaction.channel.send(message);
|
||||||
|
}
|
26
database/birthdays.json
Normal file
26
database/birthdays.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "431899299434070026",
|
||||||
|
"day": 1,
|
||||||
|
"month": 2,
|
||||||
|
"nickname": "Ľaco"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "552222387458801676",
|
||||||
|
"day": 3,
|
||||||
|
"month": 3,
|
||||||
|
"nickname": "aaaaaaaaa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "368089707965448193",
|
||||||
|
"day": 7,
|
||||||
|
"month": 4,
|
||||||
|
"nickname": "Peťko"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "246311280506437643",
|
||||||
|
"day": 14,
|
||||||
|
"month": 7,
|
||||||
|
"nickname": "Martin"
|
||||||
|
}
|
||||||
|
]
|
18
database/events.json
Normal file
18
database/events.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"global": [
|
||||||
|
{
|
||||||
|
"id": 1431220,
|
||||||
|
"name": "Valentine's Day",
|
||||||
|
"day": 14,
|
||||||
|
"month": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"770748282191740940": [
|
||||||
|
{
|
||||||
|
"id": 1480921,
|
||||||
|
"name": "Valentine's Day",
|
||||||
|
"day": 14,
|
||||||
|
"month": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
14
database/test.json
Normal file
14
database/test.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"id": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 15
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nelist": {
|
||||||
|
"name": "Devucha",
|
||||||
|
"id": "s kare"
|
||||||
|
}
|
||||||
|
}
|
19
deploy-commands.js
Normal file
19
deploy-commands.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const { REST } = require('@discordjs/rest');
|
||||||
|
const { Routes } = require('discord-api-types/v9');
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
const commands = [];
|
||||||
|
const commandFiles = fs.readdirSync('./commands')
|
||||||
|
.filter(file => !file.includes('WIP'));
|
||||||
|
|
||||||
|
for (const file of commandFiles) {
|
||||||
|
const command = require(`./commands/${file}`);
|
||||||
|
commands.push(command.data.toJSON());
|
||||||
|
}
|
||||||
|
|
||||||
|
const rest = new REST({ version: '9' }).setToken(process.env.MOOTOKEN);
|
||||||
|
|
||||||
|
rest.put(Routes.applicationCommands(process.env.mooverId), { body: commands })
|
||||||
|
.then(() => console.log('Successfully registered application commands.'))
|
||||||
|
.catch(console.error);
|
72
helpFunctions.js
Normal file
72
helpFunctions.js
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
const axios = require('axios').default;
|
||||||
|
const Discord = require('discord.js');
|
||||||
|
const fs = require('fs');
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
randomColor: randomColor,
|
||||||
|
RNG: RNG,
|
||||||
|
getGifs: getGifs,
|
||||||
|
getGifEmbed: getGifEmbed,
|
||||||
|
getGifWithMessage: getGifWithMessage,
|
||||||
|
returnPromiseString: returnPromiseString,
|
||||||
|
writeToFile: writeToFile,
|
||||||
|
};
|
||||||
|
|
||||||
|
function randomColor() {
|
||||||
|
let color = '#';
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
const random = Math.random();
|
||||||
|
const bit = (random * 16) | 0;
|
||||||
|
color += (bit).toString(16);
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
function RNG(max) {
|
||||||
|
return Math.floor(Math.random() * max);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getGifs(gifs) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
resolve(axios.get(gifs));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getGifEmbed(gifQuery, gifAmount) {
|
||||||
|
const response = await getGifs(gifQuery);
|
||||||
|
const gif = response.data.results[RNG(gifAmount)].media[0].gif.url;
|
||||||
|
const gifEmbed = new Discord.MessageEmbed()
|
||||||
|
.setImage(gif)
|
||||||
|
.setColor(randomColor());
|
||||||
|
|
||||||
|
return gifEmbed;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getGifWithMessage(interaction, gifQuery, gifAmount) {
|
||||||
|
const gifEmbed = getGifEmbed(gifQuery, gifAmount);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return (interaction.user.username + ' headpats ' + interaction.options.getMentionable('who'), gifEmbed);
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return (null, gifEmbed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function returnPromiseString(guildMembers) {
|
||||||
|
return new Promise(() => {
|
||||||
|
guildMembers.fetch();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeToFile(content, path) {
|
||||||
|
const jsonString = JSON.stringify(content, null, 4);
|
||||||
|
let error = null;
|
||||||
|
fs.writeFile(path, jsonString, 'utf8', (err) => {
|
||||||
|
if (err) {
|
||||||
|
error = 'There was an error while updating the birthday list';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return error;
|
||||||
|
}
|
351
main.js
351
main.js
|
@ -1,47 +1,88 @@
|
||||||
const { Client, Intents, MessageAttachment, MessageEmbed } = require('discord.js');
|
|
||||||
const client = new Client({ intents: [
|
|
||||||
Intents.FLAGS.GUILDS,
|
|
||||||
Intents.FLAGS.GUILD_MESSAGES,
|
|
||||||
Intents.FLAGS.GUILD_MESSAGE_REACTIONS
|
|
||||||
] });
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
List of intents
|
List of intents
|
||||||
https://discord.com/developers/docs/topics/gateway#privileged-intents
|
https://discord.com/developers/docs/topics/gateway#privileged-intents
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require("dotenv").config()
|
const Discord = require('discord.js');
|
||||||
|
const {
|
||||||
var hugGifs =
|
Client,
|
||||||
["https://c.tenor.com/9e1aE_xBLCsAAAAC/anime-hug.gif",
|
Collection,
|
||||||
"https://c.tenor.com/Ct4bdr2ZGeAAAAAC/teria-wang-kishuku-gakkou-no-juliet.gif",
|
Intents,
|
||||||
"https://c.tenor.com/ztEJgrjFe54AAAAd/hug-anime.gif",
|
MessageAttachment,
|
||||||
"https://c.tenor.com/UhcyGsGpLNIAAAAd/hug-anime.gif",
|
} = require('discord.js');
|
||||||
"https://c.tenor.com/fLxZt7jo1YEAAAAd/loli-dragon.gif",
|
const client = new Client({
|
||||||
"https://c.tenor.com/qF7mO4nnL0sAAAAd/abra%C3%A7o-hug.gif"]
|
intents: [
|
||||||
|
Intents.FLAGS.GUILDS,
|
||||||
client.once('ready', () => {
|
Intents.FLAGS.GUILD_MESSAGES,
|
||||||
console.log('Running');
|
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
|
||||||
|
Intents.FLAGS.GUILD_MEMBERS,
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("messageCreate", gotMessage);
|
const fs = require('fs');
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
function gotMessage(message){
|
client.commands = new Collection();
|
||||||
|
const commandFiles = fs.readdirSync('./commands')
|
||||||
|
.filter(file => !file.includes('WIP'));
|
||||||
|
|
||||||
if(message.content.includes('https://media.discordapp.net') &&
|
for (const file of commandFiles) {
|
||||||
|
const command = require(`./commands/${file}`);
|
||||||
|
// Set a new item in the Collection
|
||||||
|
// With the key as the command name and the value as the exported module
|
||||||
|
client.commands.set(command.data.name, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
const help = require('./helpFunctions.js');
|
||||||
|
|
||||||
|
client.once('ready', () => {
|
||||||
|
if (client.user.username != 'MOOver Debug') {
|
||||||
|
client.channels.cache.get('780439236867653635').send('Just turned on!');
|
||||||
|
}
|
||||||
|
console.log('Running!');
|
||||||
|
refreshPings();
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on('messageCreate', gotMessage);
|
||||||
|
|
||||||
|
client.on('interactionCreate', async interaction => {
|
||||||
|
if (!interaction.isCommand()) return;
|
||||||
|
|
||||||
|
const command = client.commands.get(interaction.commandName);
|
||||||
|
|
||||||
|
if (!command) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await command.execute(interaction);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
await interaction.reply({
|
||||||
|
content: 'There was an error while executing this command!',
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function gotMessage(message) {
|
||||||
|
if (message.content.includes('https://media.discordapp.net') &&
|
||||||
(message.content.includes('webm') ||
|
(message.content.includes('webm') ||
|
||||||
message.content.includes('mov') ||
|
message.content.includes('mov') ||
|
||||||
message.content.includes('mp4'))) {
|
message.content.includes('mp4'))) {
|
||||||
console.log("aaa")
|
|
||||||
const linkArr = message.content.split('https://media.discordapp.net');
|
const linkArr = message.content.split('https://media.discordapp.net');
|
||||||
message.channel.send('https://cdn.discordapp.com' + linkArr[1])
|
message.channel.send('https://cdn.discordapp.com' + linkArr[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const msg = message.content.toLowerCase()
|
const chance = help.RNG(3000);
|
||||||
|
if (chance == 1337) {
|
||||||
|
whoAsked(message);
|
||||||
|
}
|
||||||
|
|
||||||
const content = message.content.trim()
|
const msg = message.content.toLowerCase();
|
||||||
|
|
||||||
let msgContentSplit = content.split(/[ ]+/);
|
const content = message.content.trim();
|
||||||
|
|
||||||
|
const msgContentSplit = content.split(/[ ]+/);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reference can't be null => must be a reply to message
|
* reference can't be null => must be a reply to message
|
||||||
|
@ -49,172 +90,164 @@ function gotMessage(message){
|
||||||
* that argument mentions channel
|
* that argument mentions channel
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(message.reference != null && msgContentSplit.length == 1
|
if (message.reference != null && msgContentSplit.length == 1 &&
|
||||||
&& message.mentions.channels.first() != undefined){
|
message.mentions.channels.first() != undefined) {
|
||||||
move(message, msgContentSplit[0])
|
move(message, msgContentSplit[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isBot = message.author.bot
|
const isBot = message.author.bot;
|
||||||
|
|
||||||
if (!isBot){
|
if (!isBot) {
|
||||||
if (msg.includes("henlo")) {
|
if (msg.includes('henlo')) {
|
||||||
henlo(message);
|
henlo(message);
|
||||||
}
|
}
|
||||||
else if (msg.includes("how ye")) {
|
else if (msg.includes('how ye')) {
|
||||||
mood(message)
|
mood(message);
|
||||||
}
|
}
|
||||||
else if (msg.includes("tylko jedno")) {
|
else if (msg.includes('tylko jedno')) {
|
||||||
message.channel.send("Koksu pięć gram odlecieć sam");
|
message.channel.send('Koksu pięć gram odlecieć sam');
|
||||||
}
|
|
||||||
if (msgContentSplit[0] == "hug") {
|
|
||||||
hug(message)
|
|
||||||
}
|
|
||||||
else if (msgContentSplit[0] == "!say") {
|
|
||||||
say(message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Responses
|
// Responses
|
||||||
function henlo(message){
|
function henlo(message) {
|
||||||
var emojis = ["🥰", "🐄", "🐮", "❤️", "👋", "🤠", "😊"];
|
const emojis = ['🥰', '🐄', '🐮', '❤️', '👋', '🤠', '😊'];
|
||||||
let randomNum = RNG(emojis.length);
|
const randomNum = help.RNG(emojis.length);
|
||||||
message.reply("Henlooo " + message.author.username + " " + emojis[randomNum]);
|
message.reply('Henlooo ' + message.author.username + ' ' + emojis[randomNum]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hug(message){
|
function mood(message) {
|
||||||
var mentionedUsers = message.mentions.users.values()
|
const responses = ['Not bad, how yee?', 'MOOdy', 'A bit sad 😢', 'Good, how yee?', 'I\'m fine, how yee?'];
|
||||||
var mentionedUsersSize = message.mentions.users.size
|
const randomNum = help.RNG(responses.length);
|
||||||
var mentionedRoles = message.mentions.roles.values()
|
|
||||||
var mentionedRolesSize = message.mentions.roles.size
|
|
||||||
|
|
||||||
var msg = message.content.toLowerCase()
|
|
||||||
|
|
||||||
let randomNum = RNG(hugGifs.length)
|
|
||||||
let title = message.author.username + " hugs"
|
|
||||||
let embed;
|
|
||||||
if (mentionedUsersSize > 0 || mentionedRolesSize > 0){
|
|
||||||
let allMentions = ""
|
|
||||||
for (let i = 0; i < mentionedUsersSize; i++) {
|
|
||||||
let user = mentionedUsers.next()
|
|
||||||
allMentions = allMentions + ", <@" + user.value.id + ">"
|
|
||||||
}
|
|
||||||
for (let i = 0; i < mentionedRolesSize; i++) {
|
|
||||||
let role = mentionedRoles.next()
|
|
||||||
allMentions = allMentions + ", <@&" + role.value.id + ">"
|
|
||||||
}
|
|
||||||
allMentions = allMentions.slice(2)
|
|
||||||
embed = createEmbed(title, hugGifs[randomNum], allMentions)
|
|
||||||
}
|
|
||||||
else if (msg.includes("@here") || msg.includes("all")){
|
|
||||||
embed = createEmbed(title, hugGifs[randomNum], "@here")
|
|
||||||
}
|
|
||||||
else if (msg.includes("@everyone")){
|
|
||||||
embed = createEmbed(title, hugGifs[randomNum], "@everyone")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
embed = new MessageEmbed().setImage(hugGifs[randomNum]).setColor(randomColor())
|
|
||||||
}
|
|
||||||
message.channel.send({embeds: [embed]})
|
|
||||||
}
|
|
||||||
|
|
||||||
function mood(message){
|
|
||||||
var responses = ["Not bad, how yee?", "MOOdy", "A bit sad 😢", "Good, how yee?", "I'm fine, how yee?"];
|
|
||||||
let randomNum = RNG(responses.length);
|
|
||||||
message.reply(responses[randomNum]);
|
message.reply(responses[randomNum]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function move(message, channelId){
|
function move(message, channelId) {
|
||||||
message.react('🐮')
|
message.react('🐮');
|
||||||
|
|
||||||
const replyChannel = message.channel;
|
const replyChannel = message.channel;
|
||||||
|
|
||||||
// const replyChannelId = message.reference.channelId;
|
|
||||||
// const replyChannel = client.channels.cache.get(replyChannelId);
|
|
||||||
|
|
||||||
const msgToMooveId = message.reference.messageId;
|
const msgToMooveId = message.reference.messageId;
|
||||||
|
|
||||||
const mentionedChannelId = channelId.substring(2, channelId.length - 1)
|
const mentionedChannelId = channelId.substring(2, channelId.length - 1);
|
||||||
|
|
||||||
|
|
||||||
// create embed
|
|
||||||
// add field for every attachment
|
|
||||||
// keď je tam emebed tak možnosť cez emotes či vymazať original post alebo nie
|
|
||||||
replyChannel.messages.fetch(msgToMooveId).then(msg => {
|
replyChannel.messages.fetch(msgToMooveId).then(msg => {
|
||||||
|
if (msg.attachments.size > 0) {
|
||||||
|
const newMsgAttachments = [];
|
||||||
|
const allAttachments = msg.attachments.values();
|
||||||
|
|
||||||
|
for (let i = 0; i < msg.attachments.size; i++) {
|
||||||
if (msg.attachments.size > 0){
|
const currAttachment = allAttachments.next().value;
|
||||||
// var exampleEmbed = new MessageEmbed()
|
newMsgAttachments.push(new MessageAttachment(currAttachment.url));
|
||||||
// .setTitle('Some title')
|
|
||||||
// .setImage(allAttachments.next().value)
|
|
||||||
// .addField('Inline field title', 'Some value here', true);
|
|
||||||
// .addField("Original message: ", message.content)
|
|
||||||
let newMsgAttachments = []
|
|
||||||
let allAttachments = msg.attachments.values()
|
|
||||||
|
|
||||||
for (let i = 0; i < msg.attachments.size; i++){
|
|
||||||
let currAttachment = allAttachments.next().value
|
|
||||||
newMsgAttachments.push(new MessageAttachment(currAttachment.url))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
client.channels.cache.get(mentionedChannelId).send({files: newMsgAttachments}).then(msgToEdit => {
|
client.channels.cache.get(mentionedChannelId).send({ content: `Sent by ${msg.author}\nmooved ${message.author}`, files: newMsgAttachments });
|
||||||
msgToEdit.edit(`Sent by ${msg.author}\nmooved ${message.author}\n`)
|
}
|
||||||
})
|
if (msg.embeds.length > 0) {
|
||||||
setTimeout(() => msg.delete(), 3000);
|
client.channels.cache.get(mentionedChannelId)
|
||||||
|
.send({ content: `Sent by ${msg.author}\nmooved ${message.author}`, embeds: msg.embeds });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (msg.embeds.length > 0){
|
const embed = new Discord.MessageEmbed()
|
||||||
message.channel.send("Can't really moove embeds yet, sowwy :c")
|
.setColor(help.randomColor())
|
||||||
}
|
.addField('MOO', `Sent by ${msg.author}\nmooved ${message.author}`)
|
||||||
else {
|
.addField('Message:', msg.content);
|
||||||
const embed = new MessageEmbed()
|
client.channels.cache.get(mentionedChannelId).send({
|
||||||
.setColor(randomColor())
|
embeds: [embed],
|
||||||
.addField("MOO", `Sent by ${msg.author}\nmooved ${message.author}`)
|
});
|
||||||
.addField("Message:", msg.content)
|
|
||||||
client.channels.cache.get(mentionedChannelId).send({embeds: [embed]})
|
|
||||||
setTimeout(() => msg.delete(), 3000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
setTimeout(() => msg.delete(), 3000);
|
||||||
});
|
});
|
||||||
setTimeout(() => message.delete(), 3000);
|
setTimeout(() => message.delete(), 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function say(message){
|
async function whoAsked(message) {
|
||||||
const tmp = message.content.split("!say ");
|
const searchKey = 'who-asked';
|
||||||
const msgContent = tmp[1];
|
const gifAmount = 20;
|
||||||
const msgChannel = message.channel;
|
const gifs = `https://g.tenor.com/v1/search?q=${searchKey}&key=${process.env.TENOR}&limit=${gifAmount}`;
|
||||||
message.delete()
|
|
||||||
if (msgContent != undefined && msgContent != ""){
|
message.reply({ embeds: [help.getGifEmbed(gifs, gifAmount)] });
|
||||||
msgChannel.send(msgContent);
|
}
|
||||||
|
|
||||||
|
async function pingEvent() {
|
||||||
|
const currentDay = new Date().getDate();
|
||||||
|
const currentMonth = new Date().getMonth();
|
||||||
|
|
||||||
|
const guildIds = [];
|
||||||
|
const sysChannelIds = [];
|
||||||
|
client.guilds.cache.forEach(element => {
|
||||||
|
sysChannelIds.push(element.channels.guild.systemChannelId);
|
||||||
|
guildIds.push(element.id);
|
||||||
|
});
|
||||||
|
// TODO deduplicate
|
||||||
|
const birthdays = require('./database/birthdays.json');
|
||||||
|
const todayBirthdays = [];
|
||||||
|
for (let i = 0; i < birthdays.length; i++) {
|
||||||
|
if (birthdays[i].day == currentDay && birthdays[i].month == currentMonth) {
|
||||||
|
todayBirthdays.push((birthdays[i].id, birthdays[i].nickname));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (todayBirthdays != []) {
|
||||||
|
for (let i = 0; i < guildIds.length; i++) {
|
||||||
|
const guildId = guildIds[i];
|
||||||
|
const sysChannelId = sysChannelIds[i];
|
||||||
|
const guild = client.guilds.cache.find((g) => g.id == guildId);
|
||||||
|
for (let j = 0; j < todayBirthdays.length; j++) {
|
||||||
|
const userId = todayBirthdays[i][0];
|
||||||
|
if ((await guild.members.fetch()).find(user => user.id == userId) != undefined) {
|
||||||
|
client.channels.cache.get(sysChannelId).send(`Happy birthday <@${userId}>!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventsJSON = require('./database/events.json');
|
||||||
|
const globalEvents = eventsJSON.global;
|
||||||
|
const todayGlobalEvents = [];
|
||||||
|
for (let i = 0; i < globalEvents.length; i++) {
|
||||||
|
if (globalEvents[i].day == currentDay && globalEvents[i].month == currentMonth) {
|
||||||
|
todayGlobalEvents.push((globalEvents[i].id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < guildIds.length; i++) {
|
||||||
|
const guildId = guildIds[i];
|
||||||
|
const guildEvents = eventsJSON[guild];
|
||||||
|
const sysChannelId = sysChannelIds[i];
|
||||||
|
const guild = client.guilds.cache.find((g) => g.id == guildId);
|
||||||
|
if (todayGlobalEvents != []) {
|
||||||
|
for (let j = 0; j < todayGlobalEvents.length; j++) {
|
||||||
|
let specialMessage;
|
||||||
|
if (todayGlobalEvents[i].name == 'Valentine\'s Day') {
|
||||||
|
specialMessage = '\n Don\'t forget I love you all with all my hart 🥺';
|
||||||
|
}
|
||||||
|
client.channels.cache.get(sysChannelId)
|
||||||
|
.send(`It's ${todayGlobalEvents} today!` + specialMessage);
|
||||||
|
}
|
||||||
|
for (let j = 0; j < guildEvents.length; j++) {
|
||||||
|
if (guildEvents[i].day == currentDay && guildEvents[i].month == currentMonth) {
|
||||||
|
client.channels.cache.get(sysChannelId)
|
||||||
|
.send(`It's ${todayGlobalEvents} today!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEmbed(title, img, desc){
|
async function eventsCountdown() {
|
||||||
let embed = new MessageEmbed()
|
const hour = new Date().getHours;
|
||||||
.setTitle(title)
|
if (hour < 15) {
|
||||||
.setImage(img)
|
await setTimeout(pingEvent, (15 * 60 * 60 * 100) - (hour * 60 * 60 * 100));
|
||||||
.setDescription(desc)
|
}
|
||||||
.setColor(randomColor())
|
|
||||||
return embed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function randomColor() {
|
async function refreshPings() {
|
||||||
let color = '#';
|
// eslint-disable-next-line no-constant-condition
|
||||||
for (let i = 0; i < 6; i++){
|
while (true) {
|
||||||
const random = Math.random();
|
await setTimeout(eventsCountdown, 12 * 60 * 60 * 100);
|
||||||
const bit = (random * 16) | 0;
|
}
|
||||||
color += (bit).toString(16);
|
|
||||||
};
|
|
||||||
return color;
|
|
||||||
};
|
|
||||||
|
|
||||||
function RNG(max){
|
|
||||||
return Math.floor(Math.random() * max)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// narodeniny?
|
client.login(process.env.TOKEN);
|
||||||
// vianoce, novy rok a tak
|
|
||||||
// hug cez tenor
|
|
||||||
// headpat cez tenor
|
|
||||||
// .gif
|
|
||||||
client.login(process.env.TOKEN)
|
|
1
node_modules/.bin/acorn
generated
vendored
Symbolic link
1
node_modules/.bin/acorn
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../acorn/bin/acorn
|
1
node_modules/.bin/eslint
generated
vendored
Symbolic link
1
node_modules/.bin/eslint
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../eslint/bin/eslint.js
|
1
node_modules/.bin/js-yaml
generated
vendored
Symbolic link
1
node_modules/.bin/js-yaml
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../js-yaml/bin/js-yaml.js
|
1
node_modules/.bin/node-which
generated
vendored
Symbolic link
1
node_modules/.bin/node-which
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../which/bin/node-which
|
1
node_modules/.bin/rimraf
generated
vendored
Symbolic link
1
node_modules/.bin/rimraf
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../rimraf/bin.js
|
893
node_modules/.package-lock.json
generated
vendored
893
node_modules/.package-lock.json
generated
vendored
|
@ -45,6 +45,70 @@
|
||||||
"node": ">=16.9.0"
|
"node": ">=16.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@discordjs/rest/node_modules/node-fetch": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "^6.12.4",
|
||||||
|
"debug": "^4.3.2",
|
||||||
|
"espree": "^9.2.0",
|
||||||
|
"globals": "^13.9.0",
|
||||||
|
"ignore": "^4.0.6",
|
||||||
|
"import-fresh": "^3.2.1",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"minimatch": "^3.0.4",
|
||||||
|
"strip-json-comments": "^3.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/ignore": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
|
"version": "0.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz",
|
||||||
|
"integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@humanwhocodes/object-schema": "^1.2.1",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"minimatch": "^3.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@humanwhocodes/object-schema": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
|
||||||
|
},
|
||||||
"node_modules/@sapphire/async-queue": {
|
"node_modules/@sapphire/async-queue": {
|
||||||
"version": "1.1.9",
|
"version": "1.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.9.tgz",
|
||||||
|
@ -109,11 +173,133 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/acorn": {
|
||||||
|
"version": "8.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
|
||||||
|
"integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
|
||||||
|
"bin": {
|
||||||
|
"acorn": "bin/acorn"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/acorn-jsx": {
|
||||||
|
"version": "5.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||||
|
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ajv": {
|
||||||
|
"version": "6.12.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||||
|
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.1",
|
||||||
|
"fast-json-stable-stringify": "^2.0.0",
|
||||||
|
"json-schema-traverse": "^0.4.1",
|
||||||
|
"uri-js": "^4.2.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
|
},
|
||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||||
},
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "0.25.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
|
||||||
|
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.14.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||||
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/callsites": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chalk": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.1.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
|
},
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
@ -125,6 +311,45 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||||
|
},
|
||||||
|
"node_modules/cross-spawn": {
|
||||||
|
"version": "7.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
|
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||||
|
"dependencies": {
|
||||||
|
"path-key": "^3.1.0",
|
||||||
|
"shebang-command": "^2.0.0",
|
||||||
|
"which": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "4.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
|
||||||
|
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "2.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/deep-is": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||||
|
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
|
||||||
|
},
|
||||||
"node_modules/delayed-stream": {
|
"node_modules/delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
@ -177,6 +402,36 @@
|
||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/discord.js/node_modules/node-fetch": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/doctrine": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
|
||||||
|
"dependencies": {
|
||||||
|
"esutils": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "14.2.0",
|
"version": "14.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-14.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-14.2.0.tgz",
|
||||||
|
@ -185,6 +440,226 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/escape-string-regexp": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint": {
|
||||||
|
"version": "8.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz",
|
||||||
|
"integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint/eslintrc": "^1.0.5",
|
||||||
|
"@humanwhocodes/config-array": "^0.9.2",
|
||||||
|
"ajv": "^6.10.0",
|
||||||
|
"chalk": "^4.0.0",
|
||||||
|
"cross-spawn": "^7.0.2",
|
||||||
|
"debug": "^4.3.2",
|
||||||
|
"doctrine": "^3.0.0",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"eslint-scope": "^7.1.0",
|
||||||
|
"eslint-utils": "^3.0.0",
|
||||||
|
"eslint-visitor-keys": "^3.2.0",
|
||||||
|
"espree": "^9.3.0",
|
||||||
|
"esquery": "^1.4.0",
|
||||||
|
"esutils": "^2.0.2",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"file-entry-cache": "^6.0.1",
|
||||||
|
"functional-red-black-tree": "^1.0.1",
|
||||||
|
"glob-parent": "^6.0.1",
|
||||||
|
"globals": "^13.6.0",
|
||||||
|
"ignore": "^5.2.0",
|
||||||
|
"import-fresh": "^3.0.0",
|
||||||
|
"imurmurhash": "^0.1.4",
|
||||||
|
"is-glob": "^4.0.0",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||||
|
"levn": "^0.4.1",
|
||||||
|
"lodash.merge": "^4.6.2",
|
||||||
|
"minimatch": "^3.0.4",
|
||||||
|
"natural-compare": "^1.4.0",
|
||||||
|
"optionator": "^0.9.1",
|
||||||
|
"regexpp": "^3.2.0",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"strip-json-comments": "^3.1.0",
|
||||||
|
"text-table": "^0.2.0",
|
||||||
|
"v8-compile-cache": "^2.0.3"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"eslint": "bin/eslint.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-scope": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==",
|
||||||
|
"dependencies": {
|
||||||
|
"esrecurse": "^4.3.0",
|
||||||
|
"estraverse": "^5.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-utils": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
|
||||||
|
"dependencies": {
|
||||||
|
"eslint-visitor-keys": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/mysticatea"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": ">=5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-visitor-keys": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/espree": {
|
||||||
|
"version": "9.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz",
|
||||||
|
"integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^8.7.0",
|
||||||
|
"acorn-jsx": "^5.3.1",
|
||||||
|
"eslint-visitor-keys": "^3.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/esquery": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
|
||||||
|
"dependencies": {
|
||||||
|
"estraverse": "^5.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/esrecurse": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||||
|
"dependencies": {
|
||||||
|
"estraverse": "^5.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/estraverse": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/esutils": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-deep-equal": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
|
},
|
||||||
|
"node_modules/fast-json-stable-stringify": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||||
|
},
|
||||||
|
"node_modules/fast-levenshtein": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||||
|
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
|
||||||
|
},
|
||||||
|
"node_modules/file-entry-cache": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
|
||||||
|
"dependencies": {
|
||||||
|
"flat-cache": "^3.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10.12.0 || >=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/flat-cache": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
|
||||||
|
"dependencies": {
|
||||||
|
"flatted": "^3.1.0",
|
||||||
|
"rimraf": "^3.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10.12.0 || >=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/flatted": {
|
||||||
|
"version": "3.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
|
||||||
|
"integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg=="
|
||||||
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.14.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||||
|
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/form-data": {
|
"node_modules/form-data": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||||
|
@ -198,6 +673,175 @@
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||||
|
},
|
||||||
|
"node_modules/functional-red-black-tree": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
|
||||||
|
},
|
||||||
|
"node_modules/glob": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "^3.0.4",
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/glob-parent": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/globals": {
|
||||||
|
"version": "13.12.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
|
||||||
|
"integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
|
||||||
|
"dependencies": {
|
||||||
|
"type-fest": "^0.20.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ignore": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/import-fresh": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||||
|
"dependencies": {
|
||||||
|
"parent-module": "^1.0.0",
|
||||||
|
"resolve-from": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/imurmurhash": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||||
|
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.19"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||||
|
"dependencies": {
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"node_modules/is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"dependencies": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/isexe": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||||
|
},
|
||||||
|
"node_modules/js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/json-schema-traverse": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||||
|
},
|
||||||
|
"node_modules/json-stable-stringify-without-jsonify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
|
||||||
|
},
|
||||||
|
"node_modules/levn": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"prelude-ls": "^1.2.1",
|
||||||
|
"type-check": "~0.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lodash.merge": {
|
||||||
|
"version": "4.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||||
|
},
|
||||||
"node_modules/mime-db": {
|
"node_modules/mime-db": {
|
||||||
"version": "1.51.0",
|
"version": "1.51.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
|
||||||
|
@ -217,25 +861,184 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-fetch": {
|
"node_modules/minimatch": {
|
||||||
"version": "2.6.7",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz",
|
||||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
"integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"whatwg-url": "^5.0.0"
|
"brace-expansion": "^1.1.7"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "4.x || >=6.0.0"
|
"node": "*"
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"encoding": "^0.1.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"encoding": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
|
},
|
||||||
|
"node_modules/natural-compare": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
|
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
|
||||||
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/optionator": {
|
||||||
|
"version": "0.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
||||||
|
"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
|
||||||
|
"dependencies": {
|
||||||
|
"deep-is": "^0.1.3",
|
||||||
|
"fast-levenshtein": "^2.0.6",
|
||||||
|
"levn": "^0.4.1",
|
||||||
|
"prelude-ls": "^1.2.1",
|
||||||
|
"type-check": "^0.4.0",
|
||||||
|
"word-wrap": "^1.2.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/parent-module": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
||||||
|
"dependencies": {
|
||||||
|
"callsites": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-key": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prelude-ls": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/punycode": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/regexpp": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/mysticatea"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/resolve-from": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/rimraf": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||||
|
"dependencies": {
|
||||||
|
"glob": "^7.1.3"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"rimraf": "bin.js"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-command": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
|
"dependencies": {
|
||||||
|
"shebang-regex": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-ansi": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-json-comments": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/text-table": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
|
||||||
|
},
|
||||||
"node_modules/tr46": {
|
"node_modules/tr46": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
@ -251,6 +1054,41 @@
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/type-check": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
|
||||||
|
"dependencies": {
|
||||||
|
"prelude-ls": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/type-fest": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uri-js": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/v8-compile-cache": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA=="
|
||||||
|
},
|
||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
@ -265,6 +1103,33 @@
|
||||||
"webidl-conversions": "^3.0.0"
|
"webidl-conversions": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/which": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
|
"dependencies": {
|
||||||
|
"isexe": "^2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-which": "bin/node-which"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/word-wrap": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||||
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.4.2",
|
"version": "8.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz",
|
||||||
|
|
21
node_modules/@eslint/eslintrc/LICENSE
generated
vendored
Normal file
21
node_modules/@eslint/eslintrc/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 ESLint
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
61
node_modules/@eslint/eslintrc/README.md
generated
vendored
Normal file
61
node_modules/@eslint/eslintrc/README.md
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# ESLintRC Library
|
||||||
|
|
||||||
|
This repository contains the legacy ESLintRC configuration file format for ESLint.
|
||||||
|
|
||||||
|
**Note:** This package is not intended for use outside of the ESLint ecosystem. It is ESLint-specific and not intended for use in other programs.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
You can install the package as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install @eslint/eslintrc --save-dev
|
||||||
|
|
||||||
|
# or
|
||||||
|
|
||||||
|
yarn add @eslint/eslintrc -D
|
||||||
|
```
|
||||||
|
|
||||||
|
## Future Usage
|
||||||
|
|
||||||
|
**Note:** This package is not intended for public use at this time. The following is an example of how it will be used in the future.
|
||||||
|
|
||||||
|
The primary class in this package is `FlatCompat`, which is a utility to translate ESLintRC-style configs into flat configs. Here's how you use it inside of your `eslint.config.js` file:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { FlatCompat } from "@eslint/eslintrc";
|
||||||
|
|
||||||
|
const compat = new FlatCompat();
|
||||||
|
|
||||||
|
export default [
|
||||||
|
|
||||||
|
// mimic ESLintRC-style extends
|
||||||
|
compat.extends("standard", "example"),
|
||||||
|
|
||||||
|
// mimic environments
|
||||||
|
compat.env({
|
||||||
|
es2020: true,
|
||||||
|
node: true
|
||||||
|
}),
|
||||||
|
|
||||||
|
// mimic plugins
|
||||||
|
compat.plugins("airbnb", "react"),
|
||||||
|
|
||||||
|
// translate an entire config
|
||||||
|
compat.config({
|
||||||
|
plugins: ["airbnb", "react"],
|
||||||
|
extends: "standard",
|
||||||
|
env: {
|
||||||
|
es2020: true,
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
semi: "error"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License
|
79
node_modules/@eslint/eslintrc/conf/config-schema.js
generated
vendored
Normal file
79
node_modules/@eslint/eslintrc/conf/config-schema.js
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Defines a schema for configs.
|
||||||
|
* @author Sylvan Mably
|
||||||
|
*/
|
||||||
|
|
||||||
|
const baseConfigProperties = {
|
||||||
|
$schema: { type: "string" },
|
||||||
|
env: { type: "object" },
|
||||||
|
extends: { $ref: "#/definitions/stringOrStrings" },
|
||||||
|
globals: { type: "object" },
|
||||||
|
overrides: {
|
||||||
|
type: "array",
|
||||||
|
items: { $ref: "#/definitions/overrideConfig" },
|
||||||
|
additionalItems: false
|
||||||
|
},
|
||||||
|
parser: { type: ["string", "null"] },
|
||||||
|
parserOptions: { type: "object" },
|
||||||
|
plugins: { type: "array" },
|
||||||
|
processor: { type: "string" },
|
||||||
|
rules: { type: "object" },
|
||||||
|
settings: { type: "object" },
|
||||||
|
noInlineConfig: { type: "boolean" },
|
||||||
|
reportUnusedDisableDirectives: { type: "boolean" },
|
||||||
|
|
||||||
|
ecmaFeatures: { type: "object" } // deprecated; logs a warning when used
|
||||||
|
};
|
||||||
|
|
||||||
|
const configSchema = {
|
||||||
|
definitions: {
|
||||||
|
stringOrStrings: {
|
||||||
|
oneOf: [
|
||||||
|
{ type: "string" },
|
||||||
|
{
|
||||||
|
type: "array",
|
||||||
|
items: { type: "string" },
|
||||||
|
additionalItems: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
stringOrStringsRequired: {
|
||||||
|
oneOf: [
|
||||||
|
{ type: "string" },
|
||||||
|
{
|
||||||
|
type: "array",
|
||||||
|
items: { type: "string" },
|
||||||
|
additionalItems: false,
|
||||||
|
minItems: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// Config at top-level.
|
||||||
|
objectConfig: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
root: { type: "boolean" },
|
||||||
|
ignorePatterns: { $ref: "#/definitions/stringOrStrings" },
|
||||||
|
...baseConfigProperties
|
||||||
|
},
|
||||||
|
additionalProperties: false
|
||||||
|
},
|
||||||
|
|
||||||
|
// Config in `overrides`.
|
||||||
|
overrideConfig: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
excludedFiles: { $ref: "#/definitions/stringOrStrings" },
|
||||||
|
files: { $ref: "#/definitions/stringOrStringsRequired" },
|
||||||
|
...baseConfigProperties
|
||||||
|
},
|
||||||
|
required: ["files"],
|
||||||
|
additionalProperties: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
$ref: "#/definitions/objectConfig"
|
||||||
|
};
|
||||||
|
|
||||||
|
export default configSchema;
|
179
node_modules/@eslint/eslintrc/conf/environments.js
generated
vendored
Normal file
179
node_modules/@eslint/eslintrc/conf/environments.js
generated
vendored
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Defines environment settings and globals.
|
||||||
|
* @author Elan Shanker
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import globals from "globals";
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object that has difference.
|
||||||
|
* @param {Record<string,boolean>} current The newer object.
|
||||||
|
* @param {Record<string,boolean>} prev The older object.
|
||||||
|
* @returns {Record<string,boolean>} The difference object.
|
||||||
|
*/
|
||||||
|
function getDiff(current, prev) {
|
||||||
|
const retv = {};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(current)) {
|
||||||
|
if (!Object.hasOwnProperty.call(prev, key)) {
|
||||||
|
retv[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newGlobals2015 = getDiff(globals.es2015, globals.es5); // 19 variables such as Promise, Map, ...
|
||||||
|
const newGlobals2017 = {
|
||||||
|
Atomics: false,
|
||||||
|
SharedArrayBuffer: false
|
||||||
|
};
|
||||||
|
const newGlobals2020 = {
|
||||||
|
BigInt: false,
|
||||||
|
BigInt64Array: false,
|
||||||
|
BigUint64Array: false,
|
||||||
|
globalThis: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const newGlobals2021 = {
|
||||||
|
AggregateError: false,
|
||||||
|
FinalizationRegistry: false,
|
||||||
|
WeakRef: false
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** @type {Map<string, import("../lib/shared/types").Environment>} */
|
||||||
|
export default new Map(Object.entries({
|
||||||
|
|
||||||
|
// Language
|
||||||
|
builtin: {
|
||||||
|
globals: globals.es5
|
||||||
|
},
|
||||||
|
es6: {
|
||||||
|
globals: newGlobals2015,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
es2015: {
|
||||||
|
globals: newGlobals2015,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
es2017: {
|
||||||
|
globals: { ...newGlobals2015, ...newGlobals2017 },
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
es2020: {
|
||||||
|
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 },
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 11
|
||||||
|
}
|
||||||
|
},
|
||||||
|
es2021: {
|
||||||
|
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 },
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Platforms
|
||||||
|
browser: {
|
||||||
|
globals: globals.browser
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
globals: globals.node,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaFeatures: {
|
||||||
|
globalReturn: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shared-node-browser": {
|
||||||
|
globals: globals["shared-node-browser"]
|
||||||
|
},
|
||||||
|
worker: {
|
||||||
|
globals: globals.worker
|
||||||
|
},
|
||||||
|
serviceworker: {
|
||||||
|
globals: globals.serviceworker
|
||||||
|
},
|
||||||
|
|
||||||
|
// Frameworks
|
||||||
|
commonjs: {
|
||||||
|
globals: globals.commonjs,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaFeatures: {
|
||||||
|
globalReturn: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
amd: {
|
||||||
|
globals: globals.amd
|
||||||
|
},
|
||||||
|
mocha: {
|
||||||
|
globals: globals.mocha
|
||||||
|
},
|
||||||
|
jasmine: {
|
||||||
|
globals: globals.jasmine
|
||||||
|
},
|
||||||
|
jest: {
|
||||||
|
globals: globals.jest
|
||||||
|
},
|
||||||
|
phantomjs: {
|
||||||
|
globals: globals.phantomjs
|
||||||
|
},
|
||||||
|
jquery: {
|
||||||
|
globals: globals.jquery
|
||||||
|
},
|
||||||
|
qunit: {
|
||||||
|
globals: globals.qunit
|
||||||
|
},
|
||||||
|
prototypejs: {
|
||||||
|
globals: globals.prototypejs
|
||||||
|
},
|
||||||
|
shelljs: {
|
||||||
|
globals: globals.shelljs
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
globals: globals.meteor
|
||||||
|
},
|
||||||
|
mongo: {
|
||||||
|
globals: globals.mongo
|
||||||
|
},
|
||||||
|
protractor: {
|
||||||
|
globals: globals.protractor
|
||||||
|
},
|
||||||
|
applescript: {
|
||||||
|
globals: globals.applescript
|
||||||
|
},
|
||||||
|
nashorn: {
|
||||||
|
globals: globals.nashorn
|
||||||
|
},
|
||||||
|
atomtest: {
|
||||||
|
globals: globals.atomtest
|
||||||
|
},
|
||||||
|
embertest: {
|
||||||
|
globals: globals.embertest
|
||||||
|
},
|
||||||
|
webextensions: {
|
||||||
|
globals: globals.webextensions
|
||||||
|
},
|
||||||
|
greasemonkey: {
|
||||||
|
globals: globals.greasemonkey
|
||||||
|
}
|
||||||
|
}));
|
12
node_modules/@eslint/eslintrc/conf/eslint-all.cjs
generated
vendored
Normal file
12
node_modules/@eslint/eslintrc/conf/eslint-all.cjs
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Stub eslint:all config
|
||||||
|
* @author Nicholas C. Zakas
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
settings: {
|
||||||
|
"eslint:all": true
|
||||||
|
}
|
||||||
|
};
|
12
node_modules/@eslint/eslintrc/conf/eslint-recommended.cjs
generated
vendored
Normal file
12
node_modules/@eslint/eslintrc/conf/eslint-recommended.cjs
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Stub eslint:recommended config
|
||||||
|
* @author Nicholas C. Zakas
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
settings: {
|
||||||
|
"eslint:recommended": true
|
||||||
|
}
|
||||||
|
};
|
1068
node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs
generated
vendored
Normal file
1068
node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs.map
generated
vendored
Normal file
1
node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4236
node_modules/@eslint/eslintrc/dist/eslintrc.cjs
generated
vendored
Normal file
4236
node_modules/@eslint/eslintrc/dist/eslintrc.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
node_modules/@eslint/eslintrc/dist/eslintrc.cjs.map
generated
vendored
Normal file
1
node_modules/@eslint/eslintrc/dist/eslintrc.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
520
node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js
generated
vendored
Normal file
520
node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js
generated
vendored
Normal file
|
@ -0,0 +1,520 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview `CascadingConfigArrayFactory` class.
|
||||||
|
*
|
||||||
|
* `CascadingConfigArrayFactory` class has a responsibility:
|
||||||
|
*
|
||||||
|
* 1. Handles cascading of config files.
|
||||||
|
*
|
||||||
|
* It provides two methods:
|
||||||
|
*
|
||||||
|
* - `getConfigArrayForFile(filePath)`
|
||||||
|
* Get the corresponded configuration of a given file. This method doesn't
|
||||||
|
* throw even if the given file didn't exist.
|
||||||
|
* - `clearCache()`
|
||||||
|
* Clear the internal cache. You have to call this method when
|
||||||
|
* `additionalPluginPool` was updated if `baseConfig` or `cliConfig` depends
|
||||||
|
* on the additional plugins. (`CLIEngine#addPlugin()` method calls this.)
|
||||||
|
*
|
||||||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import os from "os";
|
||||||
|
import path from "path";
|
||||||
|
import ConfigValidator from "./shared/config-validator.js";
|
||||||
|
import { emitDeprecationWarning } from "./shared/deprecation-warnings.js";
|
||||||
|
import { ConfigArrayFactory } from "./config-array-factory.js";
|
||||||
|
import { ConfigArray, ConfigDependency, IgnorePattern } from "./config-array/index.js";
|
||||||
|
import debugOrig from "debug";
|
||||||
|
|
||||||
|
const debug = debugOrig("eslintrc:cascading-config-array-factory");
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Define types for VSCode IntelliSense.
|
||||||
|
/** @typedef {import("./shared/types").ConfigData} ConfigData */
|
||||||
|
/** @typedef {import("./shared/types").Parser} Parser */
|
||||||
|
/** @typedef {import("./shared/types").Plugin} Plugin */
|
||||||
|
/** @typedef {import("./shared/types").Rule} Rule */
|
||||||
|
/** @typedef {ReturnType<ConfigArrayFactory["create"]>} ConfigArray */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} CascadingConfigArrayFactoryOptions
|
||||||
|
* @property {Map<string,Plugin>} [additionalPluginPool] The map for additional plugins.
|
||||||
|
* @property {ConfigData} [baseConfig] The config by `baseConfig` option.
|
||||||
|
* @property {ConfigData} [cliConfig] The config by CLI options (`--env`, `--global`, `--ignore-pattern`, `--parser`, `--parser-options`, `--plugin`, and `--rule`). CLI options overwrite the setting in config files.
|
||||||
|
* @property {string} [cwd] The base directory to start lookup.
|
||||||
|
* @property {string} [ignorePath] The path to the alternative file of `.eslintignore`.
|
||||||
|
* @property {string[]} [rulePaths] The value of `--rulesdir` option.
|
||||||
|
* @property {string} [specificConfigPath] The value of `--config` option.
|
||||||
|
* @property {boolean} [useEslintrc] if `false` then it doesn't load config files.
|
||||||
|
* @property {Function} loadRules The function to use to load rules.
|
||||||
|
* @property {Map<string,Rule>} builtInRules The rules that are built in to ESLint.
|
||||||
|
* @property {Object} [resolver=ModuleResolver] The module resolver object.
|
||||||
|
* @property {string} eslintAllPath The path to the definitions for eslint:all.
|
||||||
|
* @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} CascadingConfigArrayFactoryInternalSlots
|
||||||
|
* @property {ConfigArray} baseConfigArray The config array of `baseConfig` option.
|
||||||
|
* @property {ConfigData} baseConfigData The config data of `baseConfig` option. This is used to reset `baseConfigArray`.
|
||||||
|
* @property {ConfigArray} cliConfigArray The config array of CLI options.
|
||||||
|
* @property {ConfigData} cliConfigData The config data of CLI options. This is used to reset `cliConfigArray`.
|
||||||
|
* @property {ConfigArrayFactory} configArrayFactory The factory for config arrays.
|
||||||
|
* @property {Map<string, ConfigArray>} configCache The cache from directory paths to config arrays.
|
||||||
|
* @property {string} cwd The base directory to start lookup.
|
||||||
|
* @property {WeakMap<ConfigArray, ConfigArray>} finalizeCache The cache from config arrays to finalized config arrays.
|
||||||
|
* @property {string} [ignorePath] The path to the alternative file of `.eslintignore`.
|
||||||
|
* @property {string[]|null} rulePaths The value of `--rulesdir` option. This is used to reset `baseConfigArray`.
|
||||||
|
* @property {string|null} specificConfigPath The value of `--config` option. This is used to reset `cliConfigArray`.
|
||||||
|
* @property {boolean} useEslintrc if `false` then it doesn't load config files.
|
||||||
|
* @property {Function} loadRules The function to use to load rules.
|
||||||
|
* @property {Map<string,Rule>} builtInRules The rules that are built in to ESLint.
|
||||||
|
* @property {Object} [resolver=ModuleResolver] The module resolver object.
|
||||||
|
* @property {string} eslintAllPath The path to the definitions for eslint:all.
|
||||||
|
* @property {string} eslintRecommendedPath The path to the definitions for eslint:recommended.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {WeakMap<CascadingConfigArrayFactory, CascadingConfigArrayFactoryInternalSlots>} */
|
||||||
|
const internalSlotsMap = new WeakMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the config array from `baseConfig` and `rulePaths`.
|
||||||
|
* @param {CascadingConfigArrayFactoryInternalSlots} slots The slots.
|
||||||
|
* @returns {ConfigArray} The config array of the base configs.
|
||||||
|
*/
|
||||||
|
function createBaseConfigArray({
|
||||||
|
configArrayFactory,
|
||||||
|
baseConfigData,
|
||||||
|
rulePaths,
|
||||||
|
cwd,
|
||||||
|
loadRules
|
||||||
|
}) {
|
||||||
|
const baseConfigArray = configArrayFactory.create(
|
||||||
|
baseConfigData,
|
||||||
|
{ name: "BaseConfig" }
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the config array element for the default ignore patterns.
|
||||||
|
* This element has `ignorePattern` property that ignores the default
|
||||||
|
* patterns in the current working directory.
|
||||||
|
*/
|
||||||
|
baseConfigArray.unshift(configArrayFactory.create(
|
||||||
|
{ ignorePatterns: IgnorePattern.DefaultPatterns },
|
||||||
|
{ name: "DefaultIgnorePattern" }
|
||||||
|
)[0]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load rules `--rulesdir` option as a pseudo plugin.
|
||||||
|
* Use a pseudo plugin to define rules of `--rulesdir`, so we can validate
|
||||||
|
* the rule's options with only information in the config array.
|
||||||
|
*/
|
||||||
|
if (rulePaths && rulePaths.length > 0) {
|
||||||
|
baseConfigArray.push({
|
||||||
|
type: "config",
|
||||||
|
name: "--rulesdir",
|
||||||
|
filePath: "",
|
||||||
|
plugins: {
|
||||||
|
"": new ConfigDependency({
|
||||||
|
definition: {
|
||||||
|
rules: rulePaths.reduce(
|
||||||
|
(map, rulesPath) => Object.assign(
|
||||||
|
map,
|
||||||
|
loadRules(rulesPath, cwd)
|
||||||
|
),
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
filePath: "",
|
||||||
|
id: "",
|
||||||
|
importerName: "--rulesdir",
|
||||||
|
importerPath: ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseConfigArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the config array from CLI options.
|
||||||
|
* @param {CascadingConfigArrayFactoryInternalSlots} slots The slots.
|
||||||
|
* @returns {ConfigArray} The config array of the base configs.
|
||||||
|
*/
|
||||||
|
function createCLIConfigArray({
|
||||||
|
cliConfigData,
|
||||||
|
configArrayFactory,
|
||||||
|
cwd,
|
||||||
|
ignorePath,
|
||||||
|
specificConfigPath
|
||||||
|
}) {
|
||||||
|
const cliConfigArray = configArrayFactory.create(
|
||||||
|
cliConfigData,
|
||||||
|
{ name: "CLIOptions" }
|
||||||
|
);
|
||||||
|
|
||||||
|
cliConfigArray.unshift(
|
||||||
|
...(ignorePath
|
||||||
|
? configArrayFactory.loadESLintIgnore(ignorePath)
|
||||||
|
: configArrayFactory.loadDefaultESLintIgnore())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (specificConfigPath) {
|
||||||
|
cliConfigArray.unshift(
|
||||||
|
...configArrayFactory.loadFile(
|
||||||
|
specificConfigPath,
|
||||||
|
{ name: "--config", basePath: cwd }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cliConfigArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error type when there are files matched by a glob, but all of them have been ignored.
|
||||||
|
*/
|
||||||
|
class ConfigurationNotFoundError extends Error {
|
||||||
|
|
||||||
|
// eslint-disable-next-line jsdoc/require-description
|
||||||
|
/**
|
||||||
|
* @param {string} directoryPath The directory path.
|
||||||
|
*/
|
||||||
|
constructor(directoryPath) {
|
||||||
|
super(`No ESLint configuration found in ${directoryPath}.`);
|
||||||
|
this.messageTemplate = "no-config-found";
|
||||||
|
this.messageData = { directoryPath };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides the functionality that enumerates every file which is
|
||||||
|
* matched by given glob patterns and that configuration.
|
||||||
|
*/
|
||||||
|
class CascadingConfigArrayFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this enumerator.
|
||||||
|
* @param {CascadingConfigArrayFactoryOptions} options The options.
|
||||||
|
*/
|
||||||
|
constructor({
|
||||||
|
additionalPluginPool = new Map(),
|
||||||
|
baseConfig: baseConfigData = null,
|
||||||
|
cliConfig: cliConfigData = null,
|
||||||
|
cwd = process.cwd(),
|
||||||
|
ignorePath,
|
||||||
|
resolvePluginsRelativeTo,
|
||||||
|
rulePaths = [],
|
||||||
|
specificConfigPath = null,
|
||||||
|
useEslintrc = true,
|
||||||
|
builtInRules = new Map(),
|
||||||
|
loadRules,
|
||||||
|
resolver,
|
||||||
|
eslintRecommendedPath,
|
||||||
|
eslintAllPath
|
||||||
|
} = {}) {
|
||||||
|
const configArrayFactory = new ConfigArrayFactory({
|
||||||
|
additionalPluginPool,
|
||||||
|
cwd,
|
||||||
|
resolvePluginsRelativeTo,
|
||||||
|
builtInRules,
|
||||||
|
resolver,
|
||||||
|
eslintRecommendedPath,
|
||||||
|
eslintAllPath
|
||||||
|
});
|
||||||
|
|
||||||
|
internalSlotsMap.set(this, {
|
||||||
|
baseConfigArray: createBaseConfigArray({
|
||||||
|
baseConfigData,
|
||||||
|
configArrayFactory,
|
||||||
|
cwd,
|
||||||
|
rulePaths,
|
||||||
|
loadRules,
|
||||||
|
resolver
|
||||||
|
}),
|
||||||
|
baseConfigData,
|
||||||
|
cliConfigArray: createCLIConfigArray({
|
||||||
|
cliConfigData,
|
||||||
|
configArrayFactory,
|
||||||
|
cwd,
|
||||||
|
ignorePath,
|
||||||
|
specificConfigPath
|
||||||
|
}),
|
||||||
|
cliConfigData,
|
||||||
|
configArrayFactory,
|
||||||
|
configCache: new Map(),
|
||||||
|
cwd,
|
||||||
|
finalizeCache: new WeakMap(),
|
||||||
|
ignorePath,
|
||||||
|
rulePaths,
|
||||||
|
specificConfigPath,
|
||||||
|
useEslintrc,
|
||||||
|
builtInRules,
|
||||||
|
loadRules
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the current working directory.
|
||||||
|
* This is used by tests.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
get cwd() {
|
||||||
|
const { cwd } = internalSlotsMap.get(this);
|
||||||
|
|
||||||
|
return cwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the config array of a given file.
|
||||||
|
* If `filePath` was not given, it returns the config which contains only
|
||||||
|
* `baseConfigData` and `cliConfigData`.
|
||||||
|
* @param {string} [filePath] The file path to a file.
|
||||||
|
* @param {Object} [options] The options.
|
||||||
|
* @param {boolean} [options.ignoreNotFoundError] If `true` then it doesn't throw `ConfigurationNotFoundError`.
|
||||||
|
* @returns {ConfigArray} The config array of the file.
|
||||||
|
*/
|
||||||
|
getConfigArrayForFile(filePath, { ignoreNotFoundError = false } = {}) {
|
||||||
|
const {
|
||||||
|
baseConfigArray,
|
||||||
|
cliConfigArray,
|
||||||
|
cwd
|
||||||
|
} = internalSlotsMap.get(this);
|
||||||
|
|
||||||
|
if (!filePath) {
|
||||||
|
return new ConfigArray(...baseConfigArray, ...cliConfigArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
const directoryPath = path.dirname(path.resolve(cwd, filePath));
|
||||||
|
|
||||||
|
debug(`Load config files for ${directoryPath}.`);
|
||||||
|
|
||||||
|
return this._finalizeConfigArray(
|
||||||
|
this._loadConfigInAncestors(directoryPath),
|
||||||
|
directoryPath,
|
||||||
|
ignoreNotFoundError
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the config data to override all configs.
|
||||||
|
* Require to call `clearCache()` method after this method is called.
|
||||||
|
* @param {ConfigData} configData The config data to override all configs.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
setOverrideConfig(configData) {
|
||||||
|
const slots = internalSlotsMap.get(this);
|
||||||
|
|
||||||
|
slots.cliConfigData = configData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear config cache.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
clearCache() {
|
||||||
|
const slots = internalSlotsMap.get(this);
|
||||||
|
|
||||||
|
slots.baseConfigArray = createBaseConfigArray(slots);
|
||||||
|
slots.cliConfigArray = createCLIConfigArray(slots);
|
||||||
|
slots.configCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load and normalize config files from the ancestor directories.
|
||||||
|
* @param {string} directoryPath The path to a leaf directory.
|
||||||
|
* @param {boolean} configsExistInSubdirs `true` if configurations exist in subdirectories.
|
||||||
|
* @returns {ConfigArray} The loaded config.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_loadConfigInAncestors(directoryPath, configsExistInSubdirs = false) {
|
||||||
|
const {
|
||||||
|
baseConfigArray,
|
||||||
|
configArrayFactory,
|
||||||
|
configCache,
|
||||||
|
cwd,
|
||||||
|
useEslintrc
|
||||||
|
} = internalSlotsMap.get(this);
|
||||||
|
|
||||||
|
if (!useEslintrc) {
|
||||||
|
return baseConfigArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
let configArray = configCache.get(directoryPath);
|
||||||
|
|
||||||
|
// Hit cache.
|
||||||
|
if (configArray) {
|
||||||
|
debug(`Cache hit: ${directoryPath}.`);
|
||||||
|
return configArray;
|
||||||
|
}
|
||||||
|
debug(`No cache found: ${directoryPath}.`);
|
||||||
|
|
||||||
|
const homePath = os.homedir();
|
||||||
|
|
||||||
|
// Consider this is root.
|
||||||
|
if (directoryPath === homePath && cwd !== homePath) {
|
||||||
|
debug("Stop traversing because of considered root.");
|
||||||
|
if (configsExistInSubdirs) {
|
||||||
|
const filePath = ConfigArrayFactory.getPathToConfigFileInDirectory(directoryPath);
|
||||||
|
|
||||||
|
if (filePath) {
|
||||||
|
emitDeprecationWarning(
|
||||||
|
filePath,
|
||||||
|
"ESLINT_PERSONAL_CONFIG_SUPPRESS"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this._cacheConfig(directoryPath, baseConfigArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the config on this directory.
|
||||||
|
try {
|
||||||
|
configArray = configArrayFactory.loadInDirectory(directoryPath);
|
||||||
|
} catch (error) {
|
||||||
|
/* istanbul ignore next */
|
||||||
|
if (error.code === "EACCES") {
|
||||||
|
debug("Stop traversing because of 'EACCES' error.");
|
||||||
|
return this._cacheConfig(directoryPath, baseConfigArray);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configArray.length > 0 && configArray.isRoot()) {
|
||||||
|
debug("Stop traversing because of 'root:true'.");
|
||||||
|
configArray.unshift(...baseConfigArray);
|
||||||
|
return this._cacheConfig(directoryPath, configArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load from the ancestors and merge it.
|
||||||
|
const parentPath = path.dirname(directoryPath);
|
||||||
|
const parentConfigArray = parentPath && parentPath !== directoryPath
|
||||||
|
? this._loadConfigInAncestors(
|
||||||
|
parentPath,
|
||||||
|
configsExistInSubdirs || configArray.length > 0
|
||||||
|
)
|
||||||
|
: baseConfigArray;
|
||||||
|
|
||||||
|
if (configArray.length > 0) {
|
||||||
|
configArray.unshift(...parentConfigArray);
|
||||||
|
} else {
|
||||||
|
configArray = parentConfigArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache and return.
|
||||||
|
return this._cacheConfig(directoryPath, configArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Freeze and cache a given config.
|
||||||
|
* @param {string} directoryPath The path to a directory as a cache key.
|
||||||
|
* @param {ConfigArray} configArray The config array as a cache value.
|
||||||
|
* @returns {ConfigArray} The `configArray` (frozen).
|
||||||
|
*/
|
||||||
|
_cacheConfig(directoryPath, configArray) {
|
||||||
|
const { configCache } = internalSlotsMap.get(this);
|
||||||
|
|
||||||
|
Object.freeze(configArray);
|
||||||
|
configCache.set(directoryPath, configArray);
|
||||||
|
|
||||||
|
return configArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalize a given config array.
|
||||||
|
* Concatenate `--config` and other CLI options.
|
||||||
|
* @param {ConfigArray} configArray The parent config array.
|
||||||
|
* @param {string} directoryPath The path to the leaf directory to find config files.
|
||||||
|
* @param {boolean} ignoreNotFoundError If `true` then it doesn't throw `ConfigurationNotFoundError`.
|
||||||
|
* @returns {ConfigArray} The loaded config.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_finalizeConfigArray(configArray, directoryPath, ignoreNotFoundError) {
|
||||||
|
const {
|
||||||
|
cliConfigArray,
|
||||||
|
configArrayFactory,
|
||||||
|
finalizeCache,
|
||||||
|
useEslintrc,
|
||||||
|
builtInRules
|
||||||
|
} = internalSlotsMap.get(this);
|
||||||
|
|
||||||
|
let finalConfigArray = finalizeCache.get(configArray);
|
||||||
|
|
||||||
|
if (!finalConfigArray) {
|
||||||
|
finalConfigArray = configArray;
|
||||||
|
|
||||||
|
// Load the personal config if there are no regular config files.
|
||||||
|
if (
|
||||||
|
useEslintrc &&
|
||||||
|
configArray.every(c => !c.filePath) &&
|
||||||
|
cliConfigArray.every(c => !c.filePath) // `--config` option can be a file.
|
||||||
|
) {
|
||||||
|
const homePath = os.homedir();
|
||||||
|
|
||||||
|
debug("Loading the config file of the home directory:", homePath);
|
||||||
|
|
||||||
|
const personalConfigArray = configArrayFactory.loadInDirectory(
|
||||||
|
homePath,
|
||||||
|
{ name: "PersonalConfig" }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
personalConfigArray.length > 0 &&
|
||||||
|
!directoryPath.startsWith(homePath)
|
||||||
|
) {
|
||||||
|
const lastElement =
|
||||||
|
personalConfigArray[personalConfigArray.length - 1];
|
||||||
|
|
||||||
|
emitDeprecationWarning(
|
||||||
|
lastElement.filePath,
|
||||||
|
"ESLINT_PERSONAL_CONFIG_LOAD"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
finalConfigArray = finalConfigArray.concat(personalConfigArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply CLI options.
|
||||||
|
if (cliConfigArray.length > 0) {
|
||||||
|
finalConfigArray = finalConfigArray.concat(cliConfigArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate rule settings and environments.
|
||||||
|
const validator = new ConfigValidator({
|
||||||
|
builtInRules
|
||||||
|
});
|
||||||
|
|
||||||
|
validator.validateConfigArray(finalConfigArray);
|
||||||
|
|
||||||
|
// Cache it.
|
||||||
|
Object.freeze(finalConfigArray);
|
||||||
|
finalizeCache.set(configArray, finalConfigArray);
|
||||||
|
|
||||||
|
debug(
|
||||||
|
"Configuration was determined: %o on %s",
|
||||||
|
finalConfigArray,
|
||||||
|
directoryPath
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// At least one element (the default ignore patterns) exists.
|
||||||
|
if (!ignoreNotFoundError && useEslintrc && finalConfigArray.length <= 1) {
|
||||||
|
throw new ConfigurationNotFoundError(directoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalConfigArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export { CascadingConfigArrayFactory };
|
1103
node_modules/@eslint/eslintrc/lib/config-array-factory.js
generated
vendored
Normal file
1103
node_modules/@eslint/eslintrc/lib/config-array-factory.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
523
node_modules/@eslint/eslintrc/lib/config-array/config-array.js
generated
vendored
Normal file
523
node_modules/@eslint/eslintrc/lib/config-array/config-array.js
generated
vendored
Normal file
|
@ -0,0 +1,523 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview `ConfigArray` class.
|
||||||
|
*
|
||||||
|
* `ConfigArray` class expresses the full of a configuration. It has the entry
|
||||||
|
* config file, base config files that were extended, loaded parsers, and loaded
|
||||||
|
* plugins.
|
||||||
|
*
|
||||||
|
* `ConfigArray` class provides three properties and two methods.
|
||||||
|
*
|
||||||
|
* - `pluginEnvironments`
|
||||||
|
* - `pluginProcessors`
|
||||||
|
* - `pluginRules`
|
||||||
|
* The `Map` objects that contain the members of all plugins that this
|
||||||
|
* config array contains. Those map objects don't have mutation methods.
|
||||||
|
* Those keys are the member ID such as `pluginId/memberName`.
|
||||||
|
* - `isRoot()`
|
||||||
|
* If `true` then this configuration has `root:true` property.
|
||||||
|
* - `extractConfig(filePath)`
|
||||||
|
* Extract the final configuration for a given file. This means merging
|
||||||
|
* every config array element which that `criteria` property matched. The
|
||||||
|
* `filePath` argument must be an absolute path.
|
||||||
|
*
|
||||||
|
* `ConfigArrayFactory` provides the loading logic of config files.
|
||||||
|
*
|
||||||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import { ExtractedConfig } from "./extracted-config.js";
|
||||||
|
import { IgnorePattern } from "./ignore-pattern.js";
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Define types for VSCode IntelliSense.
|
||||||
|
/** @typedef {import("../../shared/types").Environment} Environment */
|
||||||
|
/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */
|
||||||
|
/** @typedef {import("../../shared/types").RuleConf} RuleConf */
|
||||||
|
/** @typedef {import("../../shared/types").Rule} Rule */
|
||||||
|
/** @typedef {import("../../shared/types").Plugin} Plugin */
|
||||||
|
/** @typedef {import("../../shared/types").Processor} Processor */
|
||||||
|
/** @typedef {import("./config-dependency").DependentParser} DependentParser */
|
||||||
|
/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */
|
||||||
|
/** @typedef {import("./override-tester")["OverrideTester"]} OverrideTester */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ConfigArrayElement
|
||||||
|
* @property {string} name The name of this config element.
|
||||||
|
* @property {string} filePath The path to the source file of this config element.
|
||||||
|
* @property {InstanceType<OverrideTester>|null} criteria The tester for the `files` and `excludedFiles` of this config element.
|
||||||
|
* @property {Record<string, boolean>|undefined} env The environment settings.
|
||||||
|
* @property {Record<string, GlobalConf>|undefined} globals The global variable settings.
|
||||||
|
* @property {IgnorePattern|undefined} ignorePattern The ignore patterns.
|
||||||
|
* @property {boolean|undefined} noInlineConfig The flag that disables directive comments.
|
||||||
|
* @property {DependentParser|undefined} parser The parser loader.
|
||||||
|
* @property {Object|undefined} parserOptions The parser options.
|
||||||
|
* @property {Record<string, DependentPlugin>|undefined} plugins The plugin loaders.
|
||||||
|
* @property {string|undefined} processor The processor name to refer plugin's processor.
|
||||||
|
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
|
||||||
|
* @property {boolean|undefined} root The flag to express root.
|
||||||
|
* @property {Record<string, RuleConf>|undefined} rules The rule settings
|
||||||
|
* @property {Object|undefined} settings The shared settings.
|
||||||
|
* @property {"config" | "ignore" | "implicit-processor"} type The element type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ConfigArrayInternalSlots
|
||||||
|
* @property {Map<string, ExtractedConfig>} cache The cache to extract configs.
|
||||||
|
* @property {ReadonlyMap<string, Environment>|null} envMap The map from environment ID to environment definition.
|
||||||
|
* @property {ReadonlyMap<string, Processor>|null} processorMap The map from processor ID to environment definition.
|
||||||
|
* @property {ReadonlyMap<string, Rule>|null} ruleMap The map from rule ID to rule definition.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {WeakMap<ConfigArray, ConfigArrayInternalSlots>} */
|
||||||
|
const internalSlotsMap = new class extends WeakMap {
|
||||||
|
get(key) {
|
||||||
|
let value = super.get(key);
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
value = {
|
||||||
|
cache: new Map(),
|
||||||
|
envMap: null,
|
||||||
|
processorMap: null,
|
||||||
|
ruleMap: null
|
||||||
|
};
|
||||||
|
super.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the indices which are matched to a given file.
|
||||||
|
* @param {ConfigArrayElement[]} elements The elements.
|
||||||
|
* @param {string} filePath The path to a target file.
|
||||||
|
* @returns {number[]} The indices.
|
||||||
|
*/
|
||||||
|
function getMatchedIndices(elements, filePath) {
|
||||||
|
const indices = [];
|
||||||
|
|
||||||
|
for (let i = elements.length - 1; i >= 0; --i) {
|
||||||
|
const element = elements[i];
|
||||||
|
|
||||||
|
if (!element.criteria || (filePath && element.criteria.test(filePath))) {
|
||||||
|
indices.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is a non-null object.
|
||||||
|
* @param {any} x The value to check.
|
||||||
|
* @returns {boolean} `true` if the value is a non-null object.
|
||||||
|
*/
|
||||||
|
function isNonNullObject(x) {
|
||||||
|
return typeof x === "object" && x !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge two objects.
|
||||||
|
*
|
||||||
|
* Assign every property values of `y` to `x` if `x` doesn't have the property.
|
||||||
|
* If `x`'s property value is an object, it does recursive.
|
||||||
|
* @param {Object} target The destination to merge
|
||||||
|
* @param {Object|undefined} source The source to merge.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function mergeWithoutOverwrite(target, source) {
|
||||||
|
if (!isNonNullObject(source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key of Object.keys(source)) {
|
||||||
|
if (key === "__proto__") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNonNullObject(target[key])) {
|
||||||
|
mergeWithoutOverwrite(target[key], source[key]);
|
||||||
|
} else if (target[key] === void 0) {
|
||||||
|
if (isNonNullObject(source[key])) {
|
||||||
|
target[key] = Array.isArray(source[key]) ? [] : {};
|
||||||
|
mergeWithoutOverwrite(target[key], source[key]);
|
||||||
|
} else if (source[key] !== void 0) {
|
||||||
|
target[key] = source[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error for plugin conflicts.
|
||||||
|
*/
|
||||||
|
class PluginConflictError extends Error {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this error object.
|
||||||
|
* @param {string} pluginId The plugin ID.
|
||||||
|
* @param {{filePath:string, importerName:string}[]} plugins The resolved plugins.
|
||||||
|
*/
|
||||||
|
constructor(pluginId, plugins) {
|
||||||
|
super(`Plugin "${pluginId}" was conflicted between ${plugins.map(p => `"${p.importerName}"`).join(" and ")}.`);
|
||||||
|
this.messageTemplate = "plugin-conflict";
|
||||||
|
this.messageData = { pluginId, plugins };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge plugins.
|
||||||
|
* `target`'s definition is prior to `source`'s.
|
||||||
|
* @param {Record<string, DependentPlugin>} target The destination to merge
|
||||||
|
* @param {Record<string, DependentPlugin>|undefined} source The source to merge.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function mergePlugins(target, source) {
|
||||||
|
if (!isNonNullObject(source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key of Object.keys(source)) {
|
||||||
|
if (key === "__proto__") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const targetValue = target[key];
|
||||||
|
const sourceValue = source[key];
|
||||||
|
|
||||||
|
// Adopt the plugin which was found at first.
|
||||||
|
if (targetValue === void 0) {
|
||||||
|
if (sourceValue.error) {
|
||||||
|
throw sourceValue.error;
|
||||||
|
}
|
||||||
|
target[key] = sourceValue;
|
||||||
|
} else if (sourceValue.filePath !== targetValue.filePath) {
|
||||||
|
throw new PluginConflictError(key, [
|
||||||
|
{
|
||||||
|
filePath: targetValue.filePath,
|
||||||
|
importerName: targetValue.importerName
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filePath: sourceValue.filePath,
|
||||||
|
importerName: sourceValue.importerName
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge rule configs.
|
||||||
|
* `target`'s definition is prior to `source`'s.
|
||||||
|
* @param {Record<string, Array>} target The destination to merge
|
||||||
|
* @param {Record<string, RuleConf>|undefined} source The source to merge.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function mergeRuleConfigs(target, source) {
|
||||||
|
if (!isNonNullObject(source)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key of Object.keys(source)) {
|
||||||
|
if (key === "__proto__") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const targetDef = target[key];
|
||||||
|
const sourceDef = source[key];
|
||||||
|
|
||||||
|
// Adopt the rule config which was found at first.
|
||||||
|
if (targetDef === void 0) {
|
||||||
|
if (Array.isArray(sourceDef)) {
|
||||||
|
target[key] = [...sourceDef];
|
||||||
|
} else {
|
||||||
|
target[key] = [sourceDef];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the first found rule config is severity only and the current rule
|
||||||
|
* config has options, merge the severity and the options.
|
||||||
|
*/
|
||||||
|
} else if (
|
||||||
|
targetDef.length === 1 &&
|
||||||
|
Array.isArray(sourceDef) &&
|
||||||
|
sourceDef.length >= 2
|
||||||
|
) {
|
||||||
|
targetDef.push(...sourceDef.slice(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the extracted config.
|
||||||
|
* @param {ConfigArray} instance The config elements.
|
||||||
|
* @param {number[]} indices The indices to use.
|
||||||
|
* @returns {ExtractedConfig} The extracted config.
|
||||||
|
*/
|
||||||
|
function createConfig(instance, indices) {
|
||||||
|
const config = new ExtractedConfig();
|
||||||
|
const ignorePatterns = [];
|
||||||
|
|
||||||
|
// Merge elements.
|
||||||
|
for (const index of indices) {
|
||||||
|
const element = instance[index];
|
||||||
|
|
||||||
|
// Adopt the parser which was found at first.
|
||||||
|
if (!config.parser && element.parser) {
|
||||||
|
if (element.parser.error) {
|
||||||
|
throw element.parser.error;
|
||||||
|
}
|
||||||
|
config.parser = element.parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adopt the processor which was found at first.
|
||||||
|
if (!config.processor && element.processor) {
|
||||||
|
config.processor = element.processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adopt the noInlineConfig which was found at first.
|
||||||
|
if (config.noInlineConfig === void 0 && element.noInlineConfig !== void 0) {
|
||||||
|
config.noInlineConfig = element.noInlineConfig;
|
||||||
|
config.configNameOfNoInlineConfig = element.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adopt the reportUnusedDisableDirectives which was found at first.
|
||||||
|
if (config.reportUnusedDisableDirectives === void 0 && element.reportUnusedDisableDirectives !== void 0) {
|
||||||
|
config.reportUnusedDisableDirectives = element.reportUnusedDisableDirectives;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect ignorePatterns
|
||||||
|
if (element.ignorePattern) {
|
||||||
|
ignorePatterns.push(element.ignorePattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge others.
|
||||||
|
mergeWithoutOverwrite(config.env, element.env);
|
||||||
|
mergeWithoutOverwrite(config.globals, element.globals);
|
||||||
|
mergeWithoutOverwrite(config.parserOptions, element.parserOptions);
|
||||||
|
mergeWithoutOverwrite(config.settings, element.settings);
|
||||||
|
mergePlugins(config.plugins, element.plugins);
|
||||||
|
mergeRuleConfigs(config.rules, element.rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the predicate function for ignore patterns.
|
||||||
|
if (ignorePatterns.length > 0) {
|
||||||
|
config.ignores = IgnorePattern.createIgnore(ignorePatterns.reverse());
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect definitions.
|
||||||
|
* @template T, U
|
||||||
|
* @param {string} pluginId The plugin ID for prefix.
|
||||||
|
* @param {Record<string,T>} defs The definitions to collect.
|
||||||
|
* @param {Map<string, U>} map The map to output.
|
||||||
|
* @param {function(T): U} [normalize] The normalize function for each value.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function collect(pluginId, defs, map, normalize) {
|
||||||
|
if (defs) {
|
||||||
|
const prefix = pluginId && `${pluginId}/`;
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(defs)) {
|
||||||
|
map.set(
|
||||||
|
`${prefix}${key}`,
|
||||||
|
normalize ? normalize(value) : value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a rule definition.
|
||||||
|
* @param {Function|Rule} rule The rule definition to normalize.
|
||||||
|
* @returns {Rule} The normalized rule definition.
|
||||||
|
*/
|
||||||
|
function normalizePluginRule(rule) {
|
||||||
|
return typeof rule === "function" ? { create: rule } : rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the mutation methods from a given map.
|
||||||
|
* @param {Map<any, any>} map The map object to delete.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function deleteMutationMethods(map) {
|
||||||
|
Object.defineProperties(map, {
|
||||||
|
clear: { configurable: true, value: void 0 },
|
||||||
|
delete: { configurable: true, value: void 0 },
|
||||||
|
set: { configurable: true, value: void 0 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create `envMap`, `processorMap`, `ruleMap` with the plugins in the config array.
|
||||||
|
* @param {ConfigArrayElement[]} elements The config elements.
|
||||||
|
* @param {ConfigArrayInternalSlots} slots The internal slots.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function initPluginMemberMaps(elements, slots) {
|
||||||
|
const processed = new Set();
|
||||||
|
|
||||||
|
slots.envMap = new Map();
|
||||||
|
slots.processorMap = new Map();
|
||||||
|
slots.ruleMap = new Map();
|
||||||
|
|
||||||
|
for (const element of elements) {
|
||||||
|
if (!element.plugins) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [pluginId, value] of Object.entries(element.plugins)) {
|
||||||
|
const plugin = value.definition;
|
||||||
|
|
||||||
|
if (!plugin || processed.has(pluginId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
processed.add(pluginId);
|
||||||
|
|
||||||
|
collect(pluginId, plugin.environments, slots.envMap);
|
||||||
|
collect(pluginId, plugin.processors, slots.processorMap);
|
||||||
|
collect(pluginId, plugin.rules, slots.ruleMap, normalizePluginRule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteMutationMethods(slots.envMap);
|
||||||
|
deleteMutationMethods(slots.processorMap);
|
||||||
|
deleteMutationMethods(slots.ruleMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create `envMap`, `processorMap`, `ruleMap` with the plugins in the config array.
|
||||||
|
* @param {ConfigArray} instance The config elements.
|
||||||
|
* @returns {ConfigArrayInternalSlots} The extracted config.
|
||||||
|
*/
|
||||||
|
function ensurePluginMemberMaps(instance) {
|
||||||
|
const slots = internalSlotsMap.get(instance);
|
||||||
|
|
||||||
|
if (!slots.ruleMap) {
|
||||||
|
initPluginMemberMaps(instance, slots);
|
||||||
|
}
|
||||||
|
|
||||||
|
return slots;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Config Array.
|
||||||
|
*
|
||||||
|
* `ConfigArray` instance contains all settings, parsers, and plugins.
|
||||||
|
* You need to call `ConfigArray#extractConfig(filePath)` method in order to
|
||||||
|
* extract, merge and get only the config data which is related to an arbitrary
|
||||||
|
* file.
|
||||||
|
* @extends {Array<ConfigArrayElement>}
|
||||||
|
*/
|
||||||
|
class ConfigArray extends Array {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin environments.
|
||||||
|
* The returned map cannot be mutated.
|
||||||
|
* @type {ReadonlyMap<string, Environment>} The plugin environments.
|
||||||
|
*/
|
||||||
|
get pluginEnvironments() {
|
||||||
|
return ensurePluginMemberMaps(this).envMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin processors.
|
||||||
|
* The returned map cannot be mutated.
|
||||||
|
* @type {ReadonlyMap<string, Processor>} The plugin processors.
|
||||||
|
*/
|
||||||
|
get pluginProcessors() {
|
||||||
|
return ensurePluginMemberMaps(this).processorMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin rules.
|
||||||
|
* The returned map cannot be mutated.
|
||||||
|
* @returns {ReadonlyMap<string, Rule>} The plugin rules.
|
||||||
|
*/
|
||||||
|
get pluginRules() {
|
||||||
|
return ensurePluginMemberMaps(this).ruleMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this config has `root` flag.
|
||||||
|
* @returns {boolean} `true` if this config array is root.
|
||||||
|
*/
|
||||||
|
isRoot() {
|
||||||
|
for (let i = this.length - 1; i >= 0; --i) {
|
||||||
|
const root = this[i].root;
|
||||||
|
|
||||||
|
if (typeof root === "boolean") {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the config data which is related to a given file.
|
||||||
|
* @param {string} filePath The absolute path to the target file.
|
||||||
|
* @returns {ExtractedConfig} The extracted config data.
|
||||||
|
*/
|
||||||
|
extractConfig(filePath) {
|
||||||
|
const { cache } = internalSlotsMap.get(this);
|
||||||
|
const indices = getMatchedIndices(this, filePath);
|
||||||
|
const cacheKey = indices.join(",");
|
||||||
|
|
||||||
|
if (!cache.has(cacheKey)) {
|
||||||
|
cache.set(cacheKey, createConfig(this, indices));
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache.get(cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given path is an additional lint target.
|
||||||
|
* @param {string} filePath The absolute path to the target file.
|
||||||
|
* @returns {boolean} `true` if the file is an additional lint target.
|
||||||
|
*/
|
||||||
|
isAdditionalTargetPath(filePath) {
|
||||||
|
for (const { criteria, type } of this) {
|
||||||
|
if (
|
||||||
|
type === "config" &&
|
||||||
|
criteria &&
|
||||||
|
!criteria.endsWithWildcard &&
|
||||||
|
criteria.test(filePath)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the used extracted configs.
|
||||||
|
* CLIEngine will use this method to collect used deprecated rules.
|
||||||
|
* @param {ConfigArray} instance The config array object to get.
|
||||||
|
* @returns {ExtractedConfig[]} The used extracted configs.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function getUsedExtractedConfigs(instance) {
|
||||||
|
const { cache } = internalSlotsMap.get(instance);
|
||||||
|
|
||||||
|
return Array.from(cache.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export {
|
||||||
|
ConfigArray,
|
||||||
|
getUsedExtractedConfigs
|
||||||
|
};
|
115
node_modules/@eslint/eslintrc/lib/config-array/config-dependency.js
generated
vendored
Normal file
115
node_modules/@eslint/eslintrc/lib/config-array/config-dependency.js
generated
vendored
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview `ConfigDependency` class.
|
||||||
|
*
|
||||||
|
* `ConfigDependency` class expresses a loaded parser or plugin.
|
||||||
|
*
|
||||||
|
* If the parser or plugin was loaded successfully, it has `definition` property
|
||||||
|
* and `filePath` property. Otherwise, it has `error` property.
|
||||||
|
*
|
||||||
|
* When `JSON.stringify()` converted a `ConfigDependency` object to a JSON, it
|
||||||
|
* omits `definition` property.
|
||||||
|
*
|
||||||
|
* `ConfigArrayFactory` creates `ConfigDependency` objects when it loads parsers
|
||||||
|
* or plugins.
|
||||||
|
*
|
||||||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import util from "util";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class is to store parsers or plugins.
|
||||||
|
* This class hides the loaded object from `JSON.stringify()` and `console.log`.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
class ConfigDependency {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this instance.
|
||||||
|
* @param {Object} data The dependency data.
|
||||||
|
* @param {T} [data.definition] The dependency if the loading succeeded.
|
||||||
|
* @param {Error} [data.error] The error object if the loading failed.
|
||||||
|
* @param {string} [data.filePath] The actual path to the dependency if the loading succeeded.
|
||||||
|
* @param {string} data.id The ID of this dependency.
|
||||||
|
* @param {string} data.importerName The name of the config file which loads this dependency.
|
||||||
|
* @param {string} data.importerPath The path to the config file which loads this dependency.
|
||||||
|
*/
|
||||||
|
constructor({
|
||||||
|
definition = null,
|
||||||
|
error = null,
|
||||||
|
filePath = null,
|
||||||
|
id,
|
||||||
|
importerName,
|
||||||
|
importerPath
|
||||||
|
}) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The loaded dependency if the loading succeeded.
|
||||||
|
* @type {T|null}
|
||||||
|
*/
|
||||||
|
this.definition = definition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error object if the loading failed.
|
||||||
|
* @type {Error|null}
|
||||||
|
*/
|
||||||
|
this.error = error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The loaded dependency if the loading succeeded.
|
||||||
|
* @type {string|null}
|
||||||
|
*/
|
||||||
|
this.filePath = filePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ID of this dependency.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.id = id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the config file which loads this dependency.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.importerName = importerName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the config file which loads this dependency.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.importerPath = importerPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line jsdoc/require-description
|
||||||
|
/**
|
||||||
|
* @returns {Object} a JSON compatible object.
|
||||||
|
*/
|
||||||
|
toJSON() {
|
||||||
|
const obj = this[util.inspect.custom]();
|
||||||
|
|
||||||
|
// Display `error.message` (`Error#message` is unenumerable).
|
||||||
|
if (obj.error instanceof Error) {
|
||||||
|
obj.error = { ...obj.error, message: obj.error.message };
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line jsdoc/require-description
|
||||||
|
/**
|
||||||
|
* @returns {Object} an object to display by `console.log()`.
|
||||||
|
*/
|
||||||
|
[util.inspect.custom]() {
|
||||||
|
const {
|
||||||
|
definition: _ignore, // eslint-disable-line no-unused-vars
|
||||||
|
...obj
|
||||||
|
} = this;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @typedef {ConfigDependency<import("../../shared/types").Parser>} DependentParser */
|
||||||
|
/** @typedef {ConfigDependency<import("../../shared/types").Plugin>} DependentPlugin */
|
||||||
|
|
||||||
|
export { ConfigDependency };
|
145
node_modules/@eslint/eslintrc/lib/config-array/extracted-config.js
generated
vendored
Normal file
145
node_modules/@eslint/eslintrc/lib/config-array/extracted-config.js
generated
vendored
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview `ExtractedConfig` class.
|
||||||
|
*
|
||||||
|
* `ExtractedConfig` class expresses a final configuration for a specific file.
|
||||||
|
*
|
||||||
|
* It provides one method.
|
||||||
|
*
|
||||||
|
* - `toCompatibleObjectAsConfigFileContent()`
|
||||||
|
* Convert this configuration to the compatible object as the content of
|
||||||
|
* config files. It converts the loaded parser and plugins to strings.
|
||||||
|
* `CLIEngine#getConfigForFile(filePath)` method uses this method.
|
||||||
|
*
|
||||||
|
* `ConfigArray#extractConfig(filePath)` creates a `ExtractedConfig` instance.
|
||||||
|
*
|
||||||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { IgnorePattern } from "./ignore-pattern.js";
|
||||||
|
|
||||||
|
// For VSCode intellisense
|
||||||
|
/** @typedef {import("../../shared/types").ConfigData} ConfigData */
|
||||||
|
/** @typedef {import("../../shared/types").GlobalConf} GlobalConf */
|
||||||
|
/** @typedef {import("../../shared/types").SeverityConf} SeverityConf */
|
||||||
|
/** @typedef {import("./config-dependency").DependentParser} DependentParser */
|
||||||
|
/** @typedef {import("./config-dependency").DependentPlugin} DependentPlugin */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if `xs` starts with `ys`.
|
||||||
|
* @template T
|
||||||
|
* @param {T[]} xs The array to check.
|
||||||
|
* @param {T[]} ys The array that may be the first part of `xs`.
|
||||||
|
* @returns {boolean} `true` if `xs` starts with `ys`.
|
||||||
|
*/
|
||||||
|
function startsWith(xs, ys) {
|
||||||
|
return xs.length >= ys.length && ys.every((y, i) => y === xs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class for extracted config data.
|
||||||
|
*/
|
||||||
|
class ExtractedConfig {
|
||||||
|
constructor() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The config name what `noInlineConfig` setting came from.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.configNameOfNoInlineConfig = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Environments.
|
||||||
|
* @type {Record<string, boolean>}
|
||||||
|
*/
|
||||||
|
this.env = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global variables.
|
||||||
|
* @type {Record<string, GlobalConf>}
|
||||||
|
*/
|
||||||
|
this.globals = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The glob patterns that ignore to lint.
|
||||||
|
* @type {(((filePath:string, dot?:boolean) => boolean) & { basePath:string; patterns:string[] }) | undefined}
|
||||||
|
*/
|
||||||
|
this.ignores = void 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The flag that disables directive comments.
|
||||||
|
* @type {boolean|undefined}
|
||||||
|
*/
|
||||||
|
this.noInlineConfig = void 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser definition.
|
||||||
|
* @type {DependentParser|null}
|
||||||
|
*/
|
||||||
|
this.parser = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for the parser.
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
this.parserOptions = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin definitions.
|
||||||
|
* @type {Record<string, DependentPlugin>}
|
||||||
|
*/
|
||||||
|
this.plugins = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processor ID.
|
||||||
|
* @type {string|null}
|
||||||
|
*/
|
||||||
|
this.processor = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The flag that reports unused `eslint-disable` directive comments.
|
||||||
|
* @type {boolean|undefined}
|
||||||
|
*/
|
||||||
|
this.reportUnusedDisableDirectives = void 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rule settings.
|
||||||
|
* @type {Record<string, [SeverityConf, ...any[]]>}
|
||||||
|
*/
|
||||||
|
this.rules = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared settings.
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
this.settings = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert this config to the compatible object as a config file content.
|
||||||
|
* @returns {ConfigData} The converted object.
|
||||||
|
*/
|
||||||
|
toCompatibleObjectAsConfigFileContent() {
|
||||||
|
const {
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
configNameOfNoInlineConfig: _ignore1,
|
||||||
|
processor: _ignore2,
|
||||||
|
/* eslint-enable no-unused-vars */
|
||||||
|
ignores,
|
||||||
|
...config
|
||||||
|
} = this;
|
||||||
|
|
||||||
|
config.parser = config.parser && config.parser.filePath;
|
||||||
|
config.plugins = Object.keys(config.plugins).filter(Boolean).reverse();
|
||||||
|
config.ignorePatterns = ignores ? ignores.patterns : [];
|
||||||
|
|
||||||
|
// Strip the default patterns from `ignorePatterns`.
|
||||||
|
if (startsWith(config.ignorePatterns, IgnorePattern.DefaultPatterns)) {
|
||||||
|
config.ignorePatterns =
|
||||||
|
config.ignorePatterns.slice(IgnorePattern.DefaultPatterns.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ExtractedConfig };
|
238
node_modules/@eslint/eslintrc/lib/config-array/ignore-pattern.js
generated
vendored
Normal file
238
node_modules/@eslint/eslintrc/lib/config-array/ignore-pattern.js
generated
vendored
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview `IgnorePattern` class.
|
||||||
|
*
|
||||||
|
* `IgnorePattern` class has the set of glob patterns and the base path.
|
||||||
|
*
|
||||||
|
* It provides two static methods.
|
||||||
|
*
|
||||||
|
* - `IgnorePattern.createDefaultIgnore(cwd)`
|
||||||
|
* Create the default predicate function.
|
||||||
|
* - `IgnorePattern.createIgnore(ignorePatterns)`
|
||||||
|
* Create the predicate function from multiple `IgnorePattern` objects.
|
||||||
|
*
|
||||||
|
* It provides two properties and a method.
|
||||||
|
*
|
||||||
|
* - `patterns`
|
||||||
|
* The glob patterns that ignore to lint.
|
||||||
|
* - `basePath`
|
||||||
|
* The base path of the glob patterns. If absolute paths existed in the
|
||||||
|
* glob patterns, those are handled as relative paths to the base path.
|
||||||
|
* - `getPatternsRelativeTo(basePath)`
|
||||||
|
* Get `patterns` as modified for a given base path. It modifies the
|
||||||
|
* absolute paths in the patterns as prepending the difference of two base
|
||||||
|
* paths.
|
||||||
|
*
|
||||||
|
* `ConfigArrayFactory` creates `IgnorePattern` objects when it processes
|
||||||
|
* `ignorePatterns` properties.
|
||||||
|
*
|
||||||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import assert from "assert";
|
||||||
|
import path from "path";
|
||||||
|
import ignore from "ignore";
|
||||||
|
import debugOrig from "debug";
|
||||||
|
|
||||||
|
const debug = debugOrig("eslintrc:ignore-pattern");
|
||||||
|
|
||||||
|
/** @typedef {ReturnType<import("ignore").default>} Ignore */
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path to the common ancestor directory of given paths.
|
||||||
|
* @param {string[]} sourcePaths The paths to calculate the common ancestor.
|
||||||
|
* @returns {string} The path to the common ancestor directory.
|
||||||
|
*/
|
||||||
|
function getCommonAncestorPath(sourcePaths) {
|
||||||
|
let result = sourcePaths[0];
|
||||||
|
|
||||||
|
for (let i = 1; i < sourcePaths.length; ++i) {
|
||||||
|
const a = result;
|
||||||
|
const b = sourcePaths[i];
|
||||||
|
|
||||||
|
// Set the shorter one (it's the common ancestor if one includes the other).
|
||||||
|
result = a.length < b.length ? a : b;
|
||||||
|
|
||||||
|
// Set the common ancestor.
|
||||||
|
for (let j = 0, lastSepPos = 0; j < a.length && j < b.length; ++j) {
|
||||||
|
if (a[j] !== b[j]) {
|
||||||
|
result = a.slice(0, lastSepPos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (a[j] === path.sep) {
|
||||||
|
lastSepPos = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let resolvedResult = result || path.sep;
|
||||||
|
|
||||||
|
// if Windows common ancestor is root of drive must have trailing slash to be absolute.
|
||||||
|
if (resolvedResult && resolvedResult.endsWith(":") && process.platform === "win32") {
|
||||||
|
resolvedResult += path.sep;
|
||||||
|
}
|
||||||
|
return resolvedResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make relative path.
|
||||||
|
* @param {string} from The source path to get relative path.
|
||||||
|
* @param {string} to The destination path to get relative path.
|
||||||
|
* @returns {string} The relative path.
|
||||||
|
*/
|
||||||
|
function relative(from, to) {
|
||||||
|
const relPath = path.relative(from, to);
|
||||||
|
|
||||||
|
if (path.sep === "/") {
|
||||||
|
return relPath;
|
||||||
|
}
|
||||||
|
return relPath.split(path.sep).join("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the trailing slash if existed.
|
||||||
|
* @param {string} filePath The path to check.
|
||||||
|
* @returns {string} The trailing slash if existed.
|
||||||
|
*/
|
||||||
|
function dirSuffix(filePath) {
|
||||||
|
const isDir = (
|
||||||
|
filePath.endsWith(path.sep) ||
|
||||||
|
(process.platform === "win32" && filePath.endsWith("/"))
|
||||||
|
);
|
||||||
|
|
||||||
|
return isDir ? "/" : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const DefaultPatterns = Object.freeze(["/**/node_modules/*"]);
|
||||||
|
const DotPatterns = Object.freeze([".*", "!.eslintrc.*", "!../"]);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class IgnorePattern {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default patterns.
|
||||||
|
* @type {string[]}
|
||||||
|
*/
|
||||||
|
static get DefaultPatterns() {
|
||||||
|
return DefaultPatterns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the default predicate function.
|
||||||
|
* @param {string} cwd The current working directory.
|
||||||
|
* @returns {((filePath:string, dot:boolean) => boolean) & {basePath:string; patterns:string[]}}
|
||||||
|
* The preficate function.
|
||||||
|
* The first argument is an absolute path that is checked.
|
||||||
|
* The second argument is the flag to not ignore dotfiles.
|
||||||
|
* If the predicate function returned `true`, it means the path should be ignored.
|
||||||
|
*/
|
||||||
|
static createDefaultIgnore(cwd) {
|
||||||
|
return this.createIgnore([new IgnorePattern(DefaultPatterns, cwd)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the predicate function from multiple `IgnorePattern` objects.
|
||||||
|
* @param {IgnorePattern[]} ignorePatterns The list of ignore patterns.
|
||||||
|
* @returns {((filePath:string, dot?:boolean) => boolean) & {basePath:string; patterns:string[]}}
|
||||||
|
* The preficate function.
|
||||||
|
* The first argument is an absolute path that is checked.
|
||||||
|
* The second argument is the flag to not ignore dotfiles.
|
||||||
|
* If the predicate function returned `true`, it means the path should be ignored.
|
||||||
|
*/
|
||||||
|
static createIgnore(ignorePatterns) {
|
||||||
|
debug("Create with: %o", ignorePatterns);
|
||||||
|
|
||||||
|
const basePath = getCommonAncestorPath(ignorePatterns.map(p => p.basePath));
|
||||||
|
const patterns = [].concat(
|
||||||
|
...ignorePatterns.map(p => p.getPatternsRelativeTo(basePath))
|
||||||
|
);
|
||||||
|
const ig = ignore().add([...DotPatterns, ...patterns]);
|
||||||
|
const dotIg = ignore().add(patterns);
|
||||||
|
|
||||||
|
debug(" processed: %o", { basePath, patterns });
|
||||||
|
|
||||||
|
return Object.assign(
|
||||||
|
(filePath, dot = false) => {
|
||||||
|
assert(path.isAbsolute(filePath), "'filePath' should be an absolute path.");
|
||||||
|
const relPathRaw = relative(basePath, filePath);
|
||||||
|
const relPath = relPathRaw && (relPathRaw + dirSuffix(filePath));
|
||||||
|
const adoptedIg = dot ? dotIg : ig;
|
||||||
|
const result = relPath !== "" && adoptedIg.ignores(relPath);
|
||||||
|
|
||||||
|
debug("Check", { filePath, dot, relativePath: relPath, result });
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
{ basePath, patterns }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `IgnorePattern` instance.
|
||||||
|
* @param {string[]} patterns The glob patterns that ignore to lint.
|
||||||
|
* @param {string} basePath The base path of `patterns`.
|
||||||
|
*/
|
||||||
|
constructor(patterns, basePath) {
|
||||||
|
assert(path.isAbsolute(basePath), "'basePath' should be an absolute path.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The glob patterns that ignore to lint.
|
||||||
|
* @type {string[]}
|
||||||
|
*/
|
||||||
|
this.patterns = patterns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base path of `patterns`.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.basePath = basePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `true` then patterns which don't start with `/` will match the paths to the outside of `basePath`. Defaults to `false`.
|
||||||
|
*
|
||||||
|
* It's set `true` for `.eslintignore`, `package.json`, and `--ignore-path` for backward compatibility.
|
||||||
|
* It's `false` as-is for `ignorePatterns` property in config files.
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
this.loose = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get `patterns` as modified for a given base path. It modifies the
|
||||||
|
* absolute paths in the patterns as prepending the difference of two base
|
||||||
|
* paths.
|
||||||
|
* @param {string} newBasePath The base path.
|
||||||
|
* @returns {string[]} Modifired patterns.
|
||||||
|
*/
|
||||||
|
getPatternsRelativeTo(newBasePath) {
|
||||||
|
assert(path.isAbsolute(newBasePath), "'newBasePath' should be an absolute path.");
|
||||||
|
const { basePath, loose, patterns } = this;
|
||||||
|
|
||||||
|
if (newBasePath === basePath) {
|
||||||
|
return patterns;
|
||||||
|
}
|
||||||
|
const prefix = `/${relative(newBasePath, basePath)}`;
|
||||||
|
|
||||||
|
return patterns.map(pattern => {
|
||||||
|
const negative = pattern.startsWith("!");
|
||||||
|
const head = negative ? "!" : "";
|
||||||
|
const body = negative ? pattern.slice(1) : pattern;
|
||||||
|
|
||||||
|
if (body.startsWith("/") || body.startsWith("../")) {
|
||||||
|
return `${head}${prefix}${body}`;
|
||||||
|
}
|
||||||
|
return loose ? pattern : `${head}${prefix}/**/${body}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { IgnorePattern };
|
19
node_modules/@eslint/eslintrc/lib/config-array/index.js
generated
vendored
Normal file
19
node_modules/@eslint/eslintrc/lib/config-array/index.js
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview `ConfigArray` class.
|
||||||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ConfigArray, getUsedExtractedConfigs } from "./config-array.js";
|
||||||
|
import { ConfigDependency } from "./config-dependency.js";
|
||||||
|
import { ExtractedConfig } from "./extracted-config.js";
|
||||||
|
import { IgnorePattern } from "./ignore-pattern.js";
|
||||||
|
import { OverrideTester } from "./override-tester.js";
|
||||||
|
|
||||||
|
export {
|
||||||
|
ConfigArray,
|
||||||
|
ConfigDependency,
|
||||||
|
ExtractedConfig,
|
||||||
|
IgnorePattern,
|
||||||
|
OverrideTester,
|
||||||
|
getUsedExtractedConfigs
|
||||||
|
};
|
225
node_modules/@eslint/eslintrc/lib/config-array/override-tester.js
generated
vendored
Normal file
225
node_modules/@eslint/eslintrc/lib/config-array/override-tester.js
generated
vendored
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview `OverrideTester` class.
|
||||||
|
*
|
||||||
|
* `OverrideTester` class handles `files` property and `excludedFiles` property
|
||||||
|
* of `overrides` config.
|
||||||
|
*
|
||||||
|
* It provides one method.
|
||||||
|
*
|
||||||
|
* - `test(filePath)`
|
||||||
|
* Test if a file path matches the pair of `files` property and
|
||||||
|
* `excludedFiles` property. The `filePath` argument must be an absolute
|
||||||
|
* path.
|
||||||
|
*
|
||||||
|
* `ConfigArrayFactory` creates `OverrideTester` objects when it processes
|
||||||
|
* `overrides` properties.
|
||||||
|
*
|
||||||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import assert from "assert";
|
||||||
|
import path from "path";
|
||||||
|
import util from "util";
|
||||||
|
import minimatch from "minimatch";
|
||||||
|
|
||||||
|
const { Minimatch } = minimatch;
|
||||||
|
|
||||||
|
const minimatchOpts = { dot: true, matchBase: true };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Pattern
|
||||||
|
* @property {InstanceType<Minimatch>[] | null} includes The positive matchers.
|
||||||
|
* @property {InstanceType<Minimatch>[] | null} excludes The negative matchers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a given pattern to an array.
|
||||||
|
* @param {string|string[]|undefined} patterns A glob pattern or an array of glob patterns.
|
||||||
|
* @returns {string[]|null} Normalized patterns.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function normalizePatterns(patterns) {
|
||||||
|
if (Array.isArray(patterns)) {
|
||||||
|
return patterns.filter(Boolean);
|
||||||
|
}
|
||||||
|
if (typeof patterns === "string" && patterns) {
|
||||||
|
return [patterns];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the matchers of given patterns.
|
||||||
|
* @param {string[]} patterns The patterns.
|
||||||
|
* @returns {InstanceType<Minimatch>[] | null} The matchers.
|
||||||
|
*/
|
||||||
|
function toMatcher(patterns) {
|
||||||
|
if (patterns.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return patterns.map(pattern => {
|
||||||
|
if (/^\.[/\\]/u.test(pattern)) {
|
||||||
|
return new Minimatch(
|
||||||
|
pattern.slice(2),
|
||||||
|
|
||||||
|
// `./*.js` should not match with `subdir/foo.js`
|
||||||
|
{ ...minimatchOpts, matchBase: false }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return new Minimatch(pattern, minimatchOpts);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a given matcher to string.
|
||||||
|
* @param {Pattern} matchers The matchers.
|
||||||
|
* @returns {string} The string expression of the matcher.
|
||||||
|
*/
|
||||||
|
function patternToJson({ includes, excludes }) {
|
||||||
|
return {
|
||||||
|
includes: includes && includes.map(m => m.pattern),
|
||||||
|
excludes: excludes && excludes.map(m => m.pattern)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class to test given paths are matched by the patterns.
|
||||||
|
*/
|
||||||
|
class OverrideTester {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a tester with given criteria.
|
||||||
|
* If there are no criteria, returns `null`.
|
||||||
|
* @param {string|string[]} files The glob patterns for included files.
|
||||||
|
* @param {string|string[]} excludedFiles The glob patterns for excluded files.
|
||||||
|
* @param {string} basePath The path to the base directory to test paths.
|
||||||
|
* @returns {OverrideTester|null} The created instance or `null`.
|
||||||
|
*/
|
||||||
|
static create(files, excludedFiles, basePath) {
|
||||||
|
const includePatterns = normalizePatterns(files);
|
||||||
|
const excludePatterns = normalizePatterns(excludedFiles);
|
||||||
|
let endsWithWildcard = false;
|
||||||
|
|
||||||
|
if (includePatterns.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rejects absolute paths or relative paths to parents.
|
||||||
|
for (const pattern of includePatterns) {
|
||||||
|
if (path.isAbsolute(pattern) || pattern.includes("..")) {
|
||||||
|
throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`);
|
||||||
|
}
|
||||||
|
if (pattern.endsWith("*")) {
|
||||||
|
endsWithWildcard = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const pattern of excludePatterns) {
|
||||||
|
if (path.isAbsolute(pattern) || pattern.includes("..")) {
|
||||||
|
throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const includes = toMatcher(includePatterns);
|
||||||
|
const excludes = toMatcher(excludePatterns);
|
||||||
|
|
||||||
|
return new OverrideTester(
|
||||||
|
[{ includes, excludes }],
|
||||||
|
basePath,
|
||||||
|
endsWithWildcard
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine two testers by logical and.
|
||||||
|
* If either of the testers was `null`, returns the other tester.
|
||||||
|
* The `basePath` property of the two must be the same value.
|
||||||
|
* @param {OverrideTester|null} a A tester.
|
||||||
|
* @param {OverrideTester|null} b Another tester.
|
||||||
|
* @returns {OverrideTester|null} Combined tester.
|
||||||
|
*/
|
||||||
|
static and(a, b) {
|
||||||
|
if (!b) {
|
||||||
|
return a && new OverrideTester(
|
||||||
|
a.patterns,
|
||||||
|
a.basePath,
|
||||||
|
a.endsWithWildcard
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!a) {
|
||||||
|
return new OverrideTester(
|
||||||
|
b.patterns,
|
||||||
|
b.basePath,
|
||||||
|
b.endsWithWildcard
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.strictEqual(a.basePath, b.basePath);
|
||||||
|
return new OverrideTester(
|
||||||
|
a.patterns.concat(b.patterns),
|
||||||
|
a.basePath,
|
||||||
|
a.endsWithWildcard || b.endsWithWildcard
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this instance.
|
||||||
|
* @param {Pattern[]} patterns The matchers.
|
||||||
|
* @param {string} basePath The base path.
|
||||||
|
* @param {boolean} endsWithWildcard If `true` then a pattern ends with `*`.
|
||||||
|
*/
|
||||||
|
constructor(patterns, basePath, endsWithWildcard = false) {
|
||||||
|
|
||||||
|
/** @type {Pattern[]} */
|
||||||
|
this.patterns = patterns;
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
this.basePath = basePath;
|
||||||
|
|
||||||
|
/** @type {boolean} */
|
||||||
|
this.endsWithWildcard = endsWithWildcard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if a given path is matched or not.
|
||||||
|
* @param {string} filePath The absolute path to the target file.
|
||||||
|
* @returns {boolean} `true` if the path was matched.
|
||||||
|
*/
|
||||||
|
test(filePath) {
|
||||||
|
if (typeof filePath !== "string" || !path.isAbsolute(filePath)) {
|
||||||
|
throw new Error(`'filePath' should be an absolute path, but got ${filePath}.`);
|
||||||
|
}
|
||||||
|
const relativePath = path.relative(this.basePath, filePath);
|
||||||
|
|
||||||
|
return this.patterns.every(({ includes, excludes }) => (
|
||||||
|
(!includes || includes.some(m => m.match(relativePath))) &&
|
||||||
|
(!excludes || !excludes.some(m => m.match(relativePath)))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line jsdoc/require-description
|
||||||
|
/**
|
||||||
|
* @returns {Object} a JSON compatible object.
|
||||||
|
*/
|
||||||
|
toJSON() {
|
||||||
|
if (this.patterns.length === 1) {
|
||||||
|
return {
|
||||||
|
...patternToJson(this.patterns[0]),
|
||||||
|
basePath: this.basePath
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
AND: this.patterns.map(patternToJson),
|
||||||
|
basePath: this.basePath
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line jsdoc/require-description
|
||||||
|
/**
|
||||||
|
* @returns {Object} an object to display by `console.log()`.
|
||||||
|
*/
|
||||||
|
[util.inspect.custom]() {
|
||||||
|
return this.toJSON();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { OverrideTester };
|
310
node_modules/@eslint/eslintrc/lib/flat-compat.js
generated
vendored
Normal file
310
node_modules/@eslint/eslintrc/lib/flat-compat.js
generated
vendored
Normal file
|
@ -0,0 +1,310 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Compatibility class for flat config.
|
||||||
|
* @author Nicholas C. Zakas
|
||||||
|
*/
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import path from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
import createDebug from "debug";
|
||||||
|
|
||||||
|
import { ConfigArrayFactory } from "./config-array-factory.js";
|
||||||
|
import environments from "../conf/environments.js";
|
||||||
|
|
||||||
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** @typedef {import("../../shared/types").Environment} Environment */
|
||||||
|
/** @typedef {import("../../shared/types").Processor} Processor */
|
||||||
|
|
||||||
|
const debug = createDebug("eslintrc:flat-compat");
|
||||||
|
const cafactory = Symbol("cafactory");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates an ESLintRC-style config object into a flag-config-style config
|
||||||
|
* object.
|
||||||
|
* @param {Object} eslintrcConfig An ESLintRC-style config object.
|
||||||
|
* @param {Object} options Options to help translate the config.
|
||||||
|
* @param {string} options.resolveConfigRelativeTo To the directory to resolve
|
||||||
|
* configs from.
|
||||||
|
* @param {string} options.resolvePluginsRelativeTo The directory to resolve
|
||||||
|
* plugins from.
|
||||||
|
* @param {ReadOnlyMap<string,Environment>} options.pluginEnvironments A map of plugin environment
|
||||||
|
* names to objects.
|
||||||
|
* @param {ReadOnlyMap<string,Processor>} options.pluginProcessors A map of plugin processor
|
||||||
|
* names to objects.
|
||||||
|
* @returns {Object} A flag-config-style config object.
|
||||||
|
*/
|
||||||
|
function translateESLintRC(eslintrcConfig, {
|
||||||
|
resolveConfigRelativeTo,
|
||||||
|
resolvePluginsRelativeTo,
|
||||||
|
pluginEnvironments,
|
||||||
|
pluginProcessors
|
||||||
|
}) {
|
||||||
|
|
||||||
|
const flatConfig = {};
|
||||||
|
const configs = [];
|
||||||
|
const languageOptions = {};
|
||||||
|
const linterOptions = {};
|
||||||
|
const keysToCopy = ["settings", "rules", "processor"];
|
||||||
|
const languageOptionsKeysToCopy = ["globals", "parser", "parserOptions"];
|
||||||
|
const linterOptionsKeysToCopy = ["noInlineConfig", "reportUnusedDisableDirectives"];
|
||||||
|
|
||||||
|
// check for special settings for eslint:all and eslint:recommended:
|
||||||
|
if (eslintrcConfig.settings) {
|
||||||
|
if (eslintrcConfig.settings["eslint:all"] === true) {
|
||||||
|
return ["eslint:all"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eslintrcConfig.settings["eslint:recommended"] === true) {
|
||||||
|
return ["eslint:recommended"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy over simple translations
|
||||||
|
for (const key of keysToCopy) {
|
||||||
|
if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") {
|
||||||
|
flatConfig[key] = eslintrcConfig[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy over languageOptions
|
||||||
|
for (const key of languageOptionsKeysToCopy) {
|
||||||
|
if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") {
|
||||||
|
|
||||||
|
// create the languageOptions key in the flat config
|
||||||
|
flatConfig.languageOptions = languageOptions;
|
||||||
|
|
||||||
|
if (key === "parser") {
|
||||||
|
debug(`Resolving parser '${languageOptions[key]}' relative to ${resolveConfigRelativeTo}`);
|
||||||
|
|
||||||
|
if (eslintrcConfig[key].error) {
|
||||||
|
throw eslintrcConfig[key].error;
|
||||||
|
}
|
||||||
|
|
||||||
|
languageOptions[key] = eslintrcConfig[key].definition;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clone any object values that are in the eslintrc config
|
||||||
|
if (eslintrcConfig[key] && typeof eslintrcConfig[key] === "object") {
|
||||||
|
languageOptions[key] = {
|
||||||
|
...eslintrcConfig[key]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
languageOptions[key] = eslintrcConfig[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy over linterOptions
|
||||||
|
for (const key of linterOptionsKeysToCopy) {
|
||||||
|
if (key in eslintrcConfig && typeof eslintrcConfig[key] !== "undefined") {
|
||||||
|
flatConfig.linterOptions = linterOptions;
|
||||||
|
linterOptions[key] = eslintrcConfig[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move ecmaVersion a level up
|
||||||
|
if (languageOptions.parserOptions) {
|
||||||
|
|
||||||
|
if ("ecmaVersion" in languageOptions.parserOptions) {
|
||||||
|
languageOptions.ecmaVersion = languageOptions.parserOptions.ecmaVersion;
|
||||||
|
delete languageOptions.parserOptions.ecmaVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("sourceType" in languageOptions.parserOptions) {
|
||||||
|
languageOptions.sourceType = languageOptions.parserOptions.sourceType;
|
||||||
|
delete languageOptions.parserOptions.sourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to see if we even need parserOptions anymore and remove it if not
|
||||||
|
if (Object.keys(languageOptions.parserOptions).length === 0) {
|
||||||
|
delete languageOptions.parserOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// overrides
|
||||||
|
if (eslintrcConfig.criteria) {
|
||||||
|
flatConfig.files = [absoluteFilePath => eslintrcConfig.criteria.test(absoluteFilePath)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// translate plugins
|
||||||
|
if (eslintrcConfig.plugins && typeof eslintrcConfig.plugins === "object") {
|
||||||
|
debug(`Translating plugins: ${eslintrcConfig.plugins}`);
|
||||||
|
|
||||||
|
flatConfig.plugins = {};
|
||||||
|
|
||||||
|
for (const pluginName of Object.keys(eslintrcConfig.plugins)) {
|
||||||
|
|
||||||
|
debug(`Translating plugin: ${pluginName}`);
|
||||||
|
debug(`Resolving plugin '${pluginName} relative to ${resolvePluginsRelativeTo}`);
|
||||||
|
|
||||||
|
const { definition: plugin, error } = eslintrcConfig.plugins[pluginName];
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatConfig.plugins[pluginName] = plugin;
|
||||||
|
|
||||||
|
// create a config for any processors
|
||||||
|
if (plugin.processors) {
|
||||||
|
for (const processorName of Object.keys(plugin.processors)) {
|
||||||
|
if (processorName.startsWith(".")) {
|
||||||
|
debug(`Assigning processor: ${pluginName}/${processorName}`);
|
||||||
|
|
||||||
|
configs.unshift({
|
||||||
|
files: [`**/*${processorName}`],
|
||||||
|
processor: pluginProcessors.get(`${pluginName}/${processorName}`)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// translate env - must come after plugins
|
||||||
|
if (eslintrcConfig.env && typeof eslintrcConfig.env === "object") {
|
||||||
|
for (const envName of Object.keys(eslintrcConfig.env)) {
|
||||||
|
|
||||||
|
// only add environments that are true
|
||||||
|
if (eslintrcConfig.env[envName]) {
|
||||||
|
debug(`Translating environment: ${envName}`);
|
||||||
|
|
||||||
|
if (environments.has(envName)) {
|
||||||
|
|
||||||
|
// built-in environments should be defined first
|
||||||
|
configs.unshift(...translateESLintRC(environments.get(envName), {
|
||||||
|
resolveConfigRelativeTo,
|
||||||
|
resolvePluginsRelativeTo
|
||||||
|
}));
|
||||||
|
} else if (pluginEnvironments.has(envName)) {
|
||||||
|
|
||||||
|
// if the environment comes from a plugin, it should come after the plugin config
|
||||||
|
configs.push(...translateESLintRC(pluginEnvironments.get(envName), {
|
||||||
|
resolveConfigRelativeTo,
|
||||||
|
resolvePluginsRelativeTo
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only add if there are actually keys in the config
|
||||||
|
if (Object.keys(flatConfig).length > 0) {
|
||||||
|
configs.push(flatConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Exports
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A compatibility class for working with configs.
|
||||||
|
*/
|
||||||
|
class FlatCompat {
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
baseDirectory = process.cwd(),
|
||||||
|
resolvePluginsRelativeTo = baseDirectory
|
||||||
|
} = {}) {
|
||||||
|
this.baseDirectory = baseDirectory;
|
||||||
|
this.resolvePluginsRelativeTo = resolvePluginsRelativeTo;
|
||||||
|
this[cafactory] = new ConfigArrayFactory({
|
||||||
|
cwd: baseDirectory,
|
||||||
|
resolvePluginsRelativeTo,
|
||||||
|
eslintAllPath: path.resolve(dirname, "../conf/eslint-all.cjs"),
|
||||||
|
eslintRecommendedPath: path.resolve(dirname, "../conf/eslint-recommended.cjs")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates an ESLintRC-style config into a flag-config-style config.
|
||||||
|
* @param {Object} eslintrcConfig The ESLintRC-style config object.
|
||||||
|
* @returns {Object} A flag-config-style config object.
|
||||||
|
*/
|
||||||
|
config(eslintrcConfig) {
|
||||||
|
const eslintrcArray = this[cafactory].create(eslintrcConfig, {
|
||||||
|
basePath: this.baseDirectory
|
||||||
|
});
|
||||||
|
|
||||||
|
const flatArray = [];
|
||||||
|
let hasIgnorePatterns = false;
|
||||||
|
|
||||||
|
eslintrcArray.forEach(configData => {
|
||||||
|
if (configData.type === "config") {
|
||||||
|
hasIgnorePatterns = hasIgnorePatterns || configData.ignorePattern;
|
||||||
|
flatArray.push(...translateESLintRC(configData, {
|
||||||
|
resolveConfigRelativeTo: path.join(this.baseDirectory, "__placeholder.js"),
|
||||||
|
resolvePluginsRelativeTo: path.join(this.resolvePluginsRelativeTo, "__placeholder.js"),
|
||||||
|
pluginEnvironments: eslintrcArray.pluginEnvironments,
|
||||||
|
pluginProcessors: eslintrcArray.pluginProcessors
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// combine ignorePatterns to emulate ESLintRC behavior better
|
||||||
|
if (hasIgnorePatterns) {
|
||||||
|
flatArray.unshift({
|
||||||
|
ignores: [filePath => {
|
||||||
|
|
||||||
|
// Compute the final config for this file.
|
||||||
|
// This filters config array elements by `files`/`excludedFiles` then merges the elements.
|
||||||
|
const finalConfig = eslintrcArray.extractConfig(filePath);
|
||||||
|
|
||||||
|
// Test the `ignorePattern` properties of the final config.
|
||||||
|
return Boolean(finalConfig.ignores) && finalConfig.ignores(filePath);
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return flatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates the `env` section of an ESLintRC-style config.
|
||||||
|
* @param {Object} envConfig The `env` section of an ESLintRC config.
|
||||||
|
* @returns {Object} A flag-config object representing the environments.
|
||||||
|
*/
|
||||||
|
env(envConfig) {
|
||||||
|
return this.config({
|
||||||
|
env: envConfig
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates the `extends` section of an ESLintRC-style config.
|
||||||
|
* @param {...string} configsToExtend The names of the configs to load.
|
||||||
|
* @returns {Object} A flag-config object representing the config.
|
||||||
|
*/
|
||||||
|
extends(...configsToExtend) {
|
||||||
|
return this.config({
|
||||||
|
extends: configsToExtend
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates the `plugins` section of an ESLintRC-style config.
|
||||||
|
* @param {...string} plugins The names of the plugins to load.
|
||||||
|
* @returns {Object} A flag-config object representing the plugins.
|
||||||
|
*/
|
||||||
|
plugins(...plugins) {
|
||||||
|
return this.config({
|
||||||
|
plugins
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { FlatCompat };
|
29
node_modules/@eslint/eslintrc/lib/index-universal.js
generated
vendored
Normal file
29
node_modules/@eslint/eslintrc/lib/index-universal.js
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Package exports for @eslint/eslintrc
|
||||||
|
* @author Nicholas C. Zakas
|
||||||
|
*/
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import * as ConfigOps from "./shared/config-ops.js";
|
||||||
|
import ConfigValidator from "./shared/config-validator.js";
|
||||||
|
import * as naming from "./shared/naming.js";
|
||||||
|
import environments from "../conf/environments.js";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Exports
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Legacy = {
|
||||||
|
environments,
|
||||||
|
|
||||||
|
// shared
|
||||||
|
ConfigOps,
|
||||||
|
ConfigValidator,
|
||||||
|
naming
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
Legacy
|
||||||
|
};
|
56
node_modules/@eslint/eslintrc/lib/index.js
generated
vendored
Normal file
56
node_modules/@eslint/eslintrc/lib/index.js
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Package exports for @eslint/eslintrc
|
||||||
|
* @author Nicholas C. Zakas
|
||||||
|
*/
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import {
|
||||||
|
ConfigArrayFactory,
|
||||||
|
createContext as createConfigArrayFactoryContext
|
||||||
|
} from "./config-array-factory.js";
|
||||||
|
|
||||||
|
import { CascadingConfigArrayFactory } from "./cascading-config-array-factory.js";
|
||||||
|
import * as ModuleResolver from "./shared/relative-module-resolver.js";
|
||||||
|
import { ConfigArray, getUsedExtractedConfigs } from "./config-array/index.js";
|
||||||
|
import { ConfigDependency } from "./config-array/config-dependency.js";
|
||||||
|
import { ExtractedConfig } from "./config-array/extracted-config.js";
|
||||||
|
import { IgnorePattern } from "./config-array/ignore-pattern.js";
|
||||||
|
import { OverrideTester } from "./config-array/override-tester.js";
|
||||||
|
import * as ConfigOps from "./shared/config-ops.js";
|
||||||
|
import ConfigValidator from "./shared/config-validator.js";
|
||||||
|
import * as naming from "./shared/naming.js";
|
||||||
|
import { FlatCompat } from "./flat-compat.js";
|
||||||
|
import environments from "../conf/environments.js";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Exports
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Legacy = {
|
||||||
|
ConfigArray,
|
||||||
|
createConfigArrayFactoryContext,
|
||||||
|
CascadingConfigArrayFactory,
|
||||||
|
ConfigArrayFactory,
|
||||||
|
ConfigDependency,
|
||||||
|
ExtractedConfig,
|
||||||
|
IgnorePattern,
|
||||||
|
OverrideTester,
|
||||||
|
getUsedExtractedConfigs,
|
||||||
|
environments,
|
||||||
|
|
||||||
|
// shared
|
||||||
|
ConfigOps,
|
||||||
|
ConfigValidator,
|
||||||
|
ModuleResolver,
|
||||||
|
naming
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
|
||||||
|
Legacy,
|
||||||
|
|
||||||
|
FlatCompat
|
||||||
|
|
||||||
|
};
|
191
node_modules/@eslint/eslintrc/lib/shared/ajv.js
generated
vendored
Normal file
191
node_modules/@eslint/eslintrc/lib/shared/ajv.js
generated
vendored
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview The instance of Ajv validator.
|
||||||
|
* @author Evgeny Poberezkin
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import Ajv from "ajv";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copied from ajv/lib/refs/json-schema-draft-04.json
|
||||||
|
* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2015-2017 Evgeny Poberezkin
|
||||||
|
*/
|
||||||
|
const metaSchema = {
|
||||||
|
id: "http://json-schema.org/draft-04/schema#",
|
||||||
|
$schema: "http://json-schema.org/draft-04/schema#",
|
||||||
|
description: "Core schema meta-schema",
|
||||||
|
definitions: {
|
||||||
|
schemaArray: {
|
||||||
|
type: "array",
|
||||||
|
minItems: 1,
|
||||||
|
items: { $ref: "#" }
|
||||||
|
},
|
||||||
|
positiveInteger: {
|
||||||
|
type: "integer",
|
||||||
|
minimum: 0
|
||||||
|
},
|
||||||
|
positiveIntegerDefault0: {
|
||||||
|
allOf: [{ $ref: "#/definitions/positiveInteger" }, { default: 0 }]
|
||||||
|
},
|
||||||
|
simpleTypes: {
|
||||||
|
enum: ["array", "boolean", "integer", "null", "number", "object", "string"]
|
||||||
|
},
|
||||||
|
stringArray: {
|
||||||
|
type: "array",
|
||||||
|
items: { type: "string" },
|
||||||
|
minItems: 1,
|
||||||
|
uniqueItems: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: "string"
|
||||||
|
},
|
||||||
|
$schema: {
|
||||||
|
type: "string"
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: "string"
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: "string"
|
||||||
|
},
|
||||||
|
default: { },
|
||||||
|
multipleOf: {
|
||||||
|
type: "number",
|
||||||
|
minimum: 0,
|
||||||
|
exclusiveMinimum: true
|
||||||
|
},
|
||||||
|
maximum: {
|
||||||
|
type: "number"
|
||||||
|
},
|
||||||
|
exclusiveMaximum: {
|
||||||
|
type: "boolean",
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
minimum: {
|
||||||
|
type: "number"
|
||||||
|
},
|
||||||
|
exclusiveMinimum: {
|
||||||
|
type: "boolean",
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
maxLength: { $ref: "#/definitions/positiveInteger" },
|
||||||
|
minLength: { $ref: "#/definitions/positiveIntegerDefault0" },
|
||||||
|
pattern: {
|
||||||
|
type: "string",
|
||||||
|
format: "regex"
|
||||||
|
},
|
||||||
|
additionalItems: {
|
||||||
|
anyOf: [
|
||||||
|
{ type: "boolean" },
|
||||||
|
{ $ref: "#" }
|
||||||
|
],
|
||||||
|
default: { }
|
||||||
|
},
|
||||||
|
items: {
|
||||||
|
anyOf: [
|
||||||
|
{ $ref: "#" },
|
||||||
|
{ $ref: "#/definitions/schemaArray" }
|
||||||
|
],
|
||||||
|
default: { }
|
||||||
|
},
|
||||||
|
maxItems: { $ref: "#/definitions/positiveInteger" },
|
||||||
|
minItems: { $ref: "#/definitions/positiveIntegerDefault0" },
|
||||||
|
uniqueItems: {
|
||||||
|
type: "boolean",
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
maxProperties: { $ref: "#/definitions/positiveInteger" },
|
||||||
|
minProperties: { $ref: "#/definitions/positiveIntegerDefault0" },
|
||||||
|
required: { $ref: "#/definitions/stringArray" },
|
||||||
|
additionalProperties: {
|
||||||
|
anyOf: [
|
||||||
|
{ type: "boolean" },
|
||||||
|
{ $ref: "#" }
|
||||||
|
],
|
||||||
|
default: { }
|
||||||
|
},
|
||||||
|
definitions: {
|
||||||
|
type: "object",
|
||||||
|
additionalProperties: { $ref: "#" },
|
||||||
|
default: { }
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
type: "object",
|
||||||
|
additionalProperties: { $ref: "#" },
|
||||||
|
default: { }
|
||||||
|
},
|
||||||
|
patternProperties: {
|
||||||
|
type: "object",
|
||||||
|
additionalProperties: { $ref: "#" },
|
||||||
|
default: { }
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
type: "object",
|
||||||
|
additionalProperties: {
|
||||||
|
anyOf: [
|
||||||
|
{ $ref: "#" },
|
||||||
|
{ $ref: "#/definitions/stringArray" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enum: {
|
||||||
|
type: "array",
|
||||||
|
minItems: 1,
|
||||||
|
uniqueItems: true
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
anyOf: [
|
||||||
|
{ $ref: "#/definitions/simpleTypes" },
|
||||||
|
{
|
||||||
|
type: "array",
|
||||||
|
items: { $ref: "#/definitions/simpleTypes" },
|
||||||
|
minItems: 1,
|
||||||
|
uniqueItems: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
format: { type: "string" },
|
||||||
|
allOf: { $ref: "#/definitions/schemaArray" },
|
||||||
|
anyOf: { $ref: "#/definitions/schemaArray" },
|
||||||
|
oneOf: { $ref: "#/definitions/schemaArray" },
|
||||||
|
not: { $ref: "#" }
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
exclusiveMaximum: ["maximum"],
|
||||||
|
exclusiveMinimum: ["minimum"]
|
||||||
|
},
|
||||||
|
default: { }
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export default (additionalOptions = {}) => {
|
||||||
|
const ajv = new Ajv({
|
||||||
|
meta: false,
|
||||||
|
useDefaults: true,
|
||||||
|
validateSchema: false,
|
||||||
|
missingRefs: "ignore",
|
||||||
|
verbose: true,
|
||||||
|
schemaId: "auto",
|
||||||
|
...additionalOptions
|
||||||
|
});
|
||||||
|
|
||||||
|
ajv.addMetaSchema(metaSchema);
|
||||||
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
|
ajv._opts.defaultMeta = metaSchema.id;
|
||||||
|
|
||||||
|
return ajv;
|
||||||
|
};
|
135
node_modules/@eslint/eslintrc/lib/shared/config-ops.js
generated
vendored
Normal file
135
node_modules/@eslint/eslintrc/lib/shared/config-ops.js
generated
vendored
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Config file operations. This file must be usable in the browser,
|
||||||
|
* so no Node-specific code can be here.
|
||||||
|
* @author Nicholas C. Zakas
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Private
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const RULE_SEVERITY_STRINGS = ["off", "warn", "error"],
|
||||||
|
RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => {
|
||||||
|
map[value] = index;
|
||||||
|
return map;
|
||||||
|
}, {}),
|
||||||
|
VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"];
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the severity value of a rule's configuration to a number
|
||||||
|
* @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally
|
||||||
|
* received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0),
|
||||||
|
* the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array
|
||||||
|
* whose first element is one of the above values. Strings are matched case-insensitively.
|
||||||
|
* @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0.
|
||||||
|
*/
|
||||||
|
function getRuleSeverity(ruleConfig) {
|
||||||
|
const severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
|
||||||
|
|
||||||
|
if (severityValue === 0 || severityValue === 1 || severityValue === 2) {
|
||||||
|
return severityValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof severityValue === "string") {
|
||||||
|
return RULE_SEVERITY[severityValue.toLowerCase()] || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts old-style severity settings (0, 1, 2) into new-style
|
||||||
|
* severity settings (off, warn, error) for all rules. Assumption is that severity
|
||||||
|
* values have already been validated as correct.
|
||||||
|
* @param {Object} config The config object to normalize.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function normalizeToStrings(config) {
|
||||||
|
|
||||||
|
if (config.rules) {
|
||||||
|
Object.keys(config.rules).forEach(ruleId => {
|
||||||
|
const ruleConfig = config.rules[ruleId];
|
||||||
|
|
||||||
|
if (typeof ruleConfig === "number") {
|
||||||
|
config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0];
|
||||||
|
} else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") {
|
||||||
|
ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the severity for the given rule configuration represents an error.
|
||||||
|
* @param {int|string|Array} ruleConfig The configuration for an individual rule.
|
||||||
|
* @returns {boolean} True if the rule represents an error, false if not.
|
||||||
|
*/
|
||||||
|
function isErrorSeverity(ruleConfig) {
|
||||||
|
return getRuleSeverity(ruleConfig) === 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given config has valid severity or not.
|
||||||
|
* @param {number|string|Array} ruleConfig The configuration for an individual rule.
|
||||||
|
* @returns {boolean} `true` if the configuration has valid severity.
|
||||||
|
*/
|
||||||
|
function isValidSeverity(ruleConfig) {
|
||||||
|
let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
|
||||||
|
|
||||||
|
if (typeof severity === "string") {
|
||||||
|
severity = severity.toLowerCase();
|
||||||
|
}
|
||||||
|
return VALID_SEVERITIES.indexOf(severity) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether every rule of a given config has valid severity or not.
|
||||||
|
* @param {Object} config The configuration for rules.
|
||||||
|
* @returns {boolean} `true` if the configuration has valid severity.
|
||||||
|
*/
|
||||||
|
function isEverySeverityValid(config) {
|
||||||
|
return Object.keys(config).every(ruleId => isValidSeverity(config[ruleId]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a value for a global in a config
|
||||||
|
* @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in
|
||||||
|
* a global directive comment
|
||||||
|
* @returns {("readable"|"writeable"|"off")} The value normalized as a string
|
||||||
|
* @throws Error if global value is invalid
|
||||||
|
*/
|
||||||
|
function normalizeConfigGlobal(configuredValue) {
|
||||||
|
switch (configuredValue) {
|
||||||
|
case "off":
|
||||||
|
return "off";
|
||||||
|
|
||||||
|
case true:
|
||||||
|
case "true":
|
||||||
|
case "writeable":
|
||||||
|
case "writable":
|
||||||
|
return "writable";
|
||||||
|
|
||||||
|
case null:
|
||||||
|
case false:
|
||||||
|
case "false":
|
||||||
|
case "readable":
|
||||||
|
case "readonly":
|
||||||
|
return "readonly";
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getRuleSeverity,
|
||||||
|
normalizeToStrings,
|
||||||
|
isErrorSeverity,
|
||||||
|
isValidSeverity,
|
||||||
|
isEverySeverityValid,
|
||||||
|
normalizeConfigGlobal
|
||||||
|
};
|
325
node_modules/@eslint/eslintrc/lib/shared/config-validator.js
generated
vendored
Normal file
325
node_modules/@eslint/eslintrc/lib/shared/config-validator.js
generated
vendored
Normal file
|
@ -0,0 +1,325 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Validates configs.
|
||||||
|
* @author Brandon Mills
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint class-methods-use-this: "off" */
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import util from "util";
|
||||||
|
import * as ConfigOps from "./config-ops.js";
|
||||||
|
import { emitDeprecationWarning } from "./deprecation-warnings.js";
|
||||||
|
import ajvOrig from "./ajv.js";
|
||||||
|
import configSchema from "../../conf/config-schema.js";
|
||||||
|
import BuiltInEnvironments from "../../conf/environments.js";
|
||||||
|
|
||||||
|
const ajv = ajvOrig();
|
||||||
|
|
||||||
|
const ruleValidators = new WeakMap();
|
||||||
|
const noop = Function.prototype;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Private
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
let validateSchema;
|
||||||
|
const severityMap = {
|
||||||
|
error: 2,
|
||||||
|
warn: 1,
|
||||||
|
off: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
const validated = new WeakSet();
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Exports
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export default class ConfigValidator {
|
||||||
|
constructor({ builtInRules = new Map() } = {}) {
|
||||||
|
this.builtInRules = builtInRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a complete options schema for a rule.
|
||||||
|
* @param {{create: Function, schema: (Array|null)}} rule A new-style rule object
|
||||||
|
* @returns {Object} JSON Schema for the rule's options.
|
||||||
|
*/
|
||||||
|
getRuleOptionsSchema(rule) {
|
||||||
|
if (!rule) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const schema = rule.schema || rule.meta && rule.meta.schema;
|
||||||
|
|
||||||
|
// Given a tuple of schemas, insert warning level at the beginning
|
||||||
|
if (Array.isArray(schema)) {
|
||||||
|
if (schema.length) {
|
||||||
|
return {
|
||||||
|
type: "array",
|
||||||
|
items: schema,
|
||||||
|
minItems: 0,
|
||||||
|
maxItems: schema.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: "array",
|
||||||
|
minItems: 0,
|
||||||
|
maxItems: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a full schema, leave it alone
|
||||||
|
return schema || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid.
|
||||||
|
* @param {options} options The given options for the rule.
|
||||||
|
* @returns {number|string} The rule's severity value
|
||||||
|
*/
|
||||||
|
validateRuleSeverity(options) {
|
||||||
|
const severity = Array.isArray(options) ? options[0] : options;
|
||||||
|
const normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity;
|
||||||
|
|
||||||
|
if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) {
|
||||||
|
return normSeverity;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the non-severity options passed to a rule, based on its schema.
|
||||||
|
* @param {{create: Function}} rule The rule to validate
|
||||||
|
* @param {Array} localOptions The options for the rule, excluding severity
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validateRuleSchema(rule, localOptions) {
|
||||||
|
if (!ruleValidators.has(rule)) {
|
||||||
|
const schema = this.getRuleOptionsSchema(rule);
|
||||||
|
|
||||||
|
if (schema) {
|
||||||
|
ruleValidators.set(rule, ajv.compile(schema));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateRule = ruleValidators.get(rule);
|
||||||
|
|
||||||
|
if (validateRule) {
|
||||||
|
validateRule(localOptions);
|
||||||
|
if (validateRule.errors) {
|
||||||
|
throw new Error(validateRule.errors.map(
|
||||||
|
error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n`
|
||||||
|
).join(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a rule's options against its schema.
|
||||||
|
* @param {{create: Function}|null} rule The rule that the config is being validated for
|
||||||
|
* @param {string} ruleId The rule's unique name.
|
||||||
|
* @param {Array|number} options The given options for the rule.
|
||||||
|
* @param {string|null} source The name of the configuration source to report in any errors. If null or undefined,
|
||||||
|
* no source is prepended to the message.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validateRuleOptions(rule, ruleId, options, source = null) {
|
||||||
|
try {
|
||||||
|
const severity = this.validateRuleSeverity(options);
|
||||||
|
|
||||||
|
if (severity !== 0) {
|
||||||
|
this.validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`;
|
||||||
|
|
||||||
|
if (typeof source === "string") {
|
||||||
|
throw new Error(`${source}:\n\t${enhancedMessage}`);
|
||||||
|
} else {
|
||||||
|
throw new Error(enhancedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates an environment object
|
||||||
|
* @param {Object} environment The environment config object to validate.
|
||||||
|
* @param {string} source The name of the configuration source to report in any errors.
|
||||||
|
* @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validateEnvironment(
|
||||||
|
environment,
|
||||||
|
source,
|
||||||
|
getAdditionalEnv = noop
|
||||||
|
) {
|
||||||
|
|
||||||
|
// not having an environment is ok
|
||||||
|
if (!environment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(environment).forEach(id => {
|
||||||
|
const env = getAdditionalEnv(id) || BuiltInEnvironments.get(id) || null;
|
||||||
|
|
||||||
|
if (!env) {
|
||||||
|
const message = `${source}:\n\tEnvironment key "${id}" is unknown\n`;
|
||||||
|
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a rules config object
|
||||||
|
* @param {Object} rulesConfig The rules config object to validate.
|
||||||
|
* @param {string} source The name of the configuration source to report in any errors.
|
||||||
|
* @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validateRules(
|
||||||
|
rulesConfig,
|
||||||
|
source,
|
||||||
|
getAdditionalRule = noop
|
||||||
|
) {
|
||||||
|
if (!rulesConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(rulesConfig).forEach(id => {
|
||||||
|
const rule = getAdditionalRule(id) || this.builtInRules.get(id) || null;
|
||||||
|
|
||||||
|
this.validateRuleOptions(rule, id, rulesConfig[id], source);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a `globals` section of a config file
|
||||||
|
* @param {Object} globalsConfig The `globals` section
|
||||||
|
* @param {string|null} source The name of the configuration source to report in the event of an error.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validateGlobals(globalsConfig, source = null) {
|
||||||
|
if (!globalsConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.entries(globalsConfig)
|
||||||
|
.forEach(([configuredGlobal, configuredValue]) => {
|
||||||
|
try {
|
||||||
|
ConfigOps.normalizeConfigGlobal(configuredValue);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate `processor` configuration.
|
||||||
|
* @param {string|undefined} processorName The processor name.
|
||||||
|
* @param {string} source The name of config file.
|
||||||
|
* @param {function(id:string): Processor} getProcessor The getter of defined processors.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validateProcessor(processorName, source, getProcessor) {
|
||||||
|
if (processorName && !getProcessor(processorName)) {
|
||||||
|
throw new Error(`ESLint configuration of processor in '${source}' is invalid: '${processorName}' was not found.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats an array of schema validation errors.
|
||||||
|
* @param {Array} errors An array of error messages to format.
|
||||||
|
* @returns {string} Formatted error message
|
||||||
|
*/
|
||||||
|
formatErrors(errors) {
|
||||||
|
return errors.map(error => {
|
||||||
|
if (error.keyword === "additionalProperties") {
|
||||||
|
const formattedPropertyPath = error.dataPath.length ? `${error.dataPath.slice(1)}.${error.params.additionalProperty}` : error.params.additionalProperty;
|
||||||
|
|
||||||
|
return `Unexpected top-level property "${formattedPropertyPath}"`;
|
||||||
|
}
|
||||||
|
if (error.keyword === "type") {
|
||||||
|
const formattedField = error.dataPath.slice(1);
|
||||||
|
const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema;
|
||||||
|
const formattedValue = JSON.stringify(error.data);
|
||||||
|
|
||||||
|
return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath;
|
||||||
|
|
||||||
|
return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`;
|
||||||
|
}).map(message => `\t- ${message}.\n`).join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the top level properties of the config object.
|
||||||
|
* @param {Object} config The config object to validate.
|
||||||
|
* @param {string} source The name of the configuration source to report in any errors.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validateConfigSchema(config, source = null) {
|
||||||
|
validateSchema = validateSchema || ajv.compile(configSchema);
|
||||||
|
|
||||||
|
if (!validateSchema(config)) {
|
||||||
|
throw new Error(`ESLint configuration in ${source} is invalid:\n${this.formatErrors(validateSchema.errors)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.hasOwnProperty.call(config, "ecmaFeatures")) {
|
||||||
|
emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates an entire config object.
|
||||||
|
* @param {Object} config The config object to validate.
|
||||||
|
* @param {string} source The name of the configuration source to report in any errors.
|
||||||
|
* @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules.
|
||||||
|
* @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validate(config, source, getAdditionalRule, getAdditionalEnv) {
|
||||||
|
this.validateConfigSchema(config, source);
|
||||||
|
this.validateRules(config.rules, source, getAdditionalRule);
|
||||||
|
this.validateEnvironment(config.env, source, getAdditionalEnv);
|
||||||
|
this.validateGlobals(config.globals, source);
|
||||||
|
|
||||||
|
for (const override of config.overrides || []) {
|
||||||
|
this.validateRules(override.rules, source, getAdditionalRule);
|
||||||
|
this.validateEnvironment(override.env, source, getAdditionalEnv);
|
||||||
|
this.validateGlobals(config.globals, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate config array object.
|
||||||
|
* @param {ConfigArray} configArray The config array to validate.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
validateConfigArray(configArray) {
|
||||||
|
const getPluginEnv = Map.prototype.get.bind(configArray.pluginEnvironments);
|
||||||
|
const getPluginProcessor = Map.prototype.get.bind(configArray.pluginProcessors);
|
||||||
|
const getPluginRule = Map.prototype.get.bind(configArray.pluginRules);
|
||||||
|
|
||||||
|
// Validate.
|
||||||
|
for (const element of configArray) {
|
||||||
|
if (validated.has(element)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
validated.add(element);
|
||||||
|
|
||||||
|
this.validateEnvironment(element.env, element.name, getPluginEnv);
|
||||||
|
this.validateGlobals(element.globals, element.name);
|
||||||
|
this.validateProcessor(element.processor, element.name, getPluginProcessor);
|
||||||
|
this.validateRules(element.rules, element.name, getPluginRule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
63
node_modules/@eslint/eslintrc/lib/shared/deprecation-warnings.js
generated
vendored
Normal file
63
node_modules/@eslint/eslintrc/lib/shared/deprecation-warnings.js
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Provide the function that emits deprecation warnings.
|
||||||
|
* @author Toru Nagashima <http://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Private
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Defitions for deprecation warnings.
|
||||||
|
const deprecationWarningMessages = {
|
||||||
|
ESLINT_LEGACY_ECMAFEATURES:
|
||||||
|
"The 'ecmaFeatures' config file property is deprecated and has no effect.",
|
||||||
|
ESLINT_PERSONAL_CONFIG_LOAD:
|
||||||
|
"'~/.eslintrc.*' config files have been deprecated. " +
|
||||||
|
"Please use a config file per project or the '--config' option.",
|
||||||
|
ESLINT_PERSONAL_CONFIG_SUPPRESS:
|
||||||
|
"'~/.eslintrc.*' config files have been deprecated. " +
|
||||||
|
"Please remove it or add 'root:true' to the config files in your " +
|
||||||
|
"projects in order to avoid loading '~/.eslintrc.*' accidentally."
|
||||||
|
};
|
||||||
|
|
||||||
|
const sourceFileErrorCache = new Set();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted
|
||||||
|
* for each unique file path, but repeated invocations with the same file path have no effect.
|
||||||
|
* No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active.
|
||||||
|
* @param {string} source The name of the configuration source to report the warning for.
|
||||||
|
* @param {string} errorCode The warning message to show.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function emitDeprecationWarning(source, errorCode) {
|
||||||
|
const cacheKey = JSON.stringify({ source, errorCode });
|
||||||
|
|
||||||
|
if (sourceFileErrorCache.has(cacheKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sourceFileErrorCache.add(cacheKey);
|
||||||
|
|
||||||
|
const rel = path.relative(process.cwd(), source);
|
||||||
|
const message = deprecationWarningMessages[errorCode];
|
||||||
|
|
||||||
|
process.emitWarning(
|
||||||
|
`${message} (found in "${rel}")`,
|
||||||
|
"DeprecationWarning",
|
||||||
|
errorCode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export {
|
||||||
|
emitDeprecationWarning
|
||||||
|
};
|
96
node_modules/@eslint/eslintrc/lib/shared/naming.js
generated
vendored
Normal file
96
node_modules/@eslint/eslintrc/lib/shared/naming.js
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Common helpers for naming of plugins, formatters and configs
|
||||||
|
*/
|
||||||
|
|
||||||
|
const NAMESPACE_REGEX = /^@.*\//iu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Brings package name to correct format based on prefix
|
||||||
|
* @param {string} name The name of the package.
|
||||||
|
* @param {string} prefix Can be either "eslint-plugin", "eslint-config" or "eslint-formatter"
|
||||||
|
* @returns {string} Normalized name of the package
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function normalizePackageName(name, prefix) {
|
||||||
|
let normalizedName = name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On Windows, name can come in with Windows slashes instead of Unix slashes.
|
||||||
|
* Normalize to Unix first to avoid errors later on.
|
||||||
|
* https://github.com/eslint/eslint/issues/5644
|
||||||
|
*/
|
||||||
|
if (normalizedName.includes("\\")) {
|
||||||
|
normalizedName = normalizedName.replace(/\\/gu, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedName.charAt(0) === "@") {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* it's a scoped package
|
||||||
|
* package name is the prefix, or just a username
|
||||||
|
*/
|
||||||
|
const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`, "u"),
|
||||||
|
scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`, "u");
|
||||||
|
|
||||||
|
if (scopedPackageShortcutRegex.test(normalizedName)) {
|
||||||
|
normalizedName = normalizedName.replace(scopedPackageShortcutRegex, `$1/${prefix}`);
|
||||||
|
} else if (!scopedPackageNameRegex.test(normalizedName.split("/")[1])) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for scoped packages, insert the prefix after the first / unless
|
||||||
|
* the path is already @scope/eslint or @scope/eslint-xxx-yyy
|
||||||
|
*/
|
||||||
|
normalizedName = normalizedName.replace(/^@([^/]+)\/(.*)$/u, `@$1/${prefix}-$2`);
|
||||||
|
}
|
||||||
|
} else if (!normalizedName.startsWith(`${prefix}-`)) {
|
||||||
|
normalizedName = `${prefix}-${normalizedName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the prefix from a fullname.
|
||||||
|
* @param {string} fullname The term which may have the prefix.
|
||||||
|
* @param {string} prefix The prefix to remove.
|
||||||
|
* @returns {string} The term without prefix.
|
||||||
|
*/
|
||||||
|
function getShorthandName(fullname, prefix) {
|
||||||
|
if (fullname[0] === "@") {
|
||||||
|
let matchResult = new RegExp(`^(@[^/]+)/${prefix}$`, "u").exec(fullname);
|
||||||
|
|
||||||
|
if (matchResult) {
|
||||||
|
return matchResult[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
matchResult = new RegExp(`^(@[^/]+)/${prefix}-(.+)$`, "u").exec(fullname);
|
||||||
|
if (matchResult) {
|
||||||
|
return `${matchResult[1]}/${matchResult[2]}`;
|
||||||
|
}
|
||||||
|
} else if (fullname.startsWith(`${prefix}-`)) {
|
||||||
|
return fullname.slice(prefix.length + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the scope (namespace) of a term.
|
||||||
|
* @param {string} term The term which may have the namespace.
|
||||||
|
* @returns {string} The namespace of the term if it has one.
|
||||||
|
*/
|
||||||
|
function getNamespaceFromTerm(term) {
|
||||||
|
const match = term.match(NAMESPACE_REGEX);
|
||||||
|
|
||||||
|
return match ? match[0] : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export {
|
||||||
|
normalizePackageName,
|
||||||
|
getShorthandName,
|
||||||
|
getNamespaceFromTerm
|
||||||
|
};
|
42
node_modules/@eslint/eslintrc/lib/shared/relative-module-resolver.js
generated
vendored
Normal file
42
node_modules/@eslint/eslintrc/lib/shared/relative-module-resolver.js
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
* Utility for resolving a module relative to another module
|
||||||
|
* @author Teddy Katz
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Module from "module";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `Module.createRequire` is added in v12.2.0. It supports URL as well.
|
||||||
|
* We only support the case where the argument is a filepath, not a URL.
|
||||||
|
*/
|
||||||
|
const createRequire = Module.createRequire;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves a Node module relative to another module
|
||||||
|
* @param {string} moduleName The name of a Node module, or a path to a Node module.
|
||||||
|
* @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be
|
||||||
|
* a file rather than a directory, but the file need not actually exist.
|
||||||
|
* @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath`
|
||||||
|
*/
|
||||||
|
function resolve(moduleName, relativeToPath) {
|
||||||
|
try {
|
||||||
|
return createRequire(relativeToPath).resolve(moduleName);
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
// This `if` block is for older Node.js than 12.0.0. We can remove this block in the future.
|
||||||
|
if (
|
||||||
|
typeof error === "object" &&
|
||||||
|
error !== null &&
|
||||||
|
error.code === "MODULE_NOT_FOUND" &&
|
||||||
|
!error.requireStack &&
|
||||||
|
error.message.includes(moduleName)
|
||||||
|
) {
|
||||||
|
error.message += `\nRequire stack:\n- ${relativeToPath}`;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
resolve
|
||||||
|
};
|
149
node_modules/@eslint/eslintrc/lib/shared/types.js
generated
vendored
Normal file
149
node_modules/@eslint/eslintrc/lib/shared/types.js
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/**
|
||||||
|
* @fileoverview Define common types for input completion.
|
||||||
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {any} */
|
||||||
|
export default {};
|
||||||
|
|
||||||
|
/** @typedef {boolean | "off" | "readable" | "readonly" | "writable" | "writeable"} GlobalConf */
|
||||||
|
/** @typedef {0 | 1 | 2 | "off" | "warn" | "error"} SeverityConf */
|
||||||
|
/** @typedef {SeverityConf | [SeverityConf, ...any[]]} RuleConf */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} EcmaFeatures
|
||||||
|
* @property {boolean} [globalReturn] Enabling `return` statements at the top-level.
|
||||||
|
* @property {boolean} [jsx] Enabling JSX syntax.
|
||||||
|
* @property {boolean} [impliedStrict] Enabling strict mode always.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ParserOptions
|
||||||
|
* @property {EcmaFeatures} [ecmaFeatures] The optional features.
|
||||||
|
* @property {3|5|6|7|8|9|10|11|12|2015|2016|2017|2018|2019|2020|2021} [ecmaVersion] The ECMAScript version (or revision number).
|
||||||
|
* @property {"script"|"module"} [sourceType] The source code type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ConfigData
|
||||||
|
* @property {Record<string, boolean>} [env] The environment settings.
|
||||||
|
* @property {string | string[]} [extends] The path to other config files or the package name of shareable configs.
|
||||||
|
* @property {Record<string, GlobalConf>} [globals] The global variable settings.
|
||||||
|
* @property {string | string[]} [ignorePatterns] The glob patterns that ignore to lint.
|
||||||
|
* @property {boolean} [noInlineConfig] The flag that disables directive comments.
|
||||||
|
* @property {OverrideConfigData[]} [overrides] The override settings per kind of files.
|
||||||
|
* @property {string} [parser] The path to a parser or the package name of a parser.
|
||||||
|
* @property {ParserOptions} [parserOptions] The parser options.
|
||||||
|
* @property {string[]} [plugins] The plugin specifiers.
|
||||||
|
* @property {string} [processor] The processor specifier.
|
||||||
|
* @property {boolean} [reportUnusedDisableDirectives] The flag to report unused `eslint-disable` comments.
|
||||||
|
* @property {boolean} [root] The root flag.
|
||||||
|
* @property {Record<string, RuleConf>} [rules] The rule settings.
|
||||||
|
* @property {Object} [settings] The shared settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} OverrideConfigData
|
||||||
|
* @property {Record<string, boolean>} [env] The environment settings.
|
||||||
|
* @property {string | string[]} [excludedFiles] The glob pattarns for excluded files.
|
||||||
|
* @property {string | string[]} [extends] The path to other config files or the package name of shareable configs.
|
||||||
|
* @property {string | string[]} files The glob patterns for target files.
|
||||||
|
* @property {Record<string, GlobalConf>} [globals] The global variable settings.
|
||||||
|
* @property {boolean} [noInlineConfig] The flag that disables directive comments.
|
||||||
|
* @property {OverrideConfigData[]} [overrides] The override settings per kind of files.
|
||||||
|
* @property {string} [parser] The path to a parser or the package name of a parser.
|
||||||
|
* @property {ParserOptions} [parserOptions] The parser options.
|
||||||
|
* @property {string[]} [plugins] The plugin specifiers.
|
||||||
|
* @property {string} [processor] The processor specifier.
|
||||||
|
* @property {boolean} [reportUnusedDisableDirectives] The flag to report unused `eslint-disable` comments.
|
||||||
|
* @property {Record<string, RuleConf>} [rules] The rule settings.
|
||||||
|
* @property {Object} [settings] The shared settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ParseResult
|
||||||
|
* @property {Object} ast The AST.
|
||||||
|
* @property {ScopeManager} [scopeManager] The scope manager of the AST.
|
||||||
|
* @property {Record<string, any>} [services] The services that the parser provides.
|
||||||
|
* @property {Record<string, string[]>} [visitorKeys] The visitor keys of the AST.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Parser
|
||||||
|
* @property {(text:string, options:ParserOptions) => Object} parse The definition of global variables.
|
||||||
|
* @property {(text:string, options:ParserOptions) => ParseResult} [parseForESLint] The parser options that will be enabled under this environment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Environment
|
||||||
|
* @property {Record<string, GlobalConf>} [globals] The definition of global variables.
|
||||||
|
* @property {ParserOptions} [parserOptions] The parser options that will be enabled under this environment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} LintMessage
|
||||||
|
* @property {number} column The 1-based column number.
|
||||||
|
* @property {number} [endColumn] The 1-based column number of the end location.
|
||||||
|
* @property {number} [endLine] The 1-based line number of the end location.
|
||||||
|
* @property {boolean} fatal If `true` then this is a fatal error.
|
||||||
|
* @property {{range:[number,number], text:string}} [fix] Information for autofix.
|
||||||
|
* @property {number} line The 1-based line number.
|
||||||
|
* @property {string} message The error message.
|
||||||
|
* @property {string|null} ruleId The ID of the rule which makes this message.
|
||||||
|
* @property {0|1|2} severity The severity of this message.
|
||||||
|
* @property {Array<{desc?: string, messageId?: string, fix: {range: [number, number], text: string}}>} [suggestions] Information for suggestions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} SuggestionResult
|
||||||
|
* @property {string} desc A short description.
|
||||||
|
* @property {string} [messageId] Id referencing a message for the description.
|
||||||
|
* @property {{ text: string, range: number[] }} fix fix result info
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Processor
|
||||||
|
* @property {(text:string, filename:string) => Array<string | { text:string, filename:string }>} [preprocess] The function to extract code blocks.
|
||||||
|
* @property {(messagesList:LintMessage[][], filename:string) => LintMessage[]} [postprocess] The function to merge messages.
|
||||||
|
* @property {boolean} [supportsAutofix] If `true` then it means the processor supports autofix.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} RuleMetaDocs
|
||||||
|
* @property {string} category The category of the rule.
|
||||||
|
* @property {string} description The description of the rule.
|
||||||
|
* @property {boolean} recommended If `true` then the rule is included in `eslint:recommended` preset.
|
||||||
|
* @property {string} url The URL of the rule documentation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} RuleMeta
|
||||||
|
* @property {boolean} [deprecated] If `true` then the rule has been deprecated.
|
||||||
|
* @property {RuleMetaDocs} docs The document information of the rule.
|
||||||
|
* @property {"code"|"whitespace"} [fixable] The autofix type.
|
||||||
|
* @property {Record<string,string>} [messages] The messages the rule reports.
|
||||||
|
* @property {string[]} [replacedBy] The IDs of the alternative rules.
|
||||||
|
* @property {Array|Object} schema The option schema of the rule.
|
||||||
|
* @property {"problem"|"suggestion"|"layout"} type The rule type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Rule
|
||||||
|
* @property {Function} create The factory of the rule.
|
||||||
|
* @property {RuleMeta} meta The meta data of the rule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Plugin
|
||||||
|
* @property {Record<string, ConfigData>} [configs] The definition of plugin configs.
|
||||||
|
* @property {Record<string, Environment>} [environments] The definition of plugin environments.
|
||||||
|
* @property {Record<string, Processor>} [processors] The definition of plugin processors.
|
||||||
|
* @property {Record<string, Function | Rule>} [rules] The definition of plugin rules.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information of deprecated rules.
|
||||||
|
* @typedef {Object} DeprecatedRuleInfo
|
||||||
|
* @property {string} ruleId The rule ID.
|
||||||
|
* @property {string[]} replacedBy The rule IDs that replace this deprecated rule.
|
||||||
|
*/
|
19
node_modules/@eslint/eslintrc/node_modules/ignore/CHANGELOG.md
generated
vendored
Normal file
19
node_modules/@eslint/eslintrc/node_modules/ignore/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# `node-ignore` 4 ChangeLog
|
||||||
|
|
||||||
|
# 4.x
|
||||||
|
|
||||||
|
## 2018-06-22, Version 4.0.0
|
||||||
|
|
||||||
|
- **SEMVER-MAJOR**: Drop support for node < 6 by default.
|
||||||
|
- **FEATURE**: supports the missing character ranges and sets, such as `*.[a-z]` and `*.[jJ][pP][gG]`
|
||||||
|
- **FEATURE**: new option: `ignorecase` to make `ignore` case sensitive.
|
||||||
|
- **FEATURE**: supports question mark which matches a single character.
|
||||||
|
- **PATCH**: fixes typescript declaration.
|
||||||
|
|
||||||
|
## ~ 2018-08-09, Version 4.0.1 - 4.0.5
|
||||||
|
|
||||||
|
- **PATCH**: updates README.md about frequent asked quesions from github issues.
|
||||||
|
|
||||||
|
## 2018-08-12, Version 4.0.6
|
||||||
|
|
||||||
|
- **PATCH**: `Object.prototype` methods will not ruin the result any more.
|
21
node_modules/@eslint/eslintrc/node_modules/ignore/LICENSE-MIT
generated
vendored
Executable file
21
node_modules/@eslint/eslintrc/node_modules/ignore/LICENSE-MIT
generated
vendored
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
Copyright (c) 2013 Kael Zhang <i@kael.me>, contributors
|
||||||
|
http://kael.me/
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
307
node_modules/@eslint/eslintrc/node_modules/ignore/README.md
generated
vendored
Executable file
307
node_modules/@eslint/eslintrc/node_modules/ignore/README.md
generated
vendored
Executable file
|
@ -0,0 +1,307 @@
|
||||||
|
<table><thead>
|
||||||
|
<tr>
|
||||||
|
<th>Linux</th>
|
||||||
|
<th>OS X</th>
|
||||||
|
<th>Windows</th>
|
||||||
|
<th>Coverage</th>
|
||||||
|
<th>Downloads</th>
|
||||||
|
</tr>
|
||||||
|
</thead><tbody><tr>
|
||||||
|
<td colspan="2" align="center">
|
||||||
|
<a href="https://travis-ci.org/kaelzhang/node-ignore">
|
||||||
|
<img
|
||||||
|
src="https://travis-ci.org/kaelzhang/node-ignore.svg?branch=master"
|
||||||
|
alt="Build Status" /></a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://ci.appveyor.com/project/kaelzhang/node-ignore">
|
||||||
|
<img
|
||||||
|
src="https://ci.appveyor.com/api/projects/status/github/kaelzhang/node-ignore?branch=master&svg=true"
|
||||||
|
alt="Windows Build Status" /></a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://codecov.io/gh/kaelzhang/node-ignore">
|
||||||
|
<img
|
||||||
|
src="https://codecov.io/gh/kaelzhang/node-ignore/branch/master/graph/badge.svg"
|
||||||
|
alt="Coverage Status" /></a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://www.npmjs.org/package/ignore">
|
||||||
|
<img
|
||||||
|
src="http://img.shields.io/npm/dm/ignore.svg"
|
||||||
|
alt="npm module downloads per month" /></a>
|
||||||
|
</td>
|
||||||
|
</tr></tbody></table>
|
||||||
|
|
||||||
|
# ignore
|
||||||
|
|
||||||
|
`ignore` is a manager, filter and parser which implemented in pure JavaScript according to the .gitignore [spec](http://git-scm.com/docs/gitignore).
|
||||||
|
|
||||||
|
Pay attention that [`minimatch`](https://www.npmjs.org/package/minimatch) does not work in the gitignore way. To filter filenames according to .gitignore file, I recommend this module.
|
||||||
|
|
||||||
|
##### Tested on
|
||||||
|
|
||||||
|
- Linux + Node: `0.8` - `7.x`
|
||||||
|
- Windows + Node: `0.10` - `7.x`, node < `0.10` is not tested due to the lack of support of appveyor.
|
||||||
|
|
||||||
|
Actually, `ignore` does not rely on any versions of node specially.
|
||||||
|
|
||||||
|
Since `4.0.0`, ignore will no longer support `node < 6` by default, to use in node < 6, `require('ignore/legacy')`. For details, see [CHANGELOG](https://github.com/kaelzhang/node-ignore/blob/master/CHANGELOG.md).
|
||||||
|
|
||||||
|
## Table Of Main Contents
|
||||||
|
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [`Pathname` Conventions](#pathname-conventions)
|
||||||
|
- [Guide for 2.x -> 3.x](#upgrade-2x---3x)
|
||||||
|
- [Guide for 3.x -> 4.x](#upgrade-3x---4x)
|
||||||
|
- See Also:
|
||||||
|
- [`glob-gitignore`](https://www.npmjs.com/package/glob-gitignore) matches files using patterns and filters them according to gitignore rules.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
import ignore from 'ignore'
|
||||||
|
const ig = ignore().add(['.abc/*', '!.abc/d/'])
|
||||||
|
```
|
||||||
|
|
||||||
|
### Filter the given paths
|
||||||
|
|
||||||
|
```js
|
||||||
|
const paths = [
|
||||||
|
'.abc/a.js', // filtered out
|
||||||
|
'.abc/d/e.js' // included
|
||||||
|
]
|
||||||
|
|
||||||
|
ig.filter(paths) // ['.abc/d/e.js']
|
||||||
|
ig.ignores('.abc/a.js') // true
|
||||||
|
```
|
||||||
|
|
||||||
|
### As the filter function
|
||||||
|
|
||||||
|
```js
|
||||||
|
paths.filter(ig.createFilter()); // ['.abc/d/e.js']
|
||||||
|
```
|
||||||
|
|
||||||
|
### Win32 paths will be handled
|
||||||
|
|
||||||
|
```js
|
||||||
|
ig.filter(['.abc\\a.js', '.abc\\d\\e.js'])
|
||||||
|
// if the code above runs on windows, the result will be
|
||||||
|
// ['.abc\\d\\e.js']
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why another ignore?
|
||||||
|
|
||||||
|
- `ignore` is a standalone module, and is much simpler so that it could easy work with other programs, unlike [isaacs](https://npmjs.org/~isaacs)'s [fstream-ignore](https://npmjs.org/package/fstream-ignore) which must work with the modules of the fstream family.
|
||||||
|
|
||||||
|
- `ignore` only contains utility methods to filter paths according to the specified ignore rules, so
|
||||||
|
- `ignore` never try to find out ignore rules by traversing directories or fetching from git configurations.
|
||||||
|
- `ignore` don't cares about sub-modules of git projects.
|
||||||
|
|
||||||
|
- Exactly according to [gitignore man page](http://git-scm.com/docs/gitignore), fixes some known matching issues of fstream-ignore, such as:
|
||||||
|
- '`/*.js`' should only match '`a.js`', but not '`abc/a.js`'.
|
||||||
|
- '`**/foo`' should match '`foo`' anywhere.
|
||||||
|
- Prevent re-including a file if a parent directory of that file is excluded.
|
||||||
|
- Handle trailing whitespaces:
|
||||||
|
- `'a '`(one space) should not match `'a '`(two spaces).
|
||||||
|
- `'a \ '` matches `'a '`
|
||||||
|
- All test cases are verified with the result of `git check-ignore`.
|
||||||
|
|
||||||
|
# Methods
|
||||||
|
|
||||||
|
## .add(pattern: string | Ignore): this
|
||||||
|
## .add(patterns: Array<string | Ignore>): this
|
||||||
|
|
||||||
|
- **pattern** `String | Ignore` An ignore pattern string, or the `Ignore` instance
|
||||||
|
- **patterns** `Array<String | Ignore>` Array of ignore patterns.
|
||||||
|
|
||||||
|
Adds a rule or several rules to the current manager.
|
||||||
|
|
||||||
|
Returns `this`
|
||||||
|
|
||||||
|
Notice that a line starting with `'#'`(hash) is treated as a comment. Put a backslash (`'\'`) in front of the first hash for patterns that begin with a hash, if you want to ignore a file with a hash at the beginning of the filename.
|
||||||
|
|
||||||
|
```js
|
||||||
|
ignore().add('#abc').ignores('#abc') // false
|
||||||
|
ignore().add('\#abc').ignores('#abc') // true
|
||||||
|
```
|
||||||
|
|
||||||
|
`pattern` could either be a line of ignore pattern or a string of multiple ignore patterns, which means we could just `ignore().add()` the content of a ignore file:
|
||||||
|
|
||||||
|
```js
|
||||||
|
ignore()
|
||||||
|
.add(fs.readFileSync(filenameOfGitignore).toString())
|
||||||
|
.filter(filenames)
|
||||||
|
```
|
||||||
|
|
||||||
|
`pattern` could also be an `ignore` instance, so that we could easily inherit the rules of another `Ignore` instance.
|
||||||
|
|
||||||
|
## <strike>.addIgnoreFile(path)</strike>
|
||||||
|
|
||||||
|
REMOVED in `3.x` for now.
|
||||||
|
|
||||||
|
To upgrade `ignore@2.x` up to `3.x`, use
|
||||||
|
|
||||||
|
```js
|
||||||
|
import fs from 'fs'
|
||||||
|
|
||||||
|
if (fs.existsSync(filename)) {
|
||||||
|
ignore().add(fs.readFileSync(filename).toString())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
instead.
|
||||||
|
|
||||||
|
## .filter(paths: Array<Pathname>): Array<Pathname>
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type Pathname = string
|
||||||
|
```
|
||||||
|
|
||||||
|
Filters the given array of pathnames, and returns the filtered array.
|
||||||
|
|
||||||
|
- **paths** `Array.<Pathname>` The array of `pathname`s to be filtered.
|
||||||
|
|
||||||
|
### `Pathname` Conventions:
|
||||||
|
|
||||||
|
#### 1. `Pathname` should be a `path.relative()`d pathname
|
||||||
|
|
||||||
|
`Pathname` should be a string that have been `path.join()`ed, or the return value of `path.relative()` to the current directory.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// WRONG
|
||||||
|
ig.ignores('./abc')
|
||||||
|
|
||||||
|
// WRONG, for it will never happen.
|
||||||
|
// If the gitignore rule locates at the root directory,
|
||||||
|
// `'/abc'` should be changed to `'abc'`.
|
||||||
|
// ```
|
||||||
|
// path.relative('/', '/abc') -> 'abc'
|
||||||
|
// ```
|
||||||
|
ig.ignores('/abc')
|
||||||
|
|
||||||
|
// Right
|
||||||
|
ig.ignores('abc')
|
||||||
|
|
||||||
|
// Right
|
||||||
|
ig.ignores(path.join('./abc')) // path.join('./abc') -> 'abc'
|
||||||
|
```
|
||||||
|
|
||||||
|
In other words, each `Pathname` here should be a relative path to the directory of the gitignore rules.
|
||||||
|
|
||||||
|
Suppose the dir structure is:
|
||||||
|
|
||||||
|
```
|
||||||
|
/path/to/your/repo
|
||||||
|
|-- a
|
||||||
|
| |-- a.js
|
||||||
|
|
|
||||||
|
|-- .b
|
||||||
|
|
|
||||||
|
|-- .c
|
||||||
|
|-- .DS_store
|
||||||
|
```
|
||||||
|
|
||||||
|
Then the `paths` might be like this:
|
||||||
|
|
||||||
|
```js
|
||||||
|
[
|
||||||
|
'a/a.js'
|
||||||
|
'.b',
|
||||||
|
'.c/.DS_store'
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Usually, you could use [`glob`](http://npmjs.org/package/glob) with `option.mark = true` to fetch the structure of the current directory:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import glob from 'glob'
|
||||||
|
|
||||||
|
glob('**', {
|
||||||
|
// Adds a / character to directory matches.
|
||||||
|
mark: true
|
||||||
|
}, (err, files) => {
|
||||||
|
if (err) {
|
||||||
|
return console.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
let filtered = ignore().add(patterns).filter(files)
|
||||||
|
console.log(filtered)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. filenames and dirnames
|
||||||
|
|
||||||
|
`node-ignore` does NO `fs.stat` during path matching, so for the example below:
|
||||||
|
|
||||||
|
```js
|
||||||
|
ig.add('config/')
|
||||||
|
|
||||||
|
// `ig` does NOT know if 'config' is a normal file, directory or something
|
||||||
|
ig.ignores('config') // And it returns `false`
|
||||||
|
|
||||||
|
ig.ignores('config/') // returns `true`
|
||||||
|
```
|
||||||
|
|
||||||
|
Specially for people who develop some library based on `node-ignore`, it is important to understand that.
|
||||||
|
|
||||||
|
## .ignores(pathname: Pathname): boolean
|
||||||
|
|
||||||
|
> new in 3.2.0
|
||||||
|
|
||||||
|
Returns `Boolean` whether `pathname` should be ignored.
|
||||||
|
|
||||||
|
```js
|
||||||
|
ig.ignores('.abc/a.js') // true
|
||||||
|
```
|
||||||
|
|
||||||
|
## .createFilter()
|
||||||
|
|
||||||
|
Creates a filter function which could filter an array of paths with `Array.prototype.filter`.
|
||||||
|
|
||||||
|
Returns `function(path)` the filter function.
|
||||||
|
|
||||||
|
## `options.ignorecase` since 4.0.0
|
||||||
|
|
||||||
|
Similar as the `core.ignorecase` option of [git-config](https://git-scm.com/docs/git-config), `node-ignore` will be case insensitive if `options.ignorecase` is set to `true` (default value), otherwise case sensitive.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const ig = ignore({
|
||||||
|
ignorecase: false
|
||||||
|
})
|
||||||
|
|
||||||
|
ig.add('*.png')
|
||||||
|
|
||||||
|
ig.ignores('*.PNG') // false
|
||||||
|
```
|
||||||
|
|
||||||
|
****
|
||||||
|
|
||||||
|
# Upgrade Guide
|
||||||
|
|
||||||
|
## Upgrade 2.x -> 3.x
|
||||||
|
|
||||||
|
- All `options` of 2.x are unnecessary and removed, so just remove them.
|
||||||
|
- `ignore()` instance is no longer an [`EventEmitter`](nodejs.org/api/events.html), and all events are unnecessary and removed.
|
||||||
|
- `.addIgnoreFile()` is removed, see the [.addIgnoreFile](#addignorefilepath) section for details.
|
||||||
|
|
||||||
|
## Upgrade 3.x -> 4.x
|
||||||
|
|
||||||
|
Since `4.0.0`, `ignore` will no longer support node < 6, to use `ignore` in node < 6:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var ignore = require('ignore/legacy')
|
||||||
|
```
|
||||||
|
|
||||||
|
****
|
||||||
|
|
||||||
|
# Collaborators
|
||||||
|
|
||||||
|
- [@whitecolor](https://github.com/whitecolor) *Alex*
|
||||||
|
- [@SamyPesse](https://github.com/SamyPesse) *Samy Pessé*
|
||||||
|
- [@azproduction](https://github.com/azproduction) *Mikhail Davydov*
|
||||||
|
- [@TrySound](https://github.com/TrySound) *Bogdan Chadkin*
|
||||||
|
- [@JanMattner](https://github.com/JanMattner) *Jan Mattner*
|
||||||
|
- [@ntwb](https://github.com/ntwb) *Stephen Edgar*
|
||||||
|
- [@kasperisager](https://github.com/kasperisager) *Kasper Isager*
|
||||||
|
- [@sandersn](https://github.com/sandersn) *Nathan Shively-Sanders*
|
45
node_modules/@eslint/eslintrc/node_modules/ignore/index.d.ts
generated
vendored
Normal file
45
node_modules/@eslint/eslintrc/node_modules/ignore/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
interface Ignore {
|
||||||
|
/**
|
||||||
|
* Adds a rule rules to the current manager.
|
||||||
|
* @param {string | Ignore} pattern
|
||||||
|
* @returns IgnoreBase
|
||||||
|
*/
|
||||||
|
add(pattern: string | Ignore): Ignore
|
||||||
|
/**
|
||||||
|
* Adds several rules to the current manager.
|
||||||
|
* @param {string[]} patterns
|
||||||
|
* @returns IgnoreBase
|
||||||
|
*/
|
||||||
|
add(patterns: (string | Ignore)[]): Ignore
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the given array of pathnames, and returns the filtered array.
|
||||||
|
* NOTICE that each path here should be a relative path to the root of your repository.
|
||||||
|
* @param paths the array of paths to be filtered.
|
||||||
|
* @returns The filtered array of paths
|
||||||
|
*/
|
||||||
|
filter(paths: string[]): string[]
|
||||||
|
/**
|
||||||
|
* Creates a filter function which could filter
|
||||||
|
* an array of paths with Array.prototype.filter.
|
||||||
|
*/
|
||||||
|
createFilter(): (path: string) => boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Boolean whether pathname should be ignored.
|
||||||
|
* @param {string} pathname a path to check
|
||||||
|
* @returns boolean
|
||||||
|
*/
|
||||||
|
ignores(pathname: string): boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
ignorecase?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new ignore manager.
|
||||||
|
*/
|
||||||
|
declare function ignore(options?: Options): Ignore
|
||||||
|
|
||||||
|
export default ignore
|
463
node_modules/@eslint/eslintrc/node_modules/ignore/index.js
generated
vendored
Executable file
463
node_modules/@eslint/eslintrc/node_modules/ignore/index.js
generated
vendored
Executable file
|
@ -0,0 +1,463 @@
|
||||||
|
// A simple implementation of make-array
|
||||||
|
function make_array (subject) {
|
||||||
|
return Array.isArray(subject)
|
||||||
|
? subject
|
||||||
|
: [subject]
|
||||||
|
}
|
||||||
|
|
||||||
|
const REGEX_BLANK_LINE = /^\s+$/
|
||||||
|
const REGEX_LEADING_EXCAPED_EXCLAMATION = /^\\!/
|
||||||
|
const REGEX_LEADING_EXCAPED_HASH = /^\\#/
|
||||||
|
const SLASH = '/'
|
||||||
|
const KEY_IGNORE = typeof Symbol !== 'undefined'
|
||||||
|
? Symbol.for('node-ignore')
|
||||||
|
/* istanbul ignore next */
|
||||||
|
: 'node-ignore'
|
||||||
|
|
||||||
|
const define = (object, key, value) =>
|
||||||
|
Object.defineProperty(object, key, {value})
|
||||||
|
|
||||||
|
const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g
|
||||||
|
|
||||||
|
// Sanitize the range of a regular expression
|
||||||
|
// The cases are complicated, see test cases for details
|
||||||
|
const sanitizeRange = range => range.replace(
|
||||||
|
REGEX_REGEXP_RANGE,
|
||||||
|
(match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0)
|
||||||
|
? match
|
||||||
|
// Invalid range (out of order) which is ok for gitignore rules but
|
||||||
|
// fatal for JavaScript regular expression, so eliminate it.
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
|
||||||
|
// > If the pattern ends with a slash,
|
||||||
|
// > it is removed for the purpose of the following description,
|
||||||
|
// > but it would only find a match with a directory.
|
||||||
|
// > In other words, foo/ will match a directory foo and paths underneath it,
|
||||||
|
// > but will not match a regular file or a symbolic link foo
|
||||||
|
// > (this is consistent with the way how pathspec works in general in Git).
|
||||||
|
// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'
|
||||||
|
// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call
|
||||||
|
// you could use option `mark: true` with `glob`
|
||||||
|
|
||||||
|
// '`foo/`' should not continue with the '`..`'
|
||||||
|
const DEFAULT_REPLACER_PREFIX = [
|
||||||
|
|
||||||
|
// > Trailing spaces are ignored unless they are quoted with backslash ("\")
|
||||||
|
[
|
||||||
|
// (a\ ) -> (a )
|
||||||
|
// (a ) -> (a)
|
||||||
|
// (a \ ) -> (a )
|
||||||
|
/\\?\s+$/,
|
||||||
|
match => match.indexOf('\\') === 0
|
||||||
|
? ' '
|
||||||
|
: ''
|
||||||
|
],
|
||||||
|
|
||||||
|
// replace (\ ) with ' '
|
||||||
|
[
|
||||||
|
/\\\s/g,
|
||||||
|
() => ' '
|
||||||
|
],
|
||||||
|
|
||||||
|
// Escape metacharacters
|
||||||
|
// which is written down by users but means special for regular expressions.
|
||||||
|
|
||||||
|
// > There are 12 characters with special meanings:
|
||||||
|
// > - the backslash \,
|
||||||
|
// > - the caret ^,
|
||||||
|
// > - the dollar sign $,
|
||||||
|
// > - the period or dot .,
|
||||||
|
// > - the vertical bar or pipe symbol |,
|
||||||
|
// > - the question mark ?,
|
||||||
|
// > - the asterisk or star *,
|
||||||
|
// > - the plus sign +,
|
||||||
|
// > - the opening parenthesis (,
|
||||||
|
// > - the closing parenthesis ),
|
||||||
|
// > - and the opening square bracket [,
|
||||||
|
// > - the opening curly brace {,
|
||||||
|
// > These special characters are often called "metacharacters".
|
||||||
|
[
|
||||||
|
/[\\^$.|*+(){]/g,
|
||||||
|
match => `\\${match}`
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
// > [abc] matches any character inside the brackets
|
||||||
|
// > (in this case a, b, or c);
|
||||||
|
/\[([^\]/]*)($|\])/g,
|
||||||
|
(match, p1, p2) => p2 === ']'
|
||||||
|
? `[${sanitizeRange(p1)}]`
|
||||||
|
: `\\${match}`
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
// > a question mark (?) matches a single character
|
||||||
|
/(?!\\)\?/g,
|
||||||
|
() => '[^/]'
|
||||||
|
],
|
||||||
|
|
||||||
|
// leading slash
|
||||||
|
[
|
||||||
|
|
||||||
|
// > A leading slash matches the beginning of the pathname.
|
||||||
|
// > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
|
||||||
|
// A leading slash matches the beginning of the pathname
|
||||||
|
/^\//,
|
||||||
|
() => '^'
|
||||||
|
],
|
||||||
|
|
||||||
|
// replace special metacharacter slash after the leading slash
|
||||||
|
[
|
||||||
|
/\//g,
|
||||||
|
() => '\\/'
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
// > A leading "**" followed by a slash means match in all directories.
|
||||||
|
// > For example, "**/foo" matches file or directory "foo" anywhere,
|
||||||
|
// > the same as pattern "foo".
|
||||||
|
// > "**/foo/bar" matches file or directory "bar" anywhere that is directly
|
||||||
|
// > under directory "foo".
|
||||||
|
// Notice that the '*'s have been replaced as '\\*'
|
||||||
|
/^\^*\\\*\\\*\\\//,
|
||||||
|
|
||||||
|
// '**/foo' <-> 'foo'
|
||||||
|
() => '^(?:.*\\/)?'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
const DEFAULT_REPLACER_SUFFIX = [
|
||||||
|
// starting
|
||||||
|
[
|
||||||
|
// there will be no leading '/'
|
||||||
|
// (which has been replaced by section "leading slash")
|
||||||
|
// If starts with '**', adding a '^' to the regular expression also works
|
||||||
|
/^(?=[^^])/,
|
||||||
|
function startingReplacer () {
|
||||||
|
return !/\/(?!$)/.test(this)
|
||||||
|
// > If the pattern does not contain a slash /,
|
||||||
|
// > Git treats it as a shell glob pattern
|
||||||
|
// Actually, if there is only a trailing slash,
|
||||||
|
// git also treats it as a shell glob pattern
|
||||||
|
? '(?:^|\\/)'
|
||||||
|
|
||||||
|
// > Otherwise, Git treats the pattern as a shell glob suitable for
|
||||||
|
// > consumption by fnmatch(3)
|
||||||
|
: '^'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// two globstars
|
||||||
|
[
|
||||||
|
// Use lookahead assertions so that we could match more than one `'/**'`
|
||||||
|
/\\\/\\\*\\\*(?=\\\/|$)/g,
|
||||||
|
|
||||||
|
// Zero, one or several directories
|
||||||
|
// should not use '*', or it will be replaced by the next replacer
|
||||||
|
|
||||||
|
// Check if it is not the last `'/**'`
|
||||||
|
(match, index, str) => index + 6 < str.length
|
||||||
|
|
||||||
|
// case: /**/
|
||||||
|
// > A slash followed by two consecutive asterisks then a slash matches
|
||||||
|
// > zero or more directories.
|
||||||
|
// > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
|
||||||
|
// '/**/'
|
||||||
|
? '(?:\\/[^\\/]+)*'
|
||||||
|
|
||||||
|
// case: /**
|
||||||
|
// > A trailing `"/**"` matches everything inside.
|
||||||
|
|
||||||
|
// #21: everything inside but it should not include the current folder
|
||||||
|
: '\\/.+'
|
||||||
|
],
|
||||||
|
|
||||||
|
// intermediate wildcards
|
||||||
|
[
|
||||||
|
// Never replace escaped '*'
|
||||||
|
// ignore rule '\*' will match the path '*'
|
||||||
|
|
||||||
|
// 'abc.*/' -> go
|
||||||
|
// 'abc.*' -> skip this rule
|
||||||
|
/(^|[^\\]+)\\\*(?=.+)/g,
|
||||||
|
|
||||||
|
// '*.js' matches '.js'
|
||||||
|
// '*.js' doesn't match 'abc'
|
||||||
|
(match, p1) => `${p1}[^\\/]*`
|
||||||
|
],
|
||||||
|
|
||||||
|
// trailing wildcard
|
||||||
|
[
|
||||||
|
/(\^|\\\/)?\\\*$/,
|
||||||
|
(match, p1) => {
|
||||||
|
const prefix = p1
|
||||||
|
// '\^':
|
||||||
|
// '/*' does not match ''
|
||||||
|
// '/*' does not match everything
|
||||||
|
|
||||||
|
// '\\\/':
|
||||||
|
// 'abc/*' does not match 'abc/'
|
||||||
|
? `${p1}[^/]+`
|
||||||
|
|
||||||
|
// 'a*' matches 'a'
|
||||||
|
// 'a*' matches 'aa'
|
||||||
|
: '[^/]*'
|
||||||
|
|
||||||
|
return `${prefix}(?=$|\\/$)`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
// unescape
|
||||||
|
/\\\\\\/g,
|
||||||
|
() => '\\'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
const POSITIVE_REPLACERS = [
|
||||||
|
...DEFAULT_REPLACER_PREFIX,
|
||||||
|
|
||||||
|
// 'f'
|
||||||
|
// matches
|
||||||
|
// - /f(end)
|
||||||
|
// - /f/
|
||||||
|
// - (start)f(end)
|
||||||
|
// - (start)f/
|
||||||
|
// doesn't match
|
||||||
|
// - oof
|
||||||
|
// - foo
|
||||||
|
// pseudo:
|
||||||
|
// -> (^|/)f(/|$)
|
||||||
|
|
||||||
|
// ending
|
||||||
|
[
|
||||||
|
// 'js' will not match 'js.'
|
||||||
|
// 'ab' will not match 'abc'
|
||||||
|
/(?:[^*/])$/,
|
||||||
|
|
||||||
|
// 'js*' will not match 'a.js'
|
||||||
|
// 'js/' will not match 'a.js'
|
||||||
|
// 'js' will match 'a.js' and 'a.js/'
|
||||||
|
match => `${match}(?=$|\\/)`
|
||||||
|
],
|
||||||
|
|
||||||
|
...DEFAULT_REPLACER_SUFFIX
|
||||||
|
]
|
||||||
|
|
||||||
|
const NEGATIVE_REPLACERS = [
|
||||||
|
...DEFAULT_REPLACER_PREFIX,
|
||||||
|
|
||||||
|
// #24, #38
|
||||||
|
// The MISSING rule of [gitignore docs](https://git-scm.com/docs/gitignore)
|
||||||
|
// A negative pattern without a trailing wildcard should not
|
||||||
|
// re-include the things inside that directory.
|
||||||
|
|
||||||
|
// eg:
|
||||||
|
// ['node_modules/*', '!node_modules']
|
||||||
|
// should ignore `node_modules/a.js`
|
||||||
|
[
|
||||||
|
/(?:[^*])$/,
|
||||||
|
match => `${match}(?=$|\\/$)`
|
||||||
|
],
|
||||||
|
|
||||||
|
...DEFAULT_REPLACER_SUFFIX
|
||||||
|
]
|
||||||
|
|
||||||
|
// A simple cache, because an ignore rule only has only one certain meaning
|
||||||
|
const cache = Object.create(null)
|
||||||
|
|
||||||
|
// @param {pattern}
|
||||||
|
const make_regex = (pattern, negative, ignorecase) => {
|
||||||
|
const r = cache[pattern]
|
||||||
|
if (r) {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
const replacers = negative
|
||||||
|
? NEGATIVE_REPLACERS
|
||||||
|
: POSITIVE_REPLACERS
|
||||||
|
|
||||||
|
const source = replacers.reduce(
|
||||||
|
(prev, current) => prev.replace(current[0], current[1].bind(pattern)),
|
||||||
|
pattern
|
||||||
|
)
|
||||||
|
|
||||||
|
return cache[pattern] = ignorecase
|
||||||
|
? new RegExp(source, 'i')
|
||||||
|
: new RegExp(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
// > A blank line matches no files, so it can serve as a separator for readability.
|
||||||
|
const checkPattern = pattern => pattern
|
||||||
|
&& typeof pattern === 'string'
|
||||||
|
&& !REGEX_BLANK_LINE.test(pattern)
|
||||||
|
|
||||||
|
// > A line starting with # serves as a comment.
|
||||||
|
&& pattern.indexOf('#') !== 0
|
||||||
|
|
||||||
|
const createRule = (pattern, ignorecase) => {
|
||||||
|
const origin = pattern
|
||||||
|
let negative = false
|
||||||
|
|
||||||
|
// > An optional prefix "!" which negates the pattern;
|
||||||
|
if (pattern.indexOf('!') === 0) {
|
||||||
|
negative = true
|
||||||
|
pattern = pattern.substr(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern = pattern
|
||||||
|
// > Put a backslash ("\") in front of the first "!" for patterns that
|
||||||
|
// > begin with a literal "!", for example, `"\!important!.txt"`.
|
||||||
|
.replace(REGEX_LEADING_EXCAPED_EXCLAMATION, '!')
|
||||||
|
// > Put a backslash ("\") in front of the first hash for patterns that
|
||||||
|
// > begin with a hash.
|
||||||
|
.replace(REGEX_LEADING_EXCAPED_HASH, '#')
|
||||||
|
|
||||||
|
const regex = make_regex(pattern, negative, ignorecase)
|
||||||
|
|
||||||
|
return {
|
||||||
|
origin,
|
||||||
|
pattern,
|
||||||
|
negative,
|
||||||
|
regex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IgnoreBase {
|
||||||
|
constructor ({
|
||||||
|
ignorecase = true
|
||||||
|
} = {}) {
|
||||||
|
this._rules = []
|
||||||
|
this._ignorecase = ignorecase
|
||||||
|
define(this, KEY_IGNORE, true)
|
||||||
|
this._initCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
_initCache () {
|
||||||
|
this._cache = Object.create(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @param {Array.<string>|string|Ignore} pattern
|
||||||
|
add (pattern) {
|
||||||
|
this._added = false
|
||||||
|
|
||||||
|
if (typeof pattern === 'string') {
|
||||||
|
pattern = pattern.split(/\r?\n/g)
|
||||||
|
}
|
||||||
|
|
||||||
|
make_array(pattern).forEach(this._addPattern, this)
|
||||||
|
|
||||||
|
// Some rules have just added to the ignore,
|
||||||
|
// making the behavior changed.
|
||||||
|
if (this._added) {
|
||||||
|
this._initCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy
|
||||||
|
addPattern (pattern) {
|
||||||
|
return this.add(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
_addPattern (pattern) {
|
||||||
|
// #32
|
||||||
|
if (pattern && pattern[KEY_IGNORE]) {
|
||||||
|
this._rules = this._rules.concat(pattern._rules)
|
||||||
|
this._added = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkPattern(pattern)) {
|
||||||
|
const rule = createRule(pattern, this._ignorecase)
|
||||||
|
this._added = true
|
||||||
|
this._rules.push(rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filter (paths) {
|
||||||
|
return make_array(paths).filter(path => this._filter(path))
|
||||||
|
}
|
||||||
|
|
||||||
|
createFilter () {
|
||||||
|
return path => this._filter(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
ignores (path) {
|
||||||
|
return !this._filter(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @returns `Boolean` true if the `path` is NOT ignored
|
||||||
|
_filter (path, slices) {
|
||||||
|
if (!path) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path in this._cache) {
|
||||||
|
return this._cache[path]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!slices) {
|
||||||
|
// path/to/a.js
|
||||||
|
// ['path', 'to', 'a.js']
|
||||||
|
slices = path.split(SLASH)
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.pop()
|
||||||
|
|
||||||
|
return this._cache[path] = slices.length
|
||||||
|
// > It is not possible to re-include a file if a parent directory of
|
||||||
|
// > that file is excluded.
|
||||||
|
// If the path contains a parent directory, check the parent first
|
||||||
|
? this._filter(slices.join(SLASH) + SLASH, slices)
|
||||||
|
&& this._test(path)
|
||||||
|
|
||||||
|
// Or only test the path
|
||||||
|
: this._test(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @returns {Boolean} true if a file is NOT ignored
|
||||||
|
_test (path) {
|
||||||
|
// Explicitly define variable type by setting matched to `0`
|
||||||
|
let matched = 0
|
||||||
|
|
||||||
|
this._rules.forEach(rule => {
|
||||||
|
// if matched = true, then we only test negative rules
|
||||||
|
// if matched = false, then we test non-negative rules
|
||||||
|
if (!(matched ^ rule.negative)) {
|
||||||
|
matched = rule.negative ^ rule.regex.test(path)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return !matched
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
/* istanbul ignore if */
|
||||||
|
if (
|
||||||
|
// Detect `process` so that it can run in browsers.
|
||||||
|
typeof process !== 'undefined'
|
||||||
|
&& (
|
||||||
|
process.env && process.env.IGNORE_TEST_WIN32
|
||||||
|
|| process.platform === 'win32'
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const filter = IgnoreBase.prototype._filter
|
||||||
|
|
||||||
|
/* eslint no-control-regex: "off" */
|
||||||
|
const make_posix = str => /^\\\\\?\\/.test(str)
|
||||||
|
|| /[^\x00-\x80]+/.test(str)
|
||||||
|
? str
|
||||||
|
: str.replace(/\\/g, '/')
|
||||||
|
|
||||||
|
IgnoreBase.prototype._filter = function filterWin32 (path, slices) {
|
||||||
|
path = make_posix(path)
|
||||||
|
return filter.call(this, path, slices)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = options => new IgnoreBase(options)
|
466
node_modules/@eslint/eslintrc/node_modules/ignore/legacy.js
generated
vendored
Normal file
466
node_modules/@eslint/eslintrc/node_modules/ignore/legacy.js
generated
vendored
Normal file
|
@ -0,0 +1,466 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||||
|
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
|
// A simple implementation of make-array
|
||||||
|
function make_array(subject) {
|
||||||
|
return Array.isArray(subject) ? subject : [subject];
|
||||||
|
}
|
||||||
|
|
||||||
|
var REGEX_BLANK_LINE = /^\s+$/;
|
||||||
|
var REGEX_LEADING_EXCAPED_EXCLAMATION = /^\\!/;
|
||||||
|
var REGEX_LEADING_EXCAPED_HASH = /^\\#/;
|
||||||
|
var SLASH = '/';
|
||||||
|
var KEY_IGNORE = typeof Symbol !== 'undefined' ? Symbol.for('node-ignore')
|
||||||
|
/* istanbul ignore next */
|
||||||
|
: 'node-ignore';
|
||||||
|
|
||||||
|
var define = function define(object, key, value) {
|
||||||
|
return Object.defineProperty(object, key, { value });
|
||||||
|
};
|
||||||
|
|
||||||
|
var REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g;
|
||||||
|
|
||||||
|
// Sanitize the range of a regular expression
|
||||||
|
// The cases are complicated, see test cases for details
|
||||||
|
var sanitizeRange = function sanitizeRange(range) {
|
||||||
|
return range.replace(REGEX_REGEXP_RANGE, function (match, from, to) {
|
||||||
|
return from.charCodeAt(0) <= to.charCodeAt(0) ? match
|
||||||
|
// Invalid range (out of order) which is ok for gitignore rules but
|
||||||
|
// fatal for JavaScript regular expression, so eliminate it.
|
||||||
|
: '';
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// > If the pattern ends with a slash,
|
||||||
|
// > it is removed for the purpose of the following description,
|
||||||
|
// > but it would only find a match with a directory.
|
||||||
|
// > In other words, foo/ will match a directory foo and paths underneath it,
|
||||||
|
// > but will not match a regular file or a symbolic link foo
|
||||||
|
// > (this is consistent with the way how pathspec works in general in Git).
|
||||||
|
// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'
|
||||||
|
// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call
|
||||||
|
// you could use option `mark: true` with `glob`
|
||||||
|
|
||||||
|
// '`foo/`' should not continue with the '`..`'
|
||||||
|
var DEFAULT_REPLACER_PREFIX = [
|
||||||
|
|
||||||
|
// > Trailing spaces are ignored unless they are quoted with backslash ("\")
|
||||||
|
[
|
||||||
|
// (a\ ) -> (a )
|
||||||
|
// (a ) -> (a)
|
||||||
|
// (a \ ) -> (a )
|
||||||
|
/\\?\s+$/, function (match) {
|
||||||
|
return match.indexOf('\\') === 0 ? ' ' : '';
|
||||||
|
}],
|
||||||
|
|
||||||
|
// replace (\ ) with ' '
|
||||||
|
[/\\\s/g, function () {
|
||||||
|
return ' ';
|
||||||
|
}],
|
||||||
|
|
||||||
|
// Escape metacharacters
|
||||||
|
// which is written down by users but means special for regular expressions.
|
||||||
|
|
||||||
|
// > There are 12 characters with special meanings:
|
||||||
|
// > - the backslash \,
|
||||||
|
// > - the caret ^,
|
||||||
|
// > - the dollar sign $,
|
||||||
|
// > - the period or dot .,
|
||||||
|
// > - the vertical bar or pipe symbol |,
|
||||||
|
// > - the question mark ?,
|
||||||
|
// > - the asterisk or star *,
|
||||||
|
// > - the plus sign +,
|
||||||
|
// > - the opening parenthesis (,
|
||||||
|
// > - the closing parenthesis ),
|
||||||
|
// > - and the opening square bracket [,
|
||||||
|
// > - the opening curly brace {,
|
||||||
|
// > These special characters are often called "metacharacters".
|
||||||
|
[/[\\^$.|*+(){]/g, function (match) {
|
||||||
|
return `\\${match}`;
|
||||||
|
}], [
|
||||||
|
// > [abc] matches any character inside the brackets
|
||||||
|
// > (in this case a, b, or c);
|
||||||
|
/\[([^\]/]*)($|\])/g, function (match, p1, p2) {
|
||||||
|
return p2 === ']' ? `[${sanitizeRange(p1)}]` : `\\${match}`;
|
||||||
|
}], [
|
||||||
|
// > a question mark (?) matches a single character
|
||||||
|
/(?!\\)\?/g, function () {
|
||||||
|
return '[^/]';
|
||||||
|
}],
|
||||||
|
|
||||||
|
// leading slash
|
||||||
|
[
|
||||||
|
|
||||||
|
// > A leading slash matches the beginning of the pathname.
|
||||||
|
// > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
|
||||||
|
// A leading slash matches the beginning of the pathname
|
||||||
|
/^\//, function () {
|
||||||
|
return '^';
|
||||||
|
}],
|
||||||
|
|
||||||
|
// replace special metacharacter slash after the leading slash
|
||||||
|
[/\//g, function () {
|
||||||
|
return '\\/';
|
||||||
|
}], [
|
||||||
|
// > A leading "**" followed by a slash means match in all directories.
|
||||||
|
// > For example, "**/foo" matches file or directory "foo" anywhere,
|
||||||
|
// > the same as pattern "foo".
|
||||||
|
// > "**/foo/bar" matches file or directory "bar" anywhere that is directly
|
||||||
|
// > under directory "foo".
|
||||||
|
// Notice that the '*'s have been replaced as '\\*'
|
||||||
|
/^\^*\\\*\\\*\\\//,
|
||||||
|
|
||||||
|
// '**/foo' <-> 'foo'
|
||||||
|
function () {
|
||||||
|
return '^(?:.*\\/)?';
|
||||||
|
}]];
|
||||||
|
|
||||||
|
var DEFAULT_REPLACER_SUFFIX = [
|
||||||
|
// starting
|
||||||
|
[
|
||||||
|
// there will be no leading '/'
|
||||||
|
// (which has been replaced by section "leading slash")
|
||||||
|
// If starts with '**', adding a '^' to the regular expression also works
|
||||||
|
/^(?=[^^])/, function startingReplacer() {
|
||||||
|
return !/\/(?!$)/.test(this)
|
||||||
|
// > If the pattern does not contain a slash /,
|
||||||
|
// > Git treats it as a shell glob pattern
|
||||||
|
// Actually, if there is only a trailing slash,
|
||||||
|
// git also treats it as a shell glob pattern
|
||||||
|
? '(?:^|\\/)'
|
||||||
|
|
||||||
|
// > Otherwise, Git treats the pattern as a shell glob suitable for
|
||||||
|
// > consumption by fnmatch(3)
|
||||||
|
: '^';
|
||||||
|
}],
|
||||||
|
|
||||||
|
// two globstars
|
||||||
|
[
|
||||||
|
// Use lookahead assertions so that we could match more than one `'/**'`
|
||||||
|
/\\\/\\\*\\\*(?=\\\/|$)/g,
|
||||||
|
|
||||||
|
// Zero, one or several directories
|
||||||
|
// should not use '*', or it will be replaced by the next replacer
|
||||||
|
|
||||||
|
// Check if it is not the last `'/**'`
|
||||||
|
function (match, index, str) {
|
||||||
|
return index + 6 < str.length
|
||||||
|
|
||||||
|
// case: /**/
|
||||||
|
// > A slash followed by two consecutive asterisks then a slash matches
|
||||||
|
// > zero or more directories.
|
||||||
|
// > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
|
||||||
|
// '/**/'
|
||||||
|
? '(?:\\/[^\\/]+)*'
|
||||||
|
|
||||||
|
// case: /**
|
||||||
|
// > A trailing `"/**"` matches everything inside.
|
||||||
|
|
||||||
|
// #21: everything inside but it should not include the current folder
|
||||||
|
: '\\/.+';
|
||||||
|
}],
|
||||||
|
|
||||||
|
// intermediate wildcards
|
||||||
|
[
|
||||||
|
// Never replace escaped '*'
|
||||||
|
// ignore rule '\*' will match the path '*'
|
||||||
|
|
||||||
|
// 'abc.*/' -> go
|
||||||
|
// 'abc.*' -> skip this rule
|
||||||
|
/(^|[^\\]+)\\\*(?=.+)/g,
|
||||||
|
|
||||||
|
// '*.js' matches '.js'
|
||||||
|
// '*.js' doesn't match 'abc'
|
||||||
|
function (match, p1) {
|
||||||
|
return `${p1}[^\\/]*`;
|
||||||
|
}],
|
||||||
|
|
||||||
|
// trailing wildcard
|
||||||
|
[/(\^|\\\/)?\\\*$/, function (match, p1) {
|
||||||
|
var prefix = p1
|
||||||
|
// '\^':
|
||||||
|
// '/*' does not match ''
|
||||||
|
// '/*' does not match everything
|
||||||
|
|
||||||
|
// '\\\/':
|
||||||
|
// 'abc/*' does not match 'abc/'
|
||||||
|
? `${p1}[^/]+`
|
||||||
|
|
||||||
|
// 'a*' matches 'a'
|
||||||
|
// 'a*' matches 'aa'
|
||||||
|
: '[^/]*';
|
||||||
|
|
||||||
|
return `${prefix}(?=$|\\/$)`;
|
||||||
|
}], [
|
||||||
|
// unescape
|
||||||
|
/\\\\\\/g, function () {
|
||||||
|
return '\\';
|
||||||
|
}]];
|
||||||
|
|
||||||
|
var POSITIVE_REPLACERS = [].concat(DEFAULT_REPLACER_PREFIX, [
|
||||||
|
|
||||||
|
// 'f'
|
||||||
|
// matches
|
||||||
|
// - /f(end)
|
||||||
|
// - /f/
|
||||||
|
// - (start)f(end)
|
||||||
|
// - (start)f/
|
||||||
|
// doesn't match
|
||||||
|
// - oof
|
||||||
|
// - foo
|
||||||
|
// pseudo:
|
||||||
|
// -> (^|/)f(/|$)
|
||||||
|
|
||||||
|
// ending
|
||||||
|
[
|
||||||
|
// 'js' will not match 'js.'
|
||||||
|
// 'ab' will not match 'abc'
|
||||||
|
/(?:[^*/])$/,
|
||||||
|
|
||||||
|
// 'js*' will not match 'a.js'
|
||||||
|
// 'js/' will not match 'a.js'
|
||||||
|
// 'js' will match 'a.js' and 'a.js/'
|
||||||
|
function (match) {
|
||||||
|
return `${match}(?=$|\\/)`;
|
||||||
|
}]], DEFAULT_REPLACER_SUFFIX);
|
||||||
|
|
||||||
|
var NEGATIVE_REPLACERS = [].concat(DEFAULT_REPLACER_PREFIX, [
|
||||||
|
|
||||||
|
// #24, #38
|
||||||
|
// The MISSING rule of [gitignore docs](https://git-scm.com/docs/gitignore)
|
||||||
|
// A negative pattern without a trailing wildcard should not
|
||||||
|
// re-include the things inside that directory.
|
||||||
|
|
||||||
|
// eg:
|
||||||
|
// ['node_modules/*', '!node_modules']
|
||||||
|
// should ignore `node_modules/a.js`
|
||||||
|
[/(?:[^*])$/, function (match) {
|
||||||
|
return `${match}(?=$|\\/$)`;
|
||||||
|
}]], DEFAULT_REPLACER_SUFFIX);
|
||||||
|
|
||||||
|
// A simple cache, because an ignore rule only has only one certain meaning
|
||||||
|
var cache = Object.create(null);
|
||||||
|
|
||||||
|
// @param {pattern}
|
||||||
|
var make_regex = function make_regex(pattern, negative, ignorecase) {
|
||||||
|
var r = cache[pattern];
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
var replacers = negative ? NEGATIVE_REPLACERS : POSITIVE_REPLACERS;
|
||||||
|
|
||||||
|
var source = replacers.reduce(function (prev, current) {
|
||||||
|
return prev.replace(current[0], current[1].bind(pattern));
|
||||||
|
}, pattern);
|
||||||
|
|
||||||
|
return cache[pattern] = ignorecase ? new RegExp(source, 'i') : new RegExp(source);
|
||||||
|
};
|
||||||
|
|
||||||
|
// > A blank line matches no files, so it can serve as a separator for readability.
|
||||||
|
var checkPattern = function checkPattern(pattern) {
|
||||||
|
return pattern && typeof pattern === 'string' && !REGEX_BLANK_LINE.test(pattern)
|
||||||
|
|
||||||
|
// > A line starting with # serves as a comment.
|
||||||
|
&& pattern.indexOf('#') !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
var createRule = function createRule(pattern, ignorecase) {
|
||||||
|
var origin = pattern;
|
||||||
|
var negative = false;
|
||||||
|
|
||||||
|
// > An optional prefix "!" which negates the pattern;
|
||||||
|
if (pattern.indexOf('!') === 0) {
|
||||||
|
negative = true;
|
||||||
|
pattern = pattern.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern = pattern
|
||||||
|
// > Put a backslash ("\") in front of the first "!" for patterns that
|
||||||
|
// > begin with a literal "!", for example, `"\!important!.txt"`.
|
||||||
|
.replace(REGEX_LEADING_EXCAPED_EXCLAMATION, '!')
|
||||||
|
// > Put a backslash ("\") in front of the first hash for patterns that
|
||||||
|
// > begin with a hash.
|
||||||
|
.replace(REGEX_LEADING_EXCAPED_HASH, '#');
|
||||||
|
|
||||||
|
var regex = make_regex(pattern, negative, ignorecase);
|
||||||
|
|
||||||
|
return {
|
||||||
|
origin,
|
||||||
|
pattern,
|
||||||
|
negative,
|
||||||
|
regex
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var IgnoreBase = function () {
|
||||||
|
function IgnoreBase() {
|
||||||
|
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
||||||
|
_ref$ignorecase = _ref.ignorecase,
|
||||||
|
ignorecase = _ref$ignorecase === undefined ? true : _ref$ignorecase;
|
||||||
|
|
||||||
|
_classCallCheck(this, IgnoreBase);
|
||||||
|
|
||||||
|
this._rules = [];
|
||||||
|
this._ignorecase = ignorecase;
|
||||||
|
define(this, KEY_IGNORE, true);
|
||||||
|
this._initCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(IgnoreBase, [{
|
||||||
|
key: '_initCache',
|
||||||
|
value: function _initCache() {
|
||||||
|
this._cache = Object.create(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @param {Array.<string>|string|Ignore} pattern
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: 'add',
|
||||||
|
value: function add(pattern) {
|
||||||
|
this._added = false;
|
||||||
|
|
||||||
|
if (typeof pattern === 'string') {
|
||||||
|
pattern = pattern.split(/\r?\n/g);
|
||||||
|
}
|
||||||
|
|
||||||
|
make_array(pattern).forEach(this._addPattern, this);
|
||||||
|
|
||||||
|
// Some rules have just added to the ignore,
|
||||||
|
// making the behavior changed.
|
||||||
|
if (this._added) {
|
||||||
|
this._initCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: 'addPattern',
|
||||||
|
value: function addPattern(pattern) {
|
||||||
|
return this.add(pattern);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: '_addPattern',
|
||||||
|
value: function _addPattern(pattern) {
|
||||||
|
// #32
|
||||||
|
if (pattern && pattern[KEY_IGNORE]) {
|
||||||
|
this._rules = this._rules.concat(pattern._rules);
|
||||||
|
this._added = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkPattern(pattern)) {
|
||||||
|
var rule = createRule(pattern, this._ignorecase);
|
||||||
|
this._added = true;
|
||||||
|
this._rules.push(rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'filter',
|
||||||
|
value: function filter(paths) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
return make_array(paths).filter(function (path) {
|
||||||
|
return _this._filter(path);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'createFilter',
|
||||||
|
value: function createFilter() {
|
||||||
|
var _this2 = this;
|
||||||
|
|
||||||
|
return function (path) {
|
||||||
|
return _this2._filter(path);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'ignores',
|
||||||
|
value: function ignores(path) {
|
||||||
|
return !this._filter(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @returns `Boolean` true if the `path` is NOT ignored
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: '_filter',
|
||||||
|
value: function _filter(path, slices) {
|
||||||
|
if (!path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path in this._cache) {
|
||||||
|
return this._cache[path];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!slices) {
|
||||||
|
// path/to/a.js
|
||||||
|
// ['path', 'to', 'a.js']
|
||||||
|
slices = path.split(SLASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.pop();
|
||||||
|
|
||||||
|
return this._cache[path] = slices.length
|
||||||
|
// > It is not possible to re-include a file if a parent directory of
|
||||||
|
// > that file is excluded.
|
||||||
|
// If the path contains a parent directory, check the parent first
|
||||||
|
? this._filter(slices.join(SLASH) + SLASH, slices) && this._test(path)
|
||||||
|
|
||||||
|
// Or only test the path
|
||||||
|
: this._test(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @returns {Boolean} true if a file is NOT ignored
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: '_test',
|
||||||
|
value: function _test(path) {
|
||||||
|
// Explicitly define variable type by setting matched to `0`
|
||||||
|
var matched = 0;
|
||||||
|
|
||||||
|
this._rules.forEach(function (rule) {
|
||||||
|
// if matched = true, then we only test negative rules
|
||||||
|
// if matched = false, then we test non-negative rules
|
||||||
|
if (!(matched ^ rule.negative)) {
|
||||||
|
matched = rule.negative ^ rule.regex.test(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return !matched;
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return IgnoreBase;
|
||||||
|
}();
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
// --------------------------------------------------------------
|
||||||
|
/* istanbul ignore if */
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
// Detect `process` so that it can run in browsers.
|
||||||
|
typeof process !== 'undefined' && (process.env && process.env.IGNORE_TEST_WIN32 || process.platform === 'win32')) {
|
||||||
|
var filter = IgnoreBase.prototype._filter;
|
||||||
|
|
||||||
|
/* eslint no-control-regex: "off" */
|
||||||
|
var make_posix = function make_posix(str) {
|
||||||
|
return (/^\\\\\?\\/.test(str) || /[^\x00-\x80]+/.test(str) ? str : str.replace(/\\/g, '/')
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
IgnoreBase.prototype._filter = function filterWin32(path, slices) {
|
||||||
|
path = make_posix(path);
|
||||||
|
return filter.call(this, path, slices);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (options) {
|
||||||
|
return new IgnoreBase(options);
|
||||||
|
};
|
64
node_modules/@eslint/eslintrc/node_modules/ignore/package.json
generated
vendored
Normal file
64
node_modules/@eslint/eslintrc/node_modules/ignore/package.json
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
{
|
||||||
|
"name": "ignore",
|
||||||
|
"version": "4.0.6",
|
||||||
|
"description": "Ignore is a manager and filter for .gitignore rules.",
|
||||||
|
"files": [
|
||||||
|
"legacy.js",
|
||||||
|
"index.js",
|
||||||
|
"index.d.ts",
|
||||||
|
"LICENSE-MIT"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"prepublish": "npm run build",
|
||||||
|
"build": "babel -o legacy.js index.js",
|
||||||
|
"test:lint": "eslint .",
|
||||||
|
"test:tsc": "tsc ./test/ts/simple.ts",
|
||||||
|
"test:git": "tap test/git-check-ignore.js",
|
||||||
|
"test:ignore": "tap test/ignore.js --coverage",
|
||||||
|
"test-no-cov": "npm run test:lint && npm run test:tsc && tap test/*.js --coverage",
|
||||||
|
"test": "npm run test-no-cov",
|
||||||
|
"posttest": "tap --coverage-report=html && codecov"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@github.com:kaelzhang/node-ignore.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"ignore",
|
||||||
|
".gitignore",
|
||||||
|
"gitignore",
|
||||||
|
"npmignore",
|
||||||
|
"rules",
|
||||||
|
"manager",
|
||||||
|
"filter",
|
||||||
|
"regexp",
|
||||||
|
"regex",
|
||||||
|
"fnmatch",
|
||||||
|
"glob",
|
||||||
|
"asterisks",
|
||||||
|
"regular-expression"
|
||||||
|
],
|
||||||
|
"author": "kael",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/kaelzhang/node-ignore/issues"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-cli": "^6.26.0",
|
||||||
|
"babel-preset-env": "^1.7.0",
|
||||||
|
"codecov": "^3.0.4",
|
||||||
|
"eslint": "^5.3.0",
|
||||||
|
"eslint-config-ostai": "^1.3.2",
|
||||||
|
"eslint-plugin-import": "^2.13.0",
|
||||||
|
"mkdirp": "^0.5.1",
|
||||||
|
"pre-suf": "^1.1.0",
|
||||||
|
"rimraf": "^2.6.2",
|
||||||
|
"spawn-sync": "^2.0.0",
|
||||||
|
"tap": "^12.0.1",
|
||||||
|
"tmp": "0.0.33",
|
||||||
|
"typescript": "^3.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4"
|
||||||
|
}
|
||||||
|
}
|
81
node_modules/@eslint/eslintrc/package.json
generated
vendored
Normal file
81
node_modules/@eslint/eslintrc/package.json
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
{
|
||||||
|
"name": "@eslint/eslintrc",
|
||||||
|
"version": "1.0.5",
|
||||||
|
"description": "The legacy ESLintRC config file format for ESLint",
|
||||||
|
"type": "module",
|
||||||
|
"main": "./dist/eslintrc.cjs",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./lib/index.js",
|
||||||
|
"require": "./dist/eslintrc.cjs"
|
||||||
|
},
|
||||||
|
"./package.json": "./package.json",
|
||||||
|
"./universal": {
|
||||||
|
"import": "./lib/index-universal.js",
|
||||||
|
"require": "./dist/eslintrc-universal.cjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib",
|
||||||
|
"conf",
|
||||||
|
"LICENSE",
|
||||||
|
"dist",
|
||||||
|
"universal.js"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"prepare": "npm run build",
|
||||||
|
"build": "rollup -c",
|
||||||
|
"lint": "eslint . --report-unused-disable-directives",
|
||||||
|
"fix": "npm run lint -- --fix",
|
||||||
|
"test": "mocha -R progress -c 'tests/lib/*.cjs' && c8 mocha -R progress -c 'tests/lib/**/*.js'",
|
||||||
|
"generate-release": "eslint-generate-release",
|
||||||
|
"generate-alpharelease": "eslint-generate-prerelease alpha",
|
||||||
|
"generate-betarelease": "eslint-generate-prerelease beta",
|
||||||
|
"generate-rcrelease": "eslint-generate-prerelease rc",
|
||||||
|
"publish-release": "eslint-publish-release"
|
||||||
|
},
|
||||||
|
"repository": "eslint/eslintrc",
|
||||||
|
"keywords": [
|
||||||
|
"ESLint",
|
||||||
|
"ESLintRC",
|
||||||
|
"Configuration"
|
||||||
|
],
|
||||||
|
"author": "Nicholas C. Zakas",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/eslint/eslintrc/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/eslint/eslintrc#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"c8": "^7.7.3",
|
||||||
|
"chai": "^4.3.4",
|
||||||
|
"eslint": "^7.31.0",
|
||||||
|
"eslint-config-eslint": "^7.0.0",
|
||||||
|
"eslint-plugin-jsdoc": "^35.4.1",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-release": "^3.2.0",
|
||||||
|
"fs-teardown": "^0.1.3",
|
||||||
|
"mocha": "^9.0.3",
|
||||||
|
"rollup": "^2.54.0",
|
||||||
|
"shelljs": "^0.8.4",
|
||||||
|
"sinon": "^11.1.2",
|
||||||
|
"temp-dir": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "^6.12.4",
|
||||||
|
"debug": "^4.3.2",
|
||||||
|
"espree": "^9.2.0",
|
||||||
|
"globals": "^13.9.0",
|
||||||
|
"ignore": "^4.0.6",
|
||||||
|
"import-fresh": "^3.2.1",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"minimatch": "^3.0.4",
|
||||||
|
"strip-json-comments": "^3.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
}
|
9
node_modules/@eslint/eslintrc/universal.js
generated
vendored
Normal file
9
node_modules/@eslint/eslintrc/universal.js
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// Jest (and probably some other runtimes with custom implementations of
|
||||||
|
// `require`) doesn't support `exports` in `package.json`, so this file is here
|
||||||
|
// to help them load this module. Note that it is also `.js` and not `.cjs` for
|
||||||
|
// the same reason - `cjs` files requires to be loaded with an extension, but
|
||||||
|
// since Jest doesn't respect `module` outside of ESM mode it still works in
|
||||||
|
// this case (and the `require` in _this_ file does specify the extension).
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
module.exports = require("./dist/eslintrc-universal.cjs");
|
56
node_modules/@humanwhocodes/config-array/CHANGELOG.md
generated
vendored
Normal file
56
node_modules/@humanwhocodes/config-array/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
### [0.9.3](https://www.github.com/humanwhocodes/config-array/compare/v0.9.2...v0.9.3) (2022-01-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Make negated ignore patterns work like gitignore ([4ee8e99](https://www.github.com/humanwhocodes/config-array/commit/4ee8e998436e2c4538b06476e0bead8a44fe5a1b))
|
||||||
|
|
||||||
|
### [0.9.2](https://www.github.com/humanwhocodes/config-array/compare/v0.9.1...v0.9.2) (2021-11-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Object merging error by upgrading object-schema ([377d06d](https://www.github.com/humanwhocodes/config-array/commit/377d06d2a44d781b0bec70b3389c48b3d5a63f94))
|
||||||
|
|
||||||
|
### [0.9.1](https://www.github.com/humanwhocodes/config-array/compare/v0.9.0...v0.9.1) (2021-10-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Properly build package for release ([168155f](https://www.github.com/humanwhocodes/config-array/commit/168155f3fed91ab35566c452efd28debf8ec2b85))
|
||||||
|
|
||||||
|
## [0.9.0](https://www.github.com/humanwhocodes/config-array/compare/v0.8.0...v0.9.0) (2021-10-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* getConfig() now returns undefined when no configs match. ([a563b82](https://www.github.com/humanwhocodes/config-array/commit/a563b8255d4eb2bb7745314e3f00ef53792b343f))
|
||||||
|
|
||||||
|
## [0.8.0](https://www.github.com/humanwhocodes/config-array/compare/v0.7.0...v0.8.0) (2021-10-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add isIgnored() method ([343e5a0](https://www.github.com/humanwhocodes/config-array/commit/343e5a0a9e32028bfc6c0bf1ec0c6badf74f47f9))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Ensure global ignores are honored ([343e5a0](https://www.github.com/humanwhocodes/config-array/commit/343e5a0a9e32028bfc6c0bf1ec0c6badf74f47f9))
|
||||||
|
|
||||||
|
## [0.7.0](https://www.github.com/humanwhocodes/config-array/compare/v0.6.0...v0.7.0) (2021-09-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Only object configs by default ([5645f24](https://www.github.com/humanwhocodes/config-array/commit/5645f241b2412a3263a02ef9e3a9bd19cc86035d))
|
||||||
|
|
||||||
|
## [0.6.0](https://www.github.com/humanwhocodes/config-array/compare/v0.5.0...v0.6.0) (2021-04-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add the normalizeSync() method ([3e347f9](https://www.github.com/humanwhocodes/config-array/commit/3e347f9d77c5ca2b15995e75ff7bc4fb96b7d66e))
|
||||||
|
* Allow async config functions ([a9def0f](https://www.github.com/humanwhocodes/config-array/commit/a9def0faf579c223349dfe08d2486756840538c3))
|
201
node_modules/@humanwhocodes/config-array/LICENSE
generated
vendored
Normal file
201
node_modules/@humanwhocodes/config-array/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
301
node_modules/@humanwhocodes/config-array/README.md
generated
vendored
Normal file
301
node_modules/@humanwhocodes/config-array/README.md
generated
vendored
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
# Config Array
|
||||||
|
|
||||||
|
by [Nicholas C. Zakas](https://humanwhocodes.com)
|
||||||
|
|
||||||
|
If you find this useful, please consider supporting my work with a [donation](https://humanwhocodes.com/donate).
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
A config array is a way of managing configurations that are based on glob pattern matching of filenames. Each config array contains the information needed to determine the correct configuration for any file based on the filename.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
In 2019, I submitted an [ESLint RFC](https://github.com/eslint/rfcs/pull/9) proposing a new way of configuring ESLint. The goal was to streamline what had become an increasingly complicated configuration process. Over several iterations, this proposal was eventually born.
|
||||||
|
|
||||||
|
The basic idea is that all configuration, including overrides, can be represented by a single array where each item in the array is a config object. Config objects appearing later in the array override config objects appearing earlier in the array. You can calculate a config for a given file by traversing all config objects in the array to find the ones that match the filename. Matching is done by specifying glob patterns in `files` and `ignores` properties on each config object. Here's an example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default [
|
||||||
|
|
||||||
|
// match all JSON files
|
||||||
|
{
|
||||||
|
name: "JSON Handler",
|
||||||
|
files: ["**/*.json"],
|
||||||
|
handler: jsonHandler
|
||||||
|
},
|
||||||
|
|
||||||
|
// match only package.json
|
||||||
|
{
|
||||||
|
name: "package.json Handler",
|
||||||
|
files: ["package.json"],
|
||||||
|
handler: packageJsonHandler
|
||||||
|
}
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, there are two config objects: the first matches all JSON files in all directories and the second matches just `package.json` in the base path directory (all the globs are evaluated as relative to a base path that can be specified). When you retrieve a configuration for `foo.json`, only the first config object matches so `handler` is equal to `jsonHandler`; when you retrieve a configuration for `package.json`, `handler` is equal to `packageJsonHandler` (because both config objects match, the second one wins).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
You can install the package using npm or Yarn:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @humanwhocodes/config-array --save
|
||||||
|
|
||||||
|
# or
|
||||||
|
|
||||||
|
yarn add @humanwhocodes/config-array
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
First, import the `ConfigArray` constructor:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { ConfigArray } from "@humanwhocodes/config-array";
|
||||||
|
|
||||||
|
// or using CommonJS
|
||||||
|
|
||||||
|
const { ConfigArray } = require("@humanwhocodes/config-array");
|
||||||
|
```
|
||||||
|
|
||||||
|
When you create a new instance of `ConfigArray`, you must pass in two arguments: an array of configs and an options object. The array of configs is most likely read in from a configuration file, so here's a typical example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const configFilename = path.resolve(process.cwd(), "my.config.js");
|
||||||
|
const { default: rawConfigs } = await import(configFilename);
|
||||||
|
const configs = new ConfigArray(rawConfigs, {
|
||||||
|
|
||||||
|
// the path to match filenames from
|
||||||
|
basePath: process.cwd(),
|
||||||
|
|
||||||
|
// additional items in each config
|
||||||
|
schema: mySchema
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
This example reads in an object or array from `my.config.js` and passes it into the `ConfigArray` constructor as the first argument. The second argument is an object specifying the `basePath` (the directoy in which `my.config.js` is found) and a `schema` to define the additional properties of a config object beyond `files`, `ignores`, and `name`.
|
||||||
|
|
||||||
|
### Specifying a Schema
|
||||||
|
|
||||||
|
The `schema` option is required for you to use additional properties in config objects. The schema is object that follows the format of an [`ObjectSchema`](https://npmjs.com/package/@humanwhocodes/object-schema). The schema specifies both validation and merge rules that the `ConfigArray` instance needs to combine configs when there are multiple matches. Here's an example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const configFilename = path.resolve(process.cwd(), "my.config.js");
|
||||||
|
const { default: rawConfigs } = await import(configFilename);
|
||||||
|
|
||||||
|
const mySchema = {
|
||||||
|
|
||||||
|
// define the handler key in configs
|
||||||
|
handler: {
|
||||||
|
required: true,
|
||||||
|
merge(a, b) {
|
||||||
|
if (!b) return a;
|
||||||
|
if (!a) return b;
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
if (typeof value !== "function") {
|
||||||
|
throw new TypeError("Function expected.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const configs = new ConfigArray(rawConfigs, {
|
||||||
|
|
||||||
|
// the path to match filenames from
|
||||||
|
basePath: process.cwd(),
|
||||||
|
|
||||||
|
// additional item schemas in each config
|
||||||
|
schema: mySchema,
|
||||||
|
|
||||||
|
// additional config types supported (default: [])
|
||||||
|
extraConfigTypes: ["array", "function"];
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Config Arrays
|
||||||
|
|
||||||
|
Config arrays can be multidimensional, so it's possible for a config array to contain another config array when `extraConfigTypes` contains `"array"`, such as:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default [
|
||||||
|
|
||||||
|
// JS config
|
||||||
|
{
|
||||||
|
files: ["**/*.js"],
|
||||||
|
handler: jsHandler
|
||||||
|
},
|
||||||
|
|
||||||
|
// JSON configs
|
||||||
|
[
|
||||||
|
|
||||||
|
// match all JSON files
|
||||||
|
{
|
||||||
|
name: "JSON Handler",
|
||||||
|
files: ["**/*.json"],
|
||||||
|
handler: jsonHandler
|
||||||
|
},
|
||||||
|
|
||||||
|
// match only package.json
|
||||||
|
{
|
||||||
|
name: "package.json Handler",
|
||||||
|
files: ["package.json"],
|
||||||
|
handler: packageJsonHandler
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// filename must match function
|
||||||
|
{
|
||||||
|
files: [ filePath => filePath.endsWith(".md") ],
|
||||||
|
handler: markdownHandler
|
||||||
|
},
|
||||||
|
|
||||||
|
// filename must match all patterns in subarray
|
||||||
|
{
|
||||||
|
files: [ ["*.test.*", "*.js"] ],
|
||||||
|
handler: jsTestHandler
|
||||||
|
},
|
||||||
|
|
||||||
|
// filename must not match patterns beginning with !
|
||||||
|
{
|
||||||
|
name: "Non-JS files",
|
||||||
|
files: ["!*.js"],
|
||||||
|
settings: {
|
||||||
|
js: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, the array contains both config objects and a config array. When a config array is normalized (see details below), it is flattened so only config objects remain. However, the order of evaluation remains the same.
|
||||||
|
|
||||||
|
If the `files` array contains a function, then that function is called with the absolute path of the file and is expected to return `true` if there is a match and `false` if not. (The `ignores` array can also contain functions.)
|
||||||
|
|
||||||
|
If the `files` array contains an item that is an array of strings and functions, then all patterns must match in order for the config to match. In the preceding examples, both `*.test.*` and `*.js` must match in order for the config object to be used.
|
||||||
|
|
||||||
|
If a pattern in the files array begins with `!` then it excludes that pattern. In the preceding example, any filename that doesn't end with `.js` will automatically getting a `settings.js` property set to `false`.
|
||||||
|
|
||||||
|
You can also specify an `ignores` key that will force files matching those patterns to not be included. If the `ignores` key is in a config object without a `files` key, then those ignores will always be applied; if the `ignores` key is in a config object with a `files` key, then those ignores are only applied when `files` matches. Here's an example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default [
|
||||||
|
|
||||||
|
// Always ignored
|
||||||
|
{
|
||||||
|
ignores: ["**/.git/**", "**/node_modules/**"]
|
||||||
|
},
|
||||||
|
|
||||||
|
// .eslintrc.js file is ignored only when .js file matches
|
||||||
|
{
|
||||||
|
files: ["**/*.js"],
|
||||||
|
ignores: [".eslintrc.js"]
|
||||||
|
handler: jsHandler
|
||||||
|
}
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use negated patterns in `ignores` to exclude a file that was already ignored, such as:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default [
|
||||||
|
|
||||||
|
// Ignore all JSON files except tsconfig.json
|
||||||
|
{
|
||||||
|
ignores: ["**/*.json", "!tsconfig.json"]
|
||||||
|
},
|
||||||
|
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### Config Functions
|
||||||
|
|
||||||
|
Config arrays can also include config functions when `extraConfigTypes` contains `"function"`. A config function accepts a single parameter, `context` (defined by you), and must return either a config object or a config array (it cannot return another function). Config functions allow end users to execute code in the creation of appropriate config objects. Here's an example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default [
|
||||||
|
|
||||||
|
// JS config
|
||||||
|
{
|
||||||
|
files: ["**/*.js"],
|
||||||
|
handler: jsHandler
|
||||||
|
},
|
||||||
|
|
||||||
|
// JSON configs
|
||||||
|
function (context) {
|
||||||
|
return [
|
||||||
|
|
||||||
|
// match all JSON files
|
||||||
|
{
|
||||||
|
name: context.name + " JSON Handler",
|
||||||
|
files: ["**/*.json"],
|
||||||
|
handler: jsonHandler
|
||||||
|
},
|
||||||
|
|
||||||
|
// match only package.json
|
||||||
|
{
|
||||||
|
name: context.name + " package.json Handler",
|
||||||
|
files: ["package.json"],
|
||||||
|
handler: packageJsonHandler
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
When a config array is normalized, each function is executed and replaced in the config array with the return value.
|
||||||
|
|
||||||
|
**Note:** Config functions can also be async.
|
||||||
|
|
||||||
|
### Normalizing Config Arrays
|
||||||
|
|
||||||
|
Once a config array has been created and loaded with all of the raw config data, it must be normalized before it can be used. The normalization process goes through and flattens the config array as well as executing all config functions to get their final values.
|
||||||
|
|
||||||
|
To normalize a config array, call the `normalize()` method and pass in a context object:
|
||||||
|
|
||||||
|
```js
|
||||||
|
await configs.normalize({
|
||||||
|
name: "MyApp"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
The `normalize()` method returns a promise, so be sure to use the `await` operator. The config array instance is normalized in-place, so you don't need to create a new variable.
|
||||||
|
|
||||||
|
If you want to disallow async config functions, you can call `normalizeSync()` instead. This method is completely synchronous and does not require using the `await` operator as it does not return a promise:
|
||||||
|
|
||||||
|
```js
|
||||||
|
await configs.normalizeSync({
|
||||||
|
name: "MyApp"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:** Once a `ConfigArray` is normalized, it cannot be changed further. You can, however, create a new `ConfigArray` and pass in the normalized instance to create an unnormalized copy.
|
||||||
|
|
||||||
|
### Getting Config for a File
|
||||||
|
|
||||||
|
To get the config for a file, use the `getConfig()` method on a normalized config array and pass in the filename to get a config for:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// pass in absolute filename
|
||||||
|
const fileConfig = configs.getConfig(path.resolve(process.cwd(), "package.json"));
|
||||||
|
```
|
||||||
|
|
||||||
|
The config array always returns an object, even if there are no configs matching the given filename. You can then inspect the returned config object to determine how to proceed.
|
||||||
|
|
||||||
|
A few things to keep in mind:
|
||||||
|
|
||||||
|
* You must pass in the absolute filename to get a config for.
|
||||||
|
* The returned config object never has `files`, `ignores`, or `name` properties; the only properties on the object will be the other configuration options specified.
|
||||||
|
* The config array caches configs, so subsequent calls to `getConfig()` with the same filename will return in a fast lookup rather than another calculation.
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
The design of this project was influenced by feedback on the ESLint RFC, and incorporates ideas from:
|
||||||
|
|
||||||
|
* Teddy Katz (@not-an-aardvark)
|
||||||
|
* Toru Nagashima (@mysticatea)
|
||||||
|
* Kai Cataldo (@kaicataldo)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Apache 2.0
|
698
node_modules/@humanwhocodes/config-array/api.js
generated
vendored
Normal file
698
node_modules/@humanwhocodes/config-array/api.js
generated
vendored
Normal file
|
@ -0,0 +1,698 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
Object.defineProperty(exports, '__esModule', { value: true });
|
||||||
|
|
||||||
|
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||||
|
|
||||||
|
var path = _interopDefault(require('path'));
|
||||||
|
var minimatch = _interopDefault(require('minimatch'));
|
||||||
|
var createDebug = _interopDefault(require('debug'));
|
||||||
|
var objectSchema = require('@humanwhocodes/object-schema');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fileoverview ConfigSchema
|
||||||
|
* @author Nicholas C. Zakas
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assets that a given value is an array.
|
||||||
|
* @param {*} value The value to check.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} When the value is not an array.
|
||||||
|
*/
|
||||||
|
function assertIsArray(value) {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
throw new TypeError('Expected value to be an array.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assets that a given value is an array containing only strings and functions.
|
||||||
|
* @param {*} value The value to check.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} When the value is not an array of strings and functions.
|
||||||
|
*/
|
||||||
|
function assertIsArrayOfStringsAndFunctions(value, name) {
|
||||||
|
assertIsArray(value);
|
||||||
|
|
||||||
|
if (value.some(item => typeof item !== 'string' && typeof item !== 'function')) {
|
||||||
|
throw new TypeError('Expected array to only contain strings.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Exports
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base schema that every ConfigArray uses.
|
||||||
|
* @type Object
|
||||||
|
*/
|
||||||
|
const baseSchema = Object.freeze({
|
||||||
|
name: {
|
||||||
|
required: false,
|
||||||
|
merge() {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
if (typeof value !== 'string') {
|
||||||
|
throw new TypeError('Property must be a string.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
required: false,
|
||||||
|
merge() {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
|
||||||
|
// first check if it's an array
|
||||||
|
assertIsArray(value);
|
||||||
|
|
||||||
|
// then check each member
|
||||||
|
value.forEach(item => {
|
||||||
|
if (Array.isArray(item)) {
|
||||||
|
assertIsArrayOfStringsAndFunctions(item);
|
||||||
|
} else if (typeof item !== 'string' && typeof item !== 'function') {
|
||||||
|
throw new TypeError('Items must be a string, a function, or an array of strings and functions.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ignores: {
|
||||||
|
required: false,
|
||||||
|
merge() {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
validate: assertIsArrayOfStringsAndFunctions
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fileoverview ConfigArray
|
||||||
|
* @author Nicholas C. Zakas
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Helpers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const debug = createDebug('@hwc/config-array');
|
||||||
|
|
||||||
|
const MINIMATCH_OPTIONS = {
|
||||||
|
matchBase: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const CONFIG_TYPES = new Set(['array', 'function']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shorthand for checking if a value is a string.
|
||||||
|
* @param {any} value The value to check.
|
||||||
|
* @returns {boolean} True if a string, false if not.
|
||||||
|
*/
|
||||||
|
function isString(value) {
|
||||||
|
return typeof value === 'string';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a `ConfigArray` by flattening it and executing any functions
|
||||||
|
* that are found inside.
|
||||||
|
* @param {Array} items The items in a `ConfigArray`.
|
||||||
|
* @param {Object} context The context object to pass into any function
|
||||||
|
* found.
|
||||||
|
* @param {Array<string>} extraConfigTypes The config types to check.
|
||||||
|
* @returns {Promise<Array>} A flattened array containing only config objects.
|
||||||
|
* @throws {TypeError} When a config function returns a function.
|
||||||
|
*/
|
||||||
|
async function normalize(items, context, extraConfigTypes) {
|
||||||
|
|
||||||
|
const allowFunctions = extraConfigTypes.includes('function');
|
||||||
|
const allowArrays = extraConfigTypes.includes('array');
|
||||||
|
|
||||||
|
async function *flatTraverse(array) {
|
||||||
|
for (let item of array) {
|
||||||
|
if (typeof item === 'function') {
|
||||||
|
if (!allowFunctions) {
|
||||||
|
throw new TypeError('Unexpected function.');
|
||||||
|
}
|
||||||
|
|
||||||
|
item = item(context);
|
||||||
|
if (item.then) {
|
||||||
|
item = await item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(item)) {
|
||||||
|
if (!allowArrays) {
|
||||||
|
throw new TypeError('Unexpected array.');
|
||||||
|
}
|
||||||
|
yield * flatTraverse(item);
|
||||||
|
} else if (typeof item === 'function') {
|
||||||
|
throw new TypeError('A config function can only return an object or array.');
|
||||||
|
} else {
|
||||||
|
yield item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Async iterables cannot be used with the spread operator, so we need to manually
|
||||||
|
* create the array to return.
|
||||||
|
*/
|
||||||
|
const asyncIterable = await flatTraverse(items);
|
||||||
|
const configs = [];
|
||||||
|
|
||||||
|
for await (const config of asyncIterable) {
|
||||||
|
configs.push(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a `ConfigArray` by flattening it and executing any functions
|
||||||
|
* that are found inside.
|
||||||
|
* @param {Array} items The items in a `ConfigArray`.
|
||||||
|
* @param {Object} context The context object to pass into any function
|
||||||
|
* found.
|
||||||
|
* @param {Array<string>} extraConfigTypes The config types to check.
|
||||||
|
* @returns {Array} A flattened array containing only config objects.
|
||||||
|
* @throws {TypeError} When a config function returns a function.
|
||||||
|
*/
|
||||||
|
function normalizeSync(items, context, extraConfigTypes) {
|
||||||
|
|
||||||
|
const allowFunctions = extraConfigTypes.includes('function');
|
||||||
|
const allowArrays = extraConfigTypes.includes('array');
|
||||||
|
|
||||||
|
function *flatTraverse(array) {
|
||||||
|
for (let item of array) {
|
||||||
|
if (typeof item === 'function') {
|
||||||
|
|
||||||
|
if (!allowFunctions) {
|
||||||
|
throw new TypeError('Unexpected function.');
|
||||||
|
}
|
||||||
|
|
||||||
|
item = item(context);
|
||||||
|
if (item.then) {
|
||||||
|
throw new TypeError('Async config functions are not supported.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(item)) {
|
||||||
|
|
||||||
|
if (!allowArrays) {
|
||||||
|
throw new TypeError('Unexpected array.');
|
||||||
|
}
|
||||||
|
|
||||||
|
yield * flatTraverse(item);
|
||||||
|
} else if (typeof item === 'function') {
|
||||||
|
throw new TypeError('A config function can only return an object or array.');
|
||||||
|
} else {
|
||||||
|
yield item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...flatTraverse(items)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a given file path should be ignored based on the given
|
||||||
|
* matcher.
|
||||||
|
* @param {Array<string|() => boolean>} ignores The ignore patterns to check.
|
||||||
|
* @param {string} filePath The absolute path of the file to check.
|
||||||
|
* @param {string} relativeFilePath The relative path of the file to check.
|
||||||
|
* @returns {boolean} True if the path should be ignored and false if not.
|
||||||
|
*/
|
||||||
|
function shouldIgnoreFilePath(ignores, filePath, relativeFilePath) {
|
||||||
|
|
||||||
|
let shouldIgnore = false;
|
||||||
|
|
||||||
|
for (const matcher of ignores) {
|
||||||
|
|
||||||
|
if (typeof matcher === 'function') {
|
||||||
|
shouldIgnore = shouldIgnore || matcher(filePath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there's a negated pattern, that means anything matching
|
||||||
|
* must NOT be ignored. To do that, we need to use the `flipNegate`
|
||||||
|
* option for minimatch to check if the filepath matches the
|
||||||
|
* pattern specified after the !, and if that result is true,
|
||||||
|
* then we return false immediately because this file should
|
||||||
|
* never be ignored.
|
||||||
|
*/
|
||||||
|
if (matcher.startsWith('!')) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The file must already be ignored in order to apply a negated
|
||||||
|
* pattern, because negated patterns simply remove files that
|
||||||
|
* would already be ignored.
|
||||||
|
*/
|
||||||
|
if (shouldIgnore &&
|
||||||
|
minimatch(relativeFilePath, matcher, {
|
||||||
|
...MINIMATCH_OPTIONS,
|
||||||
|
flipNegate: true
|
||||||
|
})) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shouldIgnore = shouldIgnore || minimatch(relativeFilePath, matcher, MINIMATCH_OPTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return shouldIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a given file path is matched by a config. If the config
|
||||||
|
* has no `files` field, then it matches; otherwise, if a `files` field
|
||||||
|
* is present then we match the globs in `files` and exclude any globs in
|
||||||
|
* `ignores`.
|
||||||
|
* @param {string} filePath The absolute file path to check.
|
||||||
|
* @param {Object} config The config object to check.
|
||||||
|
* @returns {boolean} True if the file path is matched by the config,
|
||||||
|
* false if not.
|
||||||
|
*/
|
||||||
|
function pathMatches(filePath, basePath, config) {
|
||||||
|
|
||||||
|
// a config without `files` field always match
|
||||||
|
if (!config.files) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For both files and ignores, functions are passed the absolute
|
||||||
|
* file path while strings are compared against the relative
|
||||||
|
* file path.
|
||||||
|
*/
|
||||||
|
const relativeFilePath = path.relative(basePath, filePath);
|
||||||
|
|
||||||
|
// if files isn't an array, throw an error
|
||||||
|
if (!Array.isArray(config.files) || config.files.length === 0) {
|
||||||
|
throw new TypeError('The files key must be a non-empty array.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// match both strings and functions
|
||||||
|
const match = pattern => {
|
||||||
|
|
||||||
|
if (isString(pattern)) {
|
||||||
|
return minimatch(relativeFilePath, pattern, MINIMATCH_OPTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof pattern === 'function') {
|
||||||
|
return pattern(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new TypeError(`Unexpected matcher type ${pattern}.`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isFilePathIgnored = matcher => {
|
||||||
|
return shouldIgnoreFilePath([matcher], filePath, relativeFilePath);
|
||||||
|
};
|
||||||
|
|
||||||
|
// check for all matches to config.files
|
||||||
|
let filePathMatchesPattern = config.files.some(pattern => {
|
||||||
|
if (Array.isArray(pattern)) {
|
||||||
|
return pattern.every(match);
|
||||||
|
}
|
||||||
|
|
||||||
|
return match(pattern);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the file path matches the config.files patterns, then check to see
|
||||||
|
* if there are any files to ignore.
|
||||||
|
*/
|
||||||
|
if (filePathMatchesPattern && config.ignores) {
|
||||||
|
filePathMatchesPattern = !config.ignores.some(isFilePathIgnored);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filePathMatchesPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that a ConfigArray has been normalized.
|
||||||
|
* @param {ConfigArray} configArray The ConfigArray to check.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} When the `ConfigArray` is not normalized.
|
||||||
|
*/
|
||||||
|
function assertNormalized(configArray) {
|
||||||
|
// TODO: Throw more verbose error
|
||||||
|
if (!configArray.isNormalized()) {
|
||||||
|
throw new Error('ConfigArray must be normalized to perform this operation.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that config types are valid.
|
||||||
|
* @param {Array<string>} extraConfigTypes The config types to check.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} When the config types array is invalid.
|
||||||
|
*/
|
||||||
|
function assertExtraConfigTypes(extraConfigTypes) {
|
||||||
|
if (extraConfigTypes.length > 2) {
|
||||||
|
throw new TypeError('configTypes must be an array with at most two items.');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const configType of extraConfigTypes) {
|
||||||
|
if (!CONFIG_TYPES.has(configType)) {
|
||||||
|
throw new TypeError(`Unexpected config type "${configType}" found. Expected one of: "object", "array", "function".`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Public Interface
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const ConfigArraySymbol = {
|
||||||
|
isNormalized: Symbol('isNormalized'),
|
||||||
|
configCache: Symbol('configCache'),
|
||||||
|
schema: Symbol('schema'),
|
||||||
|
finalizeConfig: Symbol('finalizeConfig'),
|
||||||
|
preprocessConfig: Symbol('preprocessConfig')
|
||||||
|
};
|
||||||
|
|
||||||
|
// used to store calculate data for faster lookup
|
||||||
|
const dataCache = new WeakMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an array of config objects and provides method for working with
|
||||||
|
* those config objects.
|
||||||
|
*/
|
||||||
|
class ConfigArray extends Array {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of ConfigArray.
|
||||||
|
* @param {Iterable|Function|Object} configs An iterable yielding config
|
||||||
|
* objects, or a config function, or a config object.
|
||||||
|
* @param {string} [options.basePath=""] The path of the config file
|
||||||
|
* @param {boolean} [options.normalized=false] Flag indicating if the
|
||||||
|
* configs have already been normalized.
|
||||||
|
* @param {Object} [options.schema] The additional schema
|
||||||
|
* definitions to use for the ConfigArray schema.
|
||||||
|
* @param {Array<string>} [options.configTypes] List of config types supported.
|
||||||
|
*/
|
||||||
|
constructor(configs,
|
||||||
|
{
|
||||||
|
basePath = '',
|
||||||
|
normalized = false,
|
||||||
|
schema: customSchema,
|
||||||
|
extraConfigTypes = []
|
||||||
|
} = {}
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks if the array has been normalized.
|
||||||
|
* @property isNormalized
|
||||||
|
* @type boolean
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this[ConfigArraySymbol.isNormalized] = normalized;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The schema used for validating and merging configs.
|
||||||
|
* @property schema
|
||||||
|
* @type ObjectSchema
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this[ConfigArraySymbol.schema] = new objectSchema.ObjectSchema({
|
||||||
|
...customSchema,
|
||||||
|
...baseSchema
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path of the config file that this array was loaded from.
|
||||||
|
* This is used to calculate filename matches.
|
||||||
|
* @property basePath
|
||||||
|
* @type string
|
||||||
|
*/
|
||||||
|
this.basePath = basePath;
|
||||||
|
|
||||||
|
assertExtraConfigTypes(extraConfigTypes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The supported config types.
|
||||||
|
* @property configTypes
|
||||||
|
* @type Array<string>
|
||||||
|
*/
|
||||||
|
this.extraConfigTypes = Object.freeze([...extraConfigTypes]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cache to store calculated configs for faster repeat lookup.
|
||||||
|
* @property configCache
|
||||||
|
* @type Map
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this[ConfigArraySymbol.configCache] = new Map();
|
||||||
|
|
||||||
|
// init cache
|
||||||
|
dataCache.set(this, {});
|
||||||
|
|
||||||
|
// load the configs into this array
|
||||||
|
if (Array.isArray(configs)) {
|
||||||
|
this.push(...configs);
|
||||||
|
} else {
|
||||||
|
this.push(configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent normal array methods from creating a new `ConfigArray` instance.
|
||||||
|
* This is to ensure that methods such as `slice()` won't try to create a
|
||||||
|
* new instance of `ConfigArray` behind the scenes as doing so may throw
|
||||||
|
* an error due to the different constructor signature.
|
||||||
|
* @returns {Function} The `Array` constructor.
|
||||||
|
*/
|
||||||
|
static get [Symbol.species]() {
|
||||||
|
return Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the `files` globs from every config object in the array.
|
||||||
|
* This can be used to determine which files will be matched by a
|
||||||
|
* config array or to use as a glob pattern when no patterns are provided
|
||||||
|
* for a command line interface.
|
||||||
|
* @returns {Array<string|Function>} An array of matchers.
|
||||||
|
*/
|
||||||
|
get files() {
|
||||||
|
|
||||||
|
assertNormalized(this);
|
||||||
|
|
||||||
|
// if this data has been cached, retrieve it
|
||||||
|
const cache = dataCache.get(this);
|
||||||
|
|
||||||
|
if (cache.files) {
|
||||||
|
return cache.files;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise calculate it
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
|
||||||
|
for (const config of this) {
|
||||||
|
if (config.files) {
|
||||||
|
config.files.forEach(filePattern => {
|
||||||
|
result.push(filePattern);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store result
|
||||||
|
cache.files = result;
|
||||||
|
dataCache.set(this, cache);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ignore matchers that should always be ignored regardless of
|
||||||
|
* the matching `files` fields in any configs. This is necessary to mimic
|
||||||
|
* the behavior of things like .gitignore and .eslintignore, allowing a
|
||||||
|
* globbing operation to be faster.
|
||||||
|
* @returns {string[]} An array of string patterns and functions to be ignored.
|
||||||
|
*/
|
||||||
|
get ignores() {
|
||||||
|
|
||||||
|
assertNormalized(this);
|
||||||
|
|
||||||
|
// if this data has been cached, retrieve it
|
||||||
|
const cache = dataCache.get(this);
|
||||||
|
|
||||||
|
if (cache.ignores) {
|
||||||
|
return cache.ignores;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise calculate it
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
|
||||||
|
for (const config of this) {
|
||||||
|
if (config.ignores && !config.files) {
|
||||||
|
result.push(...config.ignores);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store result
|
||||||
|
cache.ignores = result;
|
||||||
|
dataCache.set(this, cache);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the config array has been normalized.
|
||||||
|
* @returns {boolean} True if the config array is normalized, false if not.
|
||||||
|
*/
|
||||||
|
isNormalized() {
|
||||||
|
return this[ConfigArraySymbol.isNormalized];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a config array by flattening embedded arrays and executing
|
||||||
|
* config functions.
|
||||||
|
* @param {ConfigContext} context The context object for config functions.
|
||||||
|
* @returns {Promise<ConfigArray>} The current ConfigArray instance.
|
||||||
|
*/
|
||||||
|
async normalize(context = {}) {
|
||||||
|
|
||||||
|
if (!this.isNormalized()) {
|
||||||
|
const normalizedConfigs = await normalize(this, context, this.extraConfigTypes);
|
||||||
|
this.length = 0;
|
||||||
|
this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig]));
|
||||||
|
this[ConfigArraySymbol.isNormalized] = true;
|
||||||
|
|
||||||
|
// prevent further changes
|
||||||
|
Object.freeze(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a config array by flattening embedded arrays and executing
|
||||||
|
* config functions.
|
||||||
|
* @param {ConfigContext} context The context object for config functions.
|
||||||
|
* @returns {ConfigArray} The current ConfigArray instance.
|
||||||
|
*/
|
||||||
|
normalizeSync(context = {}) {
|
||||||
|
|
||||||
|
if (!this.isNormalized()) {
|
||||||
|
const normalizedConfigs = normalizeSync(this, context, this.extraConfigTypes);
|
||||||
|
this.length = 0;
|
||||||
|
this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig]));
|
||||||
|
this[ConfigArraySymbol.isNormalized] = true;
|
||||||
|
|
||||||
|
// prevent further changes
|
||||||
|
Object.freeze(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalizes the state of a config before being cached and returned by
|
||||||
|
* `getConfig()`. Does nothing by default but is provided to be
|
||||||
|
* overridden by subclasses as necessary.
|
||||||
|
* @param {Object} config The config to finalize.
|
||||||
|
* @returns {Object} The finalized config.
|
||||||
|
*/
|
||||||
|
[ConfigArraySymbol.finalizeConfig](config) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preprocesses a config during the normalization process. This is the
|
||||||
|
* method to override if you want to convert an array item before it is
|
||||||
|
* validated for the first time. For example, if you want to replace a
|
||||||
|
* string with an object, this is the method to override.
|
||||||
|
* @param {Object} config The config to preprocess.
|
||||||
|
* @returns {Object} The config to use in place of the argument.
|
||||||
|
*/
|
||||||
|
[ConfigArraySymbol.preprocessConfig](config) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the config object for a given file path.
|
||||||
|
* @param {string} filePath The complete path of a file to get a config for.
|
||||||
|
* @returns {Object} The config object for this file.
|
||||||
|
*/
|
||||||
|
getConfig(filePath) {
|
||||||
|
|
||||||
|
assertNormalized(this);
|
||||||
|
|
||||||
|
// first check the cache to avoid duplicate work
|
||||||
|
let finalConfig = this[ConfigArraySymbol.configCache].get(filePath);
|
||||||
|
|
||||||
|
if (finalConfig) {
|
||||||
|
return finalConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Maybe move elsewhere?
|
||||||
|
const relativeFilePath = path.relative(this.basePath, filePath);
|
||||||
|
|
||||||
|
if (shouldIgnoreFilePath(this.ignores, filePath, relativeFilePath)) {
|
||||||
|
|
||||||
|
// cache and return result - finalConfig is undefined at this point
|
||||||
|
this[ConfigArraySymbol.configCache].set(filePath, finalConfig);
|
||||||
|
return finalConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// filePath isn't automatically ignored, so try to construct config
|
||||||
|
|
||||||
|
const matchingConfigs = [];
|
||||||
|
|
||||||
|
for (const config of this) {
|
||||||
|
if (pathMatches(filePath, this.basePath, config)) {
|
||||||
|
debug(`Matching config found for ${filePath}`);
|
||||||
|
matchingConfigs.push(config);
|
||||||
|
} else {
|
||||||
|
debug(`No matching config found for ${filePath}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if matching both files and ignores, there will be no config to create
|
||||||
|
if (matchingConfigs.length === 0) {
|
||||||
|
// cache and return result - finalConfig is undefined at this point
|
||||||
|
this[ConfigArraySymbol.configCache].set(filePath, finalConfig);
|
||||||
|
return finalConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise construct the config
|
||||||
|
|
||||||
|
finalConfig = matchingConfigs.reduce((result, config) => {
|
||||||
|
return this[ConfigArraySymbol.schema].merge(result, config);
|
||||||
|
}, {}, this);
|
||||||
|
|
||||||
|
finalConfig = this[ConfigArraySymbol.finalizeConfig](finalConfig);
|
||||||
|
|
||||||
|
this[ConfigArraySymbol.configCache].set(filePath, finalConfig);
|
||||||
|
|
||||||
|
return finalConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the given filepath is ignored based on the configs.
|
||||||
|
* @param {string} filePath The complete path of a file to check.
|
||||||
|
* @returns {boolean} True if the path is ignored, false if not.
|
||||||
|
*/
|
||||||
|
isIgnored(filePath) {
|
||||||
|
return this.getConfig(filePath) === undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.ConfigArray = ConfigArray;
|
||||||
|
exports.ConfigArraySymbol = ConfigArraySymbol;
|
61
node_modules/@humanwhocodes/config-array/package.json
generated
vendored
Normal file
61
node_modules/@humanwhocodes/config-array/package.json
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"name": "@humanwhocodes/config-array",
|
||||||
|
"version": "0.9.3",
|
||||||
|
"description": "Glob-based configuration matching.",
|
||||||
|
"author": "Nicholas C. Zakas",
|
||||||
|
"main": "api.js",
|
||||||
|
"files": [
|
||||||
|
"api.js"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/humanwhocodes/config-array.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/humanwhocodes/config-array/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/humanwhocodes/config-array#readme",
|
||||||
|
"scripts": {
|
||||||
|
"build": "rollup -c",
|
||||||
|
"format": "nitpik",
|
||||||
|
"lint": "eslint *.config.js src/*.js tests/*.js",
|
||||||
|
"prepublish": "npm run build",
|
||||||
|
"test:coverage": "nyc --include src/*.js npm run test",
|
||||||
|
"test": "mocha -r esm tests/ --recursive"
|
||||||
|
},
|
||||||
|
"gitHooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.js": [
|
||||||
|
"nitpik",
|
||||||
|
"eslint --fix --ignore-pattern '!.eslintrc.js'"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"configuration",
|
||||||
|
"configarray",
|
||||||
|
"config file"
|
||||||
|
],
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.10.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@humanwhocodes/object-schema": "^1.2.1",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"minimatch": "^3.0.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@nitpik/javascript": "^0.3.3",
|
||||||
|
"@nitpik/node": "0.0.5",
|
||||||
|
"chai": "^4.2.0",
|
||||||
|
"eslint": "^6.7.1",
|
||||||
|
"esm": "^3.2.25",
|
||||||
|
"lint-staged": "^10.2.8",
|
||||||
|
"mocha": "^6.2.3",
|
||||||
|
"nyc": "^14.1.1",
|
||||||
|
"rollup": "^1.12.3",
|
||||||
|
"yorkie": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
29
node_modules/@humanwhocodes/object-schema/.eslintrc.js
generated
vendored
Normal file
29
node_modules/@humanwhocodes/object-schema/.eslintrc.js
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
module.exports = {
|
||||||
|
"env": {
|
||||||
|
"commonjs": true,
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2018
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"double"
|
||||||
|
],
|
||||||
|
"semi": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
27
node_modules/@humanwhocodes/object-schema/.github/workflows/nodejs-test.yml
generated
vendored
Normal file
27
node_modules/@humanwhocodes/object-schema/.github/workflows/nodejs-test.yml
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
name: Node CI
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [windows-latest, macOS-latest, ubuntu-latest]
|
||||||
|
node: [8.x, 10.x, 12.x, 14.x]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- name: npm install, build, and test
|
||||||
|
run: |
|
||||||
|
npm install
|
||||||
|
npm run build --if-present
|
||||||
|
npm test
|
||||||
|
env:
|
||||||
|
CI: true
|
39
node_modules/@humanwhocodes/object-schema/.github/workflows/release-please.yml
generated
vendored
Normal file
39
node_modules/@humanwhocodes/object-schema/.github/workflows/release-please.yml
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
name: release-please
|
||||||
|
jobs:
|
||||||
|
release-please:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: GoogleCloudPlatform/release-please-action@v2
|
||||||
|
id: release
|
||||||
|
with:
|
||||||
|
release-type: node
|
||||||
|
package-name: test-release-please
|
||||||
|
# The logic below handles the npm publication:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
# these if statements ensure that a publication only occurs when
|
||||||
|
# a new release is created:
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
- uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 12
|
||||||
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
- run: npm ci
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
- run: npm publish
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
|
||||||
|
# Tweets out release announcement
|
||||||
|
- run: 'npx @humanwhocodes/tweet "Object Schema v${{ steps.release.outputs.major }}.${{ steps.release.outputs.minor }}.${{ steps.release.outputs.patch }} has been released!\n\n${{ github.event.release.html_url }}"'
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
env:
|
||||||
|
TWITTER_CONSUMER_KEY: ${{ secrets.TWITTER_CONSUMER_KEY }}
|
||||||
|
TWITTER_CONSUMER_SECRET: ${{ secrets.TWITTER_CONSUMER_SECRET }}
|
||||||
|
TWITTER_ACCESS_TOKEN_KEY: ${{ secrets.TWITTER_ACCESS_TOKEN_KEY }}
|
||||||
|
TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
|
8
node_modules/@humanwhocodes/object-schema/CHANGELOG.md
generated
vendored
Normal file
8
node_modules/@humanwhocodes/object-schema/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
### [1.2.1](https://www.github.com/humanwhocodes/object-schema/compare/v1.2.0...v1.2.1) (2021-11-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Never return original object from individual config ([5463c5c](https://www.github.com/humanwhocodes/object-schema/commit/5463c5c6d2cb35a7b7948dffc37c899a41d1775f))
|
29
node_modules/@humanwhocodes/object-schema/LICENSE
generated
vendored
Normal file
29
node_modules/@humanwhocodes/object-schema/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
BSD 3-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2019, Human Who Codes
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
234
node_modules/@humanwhocodes/object-schema/README.md
generated
vendored
Normal file
234
node_modules/@humanwhocodes/object-schema/README.md
generated
vendored
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
# JavaScript ObjectSchema Package
|
||||||
|
|
||||||
|
by [Nicholas C. Zakas](https://humanwhocodes.com)
|
||||||
|
|
||||||
|
If you find this useful, please consider supporting my work with a [donation](https://humanwhocodes.com/donate).
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A JavaScript object merge/validation utility where you can define a different merge and validation strategy for each key. This is helpful when you need to validate complex data structures and then merge them in a way that is more complex than `Object.assign()`.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
You can install using either npm:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install @humanwhocodes/object-schema
|
||||||
|
```
|
||||||
|
|
||||||
|
Or Yarn:
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn add @humanwhocodes/object-schema
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Use CommonJS to get access to the `ObjectSchema` constructor:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { ObjectSchema } = require("@humanwhocodes/object-schema");
|
||||||
|
|
||||||
|
const schema = new ObjectSchema({
|
||||||
|
|
||||||
|
// define a definition for the "downloads" key
|
||||||
|
downloads: {
|
||||||
|
required: true,
|
||||||
|
merge(value1, value2) {
|
||||||
|
return value1 + value2;
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
if (typeof value !== "number") {
|
||||||
|
throw new Error("Expected downloads to be a number.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// define a strategy for the "versions" key
|
||||||
|
version: {
|
||||||
|
required: true,
|
||||||
|
merge(value1, value2) {
|
||||||
|
return value1.concat(value2);
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
throw new Error("Expected versions to be an array.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const record1 = {
|
||||||
|
downloads: 25,
|
||||||
|
versions: [
|
||||||
|
"v1.0.0",
|
||||||
|
"v1.1.0",
|
||||||
|
"v1.2.0"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const record2 = {
|
||||||
|
downloads: 125,
|
||||||
|
versions: [
|
||||||
|
"v2.0.0",
|
||||||
|
"v2.1.0",
|
||||||
|
"v3.0.0"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// make sure the records are valid
|
||||||
|
schema.validate(record1);
|
||||||
|
schema.validate(record2);
|
||||||
|
|
||||||
|
// merge together (schema.merge() accepts any number of objects)
|
||||||
|
const result = schema.merge(record1, record2);
|
||||||
|
|
||||||
|
// result looks like this:
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
downloads: 75,
|
||||||
|
versions: [
|
||||||
|
"v1.0.0",
|
||||||
|
"v1.1.0",
|
||||||
|
"v1.2.0",
|
||||||
|
"v2.0.0",
|
||||||
|
"v2.1.0",
|
||||||
|
"v3.0.0"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips and Tricks
|
||||||
|
|
||||||
|
### Named merge strategies
|
||||||
|
|
||||||
|
Instead of specifying a `merge()` method, you can specify one of the following strings to use a default merge strategy:
|
||||||
|
|
||||||
|
* `"assign"` - use `Object.assign()` to merge the two values into one object.
|
||||||
|
* `"overwrite"` - the second value always replaces the first.
|
||||||
|
* `"replace"` - the second value replaces the first if the second is not `undefined`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const schema = new ObjectSchema({
|
||||||
|
name: {
|
||||||
|
merge: "replace",
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Named validation strategies
|
||||||
|
|
||||||
|
Instead of specifying a `validate()` method, you can specify one of the following strings to use a default validation strategy:
|
||||||
|
|
||||||
|
* `"array"` - value must be an array.
|
||||||
|
* `"boolean"` - value must be a boolean.
|
||||||
|
* `"number"` - value must be a number.
|
||||||
|
* `"object"` - value must be an object.
|
||||||
|
* `"object?"` - value must be an object or null.
|
||||||
|
* `"string"` - value must be a string.
|
||||||
|
* `"string!"` - value must be a non-empty string.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const schema = new ObjectSchema({
|
||||||
|
name: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Subschemas
|
||||||
|
|
||||||
|
If you are defining a key that is, itself, an object, you can simplify the process by using a subschema. Instead of defining `merge()` and `validate()`, assign a `schema` key that contains a schema definition, like this:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const schema = new ObjectSchema({
|
||||||
|
name: {
|
||||||
|
schema: {
|
||||||
|
first: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
schema.validate({
|
||||||
|
name: {
|
||||||
|
first: "n",
|
||||||
|
last: "z"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Remove Keys During Merge
|
||||||
|
|
||||||
|
If the merge strategy for a key returns `undefined`, then the key will not appear in the final object. For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const schema = new ObjectSchema({
|
||||||
|
date: {
|
||||||
|
merge() {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
Date.parse(value); // throws an error when invalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const object1 = { date: "5/5/2005" };
|
||||||
|
const object2 = { date: "6/6/2006" };
|
||||||
|
|
||||||
|
const result = schema.merge(object1, object2);
|
||||||
|
|
||||||
|
console.log("date" in result); // false
|
||||||
|
```
|
||||||
|
|
||||||
|
### Requiring Another Key Be Present
|
||||||
|
|
||||||
|
If you'd like the presence of one key to require the presence of another key, you can use the `requires` property to specify an array of other properties that any key requires. For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const schema = new ObjectSchema();
|
||||||
|
|
||||||
|
const schema = new ObjectSchema({
|
||||||
|
date: {
|
||||||
|
merge() {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
Date.parse(value); // throws an error when invalid
|
||||||
|
}
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
requires: ["date"],
|
||||||
|
merge(first, second) {
|
||||||
|
return second;
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// throws error: Key "time" requires keys "date"
|
||||||
|
schema.validate({
|
||||||
|
time: "13:45"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, even though `date` is an optional key, it is required to be present whenever `time` is present.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
BSD 3-Clause
|
33
node_modules/@humanwhocodes/object-schema/package.json
generated
vendored
Normal file
33
node_modules/@humanwhocodes/object-schema/package.json
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"name": "@humanwhocodes/object-schema",
|
||||||
|
"version": "1.2.1",
|
||||||
|
"description": "An object schema merger/validator",
|
||||||
|
"main": "src/index.js",
|
||||||
|
"directories": {
|
||||||
|
"test": "tests"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "mocha tests/"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/humanwhocodes/object-schema.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"object",
|
||||||
|
"validation",
|
||||||
|
"schema",
|
||||||
|
"merge"
|
||||||
|
],
|
||||||
|
"author": "Nicholas C. Zakas",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/humanwhocodes/object-schema/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/humanwhocodes/object-schema#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"chai": "^4.2.0",
|
||||||
|
"eslint": "^5.13.0",
|
||||||
|
"mocha": "^5.2.0"
|
||||||
|
}
|
||||||
|
}
|
7
node_modules/@humanwhocodes/object-schema/src/index.js
generated
vendored
Normal file
7
node_modules/@humanwhocodes/object-schema/src/index.js
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/**
|
||||||
|
* @filedescription Object Schema Package
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.ObjectSchema = require("./object-schema").ObjectSchema;
|
||||||
|
exports.MergeStrategy = require("./merge-strategy").MergeStrategy;
|
||||||
|
exports.ValidationStrategy = require("./validation-strategy").ValidationStrategy;
|
53
node_modules/@humanwhocodes/object-schema/src/merge-strategy.js
generated
vendored
Normal file
53
node_modules/@humanwhocodes/object-schema/src/merge-strategy.js
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* @filedescription Merge Strategy
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Class
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container class for several different merge strategies.
|
||||||
|
*/
|
||||||
|
class MergeStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges two keys by overwriting the first with the second.
|
||||||
|
* @param {*} value1 The value from the first object key.
|
||||||
|
* @param {*} value2 The value from the second object key.
|
||||||
|
* @returns {*} The second value.
|
||||||
|
*/
|
||||||
|
static overwrite(value1, value2) {
|
||||||
|
return value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges two keys by replacing the first with the second only if the
|
||||||
|
* second is defined.
|
||||||
|
* @param {*} value1 The value from the first object key.
|
||||||
|
* @param {*} value2 The value from the second object key.
|
||||||
|
* @returns {*} The second value if it is defined.
|
||||||
|
*/
|
||||||
|
static replace(value1, value2) {
|
||||||
|
if (typeof value2 !== "undefined") {
|
||||||
|
return value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges two properties by assigning properties from the second to the first.
|
||||||
|
* @param {*} value1 The value from the first object key.
|
||||||
|
* @param {*} value2 The value from the second object key.
|
||||||
|
* @returns {*} A new object containing properties from both value1 and
|
||||||
|
* value2.
|
||||||
|
*/
|
||||||
|
static assign(value1, value2) {
|
||||||
|
return Object.assign({}, value1, value2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.MergeStrategy = MergeStrategy;
|
235
node_modules/@humanwhocodes/object-schema/src/object-schema.js
generated
vendored
Normal file
235
node_modules/@humanwhocodes/object-schema/src/object-schema.js
generated
vendored
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
/**
|
||||||
|
* @filedescription Object Schema
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const { MergeStrategy } = require("./merge-strategy");
|
||||||
|
const { ValidationStrategy } = require("./validation-strategy");
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Private
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const strategies = Symbol("strategies");
|
||||||
|
const requiredKeys = Symbol("requiredKeys");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a schema strategy.
|
||||||
|
* @param {string} name The name of the key this strategy is for.
|
||||||
|
* @param {Object} strategy The strategy for the object key.
|
||||||
|
* @param {boolean} [strategy.required=true] Whether the key is required.
|
||||||
|
* @param {string[]} [strategy.requires] Other keys that are required when
|
||||||
|
* this key is present.
|
||||||
|
* @param {Function} strategy.merge A method to call when merging two objects
|
||||||
|
* with the same key.
|
||||||
|
* @param {Function} strategy.validate A method to call when validating an
|
||||||
|
* object with the key.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} When the strategy is missing a name.
|
||||||
|
* @throws {Error} When the strategy is missing a merge() method.
|
||||||
|
* @throws {Error} When the strategy is missing a validate() method.
|
||||||
|
*/
|
||||||
|
function validateDefinition(name, strategy) {
|
||||||
|
|
||||||
|
let hasSchema = false;
|
||||||
|
if (strategy.schema) {
|
||||||
|
if (typeof strategy.schema === "object") {
|
||||||
|
hasSchema = true;
|
||||||
|
} else {
|
||||||
|
throw new TypeError("Schema must be an object.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof strategy.merge === "string") {
|
||||||
|
if (!(strategy.merge in MergeStrategy)) {
|
||||||
|
throw new TypeError(`Definition for key "${name}" missing valid merge strategy.`);
|
||||||
|
}
|
||||||
|
} else if (!hasSchema && typeof strategy.merge !== "function") {
|
||||||
|
throw new TypeError(`Definition for key "${name}" must have a merge property.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof strategy.validate === "string") {
|
||||||
|
if (!(strategy.validate in ValidationStrategy)) {
|
||||||
|
throw new TypeError(`Definition for key "${name}" missing valid validation strategy.`);
|
||||||
|
}
|
||||||
|
} else if (!hasSchema && typeof strategy.validate !== "function") {
|
||||||
|
throw new TypeError(`Definition for key "${name}" must have a validate() method.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Class
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object validation/merging schema.
|
||||||
|
*/
|
||||||
|
class ObjectSchema {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*/
|
||||||
|
constructor(definitions) {
|
||||||
|
|
||||||
|
if (!definitions) {
|
||||||
|
throw new Error("Schema definitions missing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track all strategies in the schema by key.
|
||||||
|
* @type {Map}
|
||||||
|
* @property strategies
|
||||||
|
*/
|
||||||
|
this[strategies] = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separately track any keys that are required for faster validation.
|
||||||
|
* @type {Map}
|
||||||
|
* @property requiredKeys
|
||||||
|
*/
|
||||||
|
this[requiredKeys] = new Map();
|
||||||
|
|
||||||
|
// add in all strategies
|
||||||
|
for (const key of Object.keys(definitions)) {
|
||||||
|
validateDefinition(key, definitions[key]);
|
||||||
|
|
||||||
|
// normalize merge and validate methods if subschema is present
|
||||||
|
if (typeof definitions[key].schema === "object") {
|
||||||
|
const schema = new ObjectSchema(definitions[key].schema);
|
||||||
|
definitions[key] = {
|
||||||
|
...definitions[key],
|
||||||
|
merge(first = {}, second = {}) {
|
||||||
|
return schema.merge(first, second);
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
ValidationStrategy.object(value);
|
||||||
|
schema.validate(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize the merge method in case there's a string
|
||||||
|
if (typeof definitions[key].merge === "string") {
|
||||||
|
definitions[key] = {
|
||||||
|
...definitions[key],
|
||||||
|
merge: MergeStrategy[definitions[key].merge]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// normalize the validate method in case there's a string
|
||||||
|
if (typeof definitions[key].validate === "string") {
|
||||||
|
definitions[key] = {
|
||||||
|
...definitions[key],
|
||||||
|
validate: ValidationStrategy[definitions[key].validate]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
this[strategies].set(key, definitions[key]);
|
||||||
|
|
||||||
|
if (definitions[key].required) {
|
||||||
|
this[requiredKeys].set(key, definitions[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a strategy has been registered for the given object key.
|
||||||
|
* @param {string} key The object key to find a strategy for.
|
||||||
|
* @returns {boolean} True if the key has a strategy registered, false if not.
|
||||||
|
*/
|
||||||
|
hasKey(key) {
|
||||||
|
return this[strategies].has(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges objects together to create a new object comprised of the keys
|
||||||
|
* of the all objects. Keys are merged based on the each key's merge
|
||||||
|
* strategy.
|
||||||
|
* @param {...Object} objects The objects to merge.
|
||||||
|
* @returns {Object} A new object with a mix of all objects' keys.
|
||||||
|
* @throws {Error} If any object is invalid.
|
||||||
|
*/
|
||||||
|
merge(...objects) {
|
||||||
|
|
||||||
|
// double check arguments
|
||||||
|
if (objects.length < 2) {
|
||||||
|
throw new Error("merge() requires at least two arguments.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objects.some(object => (object == null || typeof object !== "object"))) {
|
||||||
|
throw new Error("All arguments must be objects.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return objects.reduce((result, object) => {
|
||||||
|
|
||||||
|
this.validate(object);
|
||||||
|
|
||||||
|
for (const [key, strategy] of this[strategies]) {
|
||||||
|
try {
|
||||||
|
if (key in result || key in object) {
|
||||||
|
const value = strategy.merge.call(this, result[key], object[key]);
|
||||||
|
if (value !== undefined) {
|
||||||
|
result[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
ex.message = `Key "${key}": ` + ex.message;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates an object's keys based on the validate strategy for each key.
|
||||||
|
* @param {Object} object The object to validate.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} When the object is invalid.
|
||||||
|
*/
|
||||||
|
validate(object) {
|
||||||
|
|
||||||
|
// check existing keys first
|
||||||
|
for (const key of Object.keys(object)) {
|
||||||
|
|
||||||
|
// check to see if the key is defined
|
||||||
|
if (!this.hasKey(key)) {
|
||||||
|
throw new Error(`Unexpected key "${key}" found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate existing keys
|
||||||
|
const strategy = this[strategies].get(key);
|
||||||
|
|
||||||
|
// first check to see if any other keys are required
|
||||||
|
if (Array.isArray(strategy.requires)) {
|
||||||
|
if (!strategy.requires.every(otherKey => otherKey in object)) {
|
||||||
|
throw new Error(`Key "${key}" requires keys "${strategy.requires.join("\", \"")}".`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now apply remaining validation strategy
|
||||||
|
try {
|
||||||
|
strategy.validate.call(strategy, object[key]);
|
||||||
|
} catch (ex) {
|
||||||
|
ex.message = `Key "${key}": ` + ex.message;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure required keys aren't missing
|
||||||
|
for (const [key] of this[requiredKeys]) {
|
||||||
|
if (!(key in object)) {
|
||||||
|
throw new Error(`Missing required key "${key}".`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.ObjectSchema = ObjectSchema;
|
102
node_modules/@humanwhocodes/object-schema/src/validation-strategy.js
generated
vendored
Normal file
102
node_modules/@humanwhocodes/object-schema/src/validation-strategy.js
generated
vendored
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/**
|
||||||
|
* @filedescription Validation Strategy
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Class
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container class for several different validation strategies.
|
||||||
|
*/
|
||||||
|
class ValidationStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that a value is an array.
|
||||||
|
* @param {*} value The value to validate.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} If the value is invalid.
|
||||||
|
*/
|
||||||
|
static array(value) {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
throw new TypeError("Expected an array.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that a value is a boolean.
|
||||||
|
* @param {*} value The value to validate.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} If the value is invalid.
|
||||||
|
*/
|
||||||
|
static boolean(value) {
|
||||||
|
if (typeof value !== "boolean") {
|
||||||
|
throw new TypeError("Expected a Boolean.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that a value is a number.
|
||||||
|
* @param {*} value The value to validate.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} If the value is invalid.
|
||||||
|
*/
|
||||||
|
static number(value) {
|
||||||
|
if (typeof value !== "number") {
|
||||||
|
throw new TypeError("Expected a number.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that a value is a object.
|
||||||
|
* @param {*} value The value to validate.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} If the value is invalid.
|
||||||
|
*/
|
||||||
|
static object(value) {
|
||||||
|
if (!value || typeof value !== "object") {
|
||||||
|
throw new TypeError("Expected an object.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that a value is a object or null.
|
||||||
|
* @param {*} value The value to validate.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} If the value is invalid.
|
||||||
|
*/
|
||||||
|
static "object?"(value) {
|
||||||
|
if (typeof value !== "object") {
|
||||||
|
throw new TypeError("Expected an object or null.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that a value is a string.
|
||||||
|
* @param {*} value The value to validate.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} If the value is invalid.
|
||||||
|
*/
|
||||||
|
static string(value) {
|
||||||
|
if (typeof value !== "string") {
|
||||||
|
throw new TypeError("Expected a string.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that a value is a non-empty string.
|
||||||
|
* @param {*} value The value to validate.
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {TypeError} If the value is invalid.
|
||||||
|
*/
|
||||||
|
static "string!"(value) {
|
||||||
|
if (typeof value !== "string" || value.length === 0) {
|
||||||
|
throw new TypeError("Expected a non-empty string.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.ValidationStrategy = ValidationStrategy;
|
66
node_modules/@humanwhocodes/object-schema/tests/merge-strategy.js
generated
vendored
Normal file
66
node_modules/@humanwhocodes/object-schema/tests/merge-strategy.js
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
* @filedescription Merge Strategy Tests
|
||||||
|
*/
|
||||||
|
/* global it, describe, beforeEach */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const assert = require("chai").assert;
|
||||||
|
const { MergeStrategy } = require("../src/");
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Class
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
describe("MergeStrategy", () => {
|
||||||
|
|
||||||
|
|
||||||
|
describe("overwrite()", () => {
|
||||||
|
|
||||||
|
it("should overwrite the first value with the second when the second is defined", () => {
|
||||||
|
const result = MergeStrategy.overwrite(1, 2);
|
||||||
|
assert.strictEqual(result, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should overwrite the first value with the second when the second is undefined", () => {
|
||||||
|
const result = MergeStrategy.overwrite(1, undefined);
|
||||||
|
assert.strictEqual(result, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("replace()", () => {
|
||||||
|
|
||||||
|
it("should overwrite the first value with the second when the second is defined", () => {
|
||||||
|
const result = MergeStrategy.replace(1, 2);
|
||||||
|
assert.strictEqual(result, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return the first value when the second is undefined", () => {
|
||||||
|
const result = MergeStrategy.replace(1, undefined);
|
||||||
|
assert.strictEqual(result, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("assign()", () => {
|
||||||
|
|
||||||
|
it("should merge properties from two objects when called", () => {
|
||||||
|
|
||||||
|
const object1 = { foo: 1, bar: 3 };
|
||||||
|
const object2 = { foo: 2 };
|
||||||
|
|
||||||
|
const result = MergeStrategy.assign(object1, object2);
|
||||||
|
assert.deepStrictEqual(result, {
|
||||||
|
foo: 2,
|
||||||
|
bar: 3
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
611
node_modules/@humanwhocodes/object-schema/tests/object-schema.js
generated
vendored
Normal file
611
node_modules/@humanwhocodes/object-schema/tests/object-schema.js
generated
vendored
Normal file
|
@ -0,0 +1,611 @@
|
||||||
|
/**
|
||||||
|
* @filedescription Object Schema Tests
|
||||||
|
*/
|
||||||
|
/* global it, describe, beforeEach */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const assert = require("chai").assert;
|
||||||
|
const { ObjectSchema } = require("../src/");
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Class
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
describe("ObjectSchema", () => {
|
||||||
|
|
||||||
|
let schema;
|
||||||
|
|
||||||
|
describe("new ObjectSchema()", () => {
|
||||||
|
|
||||||
|
it("should add a new key when a strategy is passed", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {},
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.isTrue(schema.hasKey("foo"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when a strategy is missing a merge() method", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
validate() { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, /Definition for key "foo" must have a merge property/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when a strategy is missing a merge() method", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
schema = new ObjectSchema();
|
||||||
|
}, /Schema definitions missing/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when a strategy is missing a validate() method", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() { },
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, /Definition for key "foo" must have a validate\(\) method/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when merge is an invalid string", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge: "bar",
|
||||||
|
validate() { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, /key "foo" missing valid merge strategy/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when validate is an invalid string", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge: "assign",
|
||||||
|
validate: "s"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, /key "foo" missing valid validation strategy/);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe("merge()", () => {
|
||||||
|
|
||||||
|
it("should throw an error when an unexpected key is found", () => {
|
||||||
|
let schema = new ObjectSchema({});
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.merge({ foo: true }, { foo: true });
|
||||||
|
}, /Unexpected key "foo"/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when merge() throws an error", () => {
|
||||||
|
let schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
throw new Error("Boom!");
|
||||||
|
},
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.merge({ foo: true }, { foo: true });
|
||||||
|
}, /Key "foo": Boom!/);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call the merge() strategy for one key when called", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge({ foo: true }, { foo: false });
|
||||||
|
assert.propertyVal(result, "foo", "bar");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not call the merge() strategy when both objects don't contain the key", () => {
|
||||||
|
|
||||||
|
let called = false;
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
called = true;
|
||||||
|
},
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
schema.merge({}, {});
|
||||||
|
assert.isFalse(called, "The merge() strategy should not have been called.");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should omit returning the key when the merge() strategy returns undefined", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
validate() { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge({ foo: true }, { foo: false });
|
||||||
|
assert.notProperty(result, "foo");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call the merge() strategy for two keys when called", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() { }
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
merge() {
|
||||||
|
return "baz";
|
||||||
|
},
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge({ foo: true, bar: 1 }, { foo: true, bar: 2 });
|
||||||
|
assert.propertyVal(result, "foo", "bar");
|
||||||
|
assert.propertyVal(result, "bar", "baz");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call the merge() strategy for two keys when called on three objects", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() { }
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
merge() {
|
||||||
|
return "baz";
|
||||||
|
},
|
||||||
|
validate() { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge(
|
||||||
|
{ foo: true, bar: 1 },
|
||||||
|
{ foo: true, bar: 3 },
|
||||||
|
{ foo: false, bar: 2 }
|
||||||
|
);
|
||||||
|
assert.propertyVal(result, "foo", "bar");
|
||||||
|
assert.propertyVal(result, "bar", "baz");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call the merge() strategy when defined as 'overwrite'", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge: "overwrite",
|
||||||
|
validate() { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge(
|
||||||
|
{ foo: true },
|
||||||
|
{ foo: false }
|
||||||
|
);
|
||||||
|
assert.propertyVal(result, "foo", false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call the merge() strategy when defined as 'assign'", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge: "assign",
|
||||||
|
validate() { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge(
|
||||||
|
{ foo: { bar: true } },
|
||||||
|
{ foo: { baz: false } }
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(result.foo.bar, true);
|
||||||
|
assert.strictEqual(result.foo.baz, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call the merge strategy when there's a subschema", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
name: {
|
||||||
|
schema: {
|
||||||
|
first: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge({
|
||||||
|
name: {
|
||||||
|
first: "n",
|
||||||
|
last: "z"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: {
|
||||||
|
first: "g"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(result.name.first, "g");
|
||||||
|
assert.strictEqual(result.name.last, "z");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return separate objects when using subschema", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
age: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "number"
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
schema: {
|
||||||
|
street: {
|
||||||
|
schema: {
|
||||||
|
number: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "number"
|
||||||
|
},
|
||||||
|
streetName: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const baseObject = {
|
||||||
|
address: {
|
||||||
|
street: {
|
||||||
|
number: 100,
|
||||||
|
streetName: "Foo St"
|
||||||
|
},
|
||||||
|
state: "HA"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = schema.merge(baseObject, {
|
||||||
|
age: 29
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.notStrictEqual(result.address.street, baseObject.address.street);
|
||||||
|
assert.deepStrictEqual(result.address, baseObject.address);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not error when calling the merge strategy when there's a subschema and no matching key in second object", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
name: {
|
||||||
|
schema: {
|
||||||
|
first: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge({
|
||||||
|
name: {
|
||||||
|
first: "n",
|
||||||
|
last: "z"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(result.name.first, "n");
|
||||||
|
assert.strictEqual(result.name.last, "z");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not error when calling the merge strategy when there's multiple subschemas and no matching key in second object", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
user: {
|
||||||
|
schema: {
|
||||||
|
name: {
|
||||||
|
schema: {
|
||||||
|
first: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = schema.merge({
|
||||||
|
user: {
|
||||||
|
name: {
|
||||||
|
first: "n",
|
||||||
|
last: "z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(result.user.name.first, "n");
|
||||||
|
assert.strictEqual(result.user.name.last, "z");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("validate()", () => {
|
||||||
|
|
||||||
|
it("should throw an error when an unexpected key is found", () => {
|
||||||
|
let schema = new ObjectSchema({});
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.validate({ foo: true });
|
||||||
|
}, /Unexpected key "foo"/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not throw an error when an expected key is found", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
schema.validate({ foo: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should pass the property value into validate() when key is found", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate(value) {
|
||||||
|
assert.isTrue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
schema.validate({ foo: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not throw an error when expected keys are found", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() {}
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
merge() {
|
||||||
|
return "baz";
|
||||||
|
},
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
schema.validate({ foo: true, bar: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not throw an error when expected keys are found with required keys", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() { }
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
requires: ["foo"],
|
||||||
|
merge() {
|
||||||
|
return "baz";
|
||||||
|
},
|
||||||
|
validate() { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
schema.validate({ foo: true, bar: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when expected keys are found without required keys", () => {
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() { }
|
||||||
|
},
|
||||||
|
baz: {
|
||||||
|
merge() {
|
||||||
|
return "baz";
|
||||||
|
},
|
||||||
|
validate() { }
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
name: "bar",
|
||||||
|
requires: ["foo", "baz"],
|
||||||
|
merge() { },
|
||||||
|
validate() { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.validate({ bar: true });
|
||||||
|
}, /Key "bar" requires keys "foo", "baz"./);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("should throw an error when an expected key is found but is invalid", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() {
|
||||||
|
throw new Error("Invalid key.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.validate({ foo: true });
|
||||||
|
}, /Key "foo": Invalid key/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when an expected key is found but is invalid with a string validator", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.validate({ foo: true });
|
||||||
|
}, /Key "foo": Expected a string/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when an expected key is found but is invalid with a number validator", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate: "number"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.validate({ foo: true });
|
||||||
|
}, /Key "foo": Expected a number/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when a required key is missing", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
foo: {
|
||||||
|
required: true,
|
||||||
|
merge() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
validate() {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.validate({});
|
||||||
|
}, /Missing required key "foo"/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when a subschema is provided and the value doesn't validate", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
name: {
|
||||||
|
schema: {
|
||||||
|
first: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
schema.validate({
|
||||||
|
name: {
|
||||||
|
first: 123,
|
||||||
|
last: "z"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}, /Key "name": Key "first": Expected a string/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not throw an error when a subschema is provided and the value validates", () => {
|
||||||
|
|
||||||
|
schema = new ObjectSchema({
|
||||||
|
name: {
|
||||||
|
schema: {
|
||||||
|
first: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
merge: "replace",
|
||||||
|
validate: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
schema.validate({
|
||||||
|
name: {
|
||||||
|
first: "n",
|
||||||
|
last: "z"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
186
node_modules/@humanwhocodes/object-schema/tests/validation-strategy.js
generated
vendored
Normal file
186
node_modules/@humanwhocodes/object-schema/tests/validation-strategy.js
generated
vendored
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
/**
|
||||||
|
* @filedescription Merge Strategy Tests
|
||||||
|
*/
|
||||||
|
/* global it, describe, beforeEach */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Requirements
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const assert = require("chai").assert;
|
||||||
|
const { ValidationStrategy } = require("../src/");
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Class
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
describe("ValidationStrategy", () => {
|
||||||
|
|
||||||
|
describe("boolean", () => {
|
||||||
|
it("should not throw an error when the value is a boolean", () => {
|
||||||
|
ValidationStrategy.boolean(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is null", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.boolean(null);
|
||||||
|
}, /Expected a Boolean/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is a string", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.boolean("foo");
|
||||||
|
}, /Expected a Boolean/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is a number", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.boolean(123);
|
||||||
|
}, /Expected a Boolean/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is an object", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.boolean({});
|
||||||
|
}, /Expected a Boolean/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("number", () => {
|
||||||
|
it("should not throw an error when the value is a number", () => {
|
||||||
|
ValidationStrategy.number(25);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is null", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.number(null);
|
||||||
|
}, /Expected a number/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is a string", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.number("foo");
|
||||||
|
}, /Expected a number/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is a boolean", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.number(true);
|
||||||
|
}, /Expected a number/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is an object", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.number({});
|
||||||
|
}, /Expected a number/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("object", () => {
|
||||||
|
it("should not throw an error when the value is an object", () => {
|
||||||
|
ValidationStrategy.object({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is null", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.object(null);
|
||||||
|
}, /Expected an object/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is a string", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.object("");
|
||||||
|
}, /Expected an object/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("array", () => {
|
||||||
|
it("should not throw an error when the value is an array", () => {
|
||||||
|
ValidationStrategy.array([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is null", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.array(null);
|
||||||
|
}, /Expected an array/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is a string", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.array("");
|
||||||
|
}, /Expected an array/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is an object", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.array({});
|
||||||
|
}, /Expected an array/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("object?", () => {
|
||||||
|
it("should not throw an error when the value is an object", () => {
|
||||||
|
ValidationStrategy["object?"]({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not throw an error when the value is null", () => {
|
||||||
|
ValidationStrategy["object?"](null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is a string", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy["object?"]("");
|
||||||
|
}, /Expected an object/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("string", () => {
|
||||||
|
it("should not throw an error when the value is a string", () => {
|
||||||
|
ValidationStrategy.string("foo");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not throw an error when the value is an empty string", () => {
|
||||||
|
ValidationStrategy.string("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is null", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.string(null);
|
||||||
|
}, /Expected a string/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is an object", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy.string({});
|
||||||
|
}, /Expected a string/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("string!", () => {
|
||||||
|
it("should not throw an error when the value is an string", () => {
|
||||||
|
ValidationStrategy["string!"]("foo");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is an empty string", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy["string!"]("");
|
||||||
|
}, /Expected a non-empty string/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is null", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy["string!"](null);
|
||||||
|
}, /Expected a non-empty string/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error when the value is an object", () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
ValidationStrategy["string!"]({});
|
||||||
|
}, /Expected a non-empty string/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
19
node_modules/acorn-jsx/LICENSE
generated
vendored
Normal file
19
node_modules/acorn-jsx/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (C) 2012-2017 by Ingvar Stepanyan
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
40
node_modules/acorn-jsx/README.md
generated
vendored
Normal file
40
node_modules/acorn-jsx/README.md
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# Acorn-JSX
|
||||||
|
|
||||||
|
[](https://travis-ci.org/acornjs/acorn-jsx)
|
||||||
|
[](https://www.npmjs.org/package/acorn-jsx)
|
||||||
|
|
||||||
|
This is plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript.
|
||||||
|
|
||||||
|
It was created as an experimental alternative, faster [React.js JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) parser. Later, it replaced the [official parser](https://github.com/facebookarchive/esprima) and these days is used by many prominent development tools.
|
||||||
|
|
||||||
|
## Transpiler
|
||||||
|
|
||||||
|
Please note that this tool only parses source code to JSX AST, which is useful for various language tools and services. If you want to transpile your code to regular ES5-compliant JavaScript with source map, check out [Babel](https://babeljs.io/) and [Buble](https://buble.surge.sh/) transpilers which use `acorn-jsx` under the hood.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Requiring this module provides you with an Acorn plugin that you can use like this:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var acorn = require("acorn");
|
||||||
|
var jsx = require("acorn-jsx");
|
||||||
|
acorn.Parser.extend(jsx()).parse("my(<jsx/>, 'code');");
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that official spec doesn't support mix of XML namespaces and object-style access in tag names (#27) like in `<namespace:Object.Property />`, so it was deprecated in `acorn-jsx@3.0`. If you still want to opt-in to support of such constructions, you can pass the following option:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
acorn.Parser.extend(jsx({ allowNamespacedObjects: true }))
|
||||||
|
```
|
||||||
|
|
||||||
|
Also, since most apps use pure React transformer, a new option was introduced that allows to prohibit namespaces completely:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
acorn.Parser.extend(jsx({ allowNamespaces: false }))
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that by default `allowNamespaces` is enabled for spec compliancy.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This plugin is issued under the [MIT license](./LICENSE).
|
12
node_modules/acorn-jsx/index.d.ts
generated
vendored
Normal file
12
node_modules/acorn-jsx/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { Parser } from 'acorn'
|
||||||
|
|
||||||
|
declare const jsx: (options?: jsx.Options) => (BaseParser: typeof Parser) => typeof Parser;
|
||||||
|
|
||||||
|
declare namespace jsx {
|
||||||
|
interface Options {
|
||||||
|
allowNamespacedObjects?: boolean;
|
||||||
|
allowNamespaces?: boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export = jsx;
|
488
node_modules/acorn-jsx/index.js
generated
vendored
Normal file
488
node_modules/acorn-jsx/index.js
generated
vendored
Normal file
|
@ -0,0 +1,488 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const XHTMLEntities = require('./xhtml');
|
||||||
|
|
||||||
|
const hexNumber = /^[\da-fA-F]+$/;
|
||||||
|
const decimalNumber = /^\d+$/;
|
||||||
|
|
||||||
|
// The map to `acorn-jsx` tokens from `acorn` namespace objects.
|
||||||
|
const acornJsxMap = new WeakMap();
|
||||||
|
|
||||||
|
// Get the original tokens for the given `acorn` namespace object.
|
||||||
|
function getJsxTokens(acorn) {
|
||||||
|
acorn = acorn.Parser.acorn || acorn;
|
||||||
|
let acornJsx = acornJsxMap.get(acorn);
|
||||||
|
if (!acornJsx) {
|
||||||
|
const tt = acorn.tokTypes;
|
||||||
|
const TokContext = acorn.TokContext;
|
||||||
|
const TokenType = acorn.TokenType;
|
||||||
|
const tc_oTag = new TokContext('<tag', false);
|
||||||
|
const tc_cTag = new TokContext('</tag', false);
|
||||||
|
const tc_expr = new TokContext('<tag>...</tag>', true, true);
|
||||||
|
const tokContexts = {
|
||||||
|
tc_oTag: tc_oTag,
|
||||||
|
tc_cTag: tc_cTag,
|
||||||
|
tc_expr: tc_expr
|
||||||
|
};
|
||||||
|
const tokTypes = {
|
||||||
|
jsxName: new TokenType('jsxName'),
|
||||||
|
jsxText: new TokenType('jsxText', {beforeExpr: true}),
|
||||||
|
jsxTagStart: new TokenType('jsxTagStart', {startsExpr: true}),
|
||||||
|
jsxTagEnd: new TokenType('jsxTagEnd')
|
||||||
|
};
|
||||||
|
|
||||||
|
tokTypes.jsxTagStart.updateContext = function() {
|
||||||
|
this.context.push(tc_expr); // treat as beginning of JSX expression
|
||||||
|
this.context.push(tc_oTag); // start opening tag context
|
||||||
|
this.exprAllowed = false;
|
||||||
|
};
|
||||||
|
tokTypes.jsxTagEnd.updateContext = function(prevType) {
|
||||||
|
let out = this.context.pop();
|
||||||
|
if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) {
|
||||||
|
this.context.pop();
|
||||||
|
this.exprAllowed = this.curContext() === tc_expr;
|
||||||
|
} else {
|
||||||
|
this.exprAllowed = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes };
|
||||||
|
acornJsxMap.set(acorn, acornJsx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return acornJsx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transforms JSX element name to string.
|
||||||
|
|
||||||
|
function getQualifiedJSXName(object) {
|
||||||
|
if (!object)
|
||||||
|
return object;
|
||||||
|
|
||||||
|
if (object.type === 'JSXIdentifier')
|
||||||
|
return object.name;
|
||||||
|
|
||||||
|
if (object.type === 'JSXNamespacedName')
|
||||||
|
return object.namespace.name + ':' + object.name.name;
|
||||||
|
|
||||||
|
if (object.type === 'JSXMemberExpression')
|
||||||
|
return getQualifiedJSXName(object.object) + '.' +
|
||||||
|
getQualifiedJSXName(object.property);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function(options) {
|
||||||
|
options = options || {};
|
||||||
|
return function(Parser) {
|
||||||
|
return plugin({
|
||||||
|
allowNamespaces: options.allowNamespaces !== false,
|
||||||
|
allowNamespacedObjects: !!options.allowNamespacedObjects
|
||||||
|
}, Parser);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is `tokTypes` of the peer dep.
|
||||||
|
// This can be different instances from the actual `tokTypes` this plugin uses.
|
||||||
|
Object.defineProperty(module.exports, "tokTypes", {
|
||||||
|
get: function get_tokTypes() {
|
||||||
|
return getJsxTokens(require("acorn")).tokTypes;
|
||||||
|
},
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
function plugin(options, Parser) {
|
||||||
|
const acorn = Parser.acorn || require("acorn");
|
||||||
|
const acornJsx = getJsxTokens(acorn);
|
||||||
|
const tt = acorn.tokTypes;
|
||||||
|
const tok = acornJsx.tokTypes;
|
||||||
|
const tokContexts = acorn.tokContexts;
|
||||||
|
const tc_oTag = acornJsx.tokContexts.tc_oTag;
|
||||||
|
const tc_cTag = acornJsx.tokContexts.tc_cTag;
|
||||||
|
const tc_expr = acornJsx.tokContexts.tc_expr;
|
||||||
|
const isNewLine = acorn.isNewLine;
|
||||||
|
const isIdentifierStart = acorn.isIdentifierStart;
|
||||||
|
const isIdentifierChar = acorn.isIdentifierChar;
|
||||||
|
|
||||||
|
return class extends Parser {
|
||||||
|
// Expose actual `tokTypes` and `tokContexts` to other plugins.
|
||||||
|
static get acornJsx() {
|
||||||
|
return acornJsx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reads inline JSX contents token.
|
||||||
|
jsx_readToken() {
|
||||||
|
let out = '', chunkStart = this.pos;
|
||||||
|
for (;;) {
|
||||||
|
if (this.pos >= this.input.length)
|
||||||
|
this.raise(this.start, 'Unterminated JSX contents');
|
||||||
|
let ch = this.input.charCodeAt(this.pos);
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
case 60: // '<'
|
||||||
|
case 123: // '{'
|
||||||
|
if (this.pos === this.start) {
|
||||||
|
if (ch === 60 && this.exprAllowed) {
|
||||||
|
++this.pos;
|
||||||
|
return this.finishToken(tok.jsxTagStart);
|
||||||
|
}
|
||||||
|
return this.getTokenFromCode(ch);
|
||||||
|
}
|
||||||
|
out += this.input.slice(chunkStart, this.pos);
|
||||||
|
return this.finishToken(tok.jsxText, out);
|
||||||
|
|
||||||
|
case 38: // '&'
|
||||||
|
out += this.input.slice(chunkStart, this.pos);
|
||||||
|
out += this.jsx_readEntity();
|
||||||
|
chunkStart = this.pos;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 62: // '>'
|
||||||
|
case 125: // '}'
|
||||||
|
this.raise(
|
||||||
|
this.pos,
|
||||||
|
"Unexpected token `" + this.input[this.pos] + "`. Did you mean `" +
|
||||||
|
(ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?"
|
||||||
|
);
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (isNewLine(ch)) {
|
||||||
|
out += this.input.slice(chunkStart, this.pos);
|
||||||
|
out += this.jsx_readNewLine(true);
|
||||||
|
chunkStart = this.pos;
|
||||||
|
} else {
|
||||||
|
++this.pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jsx_readNewLine(normalizeCRLF) {
|
||||||
|
let ch = this.input.charCodeAt(this.pos);
|
||||||
|
let out;
|
||||||
|
++this.pos;
|
||||||
|
if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
|
||||||
|
++this.pos;
|
||||||
|
out = normalizeCRLF ? '\n' : '\r\n';
|
||||||
|
} else {
|
||||||
|
out = String.fromCharCode(ch);
|
||||||
|
}
|
||||||
|
if (this.options.locations) {
|
||||||
|
++this.curLine;
|
||||||
|
this.lineStart = this.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsx_readString(quote) {
|
||||||
|
let out = '', chunkStart = ++this.pos;
|
||||||
|
for (;;) {
|
||||||
|
if (this.pos >= this.input.length)
|
||||||
|
this.raise(this.start, 'Unterminated string constant');
|
||||||
|
let ch = this.input.charCodeAt(this.pos);
|
||||||
|
if (ch === quote) break;
|
||||||
|
if (ch === 38) { // '&'
|
||||||
|
out += this.input.slice(chunkStart, this.pos);
|
||||||
|
out += this.jsx_readEntity();
|
||||||
|
chunkStart = this.pos;
|
||||||
|
} else if (isNewLine(ch)) {
|
||||||
|
out += this.input.slice(chunkStart, this.pos);
|
||||||
|
out += this.jsx_readNewLine(false);
|
||||||
|
chunkStart = this.pos;
|
||||||
|
} else {
|
||||||
|
++this.pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out += this.input.slice(chunkStart, this.pos++);
|
||||||
|
return this.finishToken(tt.string, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsx_readEntity() {
|
||||||
|
let str = '', count = 0, entity;
|
||||||
|
let ch = this.input[this.pos];
|
||||||
|
if (ch !== '&')
|
||||||
|
this.raise(this.pos, 'Entity must start with an ampersand');
|
||||||
|
let startPos = ++this.pos;
|
||||||
|
while (this.pos < this.input.length && count++ < 10) {
|
||||||
|
ch = this.input[this.pos++];
|
||||||
|
if (ch === ';') {
|
||||||
|
if (str[0] === '#') {
|
||||||
|
if (str[1] === 'x') {
|
||||||
|
str = str.substr(2);
|
||||||
|
if (hexNumber.test(str))
|
||||||
|
entity = String.fromCharCode(parseInt(str, 16));
|
||||||
|
} else {
|
||||||
|
str = str.substr(1);
|
||||||
|
if (decimalNumber.test(str))
|
||||||
|
entity = String.fromCharCode(parseInt(str, 10));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entity = XHTMLEntities[str];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str += ch;
|
||||||
|
}
|
||||||
|
if (!entity) {
|
||||||
|
this.pos = startPos;
|
||||||
|
return '&';
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a JSX identifier (valid tag or attribute name).
|
||||||
|
//
|
||||||
|
// Optimized version since JSX identifiers can't contain
|
||||||
|
// escape characters and so can be read as single slice.
|
||||||
|
// Also assumes that first character was already checked
|
||||||
|
// by isIdentifierStart in readToken.
|
||||||
|
|
||||||
|
jsx_readWord() {
|
||||||
|
let ch, start = this.pos;
|
||||||
|
do {
|
||||||
|
ch = this.input.charCodeAt(++this.pos);
|
||||||
|
} while (isIdentifierChar(ch) || ch === 45); // '-'
|
||||||
|
return this.finishToken(tok.jsxName, this.input.slice(start, this.pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse next token as JSX identifier
|
||||||
|
|
||||||
|
jsx_parseIdentifier() {
|
||||||
|
let node = this.startNode();
|
||||||
|
if (this.type === tok.jsxName)
|
||||||
|
node.name = this.value;
|
||||||
|
else if (this.type.keyword)
|
||||||
|
node.name = this.type.keyword;
|
||||||
|
else
|
||||||
|
this.unexpected();
|
||||||
|
this.next();
|
||||||
|
return this.finishNode(node, 'JSXIdentifier');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse namespaced identifier.
|
||||||
|
|
||||||
|
jsx_parseNamespacedName() {
|
||||||
|
let startPos = this.start, startLoc = this.startLoc;
|
||||||
|
let name = this.jsx_parseIdentifier();
|
||||||
|
if (!options.allowNamespaces || !this.eat(tt.colon)) return name;
|
||||||
|
var node = this.startNodeAt(startPos, startLoc);
|
||||||
|
node.namespace = name;
|
||||||
|
node.name = this.jsx_parseIdentifier();
|
||||||
|
return this.finishNode(node, 'JSXNamespacedName');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses element name in any form - namespaced, member
|
||||||
|
// or single identifier.
|
||||||
|
|
||||||
|
jsx_parseElementName() {
|
||||||
|
if (this.type === tok.jsxTagEnd) return '';
|
||||||
|
let startPos = this.start, startLoc = this.startLoc;
|
||||||
|
let node = this.jsx_parseNamespacedName();
|
||||||
|
if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) {
|
||||||
|
this.unexpected();
|
||||||
|
}
|
||||||
|
while (this.eat(tt.dot)) {
|
||||||
|
let newNode = this.startNodeAt(startPos, startLoc);
|
||||||
|
newNode.object = node;
|
||||||
|
newNode.property = this.jsx_parseIdentifier();
|
||||||
|
node = this.finishNode(newNode, 'JSXMemberExpression');
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses any type of JSX attribute value.
|
||||||
|
|
||||||
|
jsx_parseAttributeValue() {
|
||||||
|
switch (this.type) {
|
||||||
|
case tt.braceL:
|
||||||
|
let node = this.jsx_parseExpressionContainer();
|
||||||
|
if (node.expression.type === 'JSXEmptyExpression')
|
||||||
|
this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression');
|
||||||
|
return node;
|
||||||
|
|
||||||
|
case tok.jsxTagStart:
|
||||||
|
case tt.string:
|
||||||
|
return this.parseExprAtom();
|
||||||
|
|
||||||
|
default:
|
||||||
|
this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSXEmptyExpression is unique type since it doesn't actually parse anything,
|
||||||
|
// and so it should start at the end of last read token (left brace) and finish
|
||||||
|
// at the beginning of the next one (right brace).
|
||||||
|
|
||||||
|
jsx_parseEmptyExpression() {
|
||||||
|
let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
|
||||||
|
return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses JSX expression enclosed into curly brackets.
|
||||||
|
|
||||||
|
jsx_parseExpressionContainer() {
|
||||||
|
let node = this.startNode();
|
||||||
|
this.next();
|
||||||
|
node.expression = this.type === tt.braceR
|
||||||
|
? this.jsx_parseEmptyExpression()
|
||||||
|
: this.parseExpression();
|
||||||
|
this.expect(tt.braceR);
|
||||||
|
return this.finishNode(node, 'JSXExpressionContainer');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses following JSX attribute name-value pair.
|
||||||
|
|
||||||
|
jsx_parseAttribute() {
|
||||||
|
let node = this.startNode();
|
||||||
|
if (this.eat(tt.braceL)) {
|
||||||
|
this.expect(tt.ellipsis);
|
||||||
|
node.argument = this.parseMaybeAssign();
|
||||||
|
this.expect(tt.braceR);
|
||||||
|
return this.finishNode(node, 'JSXSpreadAttribute');
|
||||||
|
}
|
||||||
|
node.name = this.jsx_parseNamespacedName();
|
||||||
|
node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null;
|
||||||
|
return this.finishNode(node, 'JSXAttribute');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses JSX opening tag starting after '<'.
|
||||||
|
|
||||||
|
jsx_parseOpeningElementAt(startPos, startLoc) {
|
||||||
|
let node = this.startNodeAt(startPos, startLoc);
|
||||||
|
node.attributes = [];
|
||||||
|
let nodeName = this.jsx_parseElementName();
|
||||||
|
if (nodeName) node.name = nodeName;
|
||||||
|
while (this.type !== tt.slash && this.type !== tok.jsxTagEnd)
|
||||||
|
node.attributes.push(this.jsx_parseAttribute());
|
||||||
|
node.selfClosing = this.eat(tt.slash);
|
||||||
|
this.expect(tok.jsxTagEnd);
|
||||||
|
return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses JSX closing tag starting after '</'.
|
||||||
|
|
||||||
|
jsx_parseClosingElementAt(startPos, startLoc) {
|
||||||
|
let node = this.startNodeAt(startPos, startLoc);
|
||||||
|
let nodeName = this.jsx_parseElementName();
|
||||||
|
if (nodeName) node.name = nodeName;
|
||||||
|
this.expect(tok.jsxTagEnd);
|
||||||
|
return this.finishNode(node, nodeName ? 'JSXClosingElement' : 'JSXClosingFragment');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses entire JSX element, including it's opening tag
|
||||||
|
// (starting after '<'), attributes, contents and closing tag.
|
||||||
|
|
||||||
|
jsx_parseElementAt(startPos, startLoc) {
|
||||||
|
let node = this.startNodeAt(startPos, startLoc);
|
||||||
|
let children = [];
|
||||||
|
let openingElement = this.jsx_parseOpeningElementAt(startPos, startLoc);
|
||||||
|
let closingElement = null;
|
||||||
|
|
||||||
|
if (!openingElement.selfClosing) {
|
||||||
|
contents: for (;;) {
|
||||||
|
switch (this.type) {
|
||||||
|
case tok.jsxTagStart:
|
||||||
|
startPos = this.start; startLoc = this.startLoc;
|
||||||
|
this.next();
|
||||||
|
if (this.eat(tt.slash)) {
|
||||||
|
closingElement = this.jsx_parseClosingElementAt(startPos, startLoc);
|
||||||
|
break contents;
|
||||||
|
}
|
||||||
|
children.push(this.jsx_parseElementAt(startPos, startLoc));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tok.jsxText:
|
||||||
|
children.push(this.parseExprAtom());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tt.braceL:
|
||||||
|
children.push(this.jsx_parseExpressionContainer());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
this.unexpected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
|
||||||
|
this.raise(
|
||||||
|
closingElement.start,
|
||||||
|
'Expected corresponding JSX closing tag for <' + getQualifiedJSXName(openingElement.name) + '>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment';
|
||||||
|
|
||||||
|
node['opening' + fragmentOrElement] = openingElement;
|
||||||
|
node['closing' + fragmentOrElement] = closingElement;
|
||||||
|
node.children = children;
|
||||||
|
if (this.type === tt.relational && this.value === "<") {
|
||||||
|
this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag");
|
||||||
|
}
|
||||||
|
return this.finishNode(node, 'JSX' + fragmentOrElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse JSX text
|
||||||
|
|
||||||
|
jsx_parseText() {
|
||||||
|
let node = this.parseLiteral(this.value);
|
||||||
|
node.type = "JSXText";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses entire JSX element from current position.
|
||||||
|
|
||||||
|
jsx_parseElement() {
|
||||||
|
let startPos = this.start, startLoc = this.startLoc;
|
||||||
|
this.next();
|
||||||
|
return this.jsx_parseElementAt(startPos, startLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseExprAtom(refShortHandDefaultPos) {
|
||||||
|
if (this.type === tok.jsxText)
|
||||||
|
return this.jsx_parseText();
|
||||||
|
else if (this.type === tok.jsxTagStart)
|
||||||
|
return this.jsx_parseElement();
|
||||||
|
else
|
||||||
|
return super.parseExprAtom(refShortHandDefaultPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
readToken(code) {
|
||||||
|
let context = this.curContext();
|
||||||
|
|
||||||
|
if (context === tc_expr) return this.jsx_readToken();
|
||||||
|
|
||||||
|
if (context === tc_oTag || context === tc_cTag) {
|
||||||
|
if (isIdentifierStart(code)) return this.jsx_readWord();
|
||||||
|
|
||||||
|
if (code == 62) {
|
||||||
|
++this.pos;
|
||||||
|
return this.finishToken(tok.jsxTagEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((code === 34 || code === 39) && context == tc_oTag)
|
||||||
|
return this.jsx_readString(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) {
|
||||||
|
++this.pos;
|
||||||
|
return this.finishToken(tok.jsxTagStart);
|
||||||
|
}
|
||||||
|
return super.readToken(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateContext(prevType) {
|
||||||
|
if (this.type == tt.braceL) {
|
||||||
|
var curContext = this.curContext();
|
||||||
|
if (curContext == tc_oTag) this.context.push(tokContexts.b_expr);
|
||||||
|
else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl);
|
||||||
|
else super.updateContext(prevType);
|
||||||
|
this.exprAllowed = true;
|
||||||
|
} else if (this.type === tt.slash && prevType === tok.jsxTagStart) {
|
||||||
|
this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
|
||||||
|
this.context.push(tc_cTag); // reconsider as closing tag context
|
||||||
|
this.exprAllowed = false;
|
||||||
|
} else {
|
||||||
|
return super.updateContext(prevType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
27
node_modules/acorn-jsx/package.json
generated
vendored
Normal file
27
node_modules/acorn-jsx/package.json
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"name": "acorn-jsx",
|
||||||
|
"description": "Modern, fast React.js JSX parser",
|
||||||
|
"homepage": "https://github.com/acornjs/acorn-jsx",
|
||||||
|
"version": "5.3.2",
|
||||||
|
"maintainers": [
|
||||||
|
{
|
||||||
|
"name": "Ingvar Stepanyan",
|
||||||
|
"email": "me@rreverser.com",
|
||||||
|
"web": "http://rreverser.com/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/acornjs/acorn-jsx"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"test": "node test/run.js"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"acorn": "^8.0.1"
|
||||||
|
}
|
||||||
|
}
|
255
node_modules/acorn-jsx/xhtml.js
generated
vendored
Normal file
255
node_modules/acorn-jsx/xhtml.js
generated
vendored
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
module.exports = {
|
||||||
|
quot: '\u0022',
|
||||||
|
amp: '&',
|
||||||
|
apos: '\u0027',
|
||||||
|
lt: '<',
|
||||||
|
gt: '>',
|
||||||
|
nbsp: '\u00A0',
|
||||||
|
iexcl: '\u00A1',
|
||||||
|
cent: '\u00A2',
|
||||||
|
pound: '\u00A3',
|
||||||
|
curren: '\u00A4',
|
||||||
|
yen: '\u00A5',
|
||||||
|
brvbar: '\u00A6',
|
||||||
|
sect: '\u00A7',
|
||||||
|
uml: '\u00A8',
|
||||||
|
copy: '\u00A9',
|
||||||
|
ordf: '\u00AA',
|
||||||
|
laquo: '\u00AB',
|
||||||
|
not: '\u00AC',
|
||||||
|
shy: '\u00AD',
|
||||||
|
reg: '\u00AE',
|
||||||
|
macr: '\u00AF',
|
||||||
|
deg: '\u00B0',
|
||||||
|
plusmn: '\u00B1',
|
||||||
|
sup2: '\u00B2',
|
||||||
|
sup3: '\u00B3',
|
||||||
|
acute: '\u00B4',
|
||||||
|
micro: '\u00B5',
|
||||||
|
para: '\u00B6',
|
||||||
|
middot: '\u00B7',
|
||||||
|
cedil: '\u00B8',
|
||||||
|
sup1: '\u00B9',
|
||||||
|
ordm: '\u00BA',
|
||||||
|
raquo: '\u00BB',
|
||||||
|
frac14: '\u00BC',
|
||||||
|
frac12: '\u00BD',
|
||||||
|
frac34: '\u00BE',
|
||||||
|
iquest: '\u00BF',
|
||||||
|
Agrave: '\u00C0',
|
||||||
|
Aacute: '\u00C1',
|
||||||
|
Acirc: '\u00C2',
|
||||||
|
Atilde: '\u00C3',
|
||||||
|
Auml: '\u00C4',
|
||||||
|
Aring: '\u00C5',
|
||||||
|
AElig: '\u00C6',
|
||||||
|
Ccedil: '\u00C7',
|
||||||
|
Egrave: '\u00C8',
|
||||||
|
Eacute: '\u00C9',
|
||||||
|
Ecirc: '\u00CA',
|
||||||
|
Euml: '\u00CB',
|
||||||
|
Igrave: '\u00CC',
|
||||||
|
Iacute: '\u00CD',
|
||||||
|
Icirc: '\u00CE',
|
||||||
|
Iuml: '\u00CF',
|
||||||
|
ETH: '\u00D0',
|
||||||
|
Ntilde: '\u00D1',
|
||||||
|
Ograve: '\u00D2',
|
||||||
|
Oacute: '\u00D3',
|
||||||
|
Ocirc: '\u00D4',
|
||||||
|
Otilde: '\u00D5',
|
||||||
|
Ouml: '\u00D6',
|
||||||
|
times: '\u00D7',
|
||||||
|
Oslash: '\u00D8',
|
||||||
|
Ugrave: '\u00D9',
|
||||||
|
Uacute: '\u00DA',
|
||||||
|
Ucirc: '\u00DB',
|
||||||
|
Uuml: '\u00DC',
|
||||||
|
Yacute: '\u00DD',
|
||||||
|
THORN: '\u00DE',
|
||||||
|
szlig: '\u00DF',
|
||||||
|
agrave: '\u00E0',
|
||||||
|
aacute: '\u00E1',
|
||||||
|
acirc: '\u00E2',
|
||||||
|
atilde: '\u00E3',
|
||||||
|
auml: '\u00E4',
|
||||||
|
aring: '\u00E5',
|
||||||
|
aelig: '\u00E6',
|
||||||
|
ccedil: '\u00E7',
|
||||||
|
egrave: '\u00E8',
|
||||||
|
eacute: '\u00E9',
|
||||||
|
ecirc: '\u00EA',
|
||||||
|
euml: '\u00EB',
|
||||||
|
igrave: '\u00EC',
|
||||||
|
iacute: '\u00ED',
|
||||||
|
icirc: '\u00EE',
|
||||||
|
iuml: '\u00EF',
|
||||||
|
eth: '\u00F0',
|
||||||
|
ntilde: '\u00F1',
|
||||||
|
ograve: '\u00F2',
|
||||||
|
oacute: '\u00F3',
|
||||||
|
ocirc: '\u00F4',
|
||||||
|
otilde: '\u00F5',
|
||||||
|
ouml: '\u00F6',
|
||||||
|
divide: '\u00F7',
|
||||||
|
oslash: '\u00F8',
|
||||||
|
ugrave: '\u00F9',
|
||||||
|
uacute: '\u00FA',
|
||||||
|
ucirc: '\u00FB',
|
||||||
|
uuml: '\u00FC',
|
||||||
|
yacute: '\u00FD',
|
||||||
|
thorn: '\u00FE',
|
||||||
|
yuml: '\u00FF',
|
||||||
|
OElig: '\u0152',
|
||||||
|
oelig: '\u0153',
|
||||||
|
Scaron: '\u0160',
|
||||||
|
scaron: '\u0161',
|
||||||
|
Yuml: '\u0178',
|
||||||
|
fnof: '\u0192',
|
||||||
|
circ: '\u02C6',
|
||||||
|
tilde: '\u02DC',
|
||||||
|
Alpha: '\u0391',
|
||||||
|
Beta: '\u0392',
|
||||||
|
Gamma: '\u0393',
|
||||||
|
Delta: '\u0394',
|
||||||
|
Epsilon: '\u0395',
|
||||||
|
Zeta: '\u0396',
|
||||||
|
Eta: '\u0397',
|
||||||
|
Theta: '\u0398',
|
||||||
|
Iota: '\u0399',
|
||||||
|
Kappa: '\u039A',
|
||||||
|
Lambda: '\u039B',
|
||||||
|
Mu: '\u039C',
|
||||||
|
Nu: '\u039D',
|
||||||
|
Xi: '\u039E',
|
||||||
|
Omicron: '\u039F',
|
||||||
|
Pi: '\u03A0',
|
||||||
|
Rho: '\u03A1',
|
||||||
|
Sigma: '\u03A3',
|
||||||
|
Tau: '\u03A4',
|
||||||
|
Upsilon: '\u03A5',
|
||||||
|
Phi: '\u03A6',
|
||||||
|
Chi: '\u03A7',
|
||||||
|
Psi: '\u03A8',
|
||||||
|
Omega: '\u03A9',
|
||||||
|
alpha: '\u03B1',
|
||||||
|
beta: '\u03B2',
|
||||||
|
gamma: '\u03B3',
|
||||||
|
delta: '\u03B4',
|
||||||
|
epsilon: '\u03B5',
|
||||||
|
zeta: '\u03B6',
|
||||||
|
eta: '\u03B7',
|
||||||
|
theta: '\u03B8',
|
||||||
|
iota: '\u03B9',
|
||||||
|
kappa: '\u03BA',
|
||||||
|
lambda: '\u03BB',
|
||||||
|
mu: '\u03BC',
|
||||||
|
nu: '\u03BD',
|
||||||
|
xi: '\u03BE',
|
||||||
|
omicron: '\u03BF',
|
||||||
|
pi: '\u03C0',
|
||||||
|
rho: '\u03C1',
|
||||||
|
sigmaf: '\u03C2',
|
||||||
|
sigma: '\u03C3',
|
||||||
|
tau: '\u03C4',
|
||||||
|
upsilon: '\u03C5',
|
||||||
|
phi: '\u03C6',
|
||||||
|
chi: '\u03C7',
|
||||||
|
psi: '\u03C8',
|
||||||
|
omega: '\u03C9',
|
||||||
|
thetasym: '\u03D1',
|
||||||
|
upsih: '\u03D2',
|
||||||
|
piv: '\u03D6',
|
||||||
|
ensp: '\u2002',
|
||||||
|
emsp: '\u2003',
|
||||||
|
thinsp: '\u2009',
|
||||||
|
zwnj: '\u200C',
|
||||||
|
zwj: '\u200D',
|
||||||
|
lrm: '\u200E',
|
||||||
|
rlm: '\u200F',
|
||||||
|
ndash: '\u2013',
|
||||||
|
mdash: '\u2014',
|
||||||
|
lsquo: '\u2018',
|
||||||
|
rsquo: '\u2019',
|
||||||
|
sbquo: '\u201A',
|
||||||
|
ldquo: '\u201C',
|
||||||
|
rdquo: '\u201D',
|
||||||
|
bdquo: '\u201E',
|
||||||
|
dagger: '\u2020',
|
||||||
|
Dagger: '\u2021',
|
||||||
|
bull: '\u2022',
|
||||||
|
hellip: '\u2026',
|
||||||
|
permil: '\u2030',
|
||||||
|
prime: '\u2032',
|
||||||
|
Prime: '\u2033',
|
||||||
|
lsaquo: '\u2039',
|
||||||
|
rsaquo: '\u203A',
|
||||||
|
oline: '\u203E',
|
||||||
|
frasl: '\u2044',
|
||||||
|
euro: '\u20AC',
|
||||||
|
image: '\u2111',
|
||||||
|
weierp: '\u2118',
|
||||||
|
real: '\u211C',
|
||||||
|
trade: '\u2122',
|
||||||
|
alefsym: '\u2135',
|
||||||
|
larr: '\u2190',
|
||||||
|
uarr: '\u2191',
|
||||||
|
rarr: '\u2192',
|
||||||
|
darr: '\u2193',
|
||||||
|
harr: '\u2194',
|
||||||
|
crarr: '\u21B5',
|
||||||
|
lArr: '\u21D0',
|
||||||
|
uArr: '\u21D1',
|
||||||
|
rArr: '\u21D2',
|
||||||
|
dArr: '\u21D3',
|
||||||
|
hArr: '\u21D4',
|
||||||
|
forall: '\u2200',
|
||||||
|
part: '\u2202',
|
||||||
|
exist: '\u2203',
|
||||||
|
empty: '\u2205',
|
||||||
|
nabla: '\u2207',
|
||||||
|
isin: '\u2208',
|
||||||
|
notin: '\u2209',
|
||||||
|
ni: '\u220B',
|
||||||
|
prod: '\u220F',
|
||||||
|
sum: '\u2211',
|
||||||
|
minus: '\u2212',
|
||||||
|
lowast: '\u2217',
|
||||||
|
radic: '\u221A',
|
||||||
|
prop: '\u221D',
|
||||||
|
infin: '\u221E',
|
||||||
|
ang: '\u2220',
|
||||||
|
and: '\u2227',
|
||||||
|
or: '\u2228',
|
||||||
|
cap: '\u2229',
|
||||||
|
cup: '\u222A',
|
||||||
|
'int': '\u222B',
|
||||||
|
there4: '\u2234',
|
||||||
|
sim: '\u223C',
|
||||||
|
cong: '\u2245',
|
||||||
|
asymp: '\u2248',
|
||||||
|
ne: '\u2260',
|
||||||
|
equiv: '\u2261',
|
||||||
|
le: '\u2264',
|
||||||
|
ge: '\u2265',
|
||||||
|
sub: '\u2282',
|
||||||
|
sup: '\u2283',
|
||||||
|
nsub: '\u2284',
|
||||||
|
sube: '\u2286',
|
||||||
|
supe: '\u2287',
|
||||||
|
oplus: '\u2295',
|
||||||
|
otimes: '\u2297',
|
||||||
|
perp: '\u22A5',
|
||||||
|
sdot: '\u22C5',
|
||||||
|
lceil: '\u2308',
|
||||||
|
rceil: '\u2309',
|
||||||
|
lfloor: '\u230A',
|
||||||
|
rfloor: '\u230B',
|
||||||
|
lang: '\u2329',
|
||||||
|
rang: '\u232A',
|
||||||
|
loz: '\u25CA',
|
||||||
|
spades: '\u2660',
|
||||||
|
clubs: '\u2663',
|
||||||
|
hearts: '\u2665',
|
||||||
|
diams: '\u2666'
|
||||||
|
};
|
788
node_modules/acorn/CHANGELOG.md
generated
vendored
Normal file
788
node_modules/acorn/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,788 @@
|
||||||
|
## 8.7.0 (2021-12-27)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Support quoted export names.
|
||||||
|
|
||||||
|
Upgrade to Unicode 14.
|
||||||
|
|
||||||
|
Add support for Unicode 13 properties in regular expressions.
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Use a loop to find line breaks, because the existing regexp search would overrun the end of the searched range and waste a lot of time in minified code.
|
||||||
|
|
||||||
|
## 8.6.0 (2021-11-18)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix a bug where an object literal with multiple `__proto__` properties would incorrectly be accepted if a later property value held an assigment.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Support class private fields with the `in` operator.
|
||||||
|
|
||||||
|
## 8.5.0 (2021-09-06)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Improve context-dependent tokenization in a number of corner cases.
|
||||||
|
|
||||||
|
Fix location tracking after a 0x2028 or 0x2029 character in a string literal (which before did not increase the line number).
|
||||||
|
|
||||||
|
Fix an issue where arrow function bodies in for loop context would inappropriately consume `in` operators.
|
||||||
|
|
||||||
|
Fix wrong end locations stored on SequenceExpression nodes.
|
||||||
|
|
||||||
|
Implement restriction that `for`/`of` loop LHS can't start with `let`.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Add support for ES2022 class static blocks.
|
||||||
|
|
||||||
|
Allow multiple input files to be passed to the CLI tool.
|
||||||
|
|
||||||
|
## 8.4.1 (2021-06-24)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources.
|
||||||
|
|
||||||
|
## 8.4.0 (2021-06-11)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context.
|
||||||
|
|
||||||
|
## 8.3.0 (2021-05-31)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher.
|
||||||
|
|
||||||
|
Add support for the `d` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag.
|
||||||
|
|
||||||
|
## 8.2.4 (2021-05-04)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix spec conformity in corner case 'for await (async of ...)'.
|
||||||
|
|
||||||
|
## 8.2.3 (2021-05-04)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix an issue where the library couldn't parse 'for (async of ...)'.
|
||||||
|
|
||||||
|
Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances.
|
||||||
|
|
||||||
|
## 8.2.2 (2021-04-29)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield.
|
||||||
|
|
||||||
|
## 8.2.1 (2021-04-24)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse.
|
||||||
|
|
||||||
|
## 8.2.0 (2021-04-24)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Add support for ES2022 class fields and private methods.
|
||||||
|
|
||||||
|
## 8.1.1 (2021-04-12)
|
||||||
|
|
||||||
|
### Various
|
||||||
|
|
||||||
|
Stop shipping source maps in the NPM package.
|
||||||
|
|
||||||
|
## 8.1.0 (2021-03-09)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix a spurious error in nested destructuring arrays.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Expose `allowAwaitOutsideFunction` in CLI interface.
|
||||||
|
|
||||||
|
Make `allowImportExportAnywhere` also apply to `import.meta`.
|
||||||
|
|
||||||
|
## 8.0.5 (2021-01-25)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Adjust package.json to work with Node 12.16.0 and 13.0-13.6.
|
||||||
|
|
||||||
|
## 8.0.4 (2020-10-05)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Make `await x ** y` an error, following the spec.
|
||||||
|
|
||||||
|
Fix potentially exponential regular expression.
|
||||||
|
|
||||||
|
## 8.0.3 (2020-10-02)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix a wasteful loop during `Parser` creation when setting `ecmaVersion` to `"latest"`.
|
||||||
|
|
||||||
|
## 8.0.2 (2020-09-30)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Make the TypeScript types reflect the current allowed values for `ecmaVersion`.
|
||||||
|
|
||||||
|
Fix another regexp/division tokenizer issue.
|
||||||
|
|
||||||
|
## 8.0.1 (2020-08-12)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Provide the correct value in the `version` export.
|
||||||
|
|
||||||
|
## 8.0.0 (2020-08-12)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Disallow expressions like `(a = b) = c`.
|
||||||
|
|
||||||
|
Make non-octal escape sequences a syntax error in strict mode.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
The package can now be loaded directly as an ECMAScript module in node 13+.
|
||||||
|
|
||||||
|
Update to the set of Unicode properties from ES2021.
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release.
|
||||||
|
|
||||||
|
Some changes to method signatures that may be used by plugins.
|
||||||
|
|
||||||
|
## 7.4.0 (2020-08-03)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Add support for logical assignment operators.
|
||||||
|
|
||||||
|
Add support for numeric separators.
|
||||||
|
|
||||||
|
## 7.3.1 (2020-06-11)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Make the string in the `version` export match the actual library version.
|
||||||
|
|
||||||
|
## 7.3.0 (2020-06-11)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix a bug that caused parsing of object patterns with a property named `set` that had a default value to fail.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Add support for optional chaining (`?.`).
|
||||||
|
|
||||||
|
## 7.2.0 (2020-05-09)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix precedence issue in parsing of async arrow functions.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Add support for nullish coalescing.
|
||||||
|
|
||||||
|
Add support for `import.meta`.
|
||||||
|
|
||||||
|
Support `export * as ...` syntax.
|
||||||
|
|
||||||
|
Upgrade to Unicode 13.
|
||||||
|
|
||||||
|
## 6.4.1 (2020-03-09)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
More carefully check for valid UTF16 surrogate pairs in regexp validator.
|
||||||
|
|
||||||
|
## 7.1.1 (2020-03-01)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Treat `\8` and `\9` as invalid escapes in template strings.
|
||||||
|
|
||||||
|
Allow unicode escapes in property names that are keywords.
|
||||||
|
|
||||||
|
Don't error on an exponential operator expression as argument to `await`.
|
||||||
|
|
||||||
|
More carefully check for valid UTF16 surrogate pairs in regexp validator.
|
||||||
|
|
||||||
|
## 7.1.0 (2019-09-24)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Disallow trailing object literal commas when ecmaVersion is less than 5.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Add a static `acorn` property to the `Parser` class that contains the entire module interface, to allow plugins to access the instance of the library that they are acting on.
|
||||||
|
|
||||||
|
## 7.0.0 (2019-08-13)
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
Changes the node format for dynamic imports to use the `ImportExpression` node type, as defined in [ESTree](https://github.com/estree/estree/blob/master/es2020.md#importexpression).
|
||||||
|
|
||||||
|
Makes 10 (ES2019) the default value for the `ecmaVersion` option.
|
||||||
|
|
||||||
|
## 6.3.0 (2019-08-12)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
`sourceType: "module"` can now be used even when `ecmaVersion` is less than 6, to parse module-style code that otherwise conforms to an older standard.
|
||||||
|
|
||||||
|
## 6.2.1 (2019-07-21)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix bug causing Acorn to treat some characters as identifier characters that shouldn't be treated as such.
|
||||||
|
|
||||||
|
Fix issue where setting the `allowReserved` option to `"never"` allowed reserved words in some circumstances.
|
||||||
|
|
||||||
|
## 6.2.0 (2019-07-04)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Improve valid assignment checking in `for`/`in` and `for`/`of` loops.
|
||||||
|
|
||||||
|
Disallow binding `let` in patterns.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Support bigint syntax with `ecmaVersion` >= 11.
|
||||||
|
|
||||||
|
Support dynamic `import` syntax with `ecmaVersion` >= 11.
|
||||||
|
|
||||||
|
Upgrade to Unicode version 12.
|
||||||
|
|
||||||
|
## 6.1.1 (2019-02-27)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix bug that caused parsing default exports of with names to fail.
|
||||||
|
|
||||||
|
## 6.1.0 (2019-02-08)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix scope checking when redefining a `var` as a lexical binding.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Split up `parseSubscripts` to use an internal `parseSubscript` method to make it easier to extend with plugins.
|
||||||
|
|
||||||
|
## 6.0.7 (2019-02-04)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Check that exported bindings are defined.
|
||||||
|
|
||||||
|
Don't treat `\u180e` as a whitespace character.
|
||||||
|
|
||||||
|
Check for duplicate parameter names in methods.
|
||||||
|
|
||||||
|
Don't allow shorthand properties when they are generators or async methods.
|
||||||
|
|
||||||
|
Forbid binding `await` in async arrow function's parameter list.
|
||||||
|
|
||||||
|
## 6.0.6 (2019-01-30)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
The content of class declarations and expressions is now always parsed in strict mode.
|
||||||
|
|
||||||
|
Don't allow `let` or `const` to bind the variable name `let`.
|
||||||
|
|
||||||
|
Treat class declarations as lexical.
|
||||||
|
|
||||||
|
Don't allow a generator function declaration as the sole body of an `if` or `else`.
|
||||||
|
|
||||||
|
Ignore `"use strict"` when after an empty statement.
|
||||||
|
|
||||||
|
Allow string line continuations with special line terminator characters.
|
||||||
|
|
||||||
|
Treat `for` bodies as part of the `for` scope when checking for conflicting bindings.
|
||||||
|
|
||||||
|
Fix bug with parsing `yield` in a `for` loop initializer.
|
||||||
|
|
||||||
|
Implement special cases around scope checking for functions.
|
||||||
|
|
||||||
|
## 6.0.5 (2019-01-02)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix TypeScript type for `Parser.extend` and add `allowAwaitOutsideFunction` to options type.
|
||||||
|
|
||||||
|
Don't treat `let` as a keyword when the next token is `{` on the next line.
|
||||||
|
|
||||||
|
Fix bug that broke checking for parentheses around an object pattern in a destructuring assignment when `preserveParens` was on.
|
||||||
|
|
||||||
|
## 6.0.4 (2018-11-05)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Further improvements to tokenizing regular expressions in corner cases.
|
||||||
|
|
||||||
|
## 6.0.3 (2018-11-04)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix bug in tokenizing an expression-less return followed by a function followed by a regular expression.
|
||||||
|
|
||||||
|
Remove stray symlink in the package tarball.
|
||||||
|
|
||||||
|
## 6.0.2 (2018-09-26)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix bug where default expressions could fail to parse inside an object destructuring assignment expression.
|
||||||
|
|
||||||
|
## 6.0.1 (2018-09-14)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix wrong value in `version` export.
|
||||||
|
|
||||||
|
## 6.0.0 (2018-09-14)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Better handle variable-redefinition checks for catch bindings and functions directly under if statements.
|
||||||
|
|
||||||
|
Forbid `new.target` in top-level arrow functions.
|
||||||
|
|
||||||
|
Fix issue with parsing a regexp after `yield` in some contexts.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
The package now comes with TypeScript definitions.
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
The default value of the `ecmaVersion` option is now 9 (2018).
|
||||||
|
|
||||||
|
Plugins work differently, and will have to be rewritten to work with this version.
|
||||||
|
|
||||||
|
The loose parser and walker have been moved into separate packages (`acorn-loose` and `acorn-walk`).
|
||||||
|
|
||||||
|
## 5.7.3 (2018-09-10)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix failure to tokenize regexps after expressions like `x.of`.
|
||||||
|
|
||||||
|
Better error message for unterminated template literals.
|
||||||
|
|
||||||
|
## 5.7.2 (2018-08-24)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Properly handle `allowAwaitOutsideFunction` in for statements.
|
||||||
|
|
||||||
|
Treat function declarations at the top level of modules like let bindings.
|
||||||
|
|
||||||
|
Don't allow async function declarations as the only statement under a label.
|
||||||
|
|
||||||
|
## 5.7.0 (2018-06-15)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Upgraded to Unicode 11.
|
||||||
|
|
||||||
|
## 5.6.0 (2018-05-31)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Allow U+2028 and U+2029 in string when ECMAVersion >= 10.
|
||||||
|
|
||||||
|
Allow binding-less catch statements when ECMAVersion >= 10.
|
||||||
|
|
||||||
|
Add `allowAwaitOutsideFunction` option for parsing top-level `await`.
|
||||||
|
|
||||||
|
## 5.5.3 (2018-03-08)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
A _second_ republish of the code in 5.5.1, this time with yarn, to hopefully get valid timestamps.
|
||||||
|
|
||||||
|
## 5.5.2 (2018-03-08)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
A republish of the code in 5.5.1 in an attempt to solve an issue with the file timestamps in the npm package being 0.
|
||||||
|
|
||||||
|
## 5.5.1 (2018-03-06)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix misleading error message for octal escapes in template strings.
|
||||||
|
|
||||||
|
## 5.5.0 (2018-02-27)
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
The identifier character categorization is now based on Unicode version 10.
|
||||||
|
|
||||||
|
Acorn will now validate the content of regular expressions, including new ES9 features.
|
||||||
|
|
||||||
|
## 5.4.0 (2018-02-01)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Disallow duplicate or escaped flags on regular expressions.
|
||||||
|
|
||||||
|
Disallow octal escapes in strings in strict mode.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Add support for async iteration.
|
||||||
|
|
||||||
|
Add support for object spread and rest.
|
||||||
|
|
||||||
|
## 5.3.0 (2017-12-28)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix parsing of floating point literals with leading zeroes in loose mode.
|
||||||
|
|
||||||
|
Allow duplicate property names in object patterns.
|
||||||
|
|
||||||
|
Don't allow static class methods named `prototype`.
|
||||||
|
|
||||||
|
Disallow async functions directly under `if` or `else`.
|
||||||
|
|
||||||
|
Parse right-hand-side of `for`/`of` as an assignment expression.
|
||||||
|
|
||||||
|
Stricter parsing of `for`/`in`.
|
||||||
|
|
||||||
|
Don't allow unicode escapes in contextual keywords.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Parsing class members was factored into smaller methods to allow plugins to hook into it.
|
||||||
|
|
||||||
|
## 5.2.1 (2017-10-30)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix a token context corruption bug.
|
||||||
|
|
||||||
|
## 5.2.0 (2017-10-30)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix token context tracking for `class` and `function` in property-name position.
|
||||||
|
|
||||||
|
Make sure `%*` isn't parsed as a valid operator.
|
||||||
|
|
||||||
|
Allow shorthand properties `get` and `set` to be followed by default values.
|
||||||
|
|
||||||
|
Disallow `super` when not in callee or object position.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Support [`directive` property](https://github.com/estree/estree/compare/b3de58c9997504d6fba04b72f76e6dd1619ee4eb...1da8e603237144f44710360f8feb7a9977e905e0) on directive expression statements.
|
||||||
|
|
||||||
|
## 5.1.2 (2017-09-04)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Disable parsing of legacy HTML-style comments in modules.
|
||||||
|
|
||||||
|
Fix parsing of async methods whose names are keywords.
|
||||||
|
|
||||||
|
## 5.1.1 (2017-07-06)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix problem with disambiguating regexp and division after a class.
|
||||||
|
|
||||||
|
## 5.1.0 (2017-07-05)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix tokenizing of regexps in an object-desctructuring `for`/`of` loop and after `yield`.
|
||||||
|
|
||||||
|
Parse zero-prefixed numbers with non-octal digits as decimal.
|
||||||
|
|
||||||
|
Allow object/array patterns in rest parameters.
|
||||||
|
|
||||||
|
Don't error when `yield` is used as a property name.
|
||||||
|
|
||||||
|
Allow `async` as a shorthand object property.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Implement the [template literal revision proposal](https://github.com/tc39/proposal-template-literal-revision) for ES9.
|
||||||
|
|
||||||
|
## 5.0.3 (2017-04-01)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix spurious duplicate variable definition errors for named functions.
|
||||||
|
|
||||||
|
## 5.0.2 (2017-03-30)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
A binary operator after a parenthesized arrow expression is no longer incorrectly treated as an error.
|
||||||
|
|
||||||
|
## 5.0.0 (2017-03-28)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Raise an error for duplicated lexical bindings.
|
||||||
|
|
||||||
|
Fix spurious error when an assignement expression occurred after a spread expression.
|
||||||
|
|
||||||
|
Accept regular expressions after `of` (in `for`/`of`), `yield` (in a generator), and braced arrow functions.
|
||||||
|
|
||||||
|
Allow labels in front or `var` declarations, even in strict mode.
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
Parse declarations following `export default` as declaration nodes, not expressions. This means that class and function declarations nodes can now have `null` as their `id`.
|
||||||
|
|
||||||
|
## 4.0.11 (2017-02-07)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Allow all forms of member expressions to be parenthesized as lvalue.
|
||||||
|
|
||||||
|
## 4.0.10 (2017-02-07)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Don't expect semicolons after default-exported functions or classes, even when they are expressions.
|
||||||
|
|
||||||
|
Check for use of `'use strict'` directives in non-simple parameter functions, even when already in strict mode.
|
||||||
|
|
||||||
|
## 4.0.9 (2017-02-06)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix incorrect error raised for parenthesized simple assignment targets, so that `(x) = 1` parses again.
|
||||||
|
|
||||||
|
## 4.0.8 (2017-02-03)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Solve spurious parenthesized pattern errors by temporarily erring on the side of accepting programs that our delayed errors don't handle correctly yet.
|
||||||
|
|
||||||
|
## 4.0.7 (2017-02-02)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Accept invalidly rejected code like `(x).y = 2` again.
|
||||||
|
|
||||||
|
Don't raise an error when a function _inside_ strict code has a non-simple parameter list.
|
||||||
|
|
||||||
|
## 4.0.6 (2017-02-02)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix exponential behavior (manifesting itself as a complete hang for even relatively small source files) introduced by the new 'use strict' check.
|
||||||
|
|
||||||
|
## 4.0.5 (2017-02-02)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Disallow parenthesized pattern expressions.
|
||||||
|
|
||||||
|
Allow keywords as export names.
|
||||||
|
|
||||||
|
Don't allow the `async` keyword to be parenthesized.
|
||||||
|
|
||||||
|
Properly raise an error when a keyword contains a character escape.
|
||||||
|
|
||||||
|
Allow `"use strict"` to appear after other string literal expressions.
|
||||||
|
|
||||||
|
Disallow labeled declarations.
|
||||||
|
|
||||||
|
## 4.0.4 (2016-12-19)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix crash when `export` was followed by a keyword that can't be
|
||||||
|
exported.
|
||||||
|
|
||||||
|
## 4.0.3 (2016-08-16)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Allow regular function declarations inside single-statement `if` branches in loose mode. Forbid them entirely in strict mode.
|
||||||
|
|
||||||
|
Properly parse properties named `async` in ES2017 mode.
|
||||||
|
|
||||||
|
Fix bug where reserved words were broken in ES2017 mode.
|
||||||
|
|
||||||
|
## 4.0.2 (2016-08-11)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Don't ignore period or 'e' characters after octal numbers.
|
||||||
|
|
||||||
|
Fix broken parsing for call expressions in default parameter values of arrow functions.
|
||||||
|
|
||||||
|
## 4.0.1 (2016-08-08)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix false positives in duplicated export name errors.
|
||||||
|
|
||||||
|
## 4.0.0 (2016-08-07)
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
The default `ecmaVersion` option value is now 7.
|
||||||
|
|
||||||
|
A number of internal method signatures changed, so plugins might need to be updated.
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
The parser now raises errors on duplicated export names.
|
||||||
|
|
||||||
|
`arguments` and `eval` can now be used in shorthand properties.
|
||||||
|
|
||||||
|
Duplicate parameter names in non-simple argument lists now always produce an error.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
The `ecmaVersion` option now also accepts year-style version numbers
|
||||||
|
(2015, etc).
|
||||||
|
|
||||||
|
Support for `async`/`await` syntax when `ecmaVersion` is >= 8.
|
||||||
|
|
||||||
|
Support for trailing commas in call expressions when `ecmaVersion` is >= 8.
|
||||||
|
|
||||||
|
## 3.3.0 (2016-07-25)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Fix bug in tokenizing of regexp operator after a function declaration.
|
||||||
|
|
||||||
|
Fix parser crash when parsing an array pattern with a hole.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Implement check against complex argument lists in functions that enable strict mode in ES7.
|
||||||
|
|
||||||
|
## 3.2.0 (2016-06-07)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Improve handling of lack of unicode regexp support in host
|
||||||
|
environment.
|
||||||
|
|
||||||
|
Properly reject shorthand properties whose name is a keyword.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Visitors created with `visit.make` now have their base as _prototype_, rather than copying properties into a fresh object.
|
||||||
|
|
||||||
|
## 3.1.0 (2016-04-18)
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
Properly tokenize the division operator directly after a function expression.
|
||||||
|
|
||||||
|
Allow trailing comma in destructuring arrays.
|
||||||
|
|
||||||
|
## 3.0.4 (2016-02-25)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
Allow update expressions as left-hand-side of the ES7 exponential operator.
|
||||||
|
|
||||||
|
## 3.0.2 (2016-02-10)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
Fix bug that accidentally made `undefined` a reserved word when parsing ES7.
|
||||||
|
|
||||||
|
## 3.0.0 (2016-02-10)
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
The default value of the `ecmaVersion` option is now 6 (used to be 5).
|
||||||
|
|
||||||
|
Support for comprehension syntax (which was dropped from the draft spec) has been removed.
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
`let` and `yield` are now “contextual keywords”, meaning you can mostly use them as identifiers in ES5 non-strict code.
|
||||||
|
|
||||||
|
A parenthesized class or function expression after `export default` is now parsed correctly.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
When `ecmaVersion` is set to 7, Acorn will parse the exponentiation operator (`**`).
|
||||||
|
|
||||||
|
The identifier character ranges are now based on Unicode 8.0.0.
|
||||||
|
|
||||||
|
Plugins can now override the `raiseRecoverable` method to override the way non-critical errors are handled.
|
||||||
|
|
||||||
|
## 2.7.0 (2016-01-04)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
Stop allowing rest parameters in setters.
|
||||||
|
|
||||||
|
Disallow `y` rexexp flag in ES5.
|
||||||
|
|
||||||
|
Disallow `\00` and `\000` escapes in strict mode.
|
||||||
|
|
||||||
|
Raise an error when an import name is a reserved word.
|
||||||
|
|
||||||
|
## 2.6.2 (2015-11-10)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
Don't crash when no options object is passed.
|
||||||
|
|
||||||
|
## 2.6.0 (2015-11-09)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
Add `await` as a reserved word in module sources.
|
||||||
|
|
||||||
|
Disallow `yield` in a parameter default value for a generator.
|
||||||
|
|
||||||
|
Forbid using a comma after a rest pattern in an array destructuring.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
Support parsing stdin in command-line tool.
|
||||||
|
|
||||||
|
## 2.5.0 (2015-10-27)
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
Fix tokenizer support in the command-line tool.
|
||||||
|
|
||||||
|
Stop allowing `new.target` outside of functions.
|
||||||
|
|
||||||
|
Remove legacy `guard` and `guardedHandler` properties from try nodes.
|
||||||
|
|
||||||
|
Stop allowing multiple `__proto__` properties on an object literal in strict mode.
|
||||||
|
|
||||||
|
Don't allow rest parameters to be non-identifier patterns.
|
||||||
|
|
||||||
|
Check for duplicate paramter names in arrow functions.
|
21
node_modules/acorn/LICENSE
generated
vendored
Normal file
21
node_modules/acorn/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (C) 2012-2020 by various contributors (see AUTHORS)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
280
node_modules/acorn/README.md
generated
vendored
Normal file
280
node_modules/acorn/README.md
generated
vendored
Normal file
|
@ -0,0 +1,280 @@
|
||||||
|
# Acorn
|
||||||
|
|
||||||
|
A tiny, fast JavaScript parser written in JavaScript.
|
||||||
|
|
||||||
|
## Community
|
||||||
|
|
||||||
|
Acorn is open source software released under an
|
||||||
|
[MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE).
|
||||||
|
|
||||||
|
You are welcome to
|
||||||
|
[report bugs](https://github.com/acornjs/acorn/issues) or create pull
|
||||||
|
requests on [github](https://github.com/acornjs/acorn). For questions
|
||||||
|
and discussion, please use the
|
||||||
|
[Tern discussion forum](https://discuss.ternjs.net).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The easiest way to install acorn is from [`npm`](https://www.npmjs.com/):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install acorn
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternately, you can download the source and build acorn yourself:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/acornjs/acorn.git
|
||||||
|
cd acorn
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interface
|
||||||
|
|
||||||
|
**parse**`(input, options)` is the main interface to the library. The
|
||||||
|
`input` parameter is a string, `options` must be an object setting
|
||||||
|
some of the options listed below. The return value will be an abstract
|
||||||
|
syntax tree object as specified by the [ESTree
|
||||||
|
spec](https://github.com/estree/estree).
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
let acorn = require("acorn");
|
||||||
|
console.log(acorn.parse("1 + 1", {ecmaVersion: 2020}));
|
||||||
|
```
|
||||||
|
|
||||||
|
When encountering a syntax error, the parser will raise a
|
||||||
|
`SyntaxError` object with a meaningful message. The error object will
|
||||||
|
have a `pos` property that indicates the string offset at which the
|
||||||
|
error occurred, and a `loc` object that contains a `{line, column}`
|
||||||
|
object referring to that same position.
|
||||||
|
|
||||||
|
Options are provided by in a second argument, which should be an
|
||||||
|
object containing any of these fields (only `ecmaVersion` is
|
||||||
|
required):
|
||||||
|
|
||||||
|
- **ecmaVersion**: Indicates the ECMAScript version to parse. Must be
|
||||||
|
either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 (2019),
|
||||||
|
11 (2020), 12 (2021), 13 (2022, partial support)
|
||||||
|
or `"latest"` (the latest the library supports). This influences
|
||||||
|
support for strict mode, the set of reserved words, and support
|
||||||
|
for new syntax features.
|
||||||
|
|
||||||
|
**NOTE**: Only 'stage 4' (finalized) ECMAScript features are being
|
||||||
|
implemented by Acorn. Other proposed new features must be
|
||||||
|
implemented through plugins.
|
||||||
|
|
||||||
|
- **sourceType**: Indicate the mode the code should be parsed in. Can be
|
||||||
|
either `"script"` or `"module"`. This influences global strict mode
|
||||||
|
and parsing of `import` and `export` declarations.
|
||||||
|
|
||||||
|
**NOTE**: If set to `"module"`, then static `import` / `export` syntax
|
||||||
|
will be valid, even if `ecmaVersion` is less than 6.
|
||||||
|
|
||||||
|
- **onInsertedSemicolon**: If given a callback, that callback will be
|
||||||
|
called whenever a missing semicolon is inserted by the parser. The
|
||||||
|
callback will be given the character offset of the point where the
|
||||||
|
semicolon is inserted as argument, and if `locations` is on, also a
|
||||||
|
`{line, column}` object representing this position.
|
||||||
|
|
||||||
|
- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing
|
||||||
|
commas.
|
||||||
|
|
||||||
|
- **allowReserved**: If `false`, using a reserved word will generate
|
||||||
|
an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher
|
||||||
|
versions. When given the value `"never"`, reserved words and
|
||||||
|
keywords can also not be used as property names (as in Internet
|
||||||
|
Explorer's old parser).
|
||||||
|
|
||||||
|
- **allowReturnOutsideFunction**: By default, a return statement at
|
||||||
|
the top level raises an error. Set this to `true` to accept such
|
||||||
|
code.
|
||||||
|
|
||||||
|
- **allowImportExportEverywhere**: By default, `import` and `export`
|
||||||
|
declarations can only appear at a program's top level. Setting this
|
||||||
|
option to `true` allows them anywhere where a statement is allowed,
|
||||||
|
and also allows `import.meta` expressions to appear in scripts
|
||||||
|
(when `sourceType` is not `"module"`).
|
||||||
|
|
||||||
|
- **allowAwaitOutsideFunction**: If `false`, `await` expressions can
|
||||||
|
only appear inside `async` functions. Defaults to `true` for
|
||||||
|
`ecmaVersion` 2022 and later, `false` for lower versions. Setting this option to
|
||||||
|
`true` allows to have top-level `await` expressions. They are
|
||||||
|
still not allowed in non-`async` functions, though.
|
||||||
|
|
||||||
|
- **allowSuperOutsideMethod**: By default, `super` outside a method
|
||||||
|
raises an error. Set this to `true` to accept such code.
|
||||||
|
|
||||||
|
- **allowHashBang**: When this is enabled (off by default), if the
|
||||||
|
code starts with the characters `#!` (as in a shellscript), the
|
||||||
|
first line will be treated as a comment.
|
||||||
|
|
||||||
|
- **locations**: When `true`, each node has a `loc` object attached
|
||||||
|
with `start` and `end` subobjects, each of which contains the
|
||||||
|
one-based line and zero-based column numbers in `{line, column}`
|
||||||
|
form. Default is `false`.
|
||||||
|
|
||||||
|
- **onToken**: If a function is passed for this option, each found
|
||||||
|
token will be passed in same format as tokens returned from
|
||||||
|
`tokenizer().getToken()`.
|
||||||
|
|
||||||
|
If array is passed, each found token is pushed to it.
|
||||||
|
|
||||||
|
Note that you are not allowed to call the parser from the
|
||||||
|
callback—that will corrupt its internal state.
|
||||||
|
|
||||||
|
- **onComment**: If a function is passed for this option, whenever a
|
||||||
|
comment is encountered the function will be called with the
|
||||||
|
following parameters:
|
||||||
|
|
||||||
|
- `block`: `true` if the comment is a block comment, false if it
|
||||||
|
is a line comment.
|
||||||
|
- `text`: The content of the comment.
|
||||||
|
- `start`: Character offset of the start of the comment.
|
||||||
|
- `end`: Character offset of the end of the comment.
|
||||||
|
|
||||||
|
When the `locations` options is on, the `{line, column}` locations
|
||||||
|
of the comment’s start and end are passed as two additional
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
If array is passed for this option, each found comment is pushed
|
||||||
|
to it as object in Esprima format:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
"type": "Line" | "Block",
|
||||||
|
"value": "comment text",
|
||||||
|
"start": Number,
|
||||||
|
"end": Number,
|
||||||
|
// If `locations` option is on:
|
||||||
|
"loc": {
|
||||||
|
"start": {line: Number, column: Number}
|
||||||
|
"end": {line: Number, column: Number}
|
||||||
|
},
|
||||||
|
// If `ranges` option is on:
|
||||||
|
"range": [Number, Number]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that you are not allowed to call the parser from the
|
||||||
|
callback—that will corrupt its internal state.
|
||||||
|
|
||||||
|
- **ranges**: Nodes have their start and end characters offsets
|
||||||
|
recorded in `start` and `end` properties (directly on the node,
|
||||||
|
rather than the `loc` object, which holds line/column data. To also
|
||||||
|
add a
|
||||||
|
[semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678)
|
||||||
|
`range` property holding a `[start, end]` array with the same
|
||||||
|
numbers, set the `ranges` option to `true`.
|
||||||
|
|
||||||
|
- **program**: It is possible to parse multiple files into a single
|
||||||
|
AST by passing the tree produced by parsing the first file as the
|
||||||
|
`program` option in subsequent parses. This will add the toplevel
|
||||||
|
forms of the parsed file to the "Program" (top) node of an existing
|
||||||
|
parse tree.
|
||||||
|
|
||||||
|
- **sourceFile**: When the `locations` option is `true`, you can pass
|
||||||
|
this option to add a `source` attribute in every node’s `loc`
|
||||||
|
object. Note that the contents of this option are not examined or
|
||||||
|
processed in any way; you are free to use whatever format you
|
||||||
|
choose.
|
||||||
|
|
||||||
|
- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property
|
||||||
|
will be added (regardless of the `location` option) directly to the
|
||||||
|
nodes, rather than the `loc` object.
|
||||||
|
|
||||||
|
- **preserveParens**: If this option is `true`, parenthesized expressions
|
||||||
|
are represented by (non-standard) `ParenthesizedExpression` nodes
|
||||||
|
that have a single `expression` property containing the expression
|
||||||
|
inside parentheses.
|
||||||
|
|
||||||
|
**parseExpressionAt**`(input, offset, options)` will parse a single
|
||||||
|
expression in a string, and return its AST. It will not complain if
|
||||||
|
there is more of the string left after the expression.
|
||||||
|
|
||||||
|
**tokenizer**`(input, options)` returns an object with a `getToken`
|
||||||
|
method that can be called repeatedly to get the next token, a `{start,
|
||||||
|
end, type, value}` object (with added `loc` property when the
|
||||||
|
`locations` option is enabled and `range` property when the `ranges`
|
||||||
|
option is enabled). When the token's type is `tokTypes.eof`, you
|
||||||
|
should stop calling the method, since it will keep returning that same
|
||||||
|
token forever.
|
||||||
|
|
||||||
|
In ES6 environment, returned result can be used as any other
|
||||||
|
protocol-compliant iterable:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
for (let token of acorn.tokenizer(str)) {
|
||||||
|
// iterate over the tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
// transform code to array of tokens:
|
||||||
|
var tokens = [...acorn.tokenizer(str)];
|
||||||
|
```
|
||||||
|
|
||||||
|
**tokTypes** holds an object mapping names to the token type objects
|
||||||
|
that end up in the `type` properties of tokens.
|
||||||
|
|
||||||
|
**getLineInfo**`(input, offset)` can be used to get a `{line,
|
||||||
|
column}` object for a given program string and offset.
|
||||||
|
|
||||||
|
### The `Parser` class
|
||||||
|
|
||||||
|
Instances of the **`Parser`** class contain all the state and logic
|
||||||
|
that drives a parse. It has static methods `parse`,
|
||||||
|
`parseExpressionAt`, and `tokenizer` that match the top-level
|
||||||
|
functions by the same name.
|
||||||
|
|
||||||
|
When extending the parser with plugins, you need to call these methods
|
||||||
|
on the extended version of the class. To extend a parser with plugins,
|
||||||
|
you can use its static `extend` method.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var acorn = require("acorn");
|
||||||
|
var jsx = require("acorn-jsx");
|
||||||
|
var JSXParser = acorn.Parser.extend(jsx());
|
||||||
|
JSXParser.parse("foo(<bar/>)", {ecmaVersion: 2020});
|
||||||
|
```
|
||||||
|
|
||||||
|
The `extend` method takes any number of plugin values, and returns a
|
||||||
|
new `Parser` class that includes the extra parser logic provided by
|
||||||
|
the plugins.
|
||||||
|
|
||||||
|
## Command line interface
|
||||||
|
|
||||||
|
The `bin/acorn` utility can be used to parse a file from the command
|
||||||
|
line. It accepts as arguments its input file and the following
|
||||||
|
options:
|
||||||
|
|
||||||
|
- `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version
|
||||||
|
to parse. Default is version 9.
|
||||||
|
|
||||||
|
- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise.
|
||||||
|
|
||||||
|
- `--locations`: Attaches a "loc" object to each node with "start" and
|
||||||
|
"end" subobjects, each of which contains the one-based line and
|
||||||
|
zero-based column numbers in `{line, column}` form.
|
||||||
|
|
||||||
|
- `--allow-hash-bang`: If the code starts with the characters #! (as
|
||||||
|
in a shellscript), the first line will be treated as a comment.
|
||||||
|
|
||||||
|
- `--allow-await-outside-function`: Allows top-level `await` expressions.
|
||||||
|
See the `allowAwaitOutsideFunction` option for more information.
|
||||||
|
|
||||||
|
- `--compact`: No whitespace is used in the AST output.
|
||||||
|
|
||||||
|
- `--silent`: Do not output the AST, just return the exit status.
|
||||||
|
|
||||||
|
- `--help`: Print the usage information and quit.
|
||||||
|
|
||||||
|
The utility spits out the syntax tree as JSON data.
|
||||||
|
|
||||||
|
## Existing plugins
|
||||||
|
|
||||||
|
- [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx)
|
||||||
|
|
||||||
|
Plugins for ECMAScript proposals:
|
||||||
|
|
||||||
|
- [`acorn-stage3`](https://github.com/acornjs/acorn-stage3): Parse most stage 3 proposals, bundling:
|
||||||
|
- [`acorn-class-fields`](https://github.com/acornjs/acorn-class-fields): Parse [class fields proposal](https://github.com/tc39/proposal-class-fields)
|
||||||
|
- [`acorn-import-meta`](https://github.com/acornjs/acorn-import-meta): Parse [import.meta proposal](https://github.com/tc39/proposal-import-meta)
|
||||||
|
- [`acorn-private-methods`](https://github.com/acornjs/acorn-private-methods): parse [private methods, getters and setters proposal](https://github.com/tc39/proposal-private-methods)n
|
4
node_modules/acorn/bin/acorn
generated
vendored
Executable file
4
node_modules/acorn/bin/acorn
generated
vendored
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('../dist/bin.js');
|
214
node_modules/acorn/dist/acorn.d.ts
generated
vendored
Normal file
214
node_modules/acorn/dist/acorn.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
export as namespace acorn
|
||||||
|
export = acorn
|
||||||
|
|
||||||
|
declare namespace acorn {
|
||||||
|
function parse(input: string, options: Options): Node
|
||||||
|
|
||||||
|
function parseExpressionAt(input: string, pos: number, options: Options): Node
|
||||||
|
|
||||||
|
function tokenizer(input: string, options: Options): {
|
||||||
|
getToken(): Token
|
||||||
|
[Symbol.iterator](): Iterator<Token>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
ecmaVersion: 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 'latest'
|
||||||
|
sourceType?: 'script' | 'module'
|
||||||
|
onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
|
||||||
|
onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
|
||||||
|
allowReserved?: boolean | 'never'
|
||||||
|
allowReturnOutsideFunction?: boolean
|
||||||
|
allowImportExportEverywhere?: boolean
|
||||||
|
allowAwaitOutsideFunction?: boolean
|
||||||
|
allowSuperOutsideMethod?: boolean
|
||||||
|
allowHashBang?: boolean
|
||||||
|
locations?: boolean
|
||||||
|
onToken?: ((token: Token) => any) | Token[]
|
||||||
|
onComment?: ((
|
||||||
|
isBlock: boolean, text: string, start: number, end: number, startLoc?: Position,
|
||||||
|
endLoc?: Position
|
||||||
|
) => void) | Comment[]
|
||||||
|
ranges?: boolean
|
||||||
|
program?: Node
|
||||||
|
sourceFile?: string
|
||||||
|
directSourceFile?: string
|
||||||
|
preserveParens?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class Parser {
|
||||||
|
constructor(options: Options, input: string, startPos?: number)
|
||||||
|
parse(this: Parser): Node
|
||||||
|
static parse(this: typeof Parser, input: string, options: Options): Node
|
||||||
|
static parseExpressionAt(this: typeof Parser, input: string, pos: number, options: Options): Node
|
||||||
|
static tokenizer(this: typeof Parser, input: string, options: Options): {
|
||||||
|
getToken(): Token
|
||||||
|
[Symbol.iterator](): Iterator<Token>
|
||||||
|
}
|
||||||
|
static extend(this: typeof Parser, ...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Position { line: number; column: number; offset: number }
|
||||||
|
|
||||||
|
const defaultOptions: Options
|
||||||
|
|
||||||
|
function getLineInfo(input: string, offset: number): Position
|
||||||
|
|
||||||
|
class SourceLocation {
|
||||||
|
start: Position
|
||||||
|
end: Position
|
||||||
|
source?: string | null
|
||||||
|
constructor(p: Parser, start: Position, end: Position)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Node {
|
||||||
|
type: string
|
||||||
|
start: number
|
||||||
|
end: number
|
||||||
|
loc?: SourceLocation
|
||||||
|
sourceFile?: string
|
||||||
|
range?: [number, number]
|
||||||
|
constructor(parser: Parser, pos: number, loc?: SourceLocation)
|
||||||
|
}
|
||||||
|
|
||||||
|
class TokenType {
|
||||||
|
label: string
|
||||||
|
keyword: string
|
||||||
|
beforeExpr: boolean
|
||||||
|
startsExpr: boolean
|
||||||
|
isLoop: boolean
|
||||||
|
isAssign: boolean
|
||||||
|
prefix: boolean
|
||||||
|
postfix: boolean
|
||||||
|
binop: number
|
||||||
|
updateContext?: (prevType: TokenType) => void
|
||||||
|
constructor(label: string, conf?: any)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokTypes: {
|
||||||
|
num: TokenType
|
||||||
|
regexp: TokenType
|
||||||
|
string: TokenType
|
||||||
|
name: TokenType
|
||||||
|
privateId: TokenType
|
||||||
|
eof: TokenType
|
||||||
|
bracketL: TokenType
|
||||||
|
bracketR: TokenType
|
||||||
|
braceL: TokenType
|
||||||
|
braceR: TokenType
|
||||||
|
parenL: TokenType
|
||||||
|
parenR: TokenType
|
||||||
|
comma: TokenType
|
||||||
|
semi: TokenType
|
||||||
|
colon: TokenType
|
||||||
|
dot: TokenType
|
||||||
|
question: TokenType
|
||||||
|
arrow: TokenType
|
||||||
|
template: TokenType
|
||||||
|
ellipsis: TokenType
|
||||||
|
backQuote: TokenType
|
||||||
|
dollarBraceL: TokenType
|
||||||
|
eq: TokenType
|
||||||
|
assign: TokenType
|
||||||
|
incDec: TokenType
|
||||||
|
prefix: TokenType
|
||||||
|
logicalOR: TokenType
|
||||||
|
logicalAND: TokenType
|
||||||
|
bitwiseOR: TokenType
|
||||||
|
bitwiseXOR: TokenType
|
||||||
|
bitwiseAND: TokenType
|
||||||
|
equality: TokenType
|
||||||
|
relational: TokenType
|
||||||
|
bitShift: TokenType
|
||||||
|
plusMin: TokenType
|
||||||
|
modulo: TokenType
|
||||||
|
star: TokenType
|
||||||
|
slash: TokenType
|
||||||
|
starstar: TokenType
|
||||||
|
_break: TokenType
|
||||||
|
_case: TokenType
|
||||||
|
_catch: TokenType
|
||||||
|
_continue: TokenType
|
||||||
|
_debugger: TokenType
|
||||||
|
_default: TokenType
|
||||||
|
_do: TokenType
|
||||||
|
_else: TokenType
|
||||||
|
_finally: TokenType
|
||||||
|
_for: TokenType
|
||||||
|
_function: TokenType
|
||||||
|
_if: TokenType
|
||||||
|
_return: TokenType
|
||||||
|
_switch: TokenType
|
||||||
|
_throw: TokenType
|
||||||
|
_try: TokenType
|
||||||
|
_var: TokenType
|
||||||
|
_const: TokenType
|
||||||
|
_while: TokenType
|
||||||
|
_with: TokenType
|
||||||
|
_new: TokenType
|
||||||
|
_this: TokenType
|
||||||
|
_super: TokenType
|
||||||
|
_class: TokenType
|
||||||
|
_extends: TokenType
|
||||||
|
_export: TokenType
|
||||||
|
_import: TokenType
|
||||||
|
_null: TokenType
|
||||||
|
_true: TokenType
|
||||||
|
_false: TokenType
|
||||||
|
_in: TokenType
|
||||||
|
_instanceof: TokenType
|
||||||
|
_typeof: TokenType
|
||||||
|
_void: TokenType
|
||||||
|
_delete: TokenType
|
||||||
|
}
|
||||||
|
|
||||||
|
class TokContext {
|
||||||
|
constructor(token: string, isExpr: boolean, preserveSpace: boolean, override?: (p: Parser) => void)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokContexts: {
|
||||||
|
b_stat: TokContext
|
||||||
|
b_expr: TokContext
|
||||||
|
b_tmpl: TokContext
|
||||||
|
p_stat: TokContext
|
||||||
|
p_expr: TokContext
|
||||||
|
q_tmpl: TokContext
|
||||||
|
f_expr: TokContext
|
||||||
|
f_stat: TokContext
|
||||||
|
f_expr_gen: TokContext
|
||||||
|
f_gen: TokContext
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIdentifierStart(code: number, astral?: boolean): boolean
|
||||||
|
|
||||||
|
function isIdentifierChar(code: number, astral?: boolean): boolean
|
||||||
|
|
||||||
|
interface AbstractToken {
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Comment extends AbstractToken {
|
||||||
|
type: string
|
||||||
|
value: string
|
||||||
|
start: number
|
||||||
|
end: number
|
||||||
|
loc?: SourceLocation
|
||||||
|
range?: [number, number]
|
||||||
|
}
|
||||||
|
|
||||||
|
class Token {
|
||||||
|
type: TokenType
|
||||||
|
value: any
|
||||||
|
start: number
|
||||||
|
end: number
|
||||||
|
loc?: SourceLocation
|
||||||
|
range?: [number, number]
|
||||||
|
constructor(p: Parser)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isNewLine(code: number): boolean
|
||||||
|
|
||||||
|
const lineBreak: RegExp
|
||||||
|
|
||||||
|
const lineBreakG: RegExp
|
||||||
|
|
||||||
|
const version: string
|
||||||
|
}
|
5619
node_modules/acorn/dist/acorn.js
generated
vendored
Normal file
5619
node_modules/acorn/dist/acorn.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
5588
node_modules/acorn/dist/acorn.mjs
generated
vendored
Normal file
5588
node_modules/acorn/dist/acorn.mjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
2
node_modules/acorn/dist/acorn.mjs.d.ts
generated
vendored
Normal file
2
node_modules/acorn/dist/acorn.mjs.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
import * as acorn from "./acorn";
|
||||||
|
export = acorn;
|
91
node_modules/acorn/dist/bin.js
generated
vendored
Normal file
91
node_modules/acorn/dist/bin.js
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
var fs = require('fs');
|
||||||
|
var acorn = require('./acorn.js');
|
||||||
|
|
||||||
|
function _interopNamespace(e) {
|
||||||
|
if (e && e.__esModule) return e;
|
||||||
|
var n = Object.create(null);
|
||||||
|
if (e) {
|
||||||
|
Object.keys(e).forEach(function (k) {
|
||||||
|
if (k !== 'default') {
|
||||||
|
var d = Object.getOwnPropertyDescriptor(e, k);
|
||||||
|
Object.defineProperty(n, k, d.get ? d : {
|
||||||
|
enumerable: true,
|
||||||
|
get: function () { return e[k]; }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
n["default"] = e;
|
||||||
|
return Object.freeze(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
var acorn__namespace = /*#__PURE__*/_interopNamespace(acorn);
|
||||||
|
|
||||||
|
var inputFilePaths = [], forceFileName = false, fileMode = false, silent = false, compact = false, tokenize = false;
|
||||||
|
var options = {};
|
||||||
|
|
||||||
|
function help(status) {
|
||||||
|
var print = (status === 0) ? console.log : console.error;
|
||||||
|
print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|...|--ecma2015|--ecma2016|--ecma2017|--ecma2018|...]");
|
||||||
|
print(" [--tokenize] [--locations] [--allow-hash-bang] [--allow-await-outside-function] [--compact] [--silent] [--module] [--help] [--] [<infile>...]");
|
||||||
|
process.exit(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 2; i < process.argv.length; ++i) {
|
||||||
|
var arg = process.argv[i];
|
||||||
|
if (arg[0] !== "-" || arg === "-") { inputFilePaths.push(arg); }
|
||||||
|
else if (arg === "--") {
|
||||||
|
inputFilePaths.push.apply(inputFilePaths, process.argv.slice(i + 1));
|
||||||
|
forceFileName = true;
|
||||||
|
break
|
||||||
|
} else if (arg === "--locations") { options.locations = true; }
|
||||||
|
else if (arg === "--allow-hash-bang") { options.allowHashBang = true; }
|
||||||
|
else if (arg === "--allow-await-outside-function") { options.allowAwaitOutsideFunction = true; }
|
||||||
|
else if (arg === "--silent") { silent = true; }
|
||||||
|
else if (arg === "--compact") { compact = true; }
|
||||||
|
else if (arg === "--help") { help(0); }
|
||||||
|
else if (arg === "--tokenize") { tokenize = true; }
|
||||||
|
else if (arg === "--module") { options.sourceType = "module"; }
|
||||||
|
else {
|
||||||
|
var match = arg.match(/^--ecma(\d+)$/);
|
||||||
|
if (match)
|
||||||
|
{ options.ecmaVersion = +match[1]; }
|
||||||
|
else
|
||||||
|
{ help(1); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run(codeList) {
|
||||||
|
var result = [], fileIdx = 0;
|
||||||
|
try {
|
||||||
|
codeList.forEach(function (code, idx) {
|
||||||
|
fileIdx = idx;
|
||||||
|
if (!tokenize) {
|
||||||
|
result = acorn__namespace.parse(code, options);
|
||||||
|
options.program = result;
|
||||||
|
} else {
|
||||||
|
var tokenizer = acorn__namespace.tokenizer(code, options), token;
|
||||||
|
do {
|
||||||
|
token = tokenizer.getToken();
|
||||||
|
result.push(token);
|
||||||
|
} while (token.type !== acorn__namespace.tokTypes.eof)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(fileMode ? e.message.replace(/\(\d+:\d+\)$/, function (m) { return m.slice(0, 1) + inputFilePaths[fileIdx] + " " + m.slice(1); }) : e.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (!silent) { console.log(JSON.stringify(result, null, compact ? null : 2)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileMode = inputFilePaths.length && (forceFileName || !inputFilePaths.includes("-") || inputFilePaths.length !== 1)) {
|
||||||
|
run(inputFilePaths.map(function (path) { return fs.readFileSync(path, "utf8"); }));
|
||||||
|
} else {
|
||||||
|
var code = "";
|
||||||
|
process.stdin.resume();
|
||||||
|
process.stdin.on("data", function (chunk) { return code += chunk; });
|
||||||
|
process.stdin.on("end", function () { return run([code]); });
|
||||||
|
}
|
46
node_modules/acorn/package.json
generated
vendored
Normal file
46
node_modules/acorn/package.json
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"name": "acorn",
|
||||||
|
"description": "ECMAScript parser",
|
||||||
|
"homepage": "https://github.com/acornjs/acorn",
|
||||||
|
"main": "dist/acorn.js",
|
||||||
|
"types": "dist/acorn.d.ts",
|
||||||
|
"module": "dist/acorn.mjs",
|
||||||
|
"exports": {
|
||||||
|
".": [
|
||||||
|
{
|
||||||
|
"import": "./dist/acorn.mjs",
|
||||||
|
"require": "./dist/acorn.js",
|
||||||
|
"default": "./dist/acorn.js"
|
||||||
|
},
|
||||||
|
"./dist/acorn.js"
|
||||||
|
],
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
|
"version": "8.7.0",
|
||||||
|
"engines": {"node": ">=0.4.0"},
|
||||||
|
"maintainers": [
|
||||||
|
{
|
||||||
|
"name": "Marijn Haverbeke",
|
||||||
|
"email": "marijnh@gmail.com",
|
||||||
|
"web": "https://marijnhaverbeke.nl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ingvar Stepanyan",
|
||||||
|
"email": "me@rreverser.com",
|
||||||
|
"web": "https://rreverser.com/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Adrian Heine",
|
||||||
|
"web": "http://adrianheine.de"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/acornjs/acorn.git"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"prepare": "cd ..; npm run build:main"
|
||||||
|
},
|
||||||
|
"bin": {"acorn": "./bin/acorn"}
|
||||||
|
}
|
20
node_modules/ajv/.tonic_example.js
generated
vendored
Normal file
20
node_modules/ajv/.tonic_example.js
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
var Ajv = require('ajv');
|
||||||
|
var ajv = new Ajv({allErrors: true});
|
||||||
|
|
||||||
|
var schema = {
|
||||||
|
"properties": {
|
||||||
|
"foo": { "type": "string" },
|
||||||
|
"bar": { "type": "number", "maximum": 3 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var validate = ajv.compile(schema);
|
||||||
|
|
||||||
|
test({"foo": "abc", "bar": 2});
|
||||||
|
test({"foo": 2, "bar": 4});
|
||||||
|
|
||||||
|
function test(data) {
|
||||||
|
var valid = validate(data);
|
||||||
|
if (valid) console.log('Valid!');
|
||||||
|
else console.log('Invalid: ' + ajv.errorsText(validate.errors));
|
||||||
|
}
|
22
node_modules/ajv/LICENSE
generated
vendored
Normal file
22
node_modules/ajv/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2017 Evgeny Poberezkin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue