diff --git a/eslint.config.mjs b/eslint.config.mjs index ba1683f..88a9226 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -6,11 +6,18 @@ import { typescript } from '@acamarata/eslint-config'; export default [ { plugins: { '@typescript-eslint': tsPlugin }, - languageOptions: { parser: tsParser }, + languageOptions: { + parser: tsParser, + parserOptions: { + project: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + files: ['src/**/*.ts'], }, - ...typescript, + ...typescript.map((config) => ({ ...config, files: ['src/**/*.ts'] })), eslintConfigPrettier, { - ignores: ['dist/', 'node_modules/', '*.cjs', '*.mjs'], + ignores: ['dist/', 'node_modules/', 'coverage/', 'test.mjs', 'test-cjs.cjs', 'test-crossval.mjs', 'tsup.config.ts', 'typedoc.json'], }, ]; diff --git a/package.json b/package.json index be6bc17..119cc2a 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,9 @@ "@eslint/js": "^10.0.1", "@types/luxon": "^3.4.2", "@types/node": "^22.15.0", + "@typescript-eslint/eslint-plugin": "^8.56.1", + "@typescript-eslint/parser": "^8.56.1", + "c8": "^10.1.2", "eslint": "^10.0.3", "eslint-config-prettier": "^10.1.8", "hijri-core": "^1.0.0", @@ -82,8 +85,7 @@ "typedoc": "^0.28.19", "typedoc-plugin-markdown": "^4.11.0", "typescript": "^5.5.0", - "typescript-eslint": "^8.56.1", - "c8": "^10.1.2" + "typescript-eslint": "^8.56.1" }, "publishConfig": { "access": "public", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a7e5a8..cfa7af3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,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.2 version: 10.1.3 diff --git a/src/formatHijriDate.ts b/src/formatHijriDate.ts index 851a160..2f6d427 100644 --- a/src/formatHijriDate.ts +++ b/src/formatHijriDate.ts @@ -1,9 +1,9 @@ // formatHijriDate.ts -import { DateTime } from 'luxon'; -import { hmLong, hmMedium } from './hMonths'; -import { hwLong, hwShort, hwNumeric } from './hWeekdays'; -import { toGregorian } from './toGregorian'; -import type { HijriDate } from './types'; +import { DateTime } from "luxon"; +import { hmLong, hmMedium } from "./hMonths"; +import { hwLong, hwShort, hwNumeric } from "./hWeekdays"; +import { toGregorian } from "./toGregorian"; +import type { HijriDate } from "./types"; // Token regex: longest tokens first to prevent partial matches. const TOKEN_RE = @@ -33,49 +33,49 @@ export function formatHijriDate(hijriDate: HijriDate, format: string): string { function getGregDt(): DateTime { if (!_gregDt) { const greg = toGregorian(hijriDate.hy, hijriDate.hm, hijriDate.hd); - _gregDt = DateTime.fromJSDate(greg, { zone: 'UTC' }); + _gregDt = DateTime.fromJSDate(greg, { zone: "UTC" }); } return _gregDt; } return format.replace(TOKEN_RE, (match): string => { switch (match) { - case 'iYYYY': - return String(hijriDate.hy).padStart(4, '0'); - case 'iYY': - return String(hijriDate.hy % 100).padStart(2, '0'); - case 'iMM': - return String(hijriDate.hm).padStart(2, '0'); - case 'iM': + case "iYYYY": + return String(hijriDate.hy).padStart(4, "0"); + case "iYY": + return String(hijriDate.hy % 100).padStart(2, "0"); + case "iMM": + return String(hijriDate.hm).padStart(2, "0"); + case "iM": return String(hijriDate.hm); - case 'iMMM': + case "iMMM": // 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': + case "iMMMM": // 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': + case "iDD": + return String(hijriDate.hd).padStart(2, "0"); + case "iD": return String(hijriDate.hd); - case 'iE': - case 'iEEE': - case 'iEEEE': { + case "iE": + case "iEEE": + case "iEEEE": { // 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; // 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]!); + if (match === "iE") return String(hwNumeric[idx]!); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (match === 'iEEE') return hwShort[idx]!; + if (match === "iEEE") return hwShort[idx]!; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return hwLong[idx]!; } - case 'iooo': - case 'ioooo': - return 'AH'; + case "iooo": + case "ioooo": + return "AH"; default: // Delegate time and timezone tokens to Luxon using the Gregorian DateTime. return getGregDt().toFormat(match); diff --git a/src/formatPatterns.ts b/src/formatPatterns.ts index 3351414..36e6f88 100644 --- a/src/formatPatterns.ts +++ b/src/formatPatterns.ts @@ -9,46 +9,46 @@ // Define a mapping of Hijri format tokens to their meanings export const formatPatterns = { // Hijri Year - iYYYY: 'Hijri year (4 digits)', - iYY: 'Hijri year (2 digits)', + iYYYY: "Hijri year (4 digits)", + iYY: "Hijri year (2 digits)", // Hijri Month - iMM: 'Hijri month (2 digits, zero-padded)', - iM: 'Hijri month (1 or 2 digits without zero-padding)', - iMMM: 'Hijri month (abbreviated name)', - iMMMM: 'Hijri month (full name)', + iMM: "Hijri month (2 digits, zero-padded)", + iM: "Hijri month (1 or 2 digits without zero-padding)", + iMMM: "Hijri month (abbreviated name)", + iMMMM: "Hijri month (full name)", // Hijri Day - iDD: 'Hijri day of the month (2 digits, zero-padded)', - iD: 'Hijri day of the month (1 or 2 digits without zero-padding)', + iDD: "Hijri day of the month (2 digits, zero-padded)", + iD: "Hijri day of the month (1 or 2 digits without zero-padding)", // Hijri Weekday - iE: 'Hijri weekday (1 digit)', - iEEE: 'Hijri weekday (abbreviated name)', - iEEEE: 'Hijri weekday (full name)', + iE: "Hijri weekday (1 digit)", + iEEE: "Hijri weekday (abbreviated name)", + iEEEE: "Hijri weekday (full name)", // Hour, Minute, Second // These can remain the same as in Gregorian as they don’t change in Hijri - HH: 'Hour (2 digits, zero-padded, 24-hour clock)', - H: 'Hour (1 or 2 digits without zero-padding, 24-hour clock)', - hh: 'Hour (2 digits, zero-padded, 12-hour clock)', - h: 'Hour (1 or 2 digits without zero-padding, 12-hour clock)', - mm: 'Minute (2 digits, zero-padded)', - m: 'Minute (1 or 2 digits without zero-padding)', - ss: 'Second (2 digits, zero-padded)', - s: 'Second (1 or 2 digits without zero-padding)', + HH: "Hour (2 digits, zero-padded, 24-hour clock)", + H: "Hour (1 or 2 digits without zero-padding, 24-hour clock)", + hh: "Hour (2 digits, zero-padded, 12-hour clock)", + h: "Hour (1 or 2 digits without zero-padding, 12-hour clock)", + mm: "Minute (2 digits, zero-padded)", + m: "Minute (1 or 2 digits without zero-padding)", + ss: "Second (2 digits, zero-padded)", + s: "Second (1 or 2 digits without zero-padding)", // AM/PM - a: 'AM/PM marker', + a: "AM/PM marker", // Other - iooo: 'Hijri era (abbreviated)', - ioooo: 'Hijri era (full)', + iooo: "Hijri era (abbreviated)", + ioooo: "Hijri era (full)", // Timezone - z: 'Timezone (abbreviated)', - zz: 'Timezone (medium)', - zzz: 'Timezone (full)', - Z: 'Timezone offset from UTC (+HH:MM)', - ZZ: 'Timezone offset from UTC (condensed)', + z: "Timezone (abbreviated)", + zz: "Timezone (medium)", + zzz: "Timezone (full)", + Z: "Timezone offset from UTC (+HH:MM)", + ZZ: "Timezone offset from UTC (condensed)", }; diff --git a/src/hDates.ts b/src/hDates.ts index e9c9d5d..af19eb0 100644 --- a/src/hDates.ts +++ b/src/hDates.ts @@ -6,5 +6,5 @@ * SPORT: packages.md — luxon-hijri row */ // hDates.ts: re-exports from hijri-core; table is maintained in the core package -export { hDatesTable } from 'hijri-core'; -export type { HijriYearRecord } from 'hijri-core'; +export { hDatesTable } from "hijri-core"; +export type { HijriYearRecord } from "hijri-core"; diff --git a/src/hMonths.ts b/src/hMonths.ts index b03c3c8..a7da14a 100644 --- a/src/hMonths.ts +++ b/src/hMonths.ts @@ -6,4 +6,4 @@ * SPORT: packages.md — luxon-hijri row */ // hMonths.ts: re-exports from hijri-core -export { hmLong, hmMedium, hmShort } from 'hijri-core'; +export { hmLong, hmMedium, hmShort } from "hijri-core"; diff --git a/src/hWeekdays.ts b/src/hWeekdays.ts index cd07c32..8b8ad2d 100644 --- a/src/hWeekdays.ts +++ b/src/hWeekdays.ts @@ -6,4 +6,4 @@ * SPORT: packages.md — luxon-hijri row */ // hWeekdays.ts: re-exports from hijri-core -export { hwLong, hwShort, hwNumeric } from 'hijri-core'; +export { hwLong, hwShort, hwNumeric } from "hijri-core"; diff --git a/src/index.ts b/src/index.ts index f0d00f8..9d86a26 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,11 @@ // index.ts -export { formatPatterns } from './formatPatterns'; -export { hDatesTable } from './hDates'; -export type { HijriYearRecord } from './hDates'; -export { hmLong, hmMedium, hmShort } from './hMonths'; -export { hwLong, hwShort, hwNumeric } from './hWeekdays'; -export { toGregorian } from './toGregorian'; -export { toHijri } from './toHijri'; -export { formatHijriDate } from './formatHijriDate'; -export { isValidHijriDate } from './utils'; -export type { HijriDate, CalendarSystem, ConversionOptions } from './types'; +export { formatPatterns } from "./formatPatterns"; +export { hDatesTable } from "./hDates"; +export type { HijriYearRecord } from "./hDates"; +export { hmLong, hmMedium, hmShort } from "./hMonths"; +export { hwLong, hwShort, hwNumeric } from "./hWeekdays"; +export { toGregorian } from "./toGregorian"; +export { toHijri } from "./toHijri"; +export { formatHijriDate } from "./formatHijriDate"; +export { isValidHijriDate } from "./utils"; +export type { HijriDate, CalendarSystem, ConversionOptions } from "./types"; diff --git a/src/toGregorian.ts b/src/toGregorian.ts index ec53c89..091b0e6 100644 --- a/src/toGregorian.ts +++ b/src/toGregorian.ts @@ -6,8 +6,8 @@ * SPORT: packages.md — luxon-hijri row */ // toGregorian.ts: thin wrapper over hijri-core; preserves throw-on-invalid behavior -import { toGregorian as coreToGregorian } from 'hijri-core'; -import type { ConversionOptions } from './types'; +import { toGregorian as coreToGregorian } from "hijri-core"; +import type { ConversionOptions } from "./types"; /** * Convert a Hijri date to a Gregorian Date object. @@ -24,6 +24,6 @@ import type { ConversionOptions } from './types'; */ export function toGregorian(hy: number, hm: number, hd: number, options?: ConversionOptions): Date { const result = coreToGregorian(hy, hm, hd, options); - if (result === null) throw new Error('Invalid Hijri date'); + if (result === null) throw new Error("Invalid Hijri date"); return result; } diff --git a/src/toHijri.ts b/src/toHijri.ts index 04acb90..fb9d067 100644 --- a/src/toHijri.ts +++ b/src/toHijri.ts @@ -6,4 +6,4 @@ * SPORT: packages.md — luxon-hijri row */ // toHijri.ts: delegates to hijri-core -export { toHijri } from 'hijri-core'; +export { toHijri } from "hijri-core"; diff --git a/src/types.ts b/src/types.ts index b988bd3..f178cee 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,7 +6,7 @@ * SPORT: packages.md — luxon-hijri row */ // types.ts: re-exports from hijri-core for backward compatibility -export type { HijriDate, HijriYearRecord, ConversionOptions } from 'hijri-core'; +export type { HijriDate, HijriYearRecord, ConversionOptions } from "hijri-core"; /** * Built-in calendar system identifiers. @@ -17,4 +17,4 @@ export type { HijriDate, HijriYearRecord, ConversionOptions } from 'hijri-core'; * hijri-core accepts any string identifier via `registerCalendar()`. This type covers * the built-in defaults only. */ -export type CalendarSystem = 'uaq' | 'fcna'; +export type CalendarSystem = "uaq" | "fcna"; diff --git a/src/utils.ts b/src/utils.ts index f82fbf0..5e26588 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,4 +6,4 @@ * SPORT: packages.md — luxon-hijri row */ // utils.ts: delegates to hijri-core -export { isValidHijriDate } from 'hijri-core'; +export { isValidHijriDate } from "hijri-core";