mirror of
https://github.com/acamarata/hijri-core.git
synced 2026-06-30 18:54:27 +00:00
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
This commit is contained in:
parent
680bc72c19
commit
6caa9eed2c
10 changed files with 95 additions and 80 deletions
|
|
@ -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,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
36
src/index.ts
36
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { CalendarEngine } from './types';
|
||||
import type { CalendarEngine } from "./types";
|
||||
|
||||
const _engines = new Map<string, CalendarEngine>();
|
||||
|
||||
|
|
@ -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().`,
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue