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 b9816c6..442dce0 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,12 +1,16 @@ -import eslint from '@eslint/js'; -import tseslint from 'typescript-eslint'; +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( - eslint.configs.recommended, - ...tseslint.configs.recommended, +export default [ + { + plugins: { '@typescript-eslint': tsPlugin }, + languageOptions: { parser: tsParser }, + }, + ...typescript, eslintConfigPrettier, { ignores: ['dist/', 'node_modules/', 'test.mjs', 'test-cjs.cjs'], }, -); +]; diff --git a/package.json b/package.json index 3a67dfd..0b3485c 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,9 @@ "hijri-core": "^1.0.0" }, "devDependencies": { + "@acamarata/eslint-config": "^0.1.0", + "@acamarata/prettier-config": "^0.1.0", + "@acamarata/tsconfig": "^0.1.0", "@eslint/js": "^10.0.1", "@types/node": "^25.3.5", "eslint": "^10.0.3", @@ -79,5 +82,6 @@ "bugs": { "url": "https://github.com/acamarata/date-fns-hijri/issues" }, - "type": "module" + "type": "module", + "prettier": "@acamarata/prettier-config" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6eeaebe..e963ab2 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) @@ -38,6 +47,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'} @@ -912,6 +947,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/index.ts b/src/index.ts index b0fb98d..6efdffc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -128,9 +128,13 @@ export function getHijriMonthName( throw new RangeError(`Hijri month must be 1–12, got ${hm}.`); } const idx = hm - 1; - if (length === 'medium') return hmMedium[idx]; - if (length === 'short') return hmShort[idx]; - return hmLong[idx]; + // Non-null: hm validated 1-12 above; idx is always 0-11, within all hm* array bounds. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (length === 'medium') return hmMedium[idx]!; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (length === 'short') return hmShort[idx]!; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return hmLong[idx]!; } /** @@ -143,7 +147,9 @@ export function getHijriMonthName( */ export function getHijriWeekdayName(date: Date, length: 'long' | 'short' = 'long'): string { const day = date.getDay(); // 0–6 - return length === 'short' ? hwShort[day] : hwLong[day]; + // Non-null: day is always 0-6 from getDay(), within hw* array bounds. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return length === 'short' ? hwShort[day]! : hwLong[day]!; } // --------------------------------------------------------------------------- @@ -186,16 +192,19 @@ export function formatHijriDate( const day = date.getDay(); // 0–6 - return formatStr.replace(TOKEN_RE, (token) => { + return formatStr.replace(TOKEN_RE, (token): string => { switch (token) { case 'iYYYY': return String(h.hy); case 'iYY': return String(h.hy).slice(-2).padStart(2, '0'); case 'iMMMM': - return hmLong[h.hm - 1]; + // Non-null: hm is a valid Hijri month 1-12; index hm-1 is within hmLong bounds. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return hmLong[h.hm - 1]!; case 'iMMM': - return hmMedium[h.hm - 1]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return hmMedium[h.hm - 1]!; case 'iMM': return String(h.hm).padStart(2, '0'); case 'iM': @@ -205,11 +214,15 @@ export function formatHijriDate( case 'iD': return String(h.hd); case 'iEEEE': - return hwLong[day]; + // Non-null: day is always 0-6 from getDay(), within hwLong bounds. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return hwLong[day]!; case 'iEEE': - return hwShort[day]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return hwShort[day]!; case 'iE': - return String(hwNumeric[day]); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return String(hwNumeric[day]!); case 'ioooo': return 'AH'; case 'iooo': diff --git a/tsconfig.json b/tsconfig.json index 61e4b47..823eb8b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,9 @@ { + "extends": "@acamarata/tsconfig/tsconfig.library.json", "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "bundler", - "strict": true, - "forceConsistentCasingInFileNames": true, - "esModuleInterop": true, - "declaration": true, - "declarationMap": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "sourceMap": true, - "outDir": "dist", + "esModuleInterop": true, "rootDir": "src", "types": ["node"] },