Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions .eslintignore

This file was deleted.

132 changes: 0 additions & 132 deletions .eslintrc.js

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
packages/**
public/**
tests/**
.eslintrc
eslint.config.mjs
.template-lintrc.js
ember-cli-build.js
package.json
Expand Down
1 change: 0 additions & 1 deletion app/services/color-scheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export default class DesignService extends Service {
*/
watcherTask = restartableTask(async () => {
let mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
// eslint-disable-next-line no-constant-condition
while (true) {
let scheme = this.scheme;
if (scheme === 'system') {
Expand Down
2 changes: 0 additions & 2 deletions app/services/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ export default class SessionService extends Service {
});

windowEventWatcherTask = task(async () => {
// eslint-disable-next-line no-constant-condition
while (true) {
let event = await waitForEvent(window, 'message');
if (event.origin !== window.location.origin || !event.data) {
Expand All @@ -161,7 +160,6 @@ export default class SessionService extends Service {
});

windowCloseWatcherTask = task(async window => {
// eslint-disable-next-line no-constant-condition
while (true) {
if (window.closed) {
return { closed: true };
Expand Down
2 changes: 1 addition & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ These files have to do with the frontend:
frontend; served under the root `/` url - (ignored in `.gitignore`)
- `.ember-cli` - Settings for the `ember` command line interface
- `ember-cli-build.js` - Contains the build specification for Broccoli
- `.eslintrc.js` - Defines Javascript coding style guidelines (enforced during CI???)
- `eslint.config.mjs` - Defines Javascript coding style guidelines
- `node_modules/` - npm dependencies - (ignored in `.gitignore`)
- `packages/crates-io-msw` - A mock backend used for testing
- `package.json` - Defines the npm package and its dependencies
Expand Down
197 changes: 197 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import babelParser from '@babel/eslint-parser';
import { FlatCompat } from '@eslint/eslintrc';
import js from '@eslint/js';
import ember from 'eslint-plugin-ember';
import emberConcurrency from 'eslint-plugin-ember-concurrency';
import importHelpers from 'eslint-plugin-import-helpers';
import prettier from 'eslint-plugin-prettier';
import globals from 'globals';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});

export default [
{
ignores: [
'.git/**/*',
'crates/',
'playwright-report/',
'target/',
'test-results/',
'tmp/',
// unconventional js
'blueprints/*/files/',
'vendor/',
// compiled output
'dist/',
'tmp/',
// dependencies
'bower_components/',
'node_modules/',
// misc
'coverage/',
'!**/.*',
// ember-try
'.node_modules.ember-try/',
'bower.json.ember-try',
'package.json.ember-try',
],
},
...compat.extends(
'eslint:recommended',
'plugin:ember/recommended',
'plugin:qunit/recommended',
'plugin:qunit-dom/recommended',
'plugin:unicorn/recommended',
'plugin:prettier/recommended',
),
{
plugins: {
ember,
'ember-concurrency': emberConcurrency,
prettier,
'import-helpers': importHelpers,
},

languageOptions: {
globals: {
...globals.browser,
},

parser: babelParser,
ecmaVersion: 2018,
sourceType: 'module',

parserOptions: {
requireConfigFile: false,

babelOptions: {
plugins: [
[
'@babel/plugin-proposal-decorators',
{
decoratorsBeforeExport: true,
},
],
],
},
},
},

rules: {
// it's fine to use `return` without a value and rely on the implicit `undefined` return value
'getter-return': 'off',

// declaration sort is taken care of by `import-helpers/order-imports`
'sort-imports': ['error', { ignoreDeclarationSort: true, ignoreCase: true }],

'prettier/prettier': 'error',

// disabled because we still use `this.set()` in a few places and it works just fine
'ember/classic-decorator-no-classic-methods': 'off',
// disabled because the alternatives are currently not worth the additional complexity
'ember/no-array-prototype-extensions': 'off',

'ember-concurrency/no-perform-without-catch': 'warn',
'ember-concurrency/require-task-name-suffix': 'error',

// disabled because of false positives in `assert.rejects()` calls
'qunit/require-expect': 'off',

// disabled because of false positives related to ember-concurrency usage
'unicorn/consistent-function-scoping': 'off',
'unicorn/explicit-length-check': ['error', { 'non-zero': 'not-equal' }],
// disabled because it conflicts with Ember.js conventions
'unicorn/no-anonymous-default-export': 'off',
// disabled because of false positives related to `EmberArray`
'unicorn/no-array-for-each': 'off',
// disabled because it is annoying in some cases...
'unicorn/no-await-expression-member': 'off',
// disabled because we need `null` since JSON has no `undefined`
'unicorn/no-null': 'off',
// disabled because this rule conflicts with prettier
'unicorn/no-nested-ternary': 'off',
// disabled because of unfixable false positives
'unicorn/prevent-abbreviations': 'off',
// disabled because we are targeting only browsers at the moment
'unicorn/prefer-global-this': 'off',
// disabled because we don't want to go all-in on ES6 modules for Node.js code yet
'unicorn/prefer-module': 'off',
// disabled because it seems unnecessary
'unicorn/prefer-number-properties': 'off',
// disabled because it seems unnecessary
'unicorn/prefer-reflect-apply': 'off',
// disabled because of false positives related to `EmberArray`
'unicorn/prefer-spread': 'off',
// disabled because it seems unnecessary
'unicorn/prefer-string-raw': 'off',
// disabled because of Sentry issues
'unicorn/prefer-string-replace-all': 'off',
// disabled because switch statements in JS are quite error-prone
'unicorn/prefer-switch': 'off',
// disabled because of false positives
'unicorn/consistent-destructuring': 'off',
'unicorn/filename-case': ['error', { case: 'kebabCase', ignore: ['^-'] }],

'import-helpers/order-imports': [
'error',
{
newlinesBetween: 'always',
groups: [
// Node.js built-in modules
'/^(assert|async_hooks|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|http2|https|inspector|module|net|os|path|perf_hooks|process|punycode|querystring|readline|repl|stream|string_decoder|timers|tls|trace_events|tty|url|util|v8|vm|zli)/',
// Testing modules
['/^(qunit|ember-qunit|@ember/test-helpers|ember-exam|htmlbars-inline-precompile)$/', '/^ember-exam\\//'],
// Ember.js modules
['/^@(ember|ember-data|glimmer)\\//', '/^(ember|ember-data|rsvp)$/', '/^ember-data\\//'],
['module'],
['/^crates-io\\//'],
['parent', 'sibling', 'index'],
],
alphabetize: { order: 'asc', ignoreCase: true },
},
],
},
},

// test files
{
files: ['tests/**/*.js'],

rules: {
'unicorn/consistent-function-scoping': 'off',
'unicorn/prefer-dom-node-dataset': 'off',
},
},

// node files
{
files: [
'eslint.config.mjs',
'**/.template-lintrc.js',
'**/ember-cli-build.js',
'**/testem.js',
'blueprints/*/index.js',
'config/**/*.js',
'lib/*/index.js',
'server/**/*.js',
],

languageOptions: {
globals: {
...Object.fromEntries(Object.entries(globals.browser).map(([key]) => [key, 'off'])),
...globals.node,
},

ecmaVersion: 2018,
sourceType: 'script',
},
},
];
Loading
Loading