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 [
|
export default [
|
||||||
{
|
{
|
||||||
plugins: { '@typescript-eslint': tsPlugin },
|
ignores: ['dist/**', 'node_modules/**', 'coverage/**', 'docs/**'],
|
||||||
languageOptions: { parser: tsParser },
|
|
||||||
},
|
},
|
||||||
...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",
|
"@acamarata/tsconfig": "^0.1.0",
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@types/node": "^22.15.0",
|
"@types/node": "^22.15.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
||||||
|
"@typescript-eslint/parser": "^8.56.1",
|
||||||
"c8": "^10.1.0",
|
"c8": "^10.1.0",
|
||||||
"eslint": "^10.0.3",
|
"eslint": "^10.0.3",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,12 @@ importers:
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.15.0
|
specifier: ^22.15.0
|
||||||
version: 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:
|
c8:
|
||||||
specifier: ^10.1.0
|
specifier: ^10.1.0
|
||||||
version: 10.1.3
|
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.
|
// Umm al-Qura reference table: Hijri years 1318-1501.
|
||||||
// Each entry records the 1 Muharram Gregorian date and a 12-bit days-per-month
|
// 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.),
|
// New moon times come from Jean Meeus, Astronomical Algorithms (2nd ed.),
|
||||||
// Chapter 49, accurate to within a few minutes for 1000-3000 CE.
|
// Chapter 49, accurate to within a few minutes for 1000-3000 CE.
|
||||||
|
|
||||||
import { hDatesTable } from '../data/hDates';
|
import { hDatesTable } from "../data/hDates";
|
||||||
import { MS_PER_DAY, MONTHS_PER_YEAR } from '../constants';
|
import { MS_PER_DAY, MONTHS_PER_YEAR } from "../constants";
|
||||||
import type { CalendarEngine, HijriDate } from '../types';
|
import type { CalendarEngine, HijriDate } from "../types";
|
||||||
|
|
||||||
// ─── Constants ───────────────────────────────────────────────────────────────
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ function fcnaDaysInMonth(hy: number, hm: number): number {
|
||||||
|
|
||||||
function fcnaToHijri(gregorianDate: Date): HijriDate | null {
|
function fcnaToHijri(gregorianDate: Date): HijriDate | null {
|
||||||
if (!(gregorianDate instanceof Date) || isNaN(gregorianDate.getTime())) {
|
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.
|
// 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 ────────────────────────────────────────────────────────────
|
// ─── Engine export ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export const fcnaEngine: CalendarEngine = {
|
export const fcnaEngine: CalendarEngine = {
|
||||||
id: 'fcna',
|
id: "fcna",
|
||||||
toHijri: fcnaToHijri,
|
toHijri: fcnaToHijri,
|
||||||
toGregorian: fcnaToGregorian,
|
toGregorian: fcnaToGregorian,
|
||||||
isValid: fcnaIsValid,
|
isValid: fcnaIsValid,
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
// (Gregorian 1900-2076). Each entry records the Gregorian date of 1 Muharram and
|
// (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.
|
// a 12-bit days-per-month bitmask. Dates outside that window return null.
|
||||||
|
|
||||||
import { hDatesTable } from '../data/hDates';
|
import { hDatesTable } from "../data/hDates";
|
||||||
import { MS_PER_DAY, MONTHS_PER_YEAR } from '../constants';
|
import { MS_PER_DAY, MONTHS_PER_YEAR } from "../constants";
|
||||||
import type { CalendarEngine, HijriDate, HijriYearRecord } from '../types';
|
import type { CalendarEngine, HijriDate, HijriYearRecord } from "../types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binary search for a Hijri year entry in the UAQ table.
|
* 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.
|
// the calendar-date lookup is timezone-safe regardless of the host environment.
|
||||||
function uaqToHijri(date: Date): HijriDate | null {
|
function uaqToHijri(date: Date): HijriDate | null {
|
||||||
if (!(date instanceof Date) || isNaN(date.getTime())) {
|
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());
|
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 = {
|
export const uaqEngine: CalendarEngine = {
|
||||||
id: 'uaq',
|
id: "uaq",
|
||||||
toHijri: uaqToHijri,
|
toHijri: uaqToHijri,
|
||||||
toGregorian: uaqToGregorian,
|
toGregorian: uaqToGregorian,
|
||||||
isValid: uaqIsValid,
|
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
|
// 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
|
// available immediately on import. This module-level side effect is intentional
|
||||||
// and documented in the sideEffects field of package.json.
|
// and documented in the sideEffects field of package.json.
|
||||||
import { uaqEngine } from './engines/uaq';
|
import { uaqEngine } from "./engines/uaq";
|
||||||
import { fcnaEngine } from './engines/fcna';
|
import { fcnaEngine } from "./engines/fcna";
|
||||||
import { registerCalendar } from './registry';
|
import { registerCalendar } from "./registry";
|
||||||
|
|
||||||
registerCalendar('uaq', uaqEngine);
|
registerCalendar("uaq", uaqEngine);
|
||||||
registerCalendar('fcna', fcnaEngine);
|
registerCalendar("fcna", fcnaEngine);
|
||||||
|
|
||||||
// Registry
|
// Registry
|
||||||
export { registerCalendar, getCalendar, listCalendars } from './registry';
|
export { registerCalendar, getCalendar, listCalendars } from "./registry";
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
export { MS_PER_DAY, MONTHS_PER_YEAR } from './constants';
|
export { MS_PER_DAY, MONTHS_PER_YEAR } from "./constants";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
export type { HijriDate, HijriYearRecord, CalendarEngine, ConversionOptions } from './types';
|
export type { HijriDate, HijriYearRecord, CalendarEngine, ConversionOptions } from "./types";
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
export { hDatesTable } from './data/hDates';
|
export { hDatesTable } from "./data/hDates";
|
||||||
|
|
||||||
// Names
|
// Names
|
||||||
export { hmLong, hmMedium, hmShort } from './names/months';
|
export { hmLong, hmMedium, hmShort } from "./names/months";
|
||||||
export { hwLong, hwShort, hwNumeric } from './names/weekdays';
|
export { hwLong, hwShort, hwNumeric } from "./names/weekdays";
|
||||||
|
|
||||||
// Convenience wrappers
|
// Convenience wrappers
|
||||||
import { getCalendar } from './registry';
|
import { getCalendar } from "./registry";
|
||||||
import type { HijriDate, ConversionOptions } from './types';
|
import type { HijriDate, ConversionOptions } from "./types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a Gregorian date to a Hijri date.
|
* 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 {
|
export function toHijri(date: Date, options?: ConversionOptions): HijriDate | null {
|
||||||
if (!(date instanceof Date) || isNaN(date.getTime())) {
|
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,
|
hd: number,
|
||||||
options?: ConversionOptions,
|
options?: ConversionOptions,
|
||||||
): Date | null {
|
): 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,
|
hd: number,
|
||||||
options?: ConversionOptions,
|
options?: ConversionOptions,
|
||||||
): boolean {
|
): 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
|
* @throws {RangeError} if the month or year is out of range
|
||||||
*/
|
*/
|
||||||
export function daysInHijriMonth(hy: number, hm: number, options?: ConversionOptions): number {
|
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"
|
* const month = hmLong[hijriDate.hm - 1]; // "Ramadan"
|
||||||
*/
|
*/
|
||||||
export const hmLong = [
|
export const hmLong = [
|
||||||
'Muharram', // 1
|
"Muharram", // 1
|
||||||
'Safar', // 2
|
"Safar", // 2
|
||||||
"Rabi'l Awwal", // 3
|
"Rabi'l Awwal", // 3
|
||||||
"Rabi'l Thani", // 4
|
"Rabi'l Thani", // 4
|
||||||
'Jumadal Awwal', // 5
|
"Jumadal Awwal", // 5
|
||||||
'Jumadal Thani', // 6
|
"Jumadal Thani", // 6
|
||||||
'Rajab', // 7
|
"Rajab", // 7
|
||||||
"Sha'ban", // 8
|
"Sha'ban", // 8
|
||||||
'Ramadan', // 9
|
"Ramadan", // 9
|
||||||
'Shawwal', // 10
|
"Shawwal", // 10
|
||||||
"Dhul Qi'dah", // 11
|
"Dhul Qi'dah", // 11
|
||||||
'Dhul Hijjah', // 12
|
"Dhul Hijjah", // 12
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -35,18 +35,18 @@ export const hmLong = [
|
||||||
* const label = hmMedium[hijriDate.hm - 1]; // "Ramadan"
|
* const label = hmMedium[hijriDate.hm - 1]; // "Ramadan"
|
||||||
*/
|
*/
|
||||||
export const hmMedium = [
|
export const hmMedium = [
|
||||||
'Muharram',
|
"Muharram",
|
||||||
'Safar',
|
"Safar",
|
||||||
'Rabi1',
|
"Rabi1",
|
||||||
'Rabi2',
|
"Rabi2",
|
||||||
'Jumada1',
|
"Jumada1",
|
||||||
'Jumada2',
|
"Jumada2",
|
||||||
'Rajab',
|
"Rajab",
|
||||||
'Shaban',
|
"Shaban",
|
||||||
'Ramadan',
|
"Ramadan",
|
||||||
'Shawwal',
|
"Shawwal",
|
||||||
'Dhul-Qidah',
|
"Dhul-Qidah",
|
||||||
'Dhul-Hijjah',
|
"Dhul-Hijjah",
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,16 +59,16 @@ export const hmMedium = [
|
||||||
* const abbr = hmShort[hijriDate.hm - 1]; // "Ram"
|
* const abbr = hmShort[hijriDate.hm - 1]; // "Ram"
|
||||||
*/
|
*/
|
||||||
export const hmShort = [
|
export const hmShort = [
|
||||||
'Muh',
|
"Muh",
|
||||||
'Saf',
|
"Saf",
|
||||||
'Ra1',
|
"Ra1",
|
||||||
'Ra2',
|
"Ra2",
|
||||||
'Ju1',
|
"Ju1",
|
||||||
'Ju2',
|
"Ju2",
|
||||||
'Raj',
|
"Raj",
|
||||||
'Shb',
|
"Shb",
|
||||||
'Ram',
|
"Ram",
|
||||||
'Shw',
|
"Shw",
|
||||||
'DhQ',
|
"DhQ",
|
||||||
'DhH',
|
"DhH",
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@
|
||||||
* const dayName = hwLong[gregorianDate.getDay()]; // "Yawm al-Jum`a"
|
* const dayName = hwLong[gregorianDate.getDay()]; // "Yawm al-Jum`a"
|
||||||
*/
|
*/
|
||||||
export const hwLong = [
|
export const hwLong = [
|
||||||
'Yawm al-Ahad', // Sunday
|
"Yawm al-Ahad", // Sunday
|
||||||
'Yawm al-Ithnayn', // Monday
|
"Yawm al-Ithnayn", // Monday
|
||||||
"Yawm ath-Thulatha'", // Tuesday
|
"Yawm ath-Thulatha'", // Tuesday
|
||||||
"Yawm al-Arba`a'", // Wednesday
|
"Yawm al-Arba`a'", // Wednesday
|
||||||
'Yawm al-Khamis', // Thursday
|
"Yawm al-Khamis", // Thursday
|
||||||
'Yawm al-Jum`a', // Friday
|
"Yawm al-Jum`a", // Friday
|
||||||
'Yawm as-Sabt', // Saturday
|
"Yawm as-Sabt", // Saturday
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -30,13 +30,13 @@ export const hwLong = [
|
||||||
* const abbr = hwShort[gregorianDate.getDay()]; // "Jum`a"
|
* const abbr = hwShort[gregorianDate.getDay()]; // "Jum`a"
|
||||||
*/
|
*/
|
||||||
export const hwShort = [
|
export const hwShort = [
|
||||||
'Ahad', // Sunday
|
"Ahad", // Sunday
|
||||||
'Ithn', // Monday
|
"Ithn", // Monday
|
||||||
'Thul', // Tuesday
|
"Thul", // Tuesday
|
||||||
'Arba', // Wednesday
|
"Arba", // Wednesday
|
||||||
'Kham', // Thursday
|
"Kham", // Thursday
|
||||||
'Jum`a', // Friday
|
"Jum`a", // Friday
|
||||||
'Sabt', // Saturday
|
"Sabt", // Saturday
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { CalendarEngine } from './types';
|
import type { CalendarEngine } from "./types";
|
||||||
|
|
||||||
const _engines = new Map<string, CalendarEngine>();
|
const _engines = new Map<string, CalendarEngine>();
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ export function registerCalendar(name: string, engine: CalendarEngine): void {
|
||||||
export function getCalendar(name: string): CalendarEngine {
|
export function getCalendar(name: string): CalendarEngine {
|
||||||
const engine = _engines.get(name);
|
const engine = _engines.get(name);
|
||||||
if (!engine) {
|
if (!engine) {
|
||||||
const available = listCalendars().join(', ');
|
const available = listCalendars().join(", ");
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Unknown Hijri calendar: "${name}". Available: ${available}. Register custom calendars with registerCalendar().`,
|
`Unknown Hijri calendar: "${name}". Available: ${available}. Register custom calendars with registerCalendar().`,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue