Skip to content
Open
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
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[{*.yml,*.yaml}]
indent_style = space
51 changes: 0 additions & 51 deletions .eslintrc.json

This file was deleted.

1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
15 changes: 15 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Ignore artifacts:
dist
coverage

# Lock file (machine-generated, not hand-formatted):
package-lock.json

# Python scripts and generated data live outside the TS project:
standalone/

# The pre-existing .github configs and README likewise predate the shared
# prettier config; reformatting them here is ESM-unrelated churn (YAML quote
# style, Markdown spacing). Defer to the same separate follow-up.
.github/
README.md
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"printWidth": 120
}
129 changes: 129 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { defineConfig } from 'eslint/config';
import js from '@eslint/js';
import love from 'eslint-config-love';
import pino from 'eslint-plugin-pino';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';

import sortExports from 'eslint-plugin-sort-exports';
import globals from 'globals';

export default defineConfig([
js.configs.recommended,
tseslint.configs.eslintRecommended,
tseslint.configs.recommendedTypeChecked,
tseslint.configs.strict,
{
...love,
languageOptions: {
parserOptions: {
project: './tsconfig.dev.json',
},
},
},
{
plugins: {
pino: pino,
},
rules: {
'pino/correct-args-position': 'error',
},
},
prettier,
{
plugins: {
'sort-exports': sortExports,
},

languageOptions: {
globals: {
...globals.node,
...globals.jest,
},

parserOptions: {
project: './tsconfig.dev.json',
},
},

rules: {
'@typescript-eslint/no-magic-numbers': [
'error',
{
detectObjects: false,
ignoreEnums: true,
// 0, 1, and -1 are conventionally not considered "magic" numbers.
ignore: [0, 1, -1],
},
],

// Unlike some code bases we explicitly do not want to use default exports.
'import/prefer-default-export': 'off',
'import/no-default-export': 'error',

'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
'newlines-between': 'never',
},
],

'@typescript-eslint/no-unused-vars': [
'error',
{
caughtErrors: 'none',
},
],
},
settings: {
'import/resolver': {
typescript: {
alwaysTryTypes: true,
project: './tsconfig.dev.json',
},
node: true,
},
},
},
{
files: ['**/index.ts'],

rules: {
'sort-exports/sort-exports': [
'error',
{
sortDir: 'asc',
ignoreCase: true,
},
],
// Indexes shouldn't care about the nature of the exports they are collating
'@typescript-eslint/consistent-type-exports': 'off',
},
},
{
files: ['**/*test.ts'],

rules: {
// Forcing return type definitions in our ad-hoc test functions is not worth
// the added effort / verbosity.
'@typescript-eslint/explicit-function-return-type': 'off',

// Tests use hard coded numbers in lots of places, and that's OK for now.
'@typescript-eslint/no-magic-numbers': 'off',

// Jest hoists mock statements, so sometimes we need to define mock functions
// that are used in mocks BEFORE the import block. There may be a better
// approach to this, but for now it is how we do it and so the rule must go.
'import/first': 'off',

// The way we organize tests our test files can be very long since we're comprehensive.
// We could refactor, potentially, but even then I imagine that a line limit is not
// going to be useful in this context.
'max-lines': 'off',

// Tests are already 2-3 levels deep in nested callbacks, so we update this rule to 5 instead of 3.
'max-nested-callbacks': ['error', 5],
},
},
]);
26 changes: 26 additions & 0 deletions jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module.exports = {
transform: {
'^.+[.]tsx?$': [
'ts-jest',
{
// The project is `"type": "module"`, so jest runs in ESM mode
// (see the `test` script's `--experimental-vm-modules` flag).
// ts-jest emits ESM and keeps `module: nodenext` from tsconfig.dev.json,
// which correctly resolves `exports` subpaths such as `csv-parse/sync`.
// Type-checking of tests is also covered by `npm run lint:tsc`.
// Authored by GLM-5.2.
tsconfig: 'tsconfig.dev.json',
useESM: true,
},
],
},
extensionsToTreatAsEsm: ['.ts'],
testEnvironment: 'node',
moduleFileExtensions: ['ts', 'js'],
moduleNameMapper: {
'^([.]{1,2}/.*)[.]js$': '$1',
},
testMatch: ['**/*.unit.test.ts'],
passWithNoTests: true,
silent: true,
};
Loading