diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 383f607..0000000 --- a/.prettierrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "all", - "printWidth": 100, - "tabWidth": 2 -} diff --git a/eslint.config.mjs b/eslint.config.mjs index f4be42a..ba1683f 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,10 +1,16 @@ -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; -import prettier from 'eslint-config-prettier'; +import tsParser from '@typescript-eslint/parser'; +import tsPlugin from '@typescript-eslint/eslint-plugin'; +import eslintConfigPrettier from 'eslint-config-prettier'; +import { typescript } from '@acamarata/eslint-config'; -export default tseslint.config( - { ignores: ['dist/', 'node_modules/', '*.cjs', '*.mjs'] }, - js.configs.recommended, - ...tseslint.configs.recommended, - prettier, -); +export default [ + { + plugins: { '@typescript-eslint': tsPlugin }, + languageOptions: { parser: tsParser }, + }, + ...typescript, + eslintConfigPrettier, + { + ignores: ['dist/', 'node_modules/', '*.cjs', '*.mjs'], + }, +]; diff --git a/package.json b/package.json index 7738514..9d7b4a6 100644 --- a/package.json +++ b/package.json @@ -66,13 +66,16 @@ } }, "devDependencies": { + "@acamarata/eslint-config": "^0.1.0", + "@acamarata/prettier-config": "^0.1.0", + "@acamarata/tsconfig": "^0.1.0", "@eslint/js": "^10.0.1", "@types/luxon": "^3.4.2", - "hijri-core": "^1.0.0", - "luxon": "^3.5.0", "@types/node": "^22.15.0", "eslint": "^10.0.3", "eslint-config-prettier": "^10.1.8", + "hijri-core": "^1.0.0", + "luxon": "^3.5.0", "prettier": "^3.8.1", "tsup": "^8.0.0", "typescript": "^5.5.0", @@ -90,5 +93,6 @@ "bugs": { "url": "https://github.com/acamarata/luxon-hijri/issues" }, - "type": "module" + "type": "module", + "prettier": "@acamarata/prettier-config" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2159303..8145deb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,15 @@ importers: .: devDependencies: + '@acamarata/eslint-config': + specifier: ^0.1.0 + version: 0.1.0(@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.3)(typescript@5.9.3))(eslint@10.0.3)(typescript@5.9.3))(@typescript-eslint/parser@8.56.1(eslint@10.0.3)(typescript@5.9.3))(eslint-config-prettier@10.1.8(eslint@10.0.3))(eslint@10.0.3) + '@acamarata/prettier-config': + specifier: ^0.1.0 + version: 0.1.0(prettier@3.8.1) + '@acamarata/tsconfig': + specifier: ^0.1.0 + version: 0.1.0 '@eslint/js': specifier: ^10.0.1 version: 10.0.1(eslint@10.0.3) @@ -44,6 +53,32 @@ importers: packages: + '@acamarata/eslint-config@0.1.0': + resolution: {integrity: sha512-St2TObpHKXBLBy1GPrXWlHzXCujJ7jaor6BuWRdLMTOjM56LPBDJx+898R7yFyI8Wi52VWNZdSTPxzHuyRAq+A==} + engines: {node: '>=20'} + peerDependencies: + '@typescript-eslint/eslint-plugin': '>=8.0.0' + '@typescript-eslint/parser': '>=8.0.0' + eslint: '>=9.0.0' + eslint-config-prettier: '>=9.0.0' + eslint-plugin-react: '>=7.0.0' + eslint-plugin-react-hooks: '>=5.0.0' + peerDependenciesMeta: + eslint-plugin-react: + optional: true + eslint-plugin-react-hooks: + optional: true + + '@acamarata/prettier-config@0.1.0': + resolution: {integrity: sha512-ImMnz/653ettR4gJVd1f7Pz61DQSeDmUtguLrnCl8RdYncqfghT+QGEO5Znml0KvgX3vk4c4roPAWYdXaZgcPA==} + engines: {node: '>=20'} + peerDependencies: + prettier: '>=3.0.0' + + '@acamarata/tsconfig@0.1.0': + resolution: {integrity: sha512-bgzyBak43mE+0HhduZX3cvaPjKcggtGGZZMjr35qtYWolsIWgZ9nx7OOswbVYoU35qoUv6rZ0mTK6GbZ8QTYjw==} + engines: {node: '>=20'} + '@esbuild/aix-ppc64@0.27.3': resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} engines: {node: '>=18'} @@ -925,6 +960,19 @@ packages: snapshots: + '@acamarata/eslint-config@0.1.0(@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.3)(typescript@5.9.3))(eslint@10.0.3)(typescript@5.9.3))(@typescript-eslint/parser@8.56.1(eslint@10.0.3)(typescript@5.9.3))(eslint-config-prettier@10.1.8(eslint@10.0.3))(eslint@10.0.3)': + dependencies: + '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.3)(typescript@5.9.3))(eslint@10.0.3)(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@10.0.3)(typescript@5.9.3) + eslint: 10.0.3 + eslint-config-prettier: 10.1.8(eslint@10.0.3) + + '@acamarata/prettier-config@0.1.0(prettier@3.8.1)': + dependencies: + prettier: 3.8.1 + + '@acamarata/tsconfig@0.1.0': {} + '@esbuild/aix-ppc64@0.27.3': optional: true diff --git a/src/formatHijriDate.ts b/src/formatHijriDate.ts index e9d3e9a..851a160 100644 --- a/src/formatHijriDate.ts +++ b/src/formatHijriDate.ts @@ -38,7 +38,7 @@ export function formatHijriDate(hijriDate: HijriDate, format: string): string { return _gregDt; } - return format.replace(TOKEN_RE, (match) => { + return format.replace(TOKEN_RE, (match): string => { switch (match) { case 'iYYYY': return String(hijriDate.hy).padStart(4, '0'); @@ -49,9 +49,12 @@ export function formatHijriDate(hijriDate: HijriDate, format: string): string { case 'iM': return String(hijriDate.hm); case 'iMMM': - return hmMedium[hijriDate.hm - 1]; + // Non-null: hm is validated 1-12 above; index hm-1 is always 0-11, within array bounds. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return hmMedium[hijriDate.hm - 1]!; case 'iMMMM': - return hmLong[hijriDate.hm - 1]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return hmLong[hijriDate.hm - 1]!; case 'iDD': return String(hijriDate.hd).padStart(2, '0'); case 'iD': @@ -62,9 +65,13 @@ export function formatHijriDate(hijriDate: HijriDate, format: string): string { // Luxon weekday: 1=Mon … 7=Sun. Modulo 7: Mon=1 … Sat=6, Sun=0. // hwLong/hwShort/hwNumeric arrays: index 0=Sunday, 1=Monday, … 6=Saturday. const idx = getGregDt().weekday % 7; - if (match === 'iE') return String(hwNumeric[idx]); - if (match === 'iEEE') return hwShort[idx]; - return hwLong[idx]; + // Non-null: idx is always 0-6 (weekday%7), within all hw* array bounds. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (match === 'iE') return String(hwNumeric[idx]!); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (match === 'iEEE') return hwShort[idx]!; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return hwLong[idx]!; } case 'iooo': case 'ioooo': diff --git a/tsconfig.json b/tsconfig.json index 035eb39..76b5a64 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,10 @@ { + "extends": "@acamarata/tsconfig/tsconfig.library.json", "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "bundler", - "strict": true, - "esModuleInterop": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "outDir": "dist", + "esModuleInterop": true, "rootDir": "src", - "forceConsistentCasingInFileNames": true, "types": ["node"] }, "include": ["src/**/*"],