@qingwu-ui/holiday-data 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +154 -0
- package/LICENSE-holiday-cn +21 -0
- package/data.json +1490 -0
- package/dist/index.cjs +1449 -0
- package/dist/index.d.cts +56 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +56 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1444 -0
- package/dist/index.mjs.map +1 -0
- package/festivals.json +899 -0
- package/package.json +61 -4
- package/schema.json +188 -0
- package/years/2024.json +195 -0
- package/years/2025.json +180 -0
- package/years/2026.json +210 -0
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["data"],"sources":["../data.json","../src/schema.ts","../src/index.ts"],"sourcesContent":["","/** 数据协议独立于运行时与农历算法;calendar/core 构建时内联本文件。 */\nexport interface DataSource {\n title: string;\n publisher: string;\n url: string;\n accessedAt: string;\n}\n\nexport interface HolidayDay {\n date: string;\n name: string;\n isOffDay: boolean;\n}\n\nexport interface HolidayYear {\n schemaVersion: 1;\n year: number;\n updatedAt: string;\n sources: DataSource[];\n days: HolidayDay[];\n}\n\nexport interface SourcedText {\n text: string;\n sources: DataSource[];\n}\n\nexport interface FestivalRecord {\n id: string;\n name: string;\n rule: {\n calendar: \"lunar\" | \"solar\" | \"solar-term\" | \"lunar-eve\";\n month?: number;\n day?: number;\n term?: string;\n };\n description: SourcedText;\n origin: SourcedText;\n customs: SourcedText;\n}\n\nexport interface HolidayData {\n schemaVersion: 1;\n updatedAt: string;\n years: HolidayYear[];\n festivals: FestivalRecord[];\n}\n\nexport function isISODate(value: unknown): value is string {\n if (typeof value !== \"string\" || !/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return false;\n const date = new Date(`${value}T00:00:00Z`);\n return Number.isFinite(date.getTime()) && date.toISOString().slice(0, 10) === value;\n}\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction source(value: unknown): boolean {\n if (\n !object(value) ||\n typeof value.title !== \"string\" ||\n typeof value.publisher !== \"string\" ||\n !isISODate(value.accessedAt) ||\n typeof value.url !== \"string\"\n )\n return false;\n try {\n return [\"https:\", \"http:\"].includes(new URL(value.url).protocol);\n } catch {\n return false;\n }\n}\n\nfunction sources(value: unknown): boolean {\n return Array.isArray(value) && value.every(source);\n}\n\nfunction sourcedText(value: unknown): boolean {\n return (\n object(value) &&\n typeof value.text === \"string\" &&\n sources(value.sources) &&\n Array.isArray(value.sources) &&\n value.sources.length > 0\n );\n}\n\nexport function validateHolidayYear(value: unknown): asserts value is HolidayYear {\n if (\n !object(value) ||\n value.schemaVersion !== 1 ||\n !Number.isInteger(value.year) ||\n !isISODate(value.updatedAt) ||\n !sources(value.sources) ||\n !Array.isArray(value.days)\n ) {\n throw new TypeError(\"年度节假日 JSON 格式不正确\");\n }\n const dates = new Set<string>();\n for (const day of value.days) {\n if (\n !object(day) ||\n !isISODate(day.date) ||\n typeof day.name !== \"string\" ||\n typeof day.isOffDay !== \"boolean\" ||\n Math.abs(Number(day.date.slice(0, 4)) - Number(value.year)) > 1 ||\n dates.has(day.date)\n ) {\n throw new TypeError(\"节假日日期无效、重复或放假/补班冲突\");\n }\n dates.add(day.date);\n }\n}\n\nexport function validateHolidayData(value: unknown): asserts value is HolidayData {\n if (\n !object(value) ||\n value.schemaVersion !== 1 ||\n !isISODate(value.updatedAt) ||\n !Array.isArray(value.years) ||\n !Array.isArray(value.festivals)\n )\n throw new TypeError(\"节假日 JSON 格式不正确\");\n const years = new Set<number>();\n for (const year of value.years) {\n validateHolidayYear(year);\n if (years.has(year.year)) throw new TypeError(\"节假日年份重复\");\n years.add(year.year);\n }\n const ids = new Set<string>();\n for (const festival of value.festivals) {\n if (\n !object(festival) ||\n typeof festival.id !== \"string\" ||\n ids.has(festival.id) ||\n typeof festival.name !== \"string\" ||\n !object(festival.rule) ||\n !sourcedText(festival.description) ||\n !sourcedText(festival.origin) ||\n !sourcedText(festival.customs)\n ) {\n throw new TypeError(\"节日资料必须包含介绍、渊源、习俗及各自来源\");\n }\n const rule = festival.rule;\n if (rule.calendar === \"lunar\" || rule.calendar === \"solar\") {\n const maxDay = rule.calendar === \"lunar\" ? 30 : 31;\n if (\n !Number.isInteger(rule.month) ||\n Number(rule.month) < 1 ||\n Number(rule.month) > 12 ||\n !Number.isInteger(rule.day) ||\n Number(rule.day) < 1 ||\n Number(rule.day) > maxDay\n )\n throw new TypeError(\"节日日期规则无效\");\n } else if (rule.calendar === \"solar-term\") {\n if (typeof rule.term !== \"string\" || !rule.term) throw new TypeError(\"节气规则无效\");\n } else if (rule.calendar !== \"lunar-eve\") throw new TypeError(\"未知节日日期规则\");\n ids.add(festival.id);\n }\n}\n\n/** 接受 JSON.parse 后的对象,也接受年度文件;年度输入不会替换其他年份。 */\nexport function parseHolidayData(value: unknown): HolidayData {\n if (object(value) && \"year\" in value) {\n validateHolidayYear(value);\n return { schemaVersion: 1, updatedAt: value.updatedAt, years: [value], festivals: [] };\n }\n validateHolidayData(value);\n return value;\n}\n\nexport function mergeHolidayData(\n base: HolidayData,\n custom: HolidayData | HolidayYear,\n): HolidayData {\n const input = parseHolidayData(custom);\n const years = new Map(base.years.map((year) => [year.year, year]));\n const festivals = new Map(base.festivals.map((festival) => [festival.id, festival]));\n for (const year of input.years) years.set(year.year, year);\n for (const festival of input.festivals) festivals.set(festival.id, festival);\n return {\n schemaVersion: 1,\n updatedAt: input.updatedAt,\n years: [...years.values()].sort((a, b) => a.year - b.year),\n festivals: [...festivals.values()],\n };\n}\n","import data from \"../data.json\";\nimport { parseHolidayData } from \"./schema\";\n\nexport * from \"./schema\";\nexport const holidayData = parseHolidayData(data);\nexport function getHolidayYear(year: number) {\n return holidayData.years.find((item) => item.year === year) ?? null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
|