From 6caa9eed2c0ad8d3efd1bac940a9a82476d24ff6 Mon Sep 17 00:00:00 2001 From: Aric Camarata Date: Sun, 31 May 2026 08:47:31 -0400 Subject: [PATCH] ci: fix eslint config, add missing ts-eslint devDeps, format src - Add @typescript-eslint/parser and @typescript-eslint/eslint-plugin to devDependencies (required by eslint.config.mjs direct imports and by @acamarata/eslint-config peerDependencies) - Fix eslint.config.mjs: scope files to src/**/*.ts, add parserOptions.project for type-aware rules, expand ignores to cover coverage/ and docs/ - Run prettier --write src/ to fix format:check failures --- eslint.config.mjs | 17 ++++++++---- package.json | 2 ++ pnpm-lock.yaml | 6 ++++ src/data/hDates.ts | 2 +- src/engines/fcna.ts | 10 +++---- src/engines/uaq.ts | 10 +++---- src/index.ts | 36 ++++++++++++------------ src/names/months.ts | 64 +++++++++++++++++++++---------------------- src/names/weekdays.ts | 24 ++++++++-------- src/registry.ts | 4 +-- 10 files changed, 95 insertions(+), 80 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index ba1683f..e1a4661 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,12 +5,19 @@ import { typescript } from '@acamarata/eslint-config'; export default [ { - plugins: { '@typescript-eslint': tsPlugin }, - languageOptions: { parser: tsParser }, + ignores: ['dist/**', 'node_modules/**', 'coverage/**', 'docs/**'], }, - ...typescript, - eslintConfigPrettier, { - ignores: ['dist/', 'node_modules/', '*.cjs', '*.mjs'], + files: ['src/**/*.ts'], + plugins: { '@typescript-eslint': tsPlugin }, + languageOptions: { + parser: tsParser, + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: import.meta.dirname, + }, + }, }, + ...typescript.map((cfg) => ({ ...cfg, files: ['src/**/*.ts'] })), + eslintConfigPrettier, ]; diff --git a/package.json b/package.json index 1ba15e8..aa84fc3 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,8 @@ "@acamarata/tsconfig": "^0.1.0", "@eslint/js": "^10.0.1", "@types/node": "^22.15.0", + "@typescript-eslint/eslint-plugin": "^8.56.1", + "@typescript-eslint/parser": "^8.56.1", "c8": "^10.1.0", "eslint": "^10.0.3", "eslint-config-prettier": "^10.1.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 47fe5f0..aab7fa8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,12 @@ importers: '@types/node': specifier: ^22.15.0 version: 22.15.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.56.1 + version: 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': + specifier: ^8.56.1 + version: 8.56.1(eslint@10.0.3)(typescript@5.9.3) c8: specifier: ^10.1.0 version: 10.1.3 diff --git a/src/data/hDates.ts b/src/data/hDates.ts index 0b34106..b0d2302 100644 --- a/src/data/hDates.ts +++ b/src/data/hDates.ts @@ -1,4 +1,4 @@ -import type { HijriYearRecord } from '../types'; +import type { HijriYearRecord } from "../types"; // Umm al-Qura reference table: Hijri years 1318-1501. // Each entry records the 1 Muharram Gregorian date and a 12-bit days-per-month diff --git a/src/engines/fcna.ts b/src/engines/fcna.ts index 2dc3952..ec5b011 100644 --- a/src/engines/fcna.ts +++ b/src/engines/fcna.ts @@ -7,9 +7,9 @@ // New moon times come from Jean Meeus, Astronomical Algorithms (2nd ed.), // Chapter 49, accurate to within a few minutes for 1000-3000 CE. -import { hDatesTable } from '../data/hDates'; -import { MS_PER_DAY, MONTHS_PER_YEAR } from '../constants'; -import type { CalendarEngine, HijriDate } from '../types'; +import { hDatesTable } from "../data/hDates"; +import { MS_PER_DAY, MONTHS_PER_YEAR } from "../constants"; +import type { CalendarEngine, HijriDate } from "../types"; // ─── Constants ─────────────────────────────────────────────────────────────── @@ -211,7 +211,7 @@ function fcnaDaysInMonth(hy: number, hm: number): number { function fcnaToHijri(gregorianDate: Date): HijriDate | null { if (!(gregorianDate instanceof Date) || isNaN(gregorianDate.getTime())) { - throw new Error('Invalid Gregorian date'); + throw new Error("Invalid Gregorian date"); } // FCNA criterion is UTC-based, so UTC date components ensure correct round-trips. @@ -271,7 +271,7 @@ function fcnaIsValid(hy: number, hm: number, hd: number): boolean { // ─── Engine export ──────────────────────────────────────────────────────────── export const fcnaEngine: CalendarEngine = { - id: 'fcna', + id: "fcna", toHijri: fcnaToHijri, toGregorian: fcnaToGregorian, isValid: fcnaIsValid, diff --git a/src/engines/uaq.ts b/src/engines/uaq.ts index cf217f1..3984391 100644 --- a/src/engines/uaq.ts +++ b/src/engines/uaq.ts @@ -4,9 +4,9 @@ // (Gregorian 1900-2076). Each entry records the Gregorian date of 1 Muharram and // a 12-bit days-per-month bitmask. Dates outside that window return null. -import { hDatesTable } from '../data/hDates'; -import { MS_PER_DAY, MONTHS_PER_YEAR } from '../constants'; -import type { CalendarEngine, HijriDate, HijriYearRecord } from '../types'; +import { hDatesTable } from "../data/hDates"; +import { MS_PER_DAY, MONTHS_PER_YEAR } from "../constants"; +import type { CalendarEngine, HijriDate, HijriYearRecord } from "../types"; /** * Binary search for a Hijri year entry in the UAQ table. @@ -38,7 +38,7 @@ function findYearEntry(hy: number): HijriYearRecord | null { // the calendar-date lookup is timezone-safe regardless of the host environment. function uaqToHijri(date: Date): HijriDate | null { if (!(date instanceof Date) || isNaN(date.getTime())) { - throw new Error('Invalid Gregorian date'); + throw new Error("Invalid Gregorian date"); } const inputUtc = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()); @@ -126,7 +126,7 @@ function uaqDaysInMonth(hy: number, hm: number): number { } export const uaqEngine: CalendarEngine = { - id: 'uaq', + id: "uaq", toHijri: uaqToHijri, toGregorian: uaqToGregorian, isValid: uaqIsValid, diff --git a/src/index.ts b/src/index.ts index 45b53fd..28751c8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,32 +1,32 @@ // Built-in engines are registered at module load so that 'uaq' and 'fcna' are // available immediately on import. This module-level side effect is intentional // and documented in the sideEffects field of package.json. -import { uaqEngine } from './engines/uaq'; -import { fcnaEngine } from './engines/fcna'; -import { registerCalendar } from './registry'; +import { uaqEngine } from "./engines/uaq"; +import { fcnaEngine } from "./engines/fcna"; +import { registerCalendar } from "./registry"; -registerCalendar('uaq', uaqEngine); -registerCalendar('fcna', fcnaEngine); +registerCalendar("uaq", uaqEngine); +registerCalendar("fcna", fcnaEngine); // Registry -export { registerCalendar, getCalendar, listCalendars } from './registry'; +export { registerCalendar, getCalendar, listCalendars } from "./registry"; // Constants -export { MS_PER_DAY, MONTHS_PER_YEAR } from './constants'; +export { MS_PER_DAY, MONTHS_PER_YEAR } from "./constants"; // Types -export type { HijriDate, HijriYearRecord, CalendarEngine, ConversionOptions } from './types'; +export type { HijriDate, HijriYearRecord, CalendarEngine, ConversionOptions } from "./types"; // Data -export { hDatesTable } from './data/hDates'; +export { hDatesTable } from "./data/hDates"; // Names -export { hmLong, hmMedium, hmShort } from './names/months'; -export { hwLong, hwShort, hwNumeric } from './names/weekdays'; +export { hmLong, hmMedium, hmShort } from "./names/months"; +export { hwLong, hwShort, hwNumeric } from "./names/weekdays"; // Convenience wrappers -import { getCalendar } from './registry'; -import type { HijriDate, ConversionOptions } from './types'; +import { getCalendar } from "./registry"; +import type { HijriDate, ConversionOptions } from "./types"; /** * Convert a Gregorian date to a Hijri date. @@ -41,9 +41,9 @@ import type { HijriDate, ConversionOptions } from './types'; */ export function toHijri(date: Date, options?: ConversionOptions): HijriDate | null { if (!(date instanceof Date) || isNaN(date.getTime())) { - throw new Error('Invalid Gregorian date'); + throw new Error("Invalid Gregorian date"); } - return getCalendar(options?.calendar ?? 'uaq').toHijri(date); + return getCalendar(options?.calendar ?? "uaq").toHijri(date); } /** @@ -63,7 +63,7 @@ export function toGregorian( hd: number, options?: ConversionOptions, ): Date | null { - return getCalendar(options?.calendar ?? 'uaq').toGregorian(hy, hm, hd); + return getCalendar(options?.calendar ?? "uaq").toGregorian(hy, hm, hd); } /** @@ -81,7 +81,7 @@ export function isValidHijriDate( hd: number, options?: ConversionOptions, ): boolean { - return getCalendar(options?.calendar ?? 'uaq').isValid(hy, hm, hd); + return getCalendar(options?.calendar ?? "uaq").isValid(hy, hm, hd); } /** @@ -94,5 +94,5 @@ export function isValidHijriDate( * @throws {RangeError} if the month or year is out of range */ export function daysInHijriMonth(hy: number, hm: number, options?: ConversionOptions): number { - return getCalendar(options?.calendar ?? 'uaq').daysInMonth(hy, hm); + return getCalendar(options?.calendar ?? "uaq").daysInMonth(hy, hm); } diff --git a/src/names/months.ts b/src/names/months.ts index cd5e81d..14f26bf 100644 --- a/src/names/months.ts +++ b/src/names/months.ts @@ -11,18 +11,18 @@ * const month = hmLong[hijriDate.hm - 1]; // "Ramadan" */ export const hmLong = [ - 'Muharram', // 1 - 'Safar', // 2 + "Muharram", // 1 + "Safar", // 2 "Rabi'l Awwal", // 3 "Rabi'l Thani", // 4 - 'Jumadal Awwal', // 5 - 'Jumadal Thani', // 6 - 'Rajab', // 7 + "Jumadal Awwal", // 5 + "Jumadal Thani", // 6 + "Rajab", // 7 "Sha'ban", // 8 - 'Ramadan', // 9 - 'Shawwal', // 10 + "Ramadan", // 9 + "Shawwal", // 10 "Dhul Qi'dah", // 11 - 'Dhul Hijjah', // 12 + "Dhul Hijjah", // 12 ]; /** @@ -35,18 +35,18 @@ export const hmLong = [ * const label = hmMedium[hijriDate.hm - 1]; // "Ramadan" */ export const hmMedium = [ - 'Muharram', - 'Safar', - 'Rabi1', - 'Rabi2', - 'Jumada1', - 'Jumada2', - 'Rajab', - 'Shaban', - 'Ramadan', - 'Shawwal', - 'Dhul-Qidah', - 'Dhul-Hijjah', + "Muharram", + "Safar", + "Rabi1", + "Rabi2", + "Jumada1", + "Jumada2", + "Rajab", + "Shaban", + "Ramadan", + "Shawwal", + "Dhul-Qidah", + "Dhul-Hijjah", ]; /** @@ -59,16 +59,16 @@ export const hmMedium = [ * const abbr = hmShort[hijriDate.hm - 1]; // "Ram" */ export const hmShort = [ - 'Muh', - 'Saf', - 'Ra1', - 'Ra2', - 'Ju1', - 'Ju2', - 'Raj', - 'Shb', - 'Ram', - 'Shw', - 'DhQ', - 'DhH', + "Muh", + "Saf", + "Ra1", + "Ra2", + "Ju1", + "Ju2", + "Raj", + "Shb", + "Ram", + "Shw", + "DhQ", + "DhH", ]; diff --git a/src/names/weekdays.ts b/src/names/weekdays.ts index 333507d..445a7f3 100644 --- a/src/names/weekdays.ts +++ b/src/names/weekdays.ts @@ -11,13 +11,13 @@ * const dayName = hwLong[gregorianDate.getDay()]; // "Yawm al-Jum`a" */ export const hwLong = [ - 'Yawm al-Ahad', // Sunday - 'Yawm al-Ithnayn', // Monday + "Yawm al-Ahad", // Sunday + "Yawm al-Ithnayn", // Monday "Yawm ath-Thulatha'", // Tuesday "Yawm al-Arba`a'", // Wednesday - 'Yawm al-Khamis', // Thursday - 'Yawm al-Jum`a', // Friday - 'Yawm as-Sabt', // Saturday + "Yawm al-Khamis", // Thursday + "Yawm al-Jum`a", // Friday + "Yawm as-Sabt", // Saturday ]; /** @@ -30,13 +30,13 @@ export const hwLong = [ * const abbr = hwShort[gregorianDate.getDay()]; // "Jum`a" */ export const hwShort = [ - 'Ahad', // Sunday - 'Ithn', // Monday - 'Thul', // Tuesday - 'Arba', // Wednesday - 'Kham', // Thursday - 'Jum`a', // Friday - 'Sabt', // Saturday + "Ahad", // Sunday + "Ithn", // Monday + "Thul", // Tuesday + "Arba", // Wednesday + "Kham", // Thursday + "Jum`a", // Friday + "Sabt", // Saturday ]; /** diff --git a/src/registry.ts b/src/registry.ts index dee6d12..f760b38 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -1,4 +1,4 @@ -import type { CalendarEngine } from './types'; +import type { CalendarEngine } from "./types"; const _engines = new Map(); @@ -25,7 +25,7 @@ export function registerCalendar(name: string, engine: CalendarEngine): void { export function getCalendar(name: string): CalendarEngine { const engine = _engines.get(name); if (!engine) { - const available = listCalendars().join(', '); + const available = listCalendars().join(", "); throw new Error( `Unknown Hijri calendar: "${name}". Available: ${available}. Register custom calendars with registerCalendar().`, );