Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0893ff3548 | ||
|
|
17a6fa6c1d |
-256
@@ -1,256 +0,0 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'airbnb-base/legacy',
|
||||
'prettier',
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:vitest-globals/recommended',
|
||||
// use recommended-legacy when upgrading the plugin to v4
|
||||
'plugin:@intlify/vue-i18n/recommended',
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*.spec.{j,t}s?(x)'],
|
||||
env: {
|
||||
'vitest-globals/env': true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.story.vue'],
|
||||
rules: {
|
||||
'vue/no-undef-components': [
|
||||
'error',
|
||||
{
|
||||
ignorePatterns: ['Variant', 'Story'],
|
||||
},
|
||||
],
|
||||
// Story files can have static strings, it doesn't need to handle i18n always.
|
||||
'vue/no-bare-strings-in-template': 'off',
|
||||
'no-console': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
plugins: ['html', 'prettier'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
'prettier/prettier': ['error'],
|
||||
camelcase: 'off',
|
||||
'no-param-reassign': 'off',
|
||||
'import/no-extraneous-dependencies': 'off',
|
||||
'import/prefer-default-export': 'off',
|
||||
'import/no-named-as-default': 'off',
|
||||
'jsx-a11y/no-static-element-interactions': 'off',
|
||||
'jsx-a11y/click-events-have-key-events': 'off',
|
||||
'jsx-a11y/label-has-associated-control': 'off',
|
||||
'jsx-a11y/label-has-for': 'off',
|
||||
'jsx-a11y/anchor-is-valid': 'off',
|
||||
'import/no-unresolved': 'off',
|
||||
'vue/html-indent': 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/next-tick-style': ['error', 'callback'],
|
||||
'vue/block-order': [
|
||||
'error',
|
||||
{
|
||||
order: ['script', 'template', 'style'],
|
||||
},
|
||||
],
|
||||
'vue/component-name-in-template-casing': [
|
||||
'error',
|
||||
'PascalCase',
|
||||
{
|
||||
registeredComponentsOnly: true,
|
||||
},
|
||||
],
|
||||
'vue/component-options-name-casing': ['error', 'PascalCase'],
|
||||
'vue/custom-event-name-casing': ['error', 'camelCase'],
|
||||
'vue/define-emits-declaration': ['error'],
|
||||
'vue/define-macros-order': [
|
||||
'error',
|
||||
{
|
||||
order: ['defineProps', 'defineEmits'],
|
||||
defineExposeLast: false,
|
||||
},
|
||||
],
|
||||
'vue/define-props-declaration': ['error', 'runtime'],
|
||||
'vue/match-component-import-name': ['error'],
|
||||
'vue/no-bare-strings-in-template': [
|
||||
'error',
|
||||
{
|
||||
allowlist: [
|
||||
'(',
|
||||
')',
|
||||
',',
|
||||
'.',
|
||||
'&',
|
||||
'+',
|
||||
'-',
|
||||
'=',
|
||||
'*',
|
||||
'/',
|
||||
'#',
|
||||
'%',
|
||||
'!',
|
||||
'?',
|
||||
':',
|
||||
'[',
|
||||
']',
|
||||
'{',
|
||||
'}',
|
||||
'<',
|
||||
'>',
|
||||
'⌘',
|
||||
'📄',
|
||||
'🎉',
|
||||
'🚀',
|
||||
'💬',
|
||||
'👥',
|
||||
'📥',
|
||||
'🔖',
|
||||
'❌',
|
||||
'✅',
|
||||
'\u00b7',
|
||||
'\u2022',
|
||||
'\u2010',
|
||||
'\u2013',
|
||||
'\u2014',
|
||||
'\u2212',
|
||||
'|',
|
||||
],
|
||||
attributes: {
|
||||
'/.+/': [
|
||||
'title',
|
||||
'aria-label',
|
||||
'aria-placeholder',
|
||||
'aria-roledescription',
|
||||
'aria-valuetext',
|
||||
],
|
||||
input: ['placeholder'],
|
||||
},
|
||||
directives: ['v-text'],
|
||||
},
|
||||
],
|
||||
'vue/no-empty-component-block': 'error',
|
||||
'vue/no-multiple-objects-in-class': 'error',
|
||||
'vue/no-root-v-if': 'warn',
|
||||
'vue/no-static-inline-styles': [
|
||||
'error',
|
||||
{
|
||||
allowBinding: false,
|
||||
},
|
||||
],
|
||||
'vue/no-template-target-blank': [
|
||||
'error',
|
||||
{
|
||||
allowReferrer: false,
|
||||
enforceDynamicLinks: 'always',
|
||||
},
|
||||
],
|
||||
'vue/no-required-prop-with-default': [
|
||||
'error',
|
||||
{
|
||||
autofix: false,
|
||||
},
|
||||
],
|
||||
'vue/no-this-in-before-route-enter': 'error',
|
||||
'vue/no-undef-components': [
|
||||
'error',
|
||||
{
|
||||
ignorePatterns: [
|
||||
'^woot-',
|
||||
'^fluent-',
|
||||
'^multiselect',
|
||||
'^router-link',
|
||||
'^router-view',
|
||||
'^ninja-keys',
|
||||
'^FormulateForm',
|
||||
'^FormulateInput',
|
||||
'^highlightjs',
|
||||
],
|
||||
},
|
||||
],
|
||||
'vue/no-unused-emit-declarations': 'error',
|
||||
'vue/no-unused-refs': 'error',
|
||||
'vue/no-use-v-else-with-v-for': 'error',
|
||||
'vue/prefer-true-attribute-shorthand': 'error',
|
||||
'vue/no-useless-v-bind': [
|
||||
'error',
|
||||
{
|
||||
ignoreIncludesComment: false,
|
||||
ignoreStringEscape: false,
|
||||
},
|
||||
],
|
||||
'vue/no-v-text': 'error',
|
||||
'vue/padding-line-between-blocks': ['error', 'always'],
|
||||
'vue/prefer-separate-static-class': 'error',
|
||||
'vue/require-explicit-slots': 'error',
|
||||
'vue/require-macro-variable-name': [
|
||||
'error',
|
||||
{
|
||||
defineProps: 'props',
|
||||
defineEmits: 'emit',
|
||||
defineSlots: 'slots',
|
||||
useSlots: 'slots',
|
||||
useAttrs: 'attrs',
|
||||
},
|
||||
],
|
||||
'vue/no-unused-properties': [
|
||||
'error',
|
||||
{
|
||||
groups: ['props'],
|
||||
deepData: false,
|
||||
ignorePublicMembers: false,
|
||||
unreferencedOptions: [],
|
||||
},
|
||||
],
|
||||
'vue/max-attributes-per-line': [
|
||||
'error',
|
||||
{
|
||||
singleline: {
|
||||
max: 20,
|
||||
},
|
||||
multiline: {
|
||||
max: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
'vue/html-self-closing': [
|
||||
'error',
|
||||
{
|
||||
html: {
|
||||
void: 'always',
|
||||
normal: 'always',
|
||||
component: 'always',
|
||||
},
|
||||
svg: 'always',
|
||||
math: 'always',
|
||||
},
|
||||
],
|
||||
'vue/no-v-html': 'off',
|
||||
'vue/component-definition-name-casing': 'off',
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
'import/extensions': ['off'],
|
||||
'no-console': 'error',
|
||||
'@intlify/vue-i18n/no-dynamic-keys': 'warn',
|
||||
'@intlify/vue-i18n/no-unused-keys': [
|
||||
'warn',
|
||||
{
|
||||
extensions: ['.js', '.vue'],
|
||||
},
|
||||
],
|
||||
},
|
||||
settings: {
|
||||
'vue-i18n': {
|
||||
localeDir: './app/javascript/*/i18n/**.json',
|
||||
},
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
globals: {
|
||||
bus: true,
|
||||
vi: true,
|
||||
},
|
||||
};
|
||||
@@ -13,7 +13,6 @@ class ApiClient {
|
||||
return `${this.baseUrl()}/${this.resource}`;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
get accountIdFromRoute() {
|
||||
const isInsideAccountScopedURLs =
|
||||
window.location.pathname.includes('/app/accounts');
|
||||
|
||||
@@ -8,7 +8,6 @@ class CacheEnabledApiClient extends ApiClient {
|
||||
this.dataManager = new DataManager(this.accountIdFromRoute);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
get cacheModelName() {
|
||||
throw new Error('cacheModelName is not defined');
|
||||
}
|
||||
@@ -25,12 +24,10 @@ class CacheEnabledApiClient extends ApiClient {
|
||||
return axios.get(this.url);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
extractDataFromResponse(response) {
|
||||
return response.data.payload;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
marshallData(dataToParse) {
|
||||
return { data: { payload: dataToParse } };
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ class ChangelogApi extends ApiClient {
|
||||
super('changelog', { apiVersion: 'v1' });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
fetchFromHub() {
|
||||
return axios.get(CHANGELOG_API_URL);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ class VoiceAPI extends ApiClient {
|
||||
super('voice', { accountScoped: true });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
initiateCall(contactId, inboxId) {
|
||||
return ContactsAPI.initiateCall(contactId, inboxId).then(r => r.data);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@ class ContactAPI extends ApiClient {
|
||||
return axios.get(requestURL);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line default-param-last
|
||||
filter(page = 1, sortAttr = 'name', queryPayload) {
|
||||
let requestURL = `${this.url}/filter?${buildContactParams(page, sortAttr)}`;
|
||||
return axios.post(requestURL, queryPayload);
|
||||
|
||||
@@ -6,7 +6,6 @@ class Inboxes extends CacheEnabledApiClient {
|
||||
super('inboxes', { accountScoped: true });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
get cacheModelName() {
|
||||
return 'inbox';
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ class LabelsAPI extends CacheEnabledApiClient {
|
||||
super('labels', { accountScoped: true });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
get cacheModelName() {
|
||||
return 'label';
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ class ReportsAPI extends ApiClient {
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line default-param-last
|
||||
getSummary(since, until, type = 'account', id, groupBy, businessHours) {
|
||||
return axios.get(`${this.url}/summary`, {
|
||||
params: {
|
||||
|
||||
@@ -7,17 +7,14 @@ export class TeamsAPI extends CacheEnabledApiClient {
|
||||
super('teams', { accountScoped: true });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
get cacheModelName() {
|
||||
return 'team';
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
extractDataFromResponse(response) {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
marshallData(dataToParse) {
|
||||
return { data: dataToParse };
|
||||
}
|
||||
|
||||
-1
@@ -56,7 +56,6 @@ const state = reactive({ ...initialState });
|
||||
const urlValidators = {
|
||||
shouldBeAValidURLPattern: value => {
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
new URLPattern(value);
|
||||
return true;
|
||||
} catch {
|
||||
|
||||
@@ -99,7 +99,6 @@ import { useBranding } from 'shared/composables/useBranding';
|
||||
* @property {number} inboxId - The ID of the inbox to which the message belongs
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line vue/define-macros-order
|
||||
const props = defineProps({
|
||||
id: { type: Number, required: true },
|
||||
messageType: {
|
||||
@@ -124,12 +123,12 @@ const props = defineProps({
|
||||
createdAt: { type: Number, required: true }, // eslint-disable-line vue/no-unused-properties
|
||||
currentUserId: { type: Number, required: true }, // eslint-disable-line vue/no-unused-properties
|
||||
groupWithNext: { type: Boolean, default: false },
|
||||
inboxId: { type: Number, default: null }, // eslint-disable-line vue/no-unused-properties
|
||||
inboxId: { type: Number, default: null },
|
||||
inboxSupportsReplyTo: { type: Object, default: () => ({}) },
|
||||
inReplyTo: { type: Object, default: null }, // eslint-disable-line vue/no-unused-properties
|
||||
isEmailInbox: { type: Boolean, default: false },
|
||||
private: { type: Boolean, default: false },
|
||||
additionalAttributes: { type: Object, default: () => ({}) }, // eslint-disable-line vue/no-unused-properties
|
||||
additionalAttributes: { type: Object, default: () => ({}) },
|
||||
sender: { type: Object, default: null },
|
||||
senderId: { type: Number, default: null },
|
||||
senderType: { type: String, default: null },
|
||||
|
||||
@@ -18,9 +18,7 @@ const MAXIMUM_FILE_UPLOAD_SIZE = 4; // in MB
|
||||
const createState = (
|
||||
content,
|
||||
placeholder,
|
||||
// eslint-disable-next-line default-param-last
|
||||
plugins = [],
|
||||
// eslint-disable-next-line default-param-last
|
||||
methods = {},
|
||||
enabledMenuOptions
|
||||
) => {
|
||||
|
||||
@@ -35,8 +35,7 @@ export default {
|
||||
default: '00:00',
|
||||
},
|
||||
// inbox prop is used in /mixins/inboxMixin,
|
||||
// remove this props when refactoring to composable if not needed
|
||||
// eslint-disable-next-line vue/no-unused-properties
|
||||
// remove this props when refactoring to composable if not neededs
|
||||
inbox: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import lamejs from '@breezystack/lamejs';
|
||||
|
||||
const writeString = (view, offset, string) => {
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
view.setUint8(offset + i, string.charCodeAt(i));
|
||||
}
|
||||
@@ -29,9 +28,8 @@ const bufferToWav = async (buffer, numChannels, sampleRate) => {
|
||||
|
||||
// WAV Data
|
||||
const offset = 44;
|
||||
// eslint-disable-next-line no-plusplus
|
||||
|
||||
for (let i = 0; i < buffer.length; i++) {
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (let channel = 0; channel < numChannels; channel++) {
|
||||
const sample = Math.max(
|
||||
-1,
|
||||
|
||||
@@ -37,12 +37,10 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onReconnect = () => {
|
||||
emitter.emit(BUS_EVENTS.WEBSOCKET_RECONNECT);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onDisconnected = () => {
|
||||
emitter.emit(BUS_EVENTS.WEBSOCKET_DISCONNECT);
|
||||
};
|
||||
@@ -90,7 +88,6 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||
this.app.$store.dispatch('updateConversation', data);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onLogout = () => AuthAPI.logout();
|
||||
|
||||
onMessageCreated = data => {
|
||||
@@ -106,7 +103,6 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||
});
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onReload = () => window.location.reload();
|
||||
|
||||
onStatusChange = data => {
|
||||
@@ -161,7 +157,6 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||
}, 30000);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
fetchConversationStats = () => {
|
||||
emitter.emit('fetch_conversation_stats');
|
||||
};
|
||||
|
||||
@@ -212,9 +212,8 @@ export const isCustomAttribute = (attrs, key) => {
|
||||
};
|
||||
|
||||
export const generateCustomAttributes = (
|
||||
// eslint-disable-next-line default-param-last
|
||||
conversationAttributes = [],
|
||||
// eslint-disable-next-line default-param-last
|
||||
|
||||
contactAttributes = [],
|
||||
conversationlabel,
|
||||
contactlabel
|
||||
|
||||
@@ -61,7 +61,6 @@ export class EmailQuoteExtractor {
|
||||
tempDiv.innerHTML = DOMPurify.sanitize(htmlContent);
|
||||
|
||||
// Check for class-based quotes
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const selector of QUOTE_INDICATORS) {
|
||||
if (tempDiv.querySelector(selector)) {
|
||||
return true;
|
||||
|
||||
@@ -18,7 +18,6 @@ export const verifyServiceWorkerExistence = (callback = () => {}) => {
|
||||
.register('/sw.js')
|
||||
.then(registration => callback(registration))
|
||||
.catch(registrationError => {
|
||||
// eslint-disable-next-line
|
||||
console.log('SW registration failed: ', registrationError);
|
||||
});
|
||||
};
|
||||
@@ -69,7 +68,6 @@ export const registerSubscription = (onSuccess = () => {}) => {
|
||||
onSuccess();
|
||||
})
|
||||
.catch(error => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Push subscription registration failed:', error);
|
||||
useAlert('This browser does not support desktop notification');
|
||||
});
|
||||
@@ -77,7 +75,6 @@ export const registerSubscription = (onSuccess = () => {}) => {
|
||||
|
||||
export const requestPushPermissions = ({ onSuccess }) => {
|
||||
if (!('Notification' in window)) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('Notification is not supported');
|
||||
useAlert('This browser does not support desktop notification');
|
||||
} else if (Notification.permission === 'granted') {
|
||||
|
||||
@@ -288,10 +288,9 @@ describe('templateHelper', () => {
|
||||
});
|
||||
|
||||
it('should handle special characters in template variables', () => {
|
||||
/* eslint-disable no-template-curly-in-string */
|
||||
const templateText =
|
||||
'Welcome {{user_name}}, your order #{{order_id}} costs ${{amount}}';
|
||||
/* eslint-enable no-template-curly-in-string */
|
||||
|
||||
const processedParams = {
|
||||
body: {
|
||||
user_name: 'John & Jane',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script>
|
||||
/* eslint-env browser */
|
||||
/* global FB */
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
|
||||
@@ -10,7 +10,6 @@ export const getAudioContext = () => {
|
||||
return audioCtx;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line default-param-last
|
||||
export const getAlertAudio = async (baseUrl = '', requestContext) => {
|
||||
const audioCtx = getAudioContext();
|
||||
const playSound = audioBuffer => {
|
||||
@@ -34,7 +33,6 @@ export const getAlertAudio = async (baseUrl = '', requestContext) => {
|
||||
.then(response => response.arrayBuffer())
|
||||
.then(buffer => {
|
||||
audioCtx.decodeAudioData(buffer).then(playSound);
|
||||
// eslint-disable-next-line no-promise-executor-return
|
||||
return new Promise(res => res());
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@@ -74,10 +74,8 @@ class BaseActionCableConnector {
|
||||
}, RECONNECT_INTERVAL);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onReconnect = () => {};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onDisconnected = () => {};
|
||||
|
||||
disconnect() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
export class DuplicateContactException extends Error {
|
||||
constructor(data) {
|
||||
super('DUPLICATE_CONTACT');
|
||||
|
||||
@@ -48,7 +48,6 @@ export default {
|
||||
}`;
|
||||
},
|
||||
avatarUrl() {
|
||||
// eslint-disable-next-line
|
||||
const displayImage = this.useInboxAvatarForBot
|
||||
? this.inboxAvatarUrl
|
||||
: '/assets/images/chatwoot_bot.png';
|
||||
|
||||
@@ -96,7 +96,6 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||
this.app.$store.dispatch('agent/updatePresence', data.users);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onContactMerge = data => {
|
||||
const { pubsub_token: pubsubToken } = data;
|
||||
ActionCableConnector.refreshConnector(pubsubToken);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
const getUuid = () =>
|
||||
'xxxxxxxx4xxx'.replace(/[xy]/g, c => {
|
||||
// eslint-disable-next-line
|
||||
const r = (Math.random() * 16) | 0;
|
||||
// eslint-disable-next-line
|
||||
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
const js = require('@eslint/js');
|
||||
const pluginVue = require('eslint-plugin-vue');
|
||||
const pluginVueI18n = require('@intlify/eslint-plugin-vue-i18n');
|
||||
const prettierRecommended = require('eslint-plugin-prettier/recommended');
|
||||
const globals = require('globals');
|
||||
|
||||
const vitestGlobals = {
|
||||
describe: 'readonly',
|
||||
it: 'readonly',
|
||||
test: 'readonly',
|
||||
expect: 'readonly',
|
||||
beforeEach: 'readonly',
|
||||
afterEach: 'readonly',
|
||||
beforeAll: 'readonly',
|
||||
afterAll: 'readonly',
|
||||
vi: 'readonly',
|
||||
vitest: 'readonly',
|
||||
suite: 'readonly',
|
||||
};
|
||||
|
||||
module.exports = [
|
||||
{ ignores: ['node_modules/**', 'public/**', 'vendor/**'] },
|
||||
|
||||
js.configs.recommended,
|
||||
...pluginVue.configs['flat/recommended'],
|
||||
...pluginVueI18n.configs['flat/recommended'],
|
||||
prettierRecommended,
|
||||
|
||||
{
|
||||
languageOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
bus: 'writable',
|
||||
vi: 'readonly',
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
'vue-i18n': {
|
||||
localeDir: './app/javascript/*/i18n/**.json',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// Carried from airbnb-base/legacy
|
||||
eqeqeq: ['error', 'always', { null: 'ignore' }],
|
||||
'no-alert': 'error',
|
||||
'no-eval': 'error',
|
||||
'no-implied-eval': 'error',
|
||||
'no-new-func': 'error',
|
||||
'no-proto': 'error',
|
||||
'no-return-assign': 'error',
|
||||
'no-script-url': 'error',
|
||||
'no-sequences': 'error',
|
||||
'no-shadow': 'error',
|
||||
'no-throw-literal': 'error',
|
||||
'no-unused-expressions': 'error',
|
||||
'no-useless-call': 'error',
|
||||
'prefer-promise-reject-errors': 'error',
|
||||
|
||||
camelcase: 'off',
|
||||
'no-console': 'error',
|
||||
'no-param-reassign': 'off',
|
||||
'no-unused-vars': ['error', { caughtErrors: 'none', ignoreRestSiblings: true }],
|
||||
'no-useless-assignment': 'warn',
|
||||
'preserve-caught-error': 'off',
|
||||
|
||||
// Vue
|
||||
'vue/block-order': ['error', { order: ['script', 'template', 'style'] }],
|
||||
'vue/component-definition-name-casing': 'off',
|
||||
'vue/component-name-in-template-casing': [
|
||||
'error',
|
||||
'PascalCase',
|
||||
{ registeredComponentsOnly: true },
|
||||
],
|
||||
'vue/component-options-name-casing': ['error', 'PascalCase'],
|
||||
'vue/custom-event-name-casing': ['error', 'camelCase'],
|
||||
'vue/define-emits-declaration': ['error'],
|
||||
'vue/define-macros-order': [
|
||||
'error',
|
||||
{ order: ['defineProps', 'defineEmits'], defineExposeLast: false },
|
||||
],
|
||||
'vue/define-props-declaration': ['error', 'runtime'],
|
||||
'vue/html-indent': 'off',
|
||||
'vue/html-self-closing': [
|
||||
'error',
|
||||
{
|
||||
html: { void: 'always', normal: 'always', component: 'always' },
|
||||
svg: 'always',
|
||||
math: 'always',
|
||||
},
|
||||
],
|
||||
'vue/match-component-import-name': ['error'],
|
||||
'vue/max-attributes-per-line': [
|
||||
'error',
|
||||
{ singleline: { max: 20 }, multiline: { max: 1 } },
|
||||
],
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/next-tick-style': ['error', 'callback'],
|
||||
'vue/no-bare-strings-in-template': [
|
||||
'error',
|
||||
{
|
||||
allowlist: [
|
||||
'(',
|
||||
')',
|
||||
',',
|
||||
'.',
|
||||
'&',
|
||||
'+',
|
||||
'-',
|
||||
'=',
|
||||
'*',
|
||||
'/',
|
||||
'#',
|
||||
'%',
|
||||
'!',
|
||||
'?',
|
||||
':',
|
||||
'[',
|
||||
']',
|
||||
'{',
|
||||
'}',
|
||||
'<',
|
||||
'>',
|
||||
'⌘',
|
||||
'📄',
|
||||
'🎉',
|
||||
'🚀',
|
||||
'💬',
|
||||
'👥',
|
||||
'📥',
|
||||
'🔖',
|
||||
'❌',
|
||||
'✅',
|
||||
'\u00b7',
|
||||
'\u2022',
|
||||
'\u2010',
|
||||
'\u2013',
|
||||
'\u2014',
|
||||
'\u2212',
|
||||
'|',
|
||||
],
|
||||
attributes: {
|
||||
'/.+/': [
|
||||
'title',
|
||||
'aria-label',
|
||||
'aria-placeholder',
|
||||
'aria-roledescription',
|
||||
'aria-valuetext',
|
||||
],
|
||||
input: ['placeholder'],
|
||||
},
|
||||
directives: ['v-text'],
|
||||
},
|
||||
],
|
||||
'vue/no-empty-component-block': 'error',
|
||||
'vue/no-multiple-objects-in-class': 'error',
|
||||
'vue/no-required-prop-with-default': ['error', { autofix: false }],
|
||||
'vue/no-root-v-if': 'warn',
|
||||
'vue/no-static-inline-styles': ['error', { allowBinding: false }],
|
||||
'vue/no-template-target-blank': [
|
||||
'error',
|
||||
{ allowReferrer: false, enforceDynamicLinks: 'always' },
|
||||
],
|
||||
'vue/no-this-in-before-route-enter': 'error',
|
||||
'vue/no-undef-components': [
|
||||
'error',
|
||||
{
|
||||
ignorePatterns: [
|
||||
'^woot-',
|
||||
'^fluent-',
|
||||
'^multiselect',
|
||||
'^router-link',
|
||||
'^router-view',
|
||||
'^ninja-keys',
|
||||
'^FormulateForm',
|
||||
'^FormulateInput',
|
||||
'^highlightjs',
|
||||
],
|
||||
},
|
||||
],
|
||||
'vue/no-unused-emit-declarations': 'error',
|
||||
'vue/no-unused-properties': [
|
||||
'error',
|
||||
{
|
||||
groups: ['props'],
|
||||
deepData: false,
|
||||
ignorePublicMembers: false,
|
||||
unreferencedOptions: [],
|
||||
},
|
||||
],
|
||||
'vue/no-unused-refs': 'error',
|
||||
'vue/no-use-v-else-with-v-for': 'error',
|
||||
'vue/no-useless-v-bind': [
|
||||
'error',
|
||||
{ ignoreIncludesComment: false, ignoreStringEscape: false },
|
||||
],
|
||||
'vue/no-v-html': 'off',
|
||||
'vue/no-v-text': 'error',
|
||||
'vue/padding-line-between-blocks': ['error', 'always'],
|
||||
'vue/prefer-separate-static-class': 'error',
|
||||
'vue/prefer-true-attribute-shorthand': 'error',
|
||||
'vue/require-explicit-slots': 'error',
|
||||
'vue/require-macro-variable-name': [
|
||||
'error',
|
||||
{
|
||||
defineProps: 'props',
|
||||
defineEmits: 'emit',
|
||||
defineSlots: 'slots',
|
||||
useSlots: 'slots',
|
||||
useAttrs: 'attrs',
|
||||
},
|
||||
],
|
||||
'vue/singleline-html-element-content-newline': 'off',
|
||||
|
||||
// Vue i18n
|
||||
'@intlify/vue-i18n/no-dynamic-keys': 'warn',
|
||||
'@intlify/vue-i18n/no-unused-keys': [
|
||||
'warn',
|
||||
{ extensions: ['.js', '.vue'] },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
// Spec files
|
||||
{
|
||||
files: ['**/*.spec.{j,t}s?(x)'],
|
||||
languageOptions: {
|
||||
globals: vitestGlobals,
|
||||
},
|
||||
},
|
||||
|
||||
// Story files
|
||||
{
|
||||
files: ['**/*.story.vue'],
|
||||
rules: {
|
||||
'vue/no-undef-components': [
|
||||
'error',
|
||||
{ ignorePatterns: ['Variant', 'Story'] },
|
||||
],
|
||||
'vue/no-bare-strings-in-template': 'off',
|
||||
'no-console': 'off',
|
||||
},
|
||||
},
|
||||
];
|
||||
+8
-9
@@ -122,16 +122,14 @@
|
||||
"@size-limit/file": "^8.2.4",
|
||||
"@vitest/coverage-v8": "3.0.5",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@eslint/js": "^10.0.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint": "^10.0.0",
|
||||
"eslint-config-prettier": "^10.0.0",
|
||||
"eslint-interactive": "^11.1.0",
|
||||
"eslint-plugin-html": "7.1.0",
|
||||
"eslint-plugin-import": "2.30.0",
|
||||
"eslint-plugin-prettier": "5.2.1",
|
||||
"eslint-plugin-vitest-globals": "^1.5.0",
|
||||
"eslint-plugin-vue": "^9.28.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-vue": "^10.8.0",
|
||||
"globals": "^16.0.0",
|
||||
"fake-indexeddb": "^6.0.0",
|
||||
"histoire": "0.17.15",
|
||||
"husky": "^7.0.0",
|
||||
@@ -160,7 +158,8 @@
|
||||
"overrides": {
|
||||
"vite-node": "2.0.1",
|
||||
"vite": "5.4.21",
|
||||
"vitest": "3.0.5"
|
||||
"vitest": "3.0.5",
|
||||
"vue-eslint-parser": "^10.0.0"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
|
||||
Generated
+255
-1445
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user