@cloudcome/utils-core 1.2.0 → 1.2.2

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.
Files changed (51) hide show
  1. package/README.md +18 -0
  2. package/dist/async.cjs.map +1 -1
  3. package/dist/async.d.ts +3 -3
  4. package/dist/async.mjs.map +1 -1
  5. package/dist/cache.cjs.map +1 -1
  6. package/dist/cache.d.ts +14 -14
  7. package/dist/cache.mjs.map +1 -1
  8. package/dist/core.cjs.map +1 -1
  9. package/dist/core.mjs.map +1 -1
  10. package/dist/date/core.d.ts +4 -4
  11. package/dist/date/days.d.ts +3 -3
  12. package/dist/date/is.d.ts +7 -7
  13. package/dist/date/relative.d.ts +10 -10
  14. package/dist/date/start-end.d.ts +13 -13
  15. package/dist/date/timezone.d.ts +2 -2
  16. package/dist/date/weeks.d.ts +4 -4
  17. package/dist/date.cjs.map +1 -1
  18. package/dist/date.mjs.map +1 -1
  19. package/dist/enum.cjs +1 -1
  20. package/dist/enum.cjs.map +1 -1
  21. package/dist/enum.d.ts +1 -1
  22. package/dist/enum.mjs +1 -1
  23. package/dist/enum.mjs.map +1 -1
  24. package/dist/fn.cjs.map +1 -1
  25. package/dist/fn.d.ts +4 -4
  26. package/dist/fn.mjs.map +1 -1
  27. package/dist/index.cjs +1 -1
  28. package/dist/index.mjs +1 -1
  29. package/dist/merge.cjs.map +1 -1
  30. package/dist/merge.mjs.map +1 -1
  31. package/dist/object/get-set.d.ts +14 -14
  32. package/dist/object/merge.d.ts +1 -1
  33. package/dist/object.cjs.map +1 -1
  34. package/dist/object.mjs.map +1 -1
  35. package/dist/time/from.d.ts +4 -4
  36. package/dist/time/to.d.ts +5 -5
  37. package/dist/time.cjs.map +1 -1
  38. package/dist/time.mjs.map +1 -1
  39. package/dist/timer.cjs.map +1 -1
  40. package/dist/timer.d.ts +6 -6
  41. package/dist/timer.mjs.map +1 -1
  42. package/dist/tree.cjs.map +1 -1
  43. package/dist/tree.d.ts +19 -19
  44. package/dist/tree.mjs.map +1 -1
  45. package/dist/url.cjs.map +1 -1
  46. package/dist/url.d.ts +6 -6
  47. package/dist/url.mjs.map +1 -1
  48. package/dist/version.cjs.map +1 -1
  49. package/dist/version.d.ts +2 -2
  50. package/dist/version.mjs.map +1 -1
  51. package/package.json +1 -1
@@ -1,16 +1,16 @@
1
- import { TDateValue } from './core';
2
- export type TDateRelativeTemplate = [
1
+ import { DateValue } from './core';
2
+ export type DateRelativeTemplate = [
3
3
  number,
4
4
  number,
5
5
  string,
6
6
  string?
7
7
  ];
8
- export type TDateRelativeTemplates = TDateRelativeTemplate[];
8
+ export type DateRelativeTemplates = DateRelativeTemplate[];
9
9
  /**
10
10
  * 相对时间
11
- * @param {TDateValue} dateValue 比较的时间
12
- * @param {TDateValue} [refDateValue] 相对的时间,默认为当前
13
- * @param {TDateRelativeTemplates} [templates] 模板
11
+ * @param {DateValue} dateValue 比较的时间
12
+ * @param {DateValue} [refDateValue] 相对的时间,默认为当前
13
+ * @param {DateRelativeTemplates} [templates] 模板
14
14
  * @returns {string} 格式化后的相对时间字符串
15
15
  * @example
16
16
  * ```typescript
@@ -38,7 +38,7 @@ export type TDateRelativeTemplates = TDateRelativeTemplate[];
38
38
  * dateRelative(new Date('2023-01-01'), new Date('2023-02-01'), templates); // '2023年01月01日'
39
39
  * ```
40
40
  */
41
- export declare function dateRelative(dateValue: TDateValue, refDateValue: TDateValue, templates: TDateRelativeTemplates): string;
42
- export declare function dateRelative(dateValue: TDateValue, refDateValue: TDateValue): string;
43
- export declare function dateRelative(dateValue: TDateValue, templates: TDateRelativeTemplates): string;
44
- export declare function dateRelative(dateValue: TDateValue): string;
41
+ export declare function dateRelative(dateValue: DateValue, refDateValue: DateValue, templates: DateRelativeTemplates): string;
42
+ export declare function dateRelative(dateValue: DateValue, refDateValue: DateValue): string;
43
+ export declare function dateRelative(dateValue: DateValue, templates: DateRelativeTemplates): string;
44
+ export declare function dateRelative(dateValue: DateValue): string;
@@ -1,73 +1,73 @@
1
- import { TDateLike, TDateValue } from './core';
1
+ import { DateLike, DateValue } from './core';
2
2
  /**
3
3
  * 返回秒级起始时间
4
4
  * @param dateValue - 可以是数值、字符串或 Date 对象
5
5
  * @returns 返回秒级起始时间,毫秒部分为 0
6
6
  */
7
- export declare function dateStartInSecond(dateValue: TDateValue): TDateLike;
7
+ export declare function dateStartInSecond(dateValue: DateValue): DateLike;
8
8
  /**
9
9
  * 返回分钟级起始时间
10
10
  * @param dateValue - 可以是数值、字符串或 Date 对象
11
11
  * @returns 返回分钟级起始时间,秒和毫秒部分为 0
12
12
  */
13
- export declare function dateStartInMinute(dateValue: TDateValue): TDateLike;
13
+ export declare function dateStartInMinute(dateValue: DateValue): DateLike;
14
14
  /**
15
15
  * 返回小时级起始时间
16
16
  * @param dateValue - 可以是数值、字符串或 Date 对象
17
17
  * @returns 返回小时级起始时间,分钟、秒和毫秒部分为 0
18
18
  */
19
- export declare function dateStartInHour(dateValue: TDateValue): TDateLike;
19
+ export declare function dateStartInHour(dateValue: DateValue): DateLike;
20
20
  /**
21
21
  * 返回天级起始时间
22
22
  * @param dateValue - 可以是数值、字符串或 Date 对象
23
23
  * @returns 返回天级起始时间,小时、分钟、秒和毫秒部分为 0
24
24
  */
25
- export declare function dateStartInDay(dateValue: TDateValue): TDateLike;
25
+ export declare function dateStartInDay(dateValue: DateValue): DateLike;
26
26
  /**
27
27
  * 返回月级起始时间
28
28
  * @param dateValue - 可以是数值、字符串或 Date 对象
29
29
  * @returns 返回月级起始时间,日期为当月第一天,时间部分为 0
30
30
  */
31
- export declare function dateStartInMonth(dateValue: TDateValue): TDateLike;
31
+ export declare function dateStartInMonth(dateValue: DateValue): DateLike;
32
32
  /**
33
33
  * 返回年级起始时间
34
34
  * @param dateValue - 可以是数值、字符串或 Date 对象
35
35
  * @returns 返回年级起始时间,月份为 1 月,日期为 1 日,时间部分为 0
36
36
  */
37
- export declare function dateStartInYear(dateValue: TDateValue): TDateLike;
37
+ export declare function dateStartInYear(dateValue: DateValue): DateLike;
38
38
  /**
39
39
  * 返回秒级结束时间
40
40
  * @param dateValue - 可以是数值、字符串或 Date 对象
41
41
  * @returns 返回秒级结束时间,毫秒部分为 999
42
42
  */
43
- export declare function dateEndInSecond(dateValue: TDateValue): TDateLike;
43
+ export declare function dateEndInSecond(dateValue: DateValue): DateLike;
44
44
  /**
45
45
  * 返回分钟级结束时间
46
46
  * @param dateValue - 可以是数值、字符串或 Date 对象
47
47
  * @returns 返回分钟级结束时间,秒为 59,毫秒为 999
48
48
  */
49
- export declare function dateEndInMinute(dateValue: TDateValue): TDateLike;
49
+ export declare function dateEndInMinute(dateValue: DateValue): DateLike;
50
50
  /**
51
51
  * 返回小时级结束时间
52
52
  * @param dateValue - 可以是数值、字符串或 Date 对象
53
53
  * @returns 返回小时级结束时间,分钟为 59,秒为 59,毫秒为 999
54
54
  */
55
- export declare function dateEndInHour(dateValue: TDateValue): TDateLike;
55
+ export declare function dateEndInHour(dateValue: DateValue): DateLike;
56
56
  /**
57
57
  * 返回天级结束时间
58
58
  * @param dateValue - 可以是数值、字符串或 Date 对象
59
59
  * @returns 返回天级结束时间,小时为 23,分钟为 59,秒为 59,毫秒为 999
60
60
  */
61
- export declare function dateEndInDay(dateValue: TDateValue): TDateLike;
61
+ export declare function dateEndInDay(dateValue: DateValue): DateLike;
62
62
  /**
63
63
  * 返回月级结束时间
64
64
  * @param dateValue - 可以是数值、字符串或 Date 对象
65
65
  * @returns 返回月级结束时间,日期为当月最后一天,时间为 23:59:59.999
66
66
  */
67
- export declare function dateEndInMonth(dateValue: TDateValue): TDateLike;
67
+ export declare function dateEndInMonth(dateValue: DateValue): DateLike;
68
68
  /**
69
69
  * 返回年级结束时间
70
70
  * @param dateValue - 可以是数值、字符串或 Date 对象
71
71
  * @returns 返回年级结束时间,月份为 12 月,日期为 31 日,时间为 23:59:59.999
72
72
  */
73
- export declare function dateEndInYear(dateValue: TDateValue): TDateLike;
73
+ export declare function dateEndInYear(dateValue: DateValue): DateLike;
@@ -1,4 +1,4 @@
1
- export type TTzDateOptions = {
1
+ export type TzDateOptions = {
2
2
  /**
3
3
  * 时间戳
4
4
  * @default Date.now()
@@ -23,7 +23,7 @@ export type TTzDateOptions = {
23
23
  };
24
24
  export declare class TzDate {
25
25
  #private;
26
- constructor(options?: TTzDateOptions | TzDate);
26
+ constructor(options?: TzDateOptions | TzDate);
27
27
  getTimezoneOffset(): number;
28
28
  getTimezoneOrder(): number;
29
29
  getFullYear(): number;
@@ -1,4 +1,4 @@
1
- import { TDateValue } from './core';
1
+ import { DateValue } from './core';
2
2
  export declare enum EWeekStart {
3
3
  /**
4
4
  * 周日作为一周的起始日
@@ -43,7 +43,7 @@ export declare enum EWeekStart {
43
43
  * _dateWeeks(date, 'Y', 1); // 1 (周一作为一周的起始日,计算年份的周数)
44
44
  * ```
45
45
  */
46
- export declare function _dateWeeks(dateValue: TDateValue, type: 'Y' | 'M', weekStart?: EWeekStart): number;
46
+ export declare function _dateWeeks(dateValue: DateValue, type: 'Y' | 'M', weekStart?: EWeekStart): number;
47
47
  /**
48
48
  * 计算指定日期所在年份的周数
49
49
  * @param dateValue - 可以是数值、字符串或 Date 对象
@@ -56,7 +56,7 @@ export declare function _dateWeeks(dateValue: TDateValue, type: 'Y' | 'M', weekS
56
56
  * weeksOfYear(date, 1); // 1 (周一作为一周的起始日)
57
57
  * ```
58
58
  */
59
- export declare function weeksOfYear(dateValue: TDateValue, weekStart?: EWeekStart): number;
59
+ export declare function weeksOfYear(dateValue: DateValue, weekStart?: EWeekStart): number;
60
60
  /**
61
61
  * 计算指定日期所在月份的周数
62
62
  * @param dateValue - 可以是数值、字符串或 Date 对象
@@ -69,4 +69,4 @@ export declare function weeksOfYear(dateValue: TDateValue, weekStart?: EWeekStar
69
69
  * weeksOfMonth(date, 1); // 1 (周一作为一周的起始日)
70
70
  * ```
71
71
  */
72
- export declare function weeksOfMonth(dateValue: TDateValue, weekStart?: EWeekStart): number;
72
+ export declare function weeksOfMonth(dateValue: DateValue, weekStart?: EWeekStart): number;
package/dist/date.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"date.cjs","sources":["../src/date/start-end.ts","../src/date/days.ts","../src/date/relative.ts","../src/date/is.ts","../src/date/weeks.ts"],"sourcesContent":["import { type TDateLike, type TDateValue, dateParse } from './core';\n\n/**\n * 时间单位符号枚举\n * - 'Y': 年\n * - 'M': 月\n * - 'D': 天\n * - 'W': 周\n * - 'h': 小时\n * - 'm': 分钟\n * - 's': 秒\n */\ntype _TDateOfSymbol = 'Y' | 'M' | 'D' | 'W' | 'h' | 'm' | 's';\n\n/**\n * 各时间单位起始时间映射表\n * 包含将日期设置到单位起始时间的函数\n */\nconst dateOfStartMap: [_TDateOfSymbol, (date: TDateLike) => unknown][] = [\n ['s', (d) => d.setMilliseconds(0)],\n ['m', (d) => d.setSeconds(0)],\n ['h', (d) => d.setMinutes(0)],\n ['D', (d) => d.setHours(0)],\n ['W', (d) => d.setHours(0)],\n ['M', (d) => d.setDate(1)],\n ['Y', (d) => d.setMonth(0)],\n];\n\n/**\n * 返回指定时间单位的起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param symbol - 时间单位符号,可选值为 'Y'(年)、'M'(月)、'D'(天)、'h'(小时)、'm'(分钟)、's'(秒),默认为 'D'\n * @returns 返回指定时间单位的起始时间\n * @example\n * ```typescript\n * const date = new Date(2023, 5, 15, 12, 30, 45, 500); // 2023-06-15 12:30:45.500\n *\n * // 返回秒级起始时间\n * dateOfStart(date, 's'); // 2023-06-15 12:30:45.000\n *\n * // 返回分钟级起始时间\n * dateOfStart(date, 'm'); // 2023-06-15 12:30:00.000\n *\n * // 返回小时级起始时间\n * dateOfStart(date, 'h'); // 2023-06-15 12:00:00.000\n *\n * // 返回天级起始时间\n * dateOfStart(date, 'D'); // 2023-06-15 00:00:00.000\n *\n * // 返回月级起始时间\n * dateOfStart(date, 'M'); // 2023-06-01 00:00:00.000\n *\n * // 返回年级起始时间\n * dateOfStart(date, 'Y'); // 2023-01-01 00:00:00.000\n *\n * // 默认返回天级起始时间\n * dateOfStart(date); // 2023-06-15 00:00:00.000\n * ```\n */\nfunction _dateStart(dateValue: TDateValue, symbol: _TDateOfSymbol = 'D') {\n const date = dateParse(dateValue);\n\n for (const [sym, fn] of dateOfStartMap) {\n fn(date);\n if (symbol === sym) break;\n }\n\n return date;\n}\n\n/**\n * 返回秒级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回秒级起始时间,毫秒部分为 0\n */\nexport function dateStartInSecond(dateValue: TDateValue) {\n return _dateStart(dateValue, 's');\n}\n\n/**\n * 返回分钟级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回分钟级起始时间,秒和毫秒部分为 0\n */\nexport function dateStartInMinute(dateValue: TDateValue) {\n return _dateStart(dateValue, 'm');\n}\n\n/**\n * 返回小时级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回小时级起始时间,分钟、秒和毫秒部分为 0\n */\nexport function dateStartInHour(dateValue: TDateValue) {\n return _dateStart(dateValue, 'h');\n}\n\n/**\n * 返回天级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回天级起始时间,小时、分钟、秒和毫秒部分为 0\n */\nexport function dateStartInDay(dateValue: TDateValue) {\n return _dateStart(dateValue, 'D');\n}\n\n/**\n * 返回月级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回月级起始时间,日期为当月第一天,时间部分为 0\n */\nexport function dateStartInMonth(dateValue: TDateValue) {\n return _dateStart(dateValue, 'M');\n}\n\n/**\n * 返回年级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回年级起始时间,月份为 1 月,日期为 1 日,时间部分为 0\n */\nexport function dateStartInYear(dateValue: TDateValue) {\n return _dateStart(dateValue, 'Y');\n}\n\n/**\n * 各时间单位结束时间映射表\n * 包含将日期设置到单位结束时间的函数\n */\nconst dateOfEndMap: [_TDateOfSymbol, (date: TDateLike) => unknown][] = [\n ['s', (d) => d.setMilliseconds(999)],\n ['m', (d) => d.setSeconds(59)],\n ['h', (d) => d.setMinutes(59)],\n ['D', (d) => d.setHours(23)],\n [\n 'M',\n (d) => {\n const d2 = dateParse(d);\n d2.setMonth(d.getMonth() + 1);\n d2.setDate(0);\n d.setDate(d2.getDate());\n },\n ],\n [\n 'Y',\n (d) => {\n d.setMonth(11);\n d.setDate(31);\n },\n ],\n];\n\n/**\n * 返回指定时间单位的结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param symbol - 时间单位符号,可选值为 'Y'(年)、'M'(月)、'D'(天)、'h'(小时)、'm'(分钟)、's'(秒),默认为 'D'\n * @returns 返回指定时间单位的结束时间\n * @example\n * ```typescript\n * const date = new Date(2023, 5, 15, 12, 30, 45, 500); // 2023-06-15 12:30:45.500\n *\n * // 返回秒级结束时间\n * dateOfEnd(date, 's'); // 2023-06-15 12:30:45.999\n *\n * // 返回分钟级结束时间\n * dateOfEnd(date, 'm'); // 2023-06-15 12:30:59.999\n *\n * // 返回小时级结束时间\n * dateOfEnd(date, 'h'); // 2023-06-15 12:59:59.999\n *\n * // 返回天级结束时间\n * dateOfEnd(date, 'D'); // 2023-06-15 23:59:59.999\n *\n * // 返回月级结束时间\n * dateOfEnd(date, 'M'); // 2023-06-30 23:59:59.999\n *\n * // 返回年级结束时间\n * dateOfEnd(date, 'Y'); // 2023-12-31 23:59:59.999\n *\n * // 默认返回天级结束时间\n * dateOfEnd(date); // 2023-06-15 23:59:59.999\n * ```\n */\nfunction _dateEnd(dateValue: TDateValue, symbol: _TDateOfSymbol = 'D') {\n const date = dateParse(dateValue);\n\n for (const [sym, fn] of dateOfEndMap) {\n fn(date);\n if (symbol === sym) break;\n }\n\n return date;\n}\n\n/**\n * 返回秒级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回秒级结束时间,毫秒部分为 999\n */\nexport function dateEndInSecond(dateValue: TDateValue) {\n return _dateEnd(dateValue, 's');\n}\n\n/**\n * 返回分钟级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回分钟级结束时间,秒为 59,毫秒为 999\n */\nexport function dateEndInMinute(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'm');\n}\n\n/**\n * 返回小时级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回小时级结束时间,分钟为 59,秒为 59,毫秒为 999\n */\nexport function dateEndInHour(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'h');\n}\n\n/**\n * 返回天级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回天级结束时间,小时为 23,分钟为 59,秒为 59,毫秒为 999\n */\nexport function dateEndInDay(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'D');\n}\n\n/**\n * 返回月级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回月级结束时间,日期为当月最后一天,时间为 23:59:59.999\n */\nexport function dateEndInMonth(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'M');\n}\n\n/**\n * 返回年级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回年级结束时间,月份为 12 月,日期为 31 日,时间为 23:59:59.999\n */\nexport function dateEndInYear(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'Y');\n}\n","import { DATE_DAY_MS } from './const';\nimport { type TDateValue, dateParse } from './core';\nimport { dateEndInMonth, dateEndInYear, dateStartInMonth, dateStartInYear } from './start-end';\n\n/**\n * 计算指定日期所在年或月的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param unit - 时间单位符号,可选值为 'Y'(年)、'M'(月),默认为 'M'\n * @returns 返回指定日期所在年或月的天数\n * @example\n * ```typescript\n * dateDays(new Date('2023-02-15')); // 28\n * dateDays(new Date('2024-02-15')); // 29 (闰年)\n * dateDays(new Date('2023-02-15'), 'Y'); // 365\n * dateDays(new Date('2024-02-15'), 'Y'); // 366 (闰年)\n * ```\n */\nfunction _dateDays(dateValue: TDateValue, unit: 'Y' | 'M') {\n const d = dateParse(dateValue);\n const ds = unit === 'M' ? dateStartInMonth(d) : dateStartInYear(d);\n const de = unit === 'M' ? dateEndInMonth(d) : dateEndInYear(d);\n return Math.ceil((de.getTime() - ds.getTime()) / DATE_DAY_MS);\n}\n\n/**\n * 计算指定日期所在月份的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回指定日期所在月份的天数\n * @example\n * ```typescript\n * dateDaysInMonth(new Date('2023-02-15')); // 28\n * dateDaysInMonth(new Date('2024-02-15')); // 29 (闰年)\n * ```\n */\nexport function dateDaysInMonth(dateValue: TDateValue) {\n return _dateDays(dateValue, 'M');\n}\n\n/**\n * 计算指定日期所在年份的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回指定日期所在年份的天数\n * @example\n * ```typescript\n * dateDaysInYear(new Date('2023-02-15')); // 365\n * dateDaysInYear(new Date('2024-02-15')); // 366 (闰年)\n * ```\n */\nexport function dateDaysInYear(dateValue: TDateValue) {\n return _dateDays(dateValue, 'Y');\n}\n","import { stringFormat } from '@/string';\nimport { isArray } from '@/type';\nimport { type TDateValue, dateFormat, dateParse } from './core';\n\nexport type TDateRelativeTemplate = [\n number /*单位时间差,为 0 表示不计算单位差值,单位秒*/,\n number /*最大时间差,单位:秒*/,\n string /*过去模板字符串,%d 表述单位差值*/,\n string? /*将来模板字符串,%d 表述单位差值,可选*/,\n];\nexport type TDateRelativeTemplates = TDateRelativeTemplate[];\n\nconst defaultDiffTemplates: TDateRelativeTemplates = [\n [0, 10, '刚刚'],\n [1, 60, '{n} 秒前', '{n} 秒后'],\n [60, 60 * 60, '{n} 分钟前', '{n} 分钟后'],\n [60 * 60, 60 * 60 * 24, '{n} 小时前', '{n} 小时后'],\n [0, 60 * 60 * 24 * 2, '昨天', '明天'],\n [0, 60 * 60 * 24 * 3, '前天', '后天'],\n [60 * 60 * 24, 60 * 60 * 24 * 30, '{n} 天前', '{n} 天后'],\n [0, Number.POSITIVE_INFINITY, 'YYYY年MM月DD日'],\n];\n\n/**\n * 相对时间\n * @param {TDateValue} dateValue 比较的时间\n * @param {TDateValue} [refDateValue] 相对的时间,默认为当前\n * @param {TDateRelativeTemplates} [templates] 模板\n * @returns {string} 格式化后的相对时间字符串\n * @example\n * ```typescript\n * // 默认模板\n * dateRelative(new Date('2023-01-01')); // '刚刚'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-02')); // '昨天'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-04')); // '3 天前'\n * dateRelative(new Date('2023-01-01'), new Date('2023-02-01')); // '2023年01月01日'\n * ```\n * @example\n * ```typescript\n * // 自定义模板\n * const templates: DateRelativeTemplates = [\n * [0, 10, '刚刚'],\n * [1, 60, '{n} 秒前', '{n} 秒后'],\n * [60, 60 * 60, '{n} 分钟前', '{n} 分钟后'],\n * [60 * 60, 60 * 60 * 24, '{n} 小时前', '{n} 小时后'],\n * [0, 60 * 60 * 24 * 2, '昨天', '明天'],\n * [0, 60 * 60 * 24 * 3, '前天', '后天'],\n * [60 * 60 * 24, 60 * 60 * 24 * 30, '{n} 天前', '{n} 天后'],\n * [0, Number.POSITIVE_INFINITY, 'YYYY年MM月DD日'],\n * ];\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-02'), templates); // '昨天'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-04'), templates); // '3 天前'\n * dateRelative(new Date('2023-01-01'), new Date('2023-02-01'), templates); // '2023年01月01日'\n * ```\n */\nexport function dateRelative(\n dateValue: TDateValue,\n refDateValue: TDateValue,\n templates: TDateRelativeTemplates,\n): string;\nexport function dateRelative(dateValue: TDateValue, refDateValue: TDateValue): string;\nexport function dateRelative(dateValue: TDateValue, templates: TDateRelativeTemplates): string;\nexport function dateRelative(dateValue: TDateValue): string;\nexport function dateRelative(\n dateValue: TDateValue,\n refDateValue?: TDateValue | TDateRelativeTemplates,\n templates?: TDateRelativeTemplates,\n): string {\n const now = Date.now();\n const refDateValueFinal = isArray(refDateValue) ? now : refDateValue || now;\n const templatesFinal = isArray(templates) ? templates : isArray(refDateValue) ? refDateValue : defaultDiffTemplates;\n const d1 = dateParse(dateValue);\n const d2 = dateParse(refDateValueFinal);\n const diff = d1.getTime() - d2.getTime();\n const isAgo = diff < 0;\n const absDiff = Math.abs(diff);\n let relative = '';\n\n for (const [base, max, agoTemplate, featureTemplate] of templatesFinal) {\n const unitFinal = base * 1000;\n const maxFinal = max * 1000;\n\n if (absDiff < maxFinal) {\n const template = isAgo ? agoTemplate : featureTemplate || agoTemplate;\n const length = unitFinal === 0 ? 0 : Math.max(Math.floor(absDiff / unitFinal), 1);\n relative = unitFinal === 0 ? dateFormat(dateValue, template) : stringFormat(template, { n: length });\n break;\n }\n }\n\n return relative;\n}\n","import { type TDateLike, type TDateValue, dateParse } from './core';\n\n/**\n * 判断给定的年份是否为闰年\n * @param year - 需要判断的年份\n * @returns 如果年份是闰年则返回 true,否则返回 false\n * @example\n * ```typescript\n * isLeapYear(2020); // true\n * isLeapYear(2021); // false\n * isLeapYear(2000); // true\n * isLeapYear(1900); // false\n * ```\n */\nexport function isLeapYear(year: number): boolean {\n if (year % 4 !== 0) return false;\n if (year % 100 !== 0) return true;\n if (year % 400 !== 0) return false;\n return true;\n}\n\n/**\n * 日期比较精度枚举类型\n * - Y = 年\n * - M = 月\n * - D = 天\n * - h = 小时\n * - m = 分钟\n * - s = 秒\n * - S = 毫秒\n */\ntype _DateSameSymbol = 'Y' | 'M' | 'D' | 'h' | 'm' | 's' | 'S';\n\n/**\n * 比较两个日期在指定精度下是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @param sameSymbol - 比较精度,默认为 'D'(天,即年月日天都相同)\n * @returns 如果两个日期在指定精度下相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30, 45, 500);\n * const date2 = new Date(2023, 5, 15, 13, 30, 45, 500);\n *\n * // 比较年份\n * isSameDate(date1, date2, 'Y'); // true\n *\n * // 比较月份(年份也要相同)\n * isSameDate(date1, date2, 'M'); // true\n *\n * // 比较日期(默认,年份、月份也要相同)\n * isSameDate(date1, date2); // true\n *\n * // 比较小时(年、月、日也要相同)\n * isSameDate(date1, date2, 'h'); // false\n *\n * // 比较分钟(年、月、日、小时也要相同)\n * isSameDate(date1, date2, 'm'); // false\n *\n * // 比较秒(年、月、日、小时、分钟也要相同)\n * isSameDate(date1, date2, 's'); // false\n *\n * // 比较毫秒(年、月、日、小时、分钟、秒数也要相同)\n * isSameDate(date1, date2, 'S'); // false\n * ```\n */\nfunction _isSameDateIn(date1: TDateValue, date2: TDateValue, sameSymbol: _DateSameSymbol = 'D') {\n const defines = [\n ['Y', (d: TDateLike) => d.getFullYear()],\n ['M', (d: TDateLike) => d.getMonth()],\n ['D', (d: TDateLike) => d.getDate()],\n ['h', (d: TDateLike) => d.getHours()],\n ['m', (d: TDateLike) => d.getMinutes()],\n ['s', (d: TDateLike) => d.getSeconds()],\n ['S', (d: TDateLike) => d.getMilliseconds()],\n ] as const;\n\n const d1 = dateParse(date1);\n const d2 = dateParse(date2);\n\n for (const [sym, fn] of defines) {\n if (fn(d1) !== fn(d2)) {\n return false;\n }\n\n if (sym === sameSymbol) break;\n }\n\n return true;\n}\n\n/**\n * 比较两个日期的年份是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 6, 20);\n * isSameDateInYear(date1, date2); // true\n * ```\n */\nexport function isSameDateInYear(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'Y');\n}\n\n/**\n * 比较两个日期的年份和月份是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份和月份相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 5, 20);\n * isSameDateInMonth(date1, date2); // true\n * ```\n */\nexport function isSameDateInMonth(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'M');\n}\n\n/**\n * 比较两个日期的年份、月份和天数是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份和天数相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 5, 15);\n * isSameDateInDay(date1, date2); // true\n * ```\n */\nexport function isSameDateInDay(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'D');\n}\n\n/**\n * 比较两个日期的年份、月份、天数和小时是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数和小时相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12);\n * const date2 = new Date(2023, 5, 15, 12);\n * isSameDateInHour(date1, date2); // true\n * ```\n */\nexport function isSameDateInHour(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'h');\n}\n\n/**\n * 比较两个日期的年份、月份、天数、小时和分钟是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数、小时和分钟相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30);\n * const date2 = new Date(2023, 5, 15, 12, 30);\n * isSameDateInMinute(date1, date2); // true\n * ```\n */\nexport function isSameDateInMinute(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'm');\n}\n\n/**\n * 比较两个日期的年份、月份、天数、小时、分钟和秒数是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数、小时、分钟和秒数相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30, 45);\n * const date2 = new Date(2023, 5, 15, 12, 30, 45);\n * isSameDateInSecond(date1, date2); // true\n * ```\n */\nexport function isSameDateInSecond(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 's');\n}\n","import { DATE_DAY_MS } from './const';\nimport { type TDateValue, dateParse } from './core';\n\nexport enum EWeekStart {\n /**\n * 周日作为一周的起始日\n */\n sunday = 0,\n /**\n * 周一作为一周的起始日\n */\n monday = 1,\n /**\n * 周二作为一周的起始日\n */\n tuesday = 2,\n /**\n * 周三作为一周的起始日\n */\n wednesday = 3,\n /**\n * 周四作为一周的起始日\n */\n thursday = 4,\n /**\n * 周五作为一周的起始日\n */\n friday = 5,\n /**\n * 周六作为一周的起始日\n */\n saturday = 6,\n // /**\n // * 1号所在的周为第一周\n // */\n // firstDate = 7,\n // /**\n // * 完整7天表示第一周\n // */\n // firstFullWeek = 8,\n}\n\n/**\n * 计算指定日期所在年份或月份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param type - 计算范围,'Y' 表示年份,'M' 表示月份\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在年份或月份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * _dateWeeks(date, 'Y'); // 1 (计算年份的周数)\n * _dateWeeks(date, 'M'); // 1 (计算月份的周数)\n * _dateWeeks(date, 'Y', 1); // 1 (周一作为一周的起始日,计算年份的周数)\n * ```\n */\nexport function _dateWeeks(dateValue: TDateValue, type: 'Y' | 'M', weekStart: EWeekStart = 0) {\n const date = dateParse(dateValue);\n\n const year = date.getFullYear();\n const month = date.getMonth();\n\n const firstDate = type === 'Y' ? new Date(year, 0, 1) : new Date(year, month, 1);\n const firstWeek = firstDate.getDay();\n const days = Math.ceil((date.getTime() - firstDate.getTime()) / DATE_DAY_MS);\n\n return Math.ceil((firstWeek + days - weekStart) / 7);\n}\n\n/**\n * 计算指定日期所在年份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在年份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * weeksOfYear(date); // 1\n * weeksOfYear(date, 1); // 1 (周一作为一周的起始日)\n * ```\n */\nexport function weeksOfYear(dateValue: TDateValue, weekStart: EWeekStart = 0) {\n return _dateWeeks(dateValue, 'Y', weekStart);\n}\n\n/**\n * 计算指定日期所在月份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在月份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * weeksOfMonth(date); // 1\n * weeksOfMonth(date, 1); // 1 (周一作为一周的起始日)\n * ```\n */\nexport function weeksOfMonth(dateValue: TDateValue, weekStart: EWeekStart = 0) {\n return _dateWeeks(dateValue, 'M', weekStart);\n}\n"],"names":["dateParse","DATE_DAY_MS","isArray","dateFormat","stringFormat","EWeekStart","type"],"mappings":"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"}
1
+ {"version":3,"file":"date.cjs","sources":["../src/date/start-end.ts","../src/date/days.ts","../src/date/relative.ts","../src/date/is.ts","../src/date/weeks.ts"],"sourcesContent":["import { type DateLike, type DateValue, dateParse } from './core';\n\n/**\n * 时间单位符号枚举\n * - 'Y': 年\n * - 'M': 月\n * - 'D': 天\n * - 'W': 周\n * - 'h': 小时\n * - 'm': 分钟\n * - 's': 秒\n */\ntype _TDateOfSymbol = 'Y' | 'M' | 'D' | 'W' | 'h' | 'm' | 's';\n\n/**\n * 各时间单位起始时间映射表\n * 包含将日期设置到单位起始时间的函数\n */\nconst dateOfStartMap: [_TDateOfSymbol, (date: DateLike) => unknown][] = [\n ['s', (d) => d.setMilliseconds(0)],\n ['m', (d) => d.setSeconds(0)],\n ['h', (d) => d.setMinutes(0)],\n ['D', (d) => d.setHours(0)],\n ['W', (d) => d.setHours(0)],\n ['M', (d) => d.setDate(1)],\n ['Y', (d) => d.setMonth(0)],\n];\n\n/**\n * 返回指定时间单位的起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param symbol - 时间单位符号,可选值为 'Y'(年)、'M'(月)、'D'(天)、'h'(小时)、'm'(分钟)、's'(秒),默认为 'D'\n * @returns 返回指定时间单位的起始时间\n * @example\n * ```typescript\n * const date = new Date(2023, 5, 15, 12, 30, 45, 500); // 2023-06-15 12:30:45.500\n *\n * // 返回秒级起始时间\n * dateOfStart(date, 's'); // 2023-06-15 12:30:45.000\n *\n * // 返回分钟级起始时间\n * dateOfStart(date, 'm'); // 2023-06-15 12:30:00.000\n *\n * // 返回小时级起始时间\n * dateOfStart(date, 'h'); // 2023-06-15 12:00:00.000\n *\n * // 返回天级起始时间\n * dateOfStart(date, 'D'); // 2023-06-15 00:00:00.000\n *\n * // 返回月级起始时间\n * dateOfStart(date, 'M'); // 2023-06-01 00:00:00.000\n *\n * // 返回年级起始时间\n * dateOfStart(date, 'Y'); // 2023-01-01 00:00:00.000\n *\n * // 默认返回天级起始时间\n * dateOfStart(date); // 2023-06-15 00:00:00.000\n * ```\n */\nfunction _dateStart(dateValue: DateValue, symbol: _TDateOfSymbol = 'D') {\n const date = dateParse(dateValue);\n\n for (const [sym, fn] of dateOfStartMap) {\n fn(date);\n if (symbol === sym) break;\n }\n\n return date;\n}\n\n/**\n * 返回秒级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回秒级起始时间,毫秒部分为 0\n */\nexport function dateStartInSecond(dateValue: DateValue) {\n return _dateStart(dateValue, 's');\n}\n\n/**\n * 返回分钟级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回分钟级起始时间,秒和毫秒部分为 0\n */\nexport function dateStartInMinute(dateValue: DateValue) {\n return _dateStart(dateValue, 'm');\n}\n\n/**\n * 返回小时级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回小时级起始时间,分钟、秒和毫秒部分为 0\n */\nexport function dateStartInHour(dateValue: DateValue) {\n return _dateStart(dateValue, 'h');\n}\n\n/**\n * 返回天级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回天级起始时间,小时、分钟、秒和毫秒部分为 0\n */\nexport function dateStartInDay(dateValue: DateValue) {\n return _dateStart(dateValue, 'D');\n}\n\n/**\n * 返回月级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回月级起始时间,日期为当月第一天,时间部分为 0\n */\nexport function dateStartInMonth(dateValue: DateValue) {\n return _dateStart(dateValue, 'M');\n}\n\n/**\n * 返回年级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回年级起始时间,月份为 1 月,日期为 1 日,时间部分为 0\n */\nexport function dateStartInYear(dateValue: DateValue) {\n return _dateStart(dateValue, 'Y');\n}\n\n/**\n * 各时间单位结束时间映射表\n * 包含将日期设置到单位结束时间的函数\n */\nconst dateOfEndMap: [_TDateOfSymbol, (date: DateLike) => unknown][] = [\n ['s', (d) => d.setMilliseconds(999)],\n ['m', (d) => d.setSeconds(59)],\n ['h', (d) => d.setMinutes(59)],\n ['D', (d) => d.setHours(23)],\n [\n 'M',\n (d) => {\n const d2 = dateParse(d);\n d2.setMonth(d.getMonth() + 1);\n d2.setDate(0);\n d.setDate(d2.getDate());\n },\n ],\n [\n 'Y',\n (d) => {\n d.setMonth(11);\n d.setDate(31);\n },\n ],\n];\n\n/**\n * 返回指定时间单位的结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param symbol - 时间单位符号,可选值为 'Y'(年)、'M'(月)、'D'(天)、'h'(小时)、'm'(分钟)、's'(秒),默认为 'D'\n * @returns 返回指定时间单位的结束时间\n * @example\n * ```typescript\n * const date = new Date(2023, 5, 15, 12, 30, 45, 500); // 2023-06-15 12:30:45.500\n *\n * // 返回秒级结束时间\n * dateOfEnd(date, 's'); // 2023-06-15 12:30:45.999\n *\n * // 返回分钟级结束时间\n * dateOfEnd(date, 'm'); // 2023-06-15 12:30:59.999\n *\n * // 返回小时级结束时间\n * dateOfEnd(date, 'h'); // 2023-06-15 12:59:59.999\n *\n * // 返回天级结束时间\n * dateOfEnd(date, 'D'); // 2023-06-15 23:59:59.999\n *\n * // 返回月级结束时间\n * dateOfEnd(date, 'M'); // 2023-06-30 23:59:59.999\n *\n * // 返回年级结束时间\n * dateOfEnd(date, 'Y'); // 2023-12-31 23:59:59.999\n *\n * // 默认返回天级结束时间\n * dateOfEnd(date); // 2023-06-15 23:59:59.999\n * ```\n */\nfunction _dateEnd(dateValue: DateValue, symbol: _TDateOfSymbol = 'D') {\n const date = dateParse(dateValue);\n\n for (const [sym, fn] of dateOfEndMap) {\n fn(date);\n if (symbol === sym) break;\n }\n\n return date;\n}\n\n/**\n * 返回秒级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回秒级结束时间,毫秒部分为 999\n */\nexport function dateEndInSecond(dateValue: DateValue) {\n return _dateEnd(dateValue, 's');\n}\n\n/**\n * 返回分钟级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回分钟级结束时间,秒为 59,毫秒为 999\n */\nexport function dateEndInMinute(dateValue: DateValue) {\n return _dateEnd(dateValue, 'm');\n}\n\n/**\n * 返回小时级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回小时级结束时间,分钟为 59,秒为 59,毫秒为 999\n */\nexport function dateEndInHour(dateValue: DateValue) {\n return _dateEnd(dateValue, 'h');\n}\n\n/**\n * 返回天级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回天级结束时间,小时为 23,分钟为 59,秒为 59,毫秒为 999\n */\nexport function dateEndInDay(dateValue: DateValue) {\n return _dateEnd(dateValue, 'D');\n}\n\n/**\n * 返回月级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回月级结束时间,日期为当月最后一天,时间为 23:59:59.999\n */\nexport function dateEndInMonth(dateValue: DateValue) {\n return _dateEnd(dateValue, 'M');\n}\n\n/**\n * 返回年级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回年级结束时间,月份为 12 月,日期为 31 日,时间为 23:59:59.999\n */\nexport function dateEndInYear(dateValue: DateValue) {\n return _dateEnd(dateValue, 'Y');\n}\n","import { DATE_DAY_MS } from './const';\nimport { type DateValue, dateParse } from './core';\nimport { dateEndInMonth, dateEndInYear, dateStartInMonth, dateStartInYear } from './start-end';\n\n/**\n * 计算指定日期所在年或月的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param unit - 时间单位符号,可选值为 'Y'(年)、'M'(月),默认为 'M'\n * @returns 返回指定日期所在年或月的天数\n * @example\n * ```typescript\n * dateDays(new Date('2023-02-15')); // 28\n * dateDays(new Date('2024-02-15')); // 29 (闰年)\n * dateDays(new Date('2023-02-15'), 'Y'); // 365\n * dateDays(new Date('2024-02-15'), 'Y'); // 366 (闰年)\n * ```\n */\nfunction _dateDays(dateValue: DateValue, unit: 'Y' | 'M') {\n const d = dateParse(dateValue);\n const ds = unit === 'M' ? dateStartInMonth(d) : dateStartInYear(d);\n const de = unit === 'M' ? dateEndInMonth(d) : dateEndInYear(d);\n return Math.ceil((de.getTime() - ds.getTime()) / DATE_DAY_MS);\n}\n\n/**\n * 计算指定日期所在月份的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回指定日期所在月份的天数\n * @example\n * ```typescript\n * dateDaysInMonth(new Date('2023-02-15')); // 28\n * dateDaysInMonth(new Date('2024-02-15')); // 29 (闰年)\n * ```\n */\nexport function dateDaysInMonth(dateValue: DateValue) {\n return _dateDays(dateValue, 'M');\n}\n\n/**\n * 计算指定日期所在年份的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回指定日期所在年份的天数\n * @example\n * ```typescript\n * dateDaysInYear(new Date('2023-02-15')); // 365\n * dateDaysInYear(new Date('2024-02-15')); // 366 (闰年)\n * ```\n */\nexport function dateDaysInYear(dateValue: DateValue) {\n return _dateDays(dateValue, 'Y');\n}\n","import { stringFormat } from '@/string';\nimport { isArray } from '@/type';\nimport { type DateValue, dateFormat, dateParse } from './core';\n\nexport type DateRelativeTemplate = [\n number /*单位时间差,为 0 表示不计算单位差值,单位秒*/,\n number /*最大时间差,单位:秒*/,\n string /*过去模板字符串,%d 表述单位差值*/,\n string? /*将来模板字符串,%d 表述单位差值,可选*/,\n];\nexport type DateRelativeTemplates = DateRelativeTemplate[];\n\nconst defaultDiffTemplates: DateRelativeTemplates = [\n [0, 10, '刚刚'],\n [1, 60, '{n} 秒前', '{n} 秒后'],\n [60, 60 * 60, '{n} 分钟前', '{n} 分钟后'],\n [60 * 60, 60 * 60 * 24, '{n} 小时前', '{n} 小时后'],\n [0, 60 * 60 * 24 * 2, '昨天', '明天'],\n [0, 60 * 60 * 24 * 3, '前天', '后天'],\n [60 * 60 * 24, 60 * 60 * 24 * 30, '{n} 天前', '{n} 天后'],\n [0, Number.POSITIVE_INFINITY, 'YYYY年MM月DD日'],\n];\n\n/**\n * 相对时间\n * @param {DateValue} dateValue 比较的时间\n * @param {DateValue} [refDateValue] 相对的时间,默认为当前\n * @param {DateRelativeTemplates} [templates] 模板\n * @returns {string} 格式化后的相对时间字符串\n * @example\n * ```typescript\n * // 默认模板\n * dateRelative(new Date('2023-01-01')); // '刚刚'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-02')); // '昨天'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-04')); // '3 天前'\n * dateRelative(new Date('2023-01-01'), new Date('2023-02-01')); // '2023年01月01日'\n * ```\n * @example\n * ```typescript\n * // 自定义模板\n * const templates: DateRelativeTemplates = [\n * [0, 10, '刚刚'],\n * [1, 60, '{n} 秒前', '{n} 秒后'],\n * [60, 60 * 60, '{n} 分钟前', '{n} 分钟后'],\n * [60 * 60, 60 * 60 * 24, '{n} 小时前', '{n} 小时后'],\n * [0, 60 * 60 * 24 * 2, '昨天', '明天'],\n * [0, 60 * 60 * 24 * 3, '前天', '后天'],\n * [60 * 60 * 24, 60 * 60 * 24 * 30, '{n} 天前', '{n} 天后'],\n * [0, Number.POSITIVE_INFINITY, 'YYYY年MM月DD日'],\n * ];\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-02'), templates); // '昨天'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-04'), templates); // '3 天前'\n * dateRelative(new Date('2023-01-01'), new Date('2023-02-01'), templates); // '2023年01月01日'\n * ```\n */\nexport function dateRelative(dateValue: DateValue, refDateValue: DateValue, templates: DateRelativeTemplates): string;\nexport function dateRelative(dateValue: DateValue, refDateValue: DateValue): string;\nexport function dateRelative(dateValue: DateValue, templates: DateRelativeTemplates): string;\nexport function dateRelative(dateValue: DateValue): string;\nexport function dateRelative(\n dateValue: DateValue,\n refDateValue?: DateValue | DateRelativeTemplates,\n templates?: DateRelativeTemplates,\n): string {\n const now = Date.now();\n const refDateValueFinal = isArray(refDateValue) ? now : refDateValue || now;\n const templatesFinal = isArray(templates) ? templates : isArray(refDateValue) ? refDateValue : defaultDiffTemplates;\n const d1 = dateParse(dateValue);\n const d2 = dateParse(refDateValueFinal);\n const diff = d1.getTime() - d2.getTime();\n const isAgo = diff < 0;\n const absDiff = Math.abs(diff);\n let relative = '';\n\n for (const [base, max, agoTemplate, featureTemplate] of templatesFinal) {\n const unitFinal = base * 1000;\n const maxFinal = max * 1000;\n\n if (absDiff < maxFinal) {\n const template = isAgo ? agoTemplate : featureTemplate || agoTemplate;\n const length = unitFinal === 0 ? 0 : Math.max(Math.floor(absDiff / unitFinal), 1);\n relative = unitFinal === 0 ? dateFormat(dateValue, template) : stringFormat(template, { n: length });\n break;\n }\n }\n\n return relative;\n}\n","import { type DateLike, type DateValue, dateParse } from './core';\n\n/**\n * 判断给定的年份是否为闰年\n * @param year - 需要判断的年份\n * @returns 如果年份是闰年则返回 true,否则返回 false\n * @example\n * ```typescript\n * isLeapYear(2020); // true\n * isLeapYear(2021); // false\n * isLeapYear(2000); // true\n * isLeapYear(1900); // false\n * ```\n */\nexport function isLeapYear(year: number): boolean {\n if (year % 4 !== 0) return false;\n if (year % 100 !== 0) return true;\n if (year % 400 !== 0) return false;\n return true;\n}\n\n/**\n * 日期比较精度枚举类型\n * - Y = 年\n * - M = 月\n * - D = 天\n * - h = 小时\n * - m = 分钟\n * - s = 秒\n * - S = 毫秒\n */\ntype _DateSameSymbol = 'Y' | 'M' | 'D' | 'h' | 'm' | 's' | 'S';\n\n/**\n * 比较两个日期在指定精度下是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @param sameSymbol - 比较精度,默认为 'D'(天,即年月日天都相同)\n * @returns 如果两个日期在指定精度下相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30, 45, 500);\n * const date2 = new Date(2023, 5, 15, 13, 30, 45, 500);\n *\n * // 比较年份\n * isSameDate(date1, date2, 'Y'); // true\n *\n * // 比较月份(年份也要相同)\n * isSameDate(date1, date2, 'M'); // true\n *\n * // 比较日期(默认,年份、月份也要相同)\n * isSameDate(date1, date2); // true\n *\n * // 比较小时(年、月、日也要相同)\n * isSameDate(date1, date2, 'h'); // false\n *\n * // 比较分钟(年、月、日、小时也要相同)\n * isSameDate(date1, date2, 'm'); // false\n *\n * // 比较秒(年、月、日、小时、分钟也要相同)\n * isSameDate(date1, date2, 's'); // false\n *\n * // 比较毫秒(年、月、日、小时、分钟、秒数也要相同)\n * isSameDate(date1, date2, 'S'); // false\n * ```\n */\nfunction _isSameDateIn(date1: DateValue, date2: DateValue, sameSymbol: _DateSameSymbol = 'D') {\n const defines = [\n ['Y', (d: DateLike) => d.getFullYear()],\n ['M', (d: DateLike) => d.getMonth()],\n ['D', (d: DateLike) => d.getDate()],\n ['h', (d: DateLike) => d.getHours()],\n ['m', (d: DateLike) => d.getMinutes()],\n ['s', (d: DateLike) => d.getSeconds()],\n ['S', (d: DateLike) => d.getMilliseconds()],\n ] as const;\n\n const d1 = dateParse(date1);\n const d2 = dateParse(date2);\n\n for (const [sym, fn] of defines) {\n if (fn(d1) !== fn(d2)) {\n return false;\n }\n\n if (sym === sameSymbol) break;\n }\n\n return true;\n}\n\n/**\n * 比较两个日期的年份是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 6, 20);\n * isSameDateInYear(date1, date2); // true\n * ```\n */\nexport function isSameDateInYear(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'Y');\n}\n\n/**\n * 比较两个日期的年份和月份是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份和月份相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 5, 20);\n * isSameDateInMonth(date1, date2); // true\n * ```\n */\nexport function isSameDateInMonth(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'M');\n}\n\n/**\n * 比较两个日期的年份、月份和天数是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份和天数相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 5, 15);\n * isSameDateInDay(date1, date2); // true\n * ```\n */\nexport function isSameDateInDay(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'D');\n}\n\n/**\n * 比较两个日期的年份、月份、天数和小时是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数和小时相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12);\n * const date2 = new Date(2023, 5, 15, 12);\n * isSameDateInHour(date1, date2); // true\n * ```\n */\nexport function isSameDateInHour(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'h');\n}\n\n/**\n * 比较两个日期的年份、月份、天数、小时和分钟是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数、小时和分钟相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30);\n * const date2 = new Date(2023, 5, 15, 12, 30);\n * isSameDateInMinute(date1, date2); // true\n * ```\n */\nexport function isSameDateInMinute(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'm');\n}\n\n/**\n * 比较两个日期的年份、月份、天数、小时、分钟和秒数是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数、小时、分钟和秒数相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30, 45);\n * const date2 = new Date(2023, 5, 15, 12, 30, 45);\n * isSameDateInSecond(date1, date2); // true\n * ```\n */\nexport function isSameDateInSecond(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 's');\n}\n","import { DATE_DAY_MS } from './const';\nimport { type DateValue, dateParse } from './core';\n\nexport enum EWeekStart {\n /**\n * 周日作为一周的起始日\n */\n sunday = 0,\n /**\n * 周一作为一周的起始日\n */\n monday = 1,\n /**\n * 周二作为一周的起始日\n */\n tuesday = 2,\n /**\n * 周三作为一周的起始日\n */\n wednesday = 3,\n /**\n * 周四作为一周的起始日\n */\n thursday = 4,\n /**\n * 周五作为一周的起始日\n */\n friday = 5,\n /**\n * 周六作为一周的起始日\n */\n saturday = 6,\n // /**\n // * 1号所在的周为第一周\n // */\n // firstDate = 7,\n // /**\n // * 完整7天表示第一周\n // */\n // firstFullWeek = 8,\n}\n\n/**\n * 计算指定日期所在年份或月份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param type - 计算范围,'Y' 表示年份,'M' 表示月份\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在年份或月份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * _dateWeeks(date, 'Y'); // 1 (计算年份的周数)\n * _dateWeeks(date, 'M'); // 1 (计算月份的周数)\n * _dateWeeks(date, 'Y', 1); // 1 (周一作为一周的起始日,计算年份的周数)\n * ```\n */\nexport function _dateWeeks(dateValue: DateValue, type: 'Y' | 'M', weekStart: EWeekStart = 0) {\n const date = dateParse(dateValue);\n\n const year = date.getFullYear();\n const month = date.getMonth();\n\n const firstDate = type === 'Y' ? new Date(year, 0, 1) : new Date(year, month, 1);\n const firstWeek = firstDate.getDay();\n const days = Math.ceil((date.getTime() - firstDate.getTime()) / DATE_DAY_MS);\n\n return Math.ceil((firstWeek + days - weekStart) / 7);\n}\n\n/**\n * 计算指定日期所在年份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在年份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * weeksOfYear(date); // 1\n * weeksOfYear(date, 1); // 1 (周一作为一周的起始日)\n * ```\n */\nexport function weeksOfYear(dateValue: DateValue, weekStart: EWeekStart = 0) {\n return _dateWeeks(dateValue, 'Y', weekStart);\n}\n\n/**\n * 计算指定日期所在月份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在月份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * weeksOfMonth(date); // 1\n * weeksOfMonth(date, 1); // 1 (周一作为一周的起始日)\n * ```\n */\nexport function weeksOfMonth(dateValue: DateValue, weekStart: EWeekStart = 0) {\n return _dateWeeks(dateValue, 'M', weekStart);\n}\n"],"names":["dateParse","DATE_DAY_MS","isArray","dateFormat","stringFormat","EWeekStart","type"],"mappings":"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"}
package/dist/date.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"date.mjs","sources":["../src/date/start-end.ts","../src/date/days.ts","../src/date/relative.ts","../src/date/is.ts","../src/date/weeks.ts"],"sourcesContent":["import { type TDateLike, type TDateValue, dateParse } from './core';\n\n/**\n * 时间单位符号枚举\n * - 'Y': 年\n * - 'M': 月\n * - 'D': 天\n * - 'W': 周\n * - 'h': 小时\n * - 'm': 分钟\n * - 's': 秒\n */\ntype _TDateOfSymbol = 'Y' | 'M' | 'D' | 'W' | 'h' | 'm' | 's';\n\n/**\n * 各时间单位起始时间映射表\n * 包含将日期设置到单位起始时间的函数\n */\nconst dateOfStartMap: [_TDateOfSymbol, (date: TDateLike) => unknown][] = [\n ['s', (d) => d.setMilliseconds(0)],\n ['m', (d) => d.setSeconds(0)],\n ['h', (d) => d.setMinutes(0)],\n ['D', (d) => d.setHours(0)],\n ['W', (d) => d.setHours(0)],\n ['M', (d) => d.setDate(1)],\n ['Y', (d) => d.setMonth(0)],\n];\n\n/**\n * 返回指定时间单位的起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param symbol - 时间单位符号,可选值为 'Y'(年)、'M'(月)、'D'(天)、'h'(小时)、'm'(分钟)、's'(秒),默认为 'D'\n * @returns 返回指定时间单位的起始时间\n * @example\n * ```typescript\n * const date = new Date(2023, 5, 15, 12, 30, 45, 500); // 2023-06-15 12:30:45.500\n *\n * // 返回秒级起始时间\n * dateOfStart(date, 's'); // 2023-06-15 12:30:45.000\n *\n * // 返回分钟级起始时间\n * dateOfStart(date, 'm'); // 2023-06-15 12:30:00.000\n *\n * // 返回小时级起始时间\n * dateOfStart(date, 'h'); // 2023-06-15 12:00:00.000\n *\n * // 返回天级起始时间\n * dateOfStart(date, 'D'); // 2023-06-15 00:00:00.000\n *\n * // 返回月级起始时间\n * dateOfStart(date, 'M'); // 2023-06-01 00:00:00.000\n *\n * // 返回年级起始时间\n * dateOfStart(date, 'Y'); // 2023-01-01 00:00:00.000\n *\n * // 默认返回天级起始时间\n * dateOfStart(date); // 2023-06-15 00:00:00.000\n * ```\n */\nfunction _dateStart(dateValue: TDateValue, symbol: _TDateOfSymbol = 'D') {\n const date = dateParse(dateValue);\n\n for (const [sym, fn] of dateOfStartMap) {\n fn(date);\n if (symbol === sym) break;\n }\n\n return date;\n}\n\n/**\n * 返回秒级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回秒级起始时间,毫秒部分为 0\n */\nexport function dateStartInSecond(dateValue: TDateValue) {\n return _dateStart(dateValue, 's');\n}\n\n/**\n * 返回分钟级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回分钟级起始时间,秒和毫秒部分为 0\n */\nexport function dateStartInMinute(dateValue: TDateValue) {\n return _dateStart(dateValue, 'm');\n}\n\n/**\n * 返回小时级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回小时级起始时间,分钟、秒和毫秒部分为 0\n */\nexport function dateStartInHour(dateValue: TDateValue) {\n return _dateStart(dateValue, 'h');\n}\n\n/**\n * 返回天级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回天级起始时间,小时、分钟、秒和毫秒部分为 0\n */\nexport function dateStartInDay(dateValue: TDateValue) {\n return _dateStart(dateValue, 'D');\n}\n\n/**\n * 返回月级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回月级起始时间,日期为当月第一天,时间部分为 0\n */\nexport function dateStartInMonth(dateValue: TDateValue) {\n return _dateStart(dateValue, 'M');\n}\n\n/**\n * 返回年级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回年级起始时间,月份为 1 月,日期为 1 日,时间部分为 0\n */\nexport function dateStartInYear(dateValue: TDateValue) {\n return _dateStart(dateValue, 'Y');\n}\n\n/**\n * 各时间单位结束时间映射表\n * 包含将日期设置到单位结束时间的函数\n */\nconst dateOfEndMap: [_TDateOfSymbol, (date: TDateLike) => unknown][] = [\n ['s', (d) => d.setMilliseconds(999)],\n ['m', (d) => d.setSeconds(59)],\n ['h', (d) => d.setMinutes(59)],\n ['D', (d) => d.setHours(23)],\n [\n 'M',\n (d) => {\n const d2 = dateParse(d);\n d2.setMonth(d.getMonth() + 1);\n d2.setDate(0);\n d.setDate(d2.getDate());\n },\n ],\n [\n 'Y',\n (d) => {\n d.setMonth(11);\n d.setDate(31);\n },\n ],\n];\n\n/**\n * 返回指定时间单位的结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param symbol - 时间单位符号,可选值为 'Y'(年)、'M'(月)、'D'(天)、'h'(小时)、'm'(分钟)、's'(秒),默认为 'D'\n * @returns 返回指定时间单位的结束时间\n * @example\n * ```typescript\n * const date = new Date(2023, 5, 15, 12, 30, 45, 500); // 2023-06-15 12:30:45.500\n *\n * // 返回秒级结束时间\n * dateOfEnd(date, 's'); // 2023-06-15 12:30:45.999\n *\n * // 返回分钟级结束时间\n * dateOfEnd(date, 'm'); // 2023-06-15 12:30:59.999\n *\n * // 返回小时级结束时间\n * dateOfEnd(date, 'h'); // 2023-06-15 12:59:59.999\n *\n * // 返回天级结束时间\n * dateOfEnd(date, 'D'); // 2023-06-15 23:59:59.999\n *\n * // 返回月级结束时间\n * dateOfEnd(date, 'M'); // 2023-06-30 23:59:59.999\n *\n * // 返回年级结束时间\n * dateOfEnd(date, 'Y'); // 2023-12-31 23:59:59.999\n *\n * // 默认返回天级结束时间\n * dateOfEnd(date); // 2023-06-15 23:59:59.999\n * ```\n */\nfunction _dateEnd(dateValue: TDateValue, symbol: _TDateOfSymbol = 'D') {\n const date = dateParse(dateValue);\n\n for (const [sym, fn] of dateOfEndMap) {\n fn(date);\n if (symbol === sym) break;\n }\n\n return date;\n}\n\n/**\n * 返回秒级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回秒级结束时间,毫秒部分为 999\n */\nexport function dateEndInSecond(dateValue: TDateValue) {\n return _dateEnd(dateValue, 's');\n}\n\n/**\n * 返回分钟级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回分钟级结束时间,秒为 59,毫秒为 999\n */\nexport function dateEndInMinute(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'm');\n}\n\n/**\n * 返回小时级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回小时级结束时间,分钟为 59,秒为 59,毫秒为 999\n */\nexport function dateEndInHour(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'h');\n}\n\n/**\n * 返回天级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回天级结束时间,小时为 23,分钟为 59,秒为 59,毫秒为 999\n */\nexport function dateEndInDay(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'D');\n}\n\n/**\n * 返回月级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回月级结束时间,日期为当月最后一天,时间为 23:59:59.999\n */\nexport function dateEndInMonth(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'M');\n}\n\n/**\n * 返回年级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回年级结束时间,月份为 12 月,日期为 31 日,时间为 23:59:59.999\n */\nexport function dateEndInYear(dateValue: TDateValue) {\n return _dateEnd(dateValue, 'Y');\n}\n","import { DATE_DAY_MS } from './const';\nimport { type TDateValue, dateParse } from './core';\nimport { dateEndInMonth, dateEndInYear, dateStartInMonth, dateStartInYear } from './start-end';\n\n/**\n * 计算指定日期所在年或月的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param unit - 时间单位符号,可选值为 'Y'(年)、'M'(月),默认为 'M'\n * @returns 返回指定日期所在年或月的天数\n * @example\n * ```typescript\n * dateDays(new Date('2023-02-15')); // 28\n * dateDays(new Date('2024-02-15')); // 29 (闰年)\n * dateDays(new Date('2023-02-15'), 'Y'); // 365\n * dateDays(new Date('2024-02-15'), 'Y'); // 366 (闰年)\n * ```\n */\nfunction _dateDays(dateValue: TDateValue, unit: 'Y' | 'M') {\n const d = dateParse(dateValue);\n const ds = unit === 'M' ? dateStartInMonth(d) : dateStartInYear(d);\n const de = unit === 'M' ? dateEndInMonth(d) : dateEndInYear(d);\n return Math.ceil((de.getTime() - ds.getTime()) / DATE_DAY_MS);\n}\n\n/**\n * 计算指定日期所在月份的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回指定日期所在月份的天数\n * @example\n * ```typescript\n * dateDaysInMonth(new Date('2023-02-15')); // 28\n * dateDaysInMonth(new Date('2024-02-15')); // 29 (闰年)\n * ```\n */\nexport function dateDaysInMonth(dateValue: TDateValue) {\n return _dateDays(dateValue, 'M');\n}\n\n/**\n * 计算指定日期所在年份的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回指定日期所在年份的天数\n * @example\n * ```typescript\n * dateDaysInYear(new Date('2023-02-15')); // 365\n * dateDaysInYear(new Date('2024-02-15')); // 366 (闰年)\n * ```\n */\nexport function dateDaysInYear(dateValue: TDateValue) {\n return _dateDays(dateValue, 'Y');\n}\n","import { stringFormat } from '@/string';\nimport { isArray } from '@/type';\nimport { type TDateValue, dateFormat, dateParse } from './core';\n\nexport type TDateRelativeTemplate = [\n number /*单位时间差,为 0 表示不计算单位差值,单位秒*/,\n number /*最大时间差,单位:秒*/,\n string /*过去模板字符串,%d 表述单位差值*/,\n string? /*将来模板字符串,%d 表述单位差值,可选*/,\n];\nexport type TDateRelativeTemplates = TDateRelativeTemplate[];\n\nconst defaultDiffTemplates: TDateRelativeTemplates = [\n [0, 10, '刚刚'],\n [1, 60, '{n} 秒前', '{n} 秒后'],\n [60, 60 * 60, '{n} 分钟前', '{n} 分钟后'],\n [60 * 60, 60 * 60 * 24, '{n} 小时前', '{n} 小时后'],\n [0, 60 * 60 * 24 * 2, '昨天', '明天'],\n [0, 60 * 60 * 24 * 3, '前天', '后天'],\n [60 * 60 * 24, 60 * 60 * 24 * 30, '{n} 天前', '{n} 天后'],\n [0, Number.POSITIVE_INFINITY, 'YYYY年MM月DD日'],\n];\n\n/**\n * 相对时间\n * @param {TDateValue} dateValue 比较的时间\n * @param {TDateValue} [refDateValue] 相对的时间,默认为当前\n * @param {TDateRelativeTemplates} [templates] 模板\n * @returns {string} 格式化后的相对时间字符串\n * @example\n * ```typescript\n * // 默认模板\n * dateRelative(new Date('2023-01-01')); // '刚刚'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-02')); // '昨天'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-04')); // '3 天前'\n * dateRelative(new Date('2023-01-01'), new Date('2023-02-01')); // '2023年01月01日'\n * ```\n * @example\n * ```typescript\n * // 自定义模板\n * const templates: DateRelativeTemplates = [\n * [0, 10, '刚刚'],\n * [1, 60, '{n} 秒前', '{n} 秒后'],\n * [60, 60 * 60, '{n} 分钟前', '{n} 分钟后'],\n * [60 * 60, 60 * 60 * 24, '{n} 小时前', '{n} 小时后'],\n * [0, 60 * 60 * 24 * 2, '昨天', '明天'],\n * [0, 60 * 60 * 24 * 3, '前天', '后天'],\n * [60 * 60 * 24, 60 * 60 * 24 * 30, '{n} 天前', '{n} 天后'],\n * [0, Number.POSITIVE_INFINITY, 'YYYY年MM月DD日'],\n * ];\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-02'), templates); // '昨天'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-04'), templates); // '3 天前'\n * dateRelative(new Date('2023-01-01'), new Date('2023-02-01'), templates); // '2023年01月01日'\n * ```\n */\nexport function dateRelative(\n dateValue: TDateValue,\n refDateValue: TDateValue,\n templates: TDateRelativeTemplates,\n): string;\nexport function dateRelative(dateValue: TDateValue, refDateValue: TDateValue): string;\nexport function dateRelative(dateValue: TDateValue, templates: TDateRelativeTemplates): string;\nexport function dateRelative(dateValue: TDateValue): string;\nexport function dateRelative(\n dateValue: TDateValue,\n refDateValue?: TDateValue | TDateRelativeTemplates,\n templates?: TDateRelativeTemplates,\n): string {\n const now = Date.now();\n const refDateValueFinal = isArray(refDateValue) ? now : refDateValue || now;\n const templatesFinal = isArray(templates) ? templates : isArray(refDateValue) ? refDateValue : defaultDiffTemplates;\n const d1 = dateParse(dateValue);\n const d2 = dateParse(refDateValueFinal);\n const diff = d1.getTime() - d2.getTime();\n const isAgo = diff < 0;\n const absDiff = Math.abs(diff);\n let relative = '';\n\n for (const [base, max, agoTemplate, featureTemplate] of templatesFinal) {\n const unitFinal = base * 1000;\n const maxFinal = max * 1000;\n\n if (absDiff < maxFinal) {\n const template = isAgo ? agoTemplate : featureTemplate || agoTemplate;\n const length = unitFinal === 0 ? 0 : Math.max(Math.floor(absDiff / unitFinal), 1);\n relative = unitFinal === 0 ? dateFormat(dateValue, template) : stringFormat(template, { n: length });\n break;\n }\n }\n\n return relative;\n}\n","import { type TDateLike, type TDateValue, dateParse } from './core';\n\n/**\n * 判断给定的年份是否为闰年\n * @param year - 需要判断的年份\n * @returns 如果年份是闰年则返回 true,否则返回 false\n * @example\n * ```typescript\n * isLeapYear(2020); // true\n * isLeapYear(2021); // false\n * isLeapYear(2000); // true\n * isLeapYear(1900); // false\n * ```\n */\nexport function isLeapYear(year: number): boolean {\n if (year % 4 !== 0) return false;\n if (year % 100 !== 0) return true;\n if (year % 400 !== 0) return false;\n return true;\n}\n\n/**\n * 日期比较精度枚举类型\n * - Y = 年\n * - M = 月\n * - D = 天\n * - h = 小时\n * - m = 分钟\n * - s = 秒\n * - S = 毫秒\n */\ntype _DateSameSymbol = 'Y' | 'M' | 'D' | 'h' | 'm' | 's' | 'S';\n\n/**\n * 比较两个日期在指定精度下是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @param sameSymbol - 比较精度,默认为 'D'(天,即年月日天都相同)\n * @returns 如果两个日期在指定精度下相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30, 45, 500);\n * const date2 = new Date(2023, 5, 15, 13, 30, 45, 500);\n *\n * // 比较年份\n * isSameDate(date1, date2, 'Y'); // true\n *\n * // 比较月份(年份也要相同)\n * isSameDate(date1, date2, 'M'); // true\n *\n * // 比较日期(默认,年份、月份也要相同)\n * isSameDate(date1, date2); // true\n *\n * // 比较小时(年、月、日也要相同)\n * isSameDate(date1, date2, 'h'); // false\n *\n * // 比较分钟(年、月、日、小时也要相同)\n * isSameDate(date1, date2, 'm'); // false\n *\n * // 比较秒(年、月、日、小时、分钟也要相同)\n * isSameDate(date1, date2, 's'); // false\n *\n * // 比较毫秒(年、月、日、小时、分钟、秒数也要相同)\n * isSameDate(date1, date2, 'S'); // false\n * ```\n */\nfunction _isSameDateIn(date1: TDateValue, date2: TDateValue, sameSymbol: _DateSameSymbol = 'D') {\n const defines = [\n ['Y', (d: TDateLike) => d.getFullYear()],\n ['M', (d: TDateLike) => d.getMonth()],\n ['D', (d: TDateLike) => d.getDate()],\n ['h', (d: TDateLike) => d.getHours()],\n ['m', (d: TDateLike) => d.getMinutes()],\n ['s', (d: TDateLike) => d.getSeconds()],\n ['S', (d: TDateLike) => d.getMilliseconds()],\n ] as const;\n\n const d1 = dateParse(date1);\n const d2 = dateParse(date2);\n\n for (const [sym, fn] of defines) {\n if (fn(d1) !== fn(d2)) {\n return false;\n }\n\n if (sym === sameSymbol) break;\n }\n\n return true;\n}\n\n/**\n * 比较两个日期的年份是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 6, 20);\n * isSameDateInYear(date1, date2); // true\n * ```\n */\nexport function isSameDateInYear(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'Y');\n}\n\n/**\n * 比较两个日期的年份和月份是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份和月份相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 5, 20);\n * isSameDateInMonth(date1, date2); // true\n * ```\n */\nexport function isSameDateInMonth(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'M');\n}\n\n/**\n * 比较两个日期的年份、月份和天数是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份和天数相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 5, 15);\n * isSameDateInDay(date1, date2); // true\n * ```\n */\nexport function isSameDateInDay(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'D');\n}\n\n/**\n * 比较两个日期的年份、月份、天数和小时是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数和小时相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12);\n * const date2 = new Date(2023, 5, 15, 12);\n * isSameDateInHour(date1, date2); // true\n * ```\n */\nexport function isSameDateInHour(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'h');\n}\n\n/**\n * 比较两个日期的年份、月份、天数、小时和分钟是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数、小时和分钟相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30);\n * const date2 = new Date(2023, 5, 15, 12, 30);\n * isSameDateInMinute(date1, date2); // true\n * ```\n */\nexport function isSameDateInMinute(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 'm');\n}\n\n/**\n * 比较两个日期的年份、月份、天数、小时、分钟和秒数是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数、小时、分钟和秒数相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30, 45);\n * const date2 = new Date(2023, 5, 15, 12, 30, 45);\n * isSameDateInSecond(date1, date2); // true\n * ```\n */\nexport function isSameDateInSecond(date1: TDateValue, date2: TDateValue) {\n return _isSameDateIn(date1, date2, 's');\n}\n","import { DATE_DAY_MS } from './const';\nimport { type TDateValue, dateParse } from './core';\n\nexport enum EWeekStart {\n /**\n * 周日作为一周的起始日\n */\n sunday = 0,\n /**\n * 周一作为一周的起始日\n */\n monday = 1,\n /**\n * 周二作为一周的起始日\n */\n tuesday = 2,\n /**\n * 周三作为一周的起始日\n */\n wednesday = 3,\n /**\n * 周四作为一周的起始日\n */\n thursday = 4,\n /**\n * 周五作为一周的起始日\n */\n friday = 5,\n /**\n * 周六作为一周的起始日\n */\n saturday = 6,\n // /**\n // * 1号所在的周为第一周\n // */\n // firstDate = 7,\n // /**\n // * 完整7天表示第一周\n // */\n // firstFullWeek = 8,\n}\n\n/**\n * 计算指定日期所在年份或月份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param type - 计算范围,'Y' 表示年份,'M' 表示月份\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在年份或月份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * _dateWeeks(date, 'Y'); // 1 (计算年份的周数)\n * _dateWeeks(date, 'M'); // 1 (计算月份的周数)\n * _dateWeeks(date, 'Y', 1); // 1 (周一作为一周的起始日,计算年份的周数)\n * ```\n */\nexport function _dateWeeks(dateValue: TDateValue, type: 'Y' | 'M', weekStart: EWeekStart = 0) {\n const date = dateParse(dateValue);\n\n const year = date.getFullYear();\n const month = date.getMonth();\n\n const firstDate = type === 'Y' ? new Date(year, 0, 1) : new Date(year, month, 1);\n const firstWeek = firstDate.getDay();\n const days = Math.ceil((date.getTime() - firstDate.getTime()) / DATE_DAY_MS);\n\n return Math.ceil((firstWeek + days - weekStart) / 7);\n}\n\n/**\n * 计算指定日期所在年份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在年份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * weeksOfYear(date); // 1\n * weeksOfYear(date, 1); // 1 (周一作为一周的起始日)\n * ```\n */\nexport function weeksOfYear(dateValue: TDateValue, weekStart: EWeekStart = 0) {\n return _dateWeeks(dateValue, 'Y', weekStart);\n}\n\n/**\n * 计算指定日期所在月份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在月份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * weeksOfMonth(date); // 1\n * weeksOfMonth(date, 1); // 1 (周一作为一周的起始日)\n * ```\n */\nexport function weeksOfMonth(dateValue: TDateValue, weekStart: EWeekStart = 0) {\n return _dateWeeks(dateValue, 'M', weekStart);\n}\n"],"names":["d","d2","EWeekStart"],"mappings":"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"}
1
+ {"version":3,"file":"date.mjs","sources":["../src/date/start-end.ts","../src/date/days.ts","../src/date/relative.ts","../src/date/is.ts","../src/date/weeks.ts"],"sourcesContent":["import { type DateLike, type DateValue, dateParse } from './core';\n\n/**\n * 时间单位符号枚举\n * - 'Y': 年\n * - 'M': 月\n * - 'D': 天\n * - 'W': 周\n * - 'h': 小时\n * - 'm': 分钟\n * - 's': 秒\n */\ntype _TDateOfSymbol = 'Y' | 'M' | 'D' | 'W' | 'h' | 'm' | 's';\n\n/**\n * 各时间单位起始时间映射表\n * 包含将日期设置到单位起始时间的函数\n */\nconst dateOfStartMap: [_TDateOfSymbol, (date: DateLike) => unknown][] = [\n ['s', (d) => d.setMilliseconds(0)],\n ['m', (d) => d.setSeconds(0)],\n ['h', (d) => d.setMinutes(0)],\n ['D', (d) => d.setHours(0)],\n ['W', (d) => d.setHours(0)],\n ['M', (d) => d.setDate(1)],\n ['Y', (d) => d.setMonth(0)],\n];\n\n/**\n * 返回指定时间单位的起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param symbol - 时间单位符号,可选值为 'Y'(年)、'M'(月)、'D'(天)、'h'(小时)、'm'(分钟)、's'(秒),默认为 'D'\n * @returns 返回指定时间单位的起始时间\n * @example\n * ```typescript\n * const date = new Date(2023, 5, 15, 12, 30, 45, 500); // 2023-06-15 12:30:45.500\n *\n * // 返回秒级起始时间\n * dateOfStart(date, 's'); // 2023-06-15 12:30:45.000\n *\n * // 返回分钟级起始时间\n * dateOfStart(date, 'm'); // 2023-06-15 12:30:00.000\n *\n * // 返回小时级起始时间\n * dateOfStart(date, 'h'); // 2023-06-15 12:00:00.000\n *\n * // 返回天级起始时间\n * dateOfStart(date, 'D'); // 2023-06-15 00:00:00.000\n *\n * // 返回月级起始时间\n * dateOfStart(date, 'M'); // 2023-06-01 00:00:00.000\n *\n * // 返回年级起始时间\n * dateOfStart(date, 'Y'); // 2023-01-01 00:00:00.000\n *\n * // 默认返回天级起始时间\n * dateOfStart(date); // 2023-06-15 00:00:00.000\n * ```\n */\nfunction _dateStart(dateValue: DateValue, symbol: _TDateOfSymbol = 'D') {\n const date = dateParse(dateValue);\n\n for (const [sym, fn] of dateOfStartMap) {\n fn(date);\n if (symbol === sym) break;\n }\n\n return date;\n}\n\n/**\n * 返回秒级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回秒级起始时间,毫秒部分为 0\n */\nexport function dateStartInSecond(dateValue: DateValue) {\n return _dateStart(dateValue, 's');\n}\n\n/**\n * 返回分钟级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回分钟级起始时间,秒和毫秒部分为 0\n */\nexport function dateStartInMinute(dateValue: DateValue) {\n return _dateStart(dateValue, 'm');\n}\n\n/**\n * 返回小时级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回小时级起始时间,分钟、秒和毫秒部分为 0\n */\nexport function dateStartInHour(dateValue: DateValue) {\n return _dateStart(dateValue, 'h');\n}\n\n/**\n * 返回天级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回天级起始时间,小时、分钟、秒和毫秒部分为 0\n */\nexport function dateStartInDay(dateValue: DateValue) {\n return _dateStart(dateValue, 'D');\n}\n\n/**\n * 返回月级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回月级起始时间,日期为当月第一天,时间部分为 0\n */\nexport function dateStartInMonth(dateValue: DateValue) {\n return _dateStart(dateValue, 'M');\n}\n\n/**\n * 返回年级起始时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回年级起始时间,月份为 1 月,日期为 1 日,时间部分为 0\n */\nexport function dateStartInYear(dateValue: DateValue) {\n return _dateStart(dateValue, 'Y');\n}\n\n/**\n * 各时间单位结束时间映射表\n * 包含将日期设置到单位结束时间的函数\n */\nconst dateOfEndMap: [_TDateOfSymbol, (date: DateLike) => unknown][] = [\n ['s', (d) => d.setMilliseconds(999)],\n ['m', (d) => d.setSeconds(59)],\n ['h', (d) => d.setMinutes(59)],\n ['D', (d) => d.setHours(23)],\n [\n 'M',\n (d) => {\n const d2 = dateParse(d);\n d2.setMonth(d.getMonth() + 1);\n d2.setDate(0);\n d.setDate(d2.getDate());\n },\n ],\n [\n 'Y',\n (d) => {\n d.setMonth(11);\n d.setDate(31);\n },\n ],\n];\n\n/**\n * 返回指定时间单位的结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param symbol - 时间单位符号,可选值为 'Y'(年)、'M'(月)、'D'(天)、'h'(小时)、'm'(分钟)、's'(秒),默认为 'D'\n * @returns 返回指定时间单位的结束时间\n * @example\n * ```typescript\n * const date = new Date(2023, 5, 15, 12, 30, 45, 500); // 2023-06-15 12:30:45.500\n *\n * // 返回秒级结束时间\n * dateOfEnd(date, 's'); // 2023-06-15 12:30:45.999\n *\n * // 返回分钟级结束时间\n * dateOfEnd(date, 'm'); // 2023-06-15 12:30:59.999\n *\n * // 返回小时级结束时间\n * dateOfEnd(date, 'h'); // 2023-06-15 12:59:59.999\n *\n * // 返回天级结束时间\n * dateOfEnd(date, 'D'); // 2023-06-15 23:59:59.999\n *\n * // 返回月级结束时间\n * dateOfEnd(date, 'M'); // 2023-06-30 23:59:59.999\n *\n * // 返回年级结束时间\n * dateOfEnd(date, 'Y'); // 2023-12-31 23:59:59.999\n *\n * // 默认返回天级结束时间\n * dateOfEnd(date); // 2023-06-15 23:59:59.999\n * ```\n */\nfunction _dateEnd(dateValue: DateValue, symbol: _TDateOfSymbol = 'D') {\n const date = dateParse(dateValue);\n\n for (const [sym, fn] of dateOfEndMap) {\n fn(date);\n if (symbol === sym) break;\n }\n\n return date;\n}\n\n/**\n * 返回秒级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回秒级结束时间,毫秒部分为 999\n */\nexport function dateEndInSecond(dateValue: DateValue) {\n return _dateEnd(dateValue, 's');\n}\n\n/**\n * 返回分钟级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回分钟级结束时间,秒为 59,毫秒为 999\n */\nexport function dateEndInMinute(dateValue: DateValue) {\n return _dateEnd(dateValue, 'm');\n}\n\n/**\n * 返回小时级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回小时级结束时间,分钟为 59,秒为 59,毫秒为 999\n */\nexport function dateEndInHour(dateValue: DateValue) {\n return _dateEnd(dateValue, 'h');\n}\n\n/**\n * 返回天级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回天级结束时间,小时为 23,分钟为 59,秒为 59,毫秒为 999\n */\nexport function dateEndInDay(dateValue: DateValue) {\n return _dateEnd(dateValue, 'D');\n}\n\n/**\n * 返回月级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回月级结束时间,日期为当月最后一天,时间为 23:59:59.999\n */\nexport function dateEndInMonth(dateValue: DateValue) {\n return _dateEnd(dateValue, 'M');\n}\n\n/**\n * 返回年级结束时间\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回年级结束时间,月份为 12 月,日期为 31 日,时间为 23:59:59.999\n */\nexport function dateEndInYear(dateValue: DateValue) {\n return _dateEnd(dateValue, 'Y');\n}\n","import { DATE_DAY_MS } from './const';\nimport { type DateValue, dateParse } from './core';\nimport { dateEndInMonth, dateEndInYear, dateStartInMonth, dateStartInYear } from './start-end';\n\n/**\n * 计算指定日期所在年或月的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param unit - 时间单位符号,可选值为 'Y'(年)、'M'(月),默认为 'M'\n * @returns 返回指定日期所在年或月的天数\n * @example\n * ```typescript\n * dateDays(new Date('2023-02-15')); // 28\n * dateDays(new Date('2024-02-15')); // 29 (闰年)\n * dateDays(new Date('2023-02-15'), 'Y'); // 365\n * dateDays(new Date('2024-02-15'), 'Y'); // 366 (闰年)\n * ```\n */\nfunction _dateDays(dateValue: DateValue, unit: 'Y' | 'M') {\n const d = dateParse(dateValue);\n const ds = unit === 'M' ? dateStartInMonth(d) : dateStartInYear(d);\n const de = unit === 'M' ? dateEndInMonth(d) : dateEndInYear(d);\n return Math.ceil((de.getTime() - ds.getTime()) / DATE_DAY_MS);\n}\n\n/**\n * 计算指定日期所在月份的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回指定日期所在月份的天数\n * @example\n * ```typescript\n * dateDaysInMonth(new Date('2023-02-15')); // 28\n * dateDaysInMonth(new Date('2024-02-15')); // 29 (闰年)\n * ```\n */\nexport function dateDaysInMonth(dateValue: DateValue) {\n return _dateDays(dateValue, 'M');\n}\n\n/**\n * 计算指定日期所在年份的天数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 返回指定日期所在年份的天数\n * @example\n * ```typescript\n * dateDaysInYear(new Date('2023-02-15')); // 365\n * dateDaysInYear(new Date('2024-02-15')); // 366 (闰年)\n * ```\n */\nexport function dateDaysInYear(dateValue: DateValue) {\n return _dateDays(dateValue, 'Y');\n}\n","import { stringFormat } from '@/string';\nimport { isArray } from '@/type';\nimport { type DateValue, dateFormat, dateParse } from './core';\n\nexport type DateRelativeTemplate = [\n number /*单位时间差,为 0 表示不计算单位差值,单位秒*/,\n number /*最大时间差,单位:秒*/,\n string /*过去模板字符串,%d 表述单位差值*/,\n string? /*将来模板字符串,%d 表述单位差值,可选*/,\n];\nexport type DateRelativeTemplates = DateRelativeTemplate[];\n\nconst defaultDiffTemplates: DateRelativeTemplates = [\n [0, 10, '刚刚'],\n [1, 60, '{n} 秒前', '{n} 秒后'],\n [60, 60 * 60, '{n} 分钟前', '{n} 分钟后'],\n [60 * 60, 60 * 60 * 24, '{n} 小时前', '{n} 小时后'],\n [0, 60 * 60 * 24 * 2, '昨天', '明天'],\n [0, 60 * 60 * 24 * 3, '前天', '后天'],\n [60 * 60 * 24, 60 * 60 * 24 * 30, '{n} 天前', '{n} 天后'],\n [0, Number.POSITIVE_INFINITY, 'YYYY年MM月DD日'],\n];\n\n/**\n * 相对时间\n * @param {DateValue} dateValue 比较的时间\n * @param {DateValue} [refDateValue] 相对的时间,默认为当前\n * @param {DateRelativeTemplates} [templates] 模板\n * @returns {string} 格式化后的相对时间字符串\n * @example\n * ```typescript\n * // 默认模板\n * dateRelative(new Date('2023-01-01')); // '刚刚'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-02')); // '昨天'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-04')); // '3 天前'\n * dateRelative(new Date('2023-01-01'), new Date('2023-02-01')); // '2023年01月01日'\n * ```\n * @example\n * ```typescript\n * // 自定义模板\n * const templates: DateRelativeTemplates = [\n * [0, 10, '刚刚'],\n * [1, 60, '{n} 秒前', '{n} 秒后'],\n * [60, 60 * 60, '{n} 分钟前', '{n} 分钟后'],\n * [60 * 60, 60 * 60 * 24, '{n} 小时前', '{n} 小时后'],\n * [0, 60 * 60 * 24 * 2, '昨天', '明天'],\n * [0, 60 * 60 * 24 * 3, '前天', '后天'],\n * [60 * 60 * 24, 60 * 60 * 24 * 30, '{n} 天前', '{n} 天后'],\n * [0, Number.POSITIVE_INFINITY, 'YYYY年MM月DD日'],\n * ];\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-02'), templates); // '昨天'\n * dateRelative(new Date('2023-01-01'), new Date('2023-01-04'), templates); // '3 天前'\n * dateRelative(new Date('2023-01-01'), new Date('2023-02-01'), templates); // '2023年01月01日'\n * ```\n */\nexport function dateRelative(dateValue: DateValue, refDateValue: DateValue, templates: DateRelativeTemplates): string;\nexport function dateRelative(dateValue: DateValue, refDateValue: DateValue): string;\nexport function dateRelative(dateValue: DateValue, templates: DateRelativeTemplates): string;\nexport function dateRelative(dateValue: DateValue): string;\nexport function dateRelative(\n dateValue: DateValue,\n refDateValue?: DateValue | DateRelativeTemplates,\n templates?: DateRelativeTemplates,\n): string {\n const now = Date.now();\n const refDateValueFinal = isArray(refDateValue) ? now : refDateValue || now;\n const templatesFinal = isArray(templates) ? templates : isArray(refDateValue) ? refDateValue : defaultDiffTemplates;\n const d1 = dateParse(dateValue);\n const d2 = dateParse(refDateValueFinal);\n const diff = d1.getTime() - d2.getTime();\n const isAgo = diff < 0;\n const absDiff = Math.abs(diff);\n let relative = '';\n\n for (const [base, max, agoTemplate, featureTemplate] of templatesFinal) {\n const unitFinal = base * 1000;\n const maxFinal = max * 1000;\n\n if (absDiff < maxFinal) {\n const template = isAgo ? agoTemplate : featureTemplate || agoTemplate;\n const length = unitFinal === 0 ? 0 : Math.max(Math.floor(absDiff / unitFinal), 1);\n relative = unitFinal === 0 ? dateFormat(dateValue, template) : stringFormat(template, { n: length });\n break;\n }\n }\n\n return relative;\n}\n","import { type DateLike, type DateValue, dateParse } from './core';\n\n/**\n * 判断给定的年份是否为闰年\n * @param year - 需要判断的年份\n * @returns 如果年份是闰年则返回 true,否则返回 false\n * @example\n * ```typescript\n * isLeapYear(2020); // true\n * isLeapYear(2021); // false\n * isLeapYear(2000); // true\n * isLeapYear(1900); // false\n * ```\n */\nexport function isLeapYear(year: number): boolean {\n if (year % 4 !== 0) return false;\n if (year % 100 !== 0) return true;\n if (year % 400 !== 0) return false;\n return true;\n}\n\n/**\n * 日期比较精度枚举类型\n * - Y = 年\n * - M = 月\n * - D = 天\n * - h = 小时\n * - m = 分钟\n * - s = 秒\n * - S = 毫秒\n */\ntype _DateSameSymbol = 'Y' | 'M' | 'D' | 'h' | 'm' | 's' | 'S';\n\n/**\n * 比较两个日期在指定精度下是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @param sameSymbol - 比较精度,默认为 'D'(天,即年月日天都相同)\n * @returns 如果两个日期在指定精度下相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30, 45, 500);\n * const date2 = new Date(2023, 5, 15, 13, 30, 45, 500);\n *\n * // 比较年份\n * isSameDate(date1, date2, 'Y'); // true\n *\n * // 比较月份(年份也要相同)\n * isSameDate(date1, date2, 'M'); // true\n *\n * // 比较日期(默认,年份、月份也要相同)\n * isSameDate(date1, date2); // true\n *\n * // 比较小时(年、月、日也要相同)\n * isSameDate(date1, date2, 'h'); // false\n *\n * // 比较分钟(年、月、日、小时也要相同)\n * isSameDate(date1, date2, 'm'); // false\n *\n * // 比较秒(年、月、日、小时、分钟也要相同)\n * isSameDate(date1, date2, 's'); // false\n *\n * // 比较毫秒(年、月、日、小时、分钟、秒数也要相同)\n * isSameDate(date1, date2, 'S'); // false\n * ```\n */\nfunction _isSameDateIn(date1: DateValue, date2: DateValue, sameSymbol: _DateSameSymbol = 'D') {\n const defines = [\n ['Y', (d: DateLike) => d.getFullYear()],\n ['M', (d: DateLike) => d.getMonth()],\n ['D', (d: DateLike) => d.getDate()],\n ['h', (d: DateLike) => d.getHours()],\n ['m', (d: DateLike) => d.getMinutes()],\n ['s', (d: DateLike) => d.getSeconds()],\n ['S', (d: DateLike) => d.getMilliseconds()],\n ] as const;\n\n const d1 = dateParse(date1);\n const d2 = dateParse(date2);\n\n for (const [sym, fn] of defines) {\n if (fn(d1) !== fn(d2)) {\n return false;\n }\n\n if (sym === sameSymbol) break;\n }\n\n return true;\n}\n\n/**\n * 比较两个日期的年份是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 6, 20);\n * isSameDateInYear(date1, date2); // true\n * ```\n */\nexport function isSameDateInYear(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'Y');\n}\n\n/**\n * 比较两个日期的年份和月份是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份和月份相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 5, 20);\n * isSameDateInMonth(date1, date2); // true\n * ```\n */\nexport function isSameDateInMonth(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'M');\n}\n\n/**\n * 比较两个日期的年份、月份和天数是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份和天数相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15);\n * const date2 = new Date(2023, 5, 15);\n * isSameDateInDay(date1, date2); // true\n * ```\n */\nexport function isSameDateInDay(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'D');\n}\n\n/**\n * 比较两个日期的年份、月份、天数和小时是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数和小时相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12);\n * const date2 = new Date(2023, 5, 15, 12);\n * isSameDateInHour(date1, date2); // true\n * ```\n */\nexport function isSameDateInHour(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'h');\n}\n\n/**\n * 比较两个日期的年份、月份、天数、小时和分钟是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数、小时和分钟相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30);\n * const date2 = new Date(2023, 5, 15, 12, 30);\n * isSameDateInMinute(date1, date2); // true\n * ```\n */\nexport function isSameDateInMinute(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 'm');\n}\n\n/**\n * 比较两个日期的年份、月份、天数、小时、分钟和秒数是否相同\n * @param date1 - 第一个日期,可以是数值、字符串或 Date 对象\n * @param date2 - 第二个日期,可以是数值、字符串或 Date 对象\n * @returns 如果两个日期的年份、月份、天数、小时、分钟和秒数相同则返回 true,否则返回 false\n * @example\n * ```typescript\n * const date1 = new Date(2023, 5, 15, 12, 30, 45);\n * const date2 = new Date(2023, 5, 15, 12, 30, 45);\n * isSameDateInSecond(date1, date2); // true\n * ```\n */\nexport function isSameDateInSecond(date1: DateValue, date2: DateValue) {\n return _isSameDateIn(date1, date2, 's');\n}\n","import { DATE_DAY_MS } from './const';\nimport { type DateValue, dateParse } from './core';\n\nexport enum EWeekStart {\n /**\n * 周日作为一周的起始日\n */\n sunday = 0,\n /**\n * 周一作为一周的起始日\n */\n monday = 1,\n /**\n * 周二作为一周的起始日\n */\n tuesday = 2,\n /**\n * 周三作为一周的起始日\n */\n wednesday = 3,\n /**\n * 周四作为一周的起始日\n */\n thursday = 4,\n /**\n * 周五作为一周的起始日\n */\n friday = 5,\n /**\n * 周六作为一周的起始日\n */\n saturday = 6,\n // /**\n // * 1号所在的周为第一周\n // */\n // firstDate = 7,\n // /**\n // * 完整7天表示第一周\n // */\n // firstFullWeek = 8,\n}\n\n/**\n * 计算指定日期所在年份或月份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param type - 计算范围,'Y' 表示年份,'M' 表示月份\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在年份或月份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * _dateWeeks(date, 'Y'); // 1 (计算年份的周数)\n * _dateWeeks(date, 'M'); // 1 (计算月份的周数)\n * _dateWeeks(date, 'Y', 1); // 1 (周一作为一周的起始日,计算年份的周数)\n * ```\n */\nexport function _dateWeeks(dateValue: DateValue, type: 'Y' | 'M', weekStart: EWeekStart = 0) {\n const date = dateParse(dateValue);\n\n const year = date.getFullYear();\n const month = date.getMonth();\n\n const firstDate = type === 'Y' ? new Date(year, 0, 1) : new Date(year, month, 1);\n const firstWeek = firstDate.getDay();\n const days = Math.ceil((date.getTime() - firstDate.getTime()) / DATE_DAY_MS);\n\n return Math.ceil((firstWeek + days - weekStart) / 7);\n}\n\n/**\n * 计算指定日期所在年份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在年份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * weeksOfYear(date); // 1\n * weeksOfYear(date, 1); // 1 (周一作为一周的起始日)\n * ```\n */\nexport function weeksOfYear(dateValue: DateValue, weekStart: EWeekStart = 0) {\n return _dateWeeks(dateValue, 'Y', weekStart);\n}\n\n/**\n * 计算指定日期所在月份的周数\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param weekStart - 一周的起始日,默认为 0(周日)\n * @returns 返回指定日期所在月份的周数\n * @example\n * ```typescript\n * const date = new Date(2023, 0, 1); // 2023-01-01\n * weeksOfMonth(date); // 1\n * weeksOfMonth(date, 1); // 1 (周一作为一周的起始日)\n * ```\n */\nexport function weeksOfMonth(dateValue: DateValue, weekStart: EWeekStart = 0) {\n return _dateWeeks(dateValue, 'M', weekStart);\n}\n"],"names":["d","d2","EWeekStart"],"mappings":"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"}
package/dist/enum.cjs CHANGED
@@ -36,7 +36,7 @@ function defineEnum(definition) {
36
36
  return acc;
37
37
  }, {});
38
38
  },
39
- toValueRecord(prop) {
39
+ toValRecord(prop) {
40
40
  return keys.reduce(
41
41
  (acc, key) => {
42
42
  acc[definition[key].value] = definition[key][prop];
package/dist/enum.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"enum.cjs","sources":["../src/enum.ts"],"sourcesContent":["import type { AnyObject, MergeIntersection, UnionToIntersection, UnionToTuple } from './types';\n\nexport type EnumKey = string;\nexport type EnumValue = number | string;\nexport type EnumMetaAppend = {\n key?: string;\n value?: string | number;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n [key: string]: any;\n};\nexport type EnumMeta<A extends EnumMetaAppend> = A & {\n value: EnumValue;\n};\nexport type EnumDescription<A extends EnumMetaAppend> = Record<EnumKey, EnumMeta<A>>;\n\nconst enumError = Symbol('enumKeyError');\n\ntype _StartWithDollarSign<T extends string> = T extends `$${infer R}` ? R : never;\n\ntype _CheckDefinition<O extends AnyObject> = {\n // [K in keyof O & string]: K extends Capitalize<K> ? O[K] : `错误:枚举键名 ${K} 必须大写字母开头`;\n [K in keyof O & string]: K extends Capitalize<K>\n ? K extends `$${infer R}`\n ? O[K] & { [enumError]: `错误:枚举键名 ${K} 不能以 $ 符号开头` }\n : O[K]\n : O[K] & { [enumError]: `错误:枚举键名 ${K} 必须以大写字母开头` };\n};\n\ntype _ToOriginDefProp<T extends AnyObject> = {\n [K in keyof T as `$${K & string}`]: MergeIntersection<T[K] & { readonly key: K }>;\n};\n\ntype _KVRecord<T> = T extends Record<string, AnyObject>\n ? {\n readonly [K in keyof T]: T[K]['value'];\n }\n : never;\n\ntype _VKRecord<T> = T extends Record<string, AnyObject>\n ? MergeIntersection<\n UnionToIntersection<\n {\n [K in keyof T]: {\n [P in keyof T[K] as P extends 'value' ? T[K][P] & (string | number) : never]: K;\n };\n }[keyof T]\n >\n >\n : never;\n\nexport type EnumExpose<A extends EnumMetaAppend, E extends EnumDescription<A>> = _ToOriginDefProp<E> &\n _KVRecord<E> & {\n readonly definition: E;\n readonly descriptions: MergeIntersection<A & { key: keyof E }>[];\n readonly keys: UnionToTuple<keyof E>;\n readonly length: UnionToTuple<keyof E>['length'];\n readonly values: UnionToTuple<E[keyof E]['value']>;\n readonly kvRecord: _KVRecord<E>;\n readonly vkRecord: _VKRecord<E>;\n toKeyRecord: <P extends keyof A>(prop: P) => Record<keyof E, A[P]>;\n toValueRecord: <P extends keyof A>(prop: P) => Record<E[keyof E]['value'], A[P]>;\n };\n\n/**\n * 定义一个枚举类型,如果需要类型提示,需要使用 declareEnum 函数定义枚举。\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @template E - 枚举描述类型,键为枚举键名,值为枚举元数据\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const Status = defineEnum({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n *\n * @property {E} definition - 原始枚举定义对象\n * @property {Array<MergeIntersection<A & { key: keyof E }>>} descriptions - 枚举项的完整描述数组\n * @property {UnionToTuple<keyof E>} keys - 枚举键名的元组\n * @property {\"UnionToTuple<keyof E>[\\\"length\\\"]\"} length - 枚举项的数量\n * @property {UnionToTuple<E[keyof E][\"value\"]>} values - 枚举值的元组\n * @property {Record<keyof E, E[keyof E][\"value\"]>} kvRecord - 键到值的映射记录\n * @property {Record<E[keyof E][\"value\"], E[keyof E]>} vkRecord - 值到键的映射记录\n * @property {function} toKeyRecord - 根据属性名创建键到属性值的映射记录\n * @property {function} toValueRecord - 根据属性名创建值到属性值的映射记录\n */\nfunction defineEnum<A extends EnumMetaAppend, const E extends EnumDescription<A>>(\n definition: _CheckDefinition<E>,\n): EnumExpose<A, E> {\n const keys = Object.keys(definition);\n\n return {\n ...[...Object.entries(definition)].reduce((acc, [key, dfn]) => {\n if (key[0].toUpperCase() !== key[0]) {\n throw new Error(`错误:枚举键名 ${key} 必须以大写字母开头`);\n }\n\n if (key.startsWith('$')) {\n throw new Error(`错误:枚举键名 ${key} 不能以 $ 符号开头`);\n }\n\n // @ts-ignore\n acc[key] = dfn.value;\n // @ts-ignore\n acc[`$${key}`] = { key, ...dfn };\n return acc;\n }, {}),\n definition,\n descriptions: keys.map((key) => ({\n key,\n ...definition[key],\n })),\n keys,\n length: keys.length,\n values: keys.map((key) => definition[key as keyof E].value),\n kvRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key].value;\n return acc;\n }, {}),\n vkRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = key;\n return acc;\n }, {}),\n toKeyRecord<P extends keyof A>(prop: P) {\n return keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key][prop];\n return acc;\n }, {});\n },\n toValueRecord<P extends keyof A>(prop: P) {\n return keys.reduce(\n (acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = definition[key][prop];\n return acc;\n },\n {} as Record<E[keyof E]['value'], A[P]>,\n );\n },\n } as unknown as EnumExpose<A, E>;\n}\n\n/**\n * 声明一个枚举工厂函数\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @returns {Object} 返回包含 define 方法的对象\n *\n * @property {function} define - 定义枚举的函数\n * @template E - 枚举描述类型\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const createStatusEnum = declareEnum<{ label: string }>();\n * const Status = createStatusEnum.define({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n */\nexport function declareEnum<A extends EnumMetaAppend>() {\n return {\n define<const E extends EnumDescription<A>>(definition: _CheckDefinition<E>): EnumExpose<A, E> {\n return defineEnum(definition);\n },\n };\n}\n"],"names":[],"mappings":";;AAuFA,SAAS,WACP,YACkB;AACZ,QAAA,OAAO,OAAO,KAAK,UAAU;AAE5B,SAAA;AAAA,IACL,GAAG,CAAC,GAAG,OAAO,QAAQ,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM;AAC7D,UAAI,IAAI,CAAC,EAAE,kBAAkB,IAAI,CAAC,GAAG;AACnC,cAAM,IAAI,MAAM,WAAW,GAAG,YAAY;AAAA,MAAA;AAGxC,UAAA,IAAI,WAAW,GAAG,GAAG;AACvB,cAAM,IAAI,MAAM,WAAW,GAAG,aAAa;AAAA,MAAA;AAIzC,UAAA,GAAG,IAAI,IAAI;AAEf,UAAI,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI;AACxB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL;AAAA,IACA,cAAc,KAAK,IAAI,CAAC,SAAS;AAAA,MAC/B;AAAA,MACA,GAAG,WAAW,GAAG;AAAA,IAAA,EACjB;AAAA,IACF;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK,IAAI,CAAC,QAAQ,WAAW,GAAc,EAAE,KAAK;AAAA,IAC1D,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,GAAG,IAAI,WAAW,GAAG,EAAE;AACpB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,WAAW,GAAG,EAAE,KAAK,IAAI;AACtB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,YAA+B,MAAS;AACtC,aAAO,KAAK,OAAO,CAAC,KAAK,QAAQ;AAE/B,YAAI,GAAG,IAAI,WAAW,GAAG,EAAE,IAAI;AACxB,eAAA;AAAA,MACT,GAAG,EAAE;AAAA,IACP;AAAA,IACA,cAAiC,MAAS;AACxC,aAAO,KAAK;AAAA,QACV,CAAC,KAAK,QAAQ;AAER,cAAA,WAAW,GAAG,EAAE,KAAK,IAAI,WAAW,GAAG,EAAE,IAAI;AAC1C,iBAAA;AAAA,QACT;AAAA,QACA,CAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AACF;AAoBO,SAAS,cAAwC;AAC/C,SAAA;AAAA,IACL,OAA2C,YAAmD;AAC5F,aAAO,WAAW,UAAU;AAAA,IAAA;AAAA,EAEhC;AACF;;"}
1
+ {"version":3,"file":"enum.cjs","sources":["../src/enum.ts"],"sourcesContent":["import type { AnyObject, MergeIntersection, UnionToIntersection, UnionToTuple } from './types';\n\nexport type EnumKey = string;\nexport type EnumValue = number | string;\nexport type EnumMetaAppend = {\n key?: string;\n value?: string | number;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n [key: string]: any;\n};\nexport type EnumMeta<A extends EnumMetaAppend> = A & {\n value: EnumValue;\n};\nexport type EnumDescription<A extends EnumMetaAppend> = Record<EnumKey, EnumMeta<A>>;\n\nconst enumError = Symbol('enumKeyError');\n\ntype _StartWithDollarSign<T extends string> = T extends `$${infer R}` ? R : never;\n\ntype _CheckDefinition<O extends AnyObject> = {\n // [K in keyof O & string]: K extends Capitalize<K> ? O[K] : `错误:枚举键名 ${K} 必须大写字母开头`;\n [K in keyof O & string]: K extends Capitalize<K>\n ? K extends `$${infer R}`\n ? O[K] & { [enumError]: `错误:枚举键名 ${K} 不能以 $ 符号开头` }\n : O[K]\n : O[K] & { [enumError]: `错误:枚举键名 ${K} 必须以大写字母开头` };\n};\n\ntype _ToOriginDefProp<T extends AnyObject> = {\n [K in keyof T as `$${K & string}`]: MergeIntersection<T[K] & { readonly key: K }>;\n};\n\ntype _KVRecord<T> = T extends Record<string, AnyObject>\n ? {\n readonly [K in keyof T]: T[K]['value'];\n }\n : never;\n\ntype _VKRecord<T> = T extends Record<string, AnyObject>\n ? MergeIntersection<\n UnionToIntersection<\n {\n [K in keyof T]: {\n [P in keyof T[K] as P extends 'value' ? T[K][P] & (string | number) : never]: K;\n };\n }[keyof T]\n >\n >\n : never;\n\nexport type EnumExpose<A extends EnumMetaAppend, E extends EnumDescription<A>> = _ToOriginDefProp<E> &\n _KVRecord<E> & {\n readonly definition: E;\n readonly descriptions: MergeIntersection<A & { key: keyof E }>[];\n readonly keys: UnionToTuple<keyof E>;\n readonly length: UnionToTuple<keyof E>['length'];\n readonly values: UnionToTuple<E[keyof E]['value']>;\n readonly kvRecord: _KVRecord<E>;\n readonly vkRecord: _VKRecord<E>;\n toKeyRecord: <P extends keyof A>(prop: P) => Record<keyof E, A[P]>;\n toValRecord: <P extends keyof A>(prop: P) => Record<E[keyof E]['value'], A[P]>;\n };\n\n/**\n * 定义一个枚举类型,如果需要类型提示,需要使用 declareEnum 函数定义枚举。\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @template E - 枚举描述类型,键为枚举键名,值为枚举元数据\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const Status = defineEnum({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n *\n * @property {E} definition - 原始枚举定义对象\n * @property {Array<MergeIntersection<A & { key: keyof E }>>} descriptions - 枚举项的完整描述数组\n * @property {UnionToTuple<keyof E>} keys - 枚举键名的元组\n * @property {\"UnionToTuple<keyof E>[\\\"length\\\"]\"} length - 枚举项的数量\n * @property {UnionToTuple<E[keyof E][\"value\"]>} values - 枚举值的元组\n * @property {Record<keyof E, E[keyof E][\"value\"]>} kvRecord - 键到值的映射记录\n * @property {Record<E[keyof E][\"value\"], E[keyof E]>} vkRecord - 值到键的映射记录\n * @property {function} toKeyRecord - 根据属性名创建键到属性值的映射记录\n * @property {function} toValueRecord - 根据属性名创建值到属性值的映射记录\n */\nfunction defineEnum<A extends EnumMetaAppend, const E extends EnumDescription<A>>(\n definition: _CheckDefinition<E>,\n): EnumExpose<A, E> {\n const keys = Object.keys(definition);\n\n return {\n ...[...Object.entries(definition)].reduce((acc, [key, dfn]) => {\n if (key[0].toUpperCase() !== key[0]) {\n throw new Error(`错误:枚举键名 ${key} 必须以大写字母开头`);\n }\n\n if (key.startsWith('$')) {\n throw new Error(`错误:枚举键名 ${key} 不能以 $ 符号开头`);\n }\n\n // @ts-ignore\n acc[key] = dfn.value;\n // @ts-ignore\n acc[`$${key}`] = { key, ...dfn };\n return acc;\n }, {}),\n definition,\n descriptions: keys.map((key) => ({\n key,\n ...definition[key],\n })),\n keys,\n length: keys.length,\n values: keys.map((key) => definition[key as keyof E].value),\n kvRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key].value;\n return acc;\n }, {}),\n vkRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = key;\n return acc;\n }, {}),\n toKeyRecord<P extends keyof A>(prop: P) {\n return keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key][prop];\n return acc;\n }, {});\n },\n toValRecord<P extends keyof A>(prop: P) {\n return keys.reduce(\n (acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = definition[key][prop];\n return acc;\n },\n {} as Record<E[keyof E]['value'], A[P]>,\n );\n },\n } as unknown as EnumExpose<A, E>;\n}\n\n/**\n * 声明一个枚举工厂函数\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @returns {Object} 返回包含 define 方法的对象\n *\n * @property {function} define - 定义枚举的函数\n * @template E - 枚举描述类型\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const createStatusEnum = declareEnum<{ label: string }>();\n * const Status = createStatusEnum.define({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n */\nexport function declareEnum<A extends EnumMetaAppend>() {\n return {\n define<const E extends EnumDescription<A>>(definition: _CheckDefinition<E>): EnumExpose<A, E> {\n return defineEnum(definition);\n },\n };\n}\n"],"names":[],"mappings":";;AAuFA,SAAS,WACP,YACkB;AACZ,QAAA,OAAO,OAAO,KAAK,UAAU;AAE5B,SAAA;AAAA,IACL,GAAG,CAAC,GAAG,OAAO,QAAQ,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM;AAC7D,UAAI,IAAI,CAAC,EAAE,kBAAkB,IAAI,CAAC,GAAG;AACnC,cAAM,IAAI,MAAM,WAAW,GAAG,YAAY;AAAA,MAAA;AAGxC,UAAA,IAAI,WAAW,GAAG,GAAG;AACvB,cAAM,IAAI,MAAM,WAAW,GAAG,aAAa;AAAA,MAAA;AAIzC,UAAA,GAAG,IAAI,IAAI;AAEf,UAAI,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI;AACxB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL;AAAA,IACA,cAAc,KAAK,IAAI,CAAC,SAAS;AAAA,MAC/B;AAAA,MACA,GAAG,WAAW,GAAG;AAAA,IAAA,EACjB;AAAA,IACF;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK,IAAI,CAAC,QAAQ,WAAW,GAAc,EAAE,KAAK;AAAA,IAC1D,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,GAAG,IAAI,WAAW,GAAG,EAAE;AACpB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,WAAW,GAAG,EAAE,KAAK,IAAI;AACtB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,YAA+B,MAAS;AACtC,aAAO,KAAK,OAAO,CAAC,KAAK,QAAQ;AAE/B,YAAI,GAAG,IAAI,WAAW,GAAG,EAAE,IAAI;AACxB,eAAA;AAAA,MACT,GAAG,EAAE;AAAA,IACP;AAAA,IACA,YAA+B,MAAS;AACtC,aAAO,KAAK;AAAA,QACV,CAAC,KAAK,QAAQ;AAER,cAAA,WAAW,GAAG,EAAE,KAAK,IAAI,WAAW,GAAG,EAAE,IAAI;AAC1C,iBAAA;AAAA,QACT;AAAA,QACA,CAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AACF;AAoBO,SAAS,cAAwC;AAC/C,SAAA;AAAA,IACL,OAA2C,YAAmD;AAC5F,aAAO,WAAW,UAAU;AAAA,IAAA;AAAA,EAEhC;AACF;;"}
package/dist/enum.d.ts CHANGED
@@ -42,7 +42,7 @@ export type EnumExpose<A extends EnumMetaAppend, E extends EnumDescription<A>> =
42
42
  readonly kvRecord: _KVRecord<E>;
43
43
  readonly vkRecord: _VKRecord<E>;
44
44
  toKeyRecord: <P extends keyof A>(prop: P) => Record<keyof E, A[P]>;
45
- toValueRecord: <P extends keyof A>(prop: P) => Record<E[keyof E]['value'], A[P]>;
45
+ toValRecord: <P extends keyof A>(prop: P) => Record<E[keyof E]['value'], A[P]>;
46
46
  };
47
47
  /**
48
48
  * 声明一个枚举工厂函数
package/dist/enum.mjs CHANGED
@@ -34,7 +34,7 @@ function defineEnum(definition) {
34
34
  return acc;
35
35
  }, {});
36
36
  },
37
- toValueRecord(prop) {
37
+ toValRecord(prop) {
38
38
  return keys.reduce(
39
39
  (acc, key) => {
40
40
  acc[definition[key].value] = definition[key][prop];
package/dist/enum.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"enum.mjs","sources":["../src/enum.ts"],"sourcesContent":["import type { AnyObject, MergeIntersection, UnionToIntersection, UnionToTuple } from './types';\n\nexport type EnumKey = string;\nexport type EnumValue = number | string;\nexport type EnumMetaAppend = {\n key?: string;\n value?: string | number;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n [key: string]: any;\n};\nexport type EnumMeta<A extends EnumMetaAppend> = A & {\n value: EnumValue;\n};\nexport type EnumDescription<A extends EnumMetaAppend> = Record<EnumKey, EnumMeta<A>>;\n\nconst enumError = Symbol('enumKeyError');\n\ntype _StartWithDollarSign<T extends string> = T extends `$${infer R}` ? R : never;\n\ntype _CheckDefinition<O extends AnyObject> = {\n // [K in keyof O & string]: K extends Capitalize<K> ? O[K] : `错误:枚举键名 ${K} 必须大写字母开头`;\n [K in keyof O & string]: K extends Capitalize<K>\n ? K extends `$${infer R}`\n ? O[K] & { [enumError]: `错误:枚举键名 ${K} 不能以 $ 符号开头` }\n : O[K]\n : O[K] & { [enumError]: `错误:枚举键名 ${K} 必须以大写字母开头` };\n};\n\ntype _ToOriginDefProp<T extends AnyObject> = {\n [K in keyof T as `$${K & string}`]: MergeIntersection<T[K] & { readonly key: K }>;\n};\n\ntype _KVRecord<T> = T extends Record<string, AnyObject>\n ? {\n readonly [K in keyof T]: T[K]['value'];\n }\n : never;\n\ntype _VKRecord<T> = T extends Record<string, AnyObject>\n ? MergeIntersection<\n UnionToIntersection<\n {\n [K in keyof T]: {\n [P in keyof T[K] as P extends 'value' ? T[K][P] & (string | number) : never]: K;\n };\n }[keyof T]\n >\n >\n : never;\n\nexport type EnumExpose<A extends EnumMetaAppend, E extends EnumDescription<A>> = _ToOriginDefProp<E> &\n _KVRecord<E> & {\n readonly definition: E;\n readonly descriptions: MergeIntersection<A & { key: keyof E }>[];\n readonly keys: UnionToTuple<keyof E>;\n readonly length: UnionToTuple<keyof E>['length'];\n readonly values: UnionToTuple<E[keyof E]['value']>;\n readonly kvRecord: _KVRecord<E>;\n readonly vkRecord: _VKRecord<E>;\n toKeyRecord: <P extends keyof A>(prop: P) => Record<keyof E, A[P]>;\n toValueRecord: <P extends keyof A>(prop: P) => Record<E[keyof E]['value'], A[P]>;\n };\n\n/**\n * 定义一个枚举类型,如果需要类型提示,需要使用 declareEnum 函数定义枚举。\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @template E - 枚举描述类型,键为枚举键名,值为枚举元数据\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const Status = defineEnum({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n *\n * @property {E} definition - 原始枚举定义对象\n * @property {Array<MergeIntersection<A & { key: keyof E }>>} descriptions - 枚举项的完整描述数组\n * @property {UnionToTuple<keyof E>} keys - 枚举键名的元组\n * @property {\"UnionToTuple<keyof E>[\\\"length\\\"]\"} length - 枚举项的数量\n * @property {UnionToTuple<E[keyof E][\"value\"]>} values - 枚举值的元组\n * @property {Record<keyof E, E[keyof E][\"value\"]>} kvRecord - 键到值的映射记录\n * @property {Record<E[keyof E][\"value\"], E[keyof E]>} vkRecord - 值到键的映射记录\n * @property {function} toKeyRecord - 根据属性名创建键到属性值的映射记录\n * @property {function} toValueRecord - 根据属性名创建值到属性值的映射记录\n */\nfunction defineEnum<A extends EnumMetaAppend, const E extends EnumDescription<A>>(\n definition: _CheckDefinition<E>,\n): EnumExpose<A, E> {\n const keys = Object.keys(definition);\n\n return {\n ...[...Object.entries(definition)].reduce((acc, [key, dfn]) => {\n if (key[0].toUpperCase() !== key[0]) {\n throw new Error(`错误:枚举键名 ${key} 必须以大写字母开头`);\n }\n\n if (key.startsWith('$')) {\n throw new Error(`错误:枚举键名 ${key} 不能以 $ 符号开头`);\n }\n\n // @ts-ignore\n acc[key] = dfn.value;\n // @ts-ignore\n acc[`$${key}`] = { key, ...dfn };\n return acc;\n }, {}),\n definition,\n descriptions: keys.map((key) => ({\n key,\n ...definition[key],\n })),\n keys,\n length: keys.length,\n values: keys.map((key) => definition[key as keyof E].value),\n kvRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key].value;\n return acc;\n }, {}),\n vkRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = key;\n return acc;\n }, {}),\n toKeyRecord<P extends keyof A>(prop: P) {\n return keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key][prop];\n return acc;\n }, {});\n },\n toValueRecord<P extends keyof A>(prop: P) {\n return keys.reduce(\n (acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = definition[key][prop];\n return acc;\n },\n {} as Record<E[keyof E]['value'], A[P]>,\n );\n },\n } as unknown as EnumExpose<A, E>;\n}\n\n/**\n * 声明一个枚举工厂函数\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @returns {Object} 返回包含 define 方法的对象\n *\n * @property {function} define - 定义枚举的函数\n * @template E - 枚举描述类型\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const createStatusEnum = declareEnum<{ label: string }>();\n * const Status = createStatusEnum.define({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n */\nexport function declareEnum<A extends EnumMetaAppend>() {\n return {\n define<const E extends EnumDescription<A>>(definition: _CheckDefinition<E>): EnumExpose<A, E> {\n return defineEnum(definition);\n },\n };\n}\n"],"names":[],"mappings":"AAuFA,SAAS,WACP,YACkB;AACZ,QAAA,OAAO,OAAO,KAAK,UAAU;AAE5B,SAAA;AAAA,IACL,GAAG,CAAC,GAAG,OAAO,QAAQ,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM;AAC7D,UAAI,IAAI,CAAC,EAAE,kBAAkB,IAAI,CAAC,GAAG;AACnC,cAAM,IAAI,MAAM,WAAW,GAAG,YAAY;AAAA,MAAA;AAGxC,UAAA,IAAI,WAAW,GAAG,GAAG;AACvB,cAAM,IAAI,MAAM,WAAW,GAAG,aAAa;AAAA,MAAA;AAIzC,UAAA,GAAG,IAAI,IAAI;AAEf,UAAI,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI;AACxB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL;AAAA,IACA,cAAc,KAAK,IAAI,CAAC,SAAS;AAAA,MAC/B;AAAA,MACA,GAAG,WAAW,GAAG;AAAA,IAAA,EACjB;AAAA,IACF;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK,IAAI,CAAC,QAAQ,WAAW,GAAc,EAAE,KAAK;AAAA,IAC1D,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,GAAG,IAAI,WAAW,GAAG,EAAE;AACpB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,WAAW,GAAG,EAAE,KAAK,IAAI;AACtB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,YAA+B,MAAS;AACtC,aAAO,KAAK,OAAO,CAAC,KAAK,QAAQ;AAE/B,YAAI,GAAG,IAAI,WAAW,GAAG,EAAE,IAAI;AACxB,eAAA;AAAA,MACT,GAAG,EAAE;AAAA,IACP;AAAA,IACA,cAAiC,MAAS;AACxC,aAAO,KAAK;AAAA,QACV,CAAC,KAAK,QAAQ;AAER,cAAA,WAAW,GAAG,EAAE,KAAK,IAAI,WAAW,GAAG,EAAE,IAAI;AAC1C,iBAAA;AAAA,QACT;AAAA,QACA,CAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AACF;AAoBO,SAAS,cAAwC;AAC/C,SAAA;AAAA,IACL,OAA2C,YAAmD;AAC5F,aAAO,WAAW,UAAU;AAAA,IAAA;AAAA,EAEhC;AACF;"}
1
+ {"version":3,"file":"enum.mjs","sources":["../src/enum.ts"],"sourcesContent":["import type { AnyObject, MergeIntersection, UnionToIntersection, UnionToTuple } from './types';\n\nexport type EnumKey = string;\nexport type EnumValue = number | string;\nexport type EnumMetaAppend = {\n key?: string;\n value?: string | number;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n [key: string]: any;\n};\nexport type EnumMeta<A extends EnumMetaAppend> = A & {\n value: EnumValue;\n};\nexport type EnumDescription<A extends EnumMetaAppend> = Record<EnumKey, EnumMeta<A>>;\n\nconst enumError = Symbol('enumKeyError');\n\ntype _StartWithDollarSign<T extends string> = T extends `$${infer R}` ? R : never;\n\ntype _CheckDefinition<O extends AnyObject> = {\n // [K in keyof O & string]: K extends Capitalize<K> ? O[K] : `错误:枚举键名 ${K} 必须大写字母开头`;\n [K in keyof O & string]: K extends Capitalize<K>\n ? K extends `$${infer R}`\n ? O[K] & { [enumError]: `错误:枚举键名 ${K} 不能以 $ 符号开头` }\n : O[K]\n : O[K] & { [enumError]: `错误:枚举键名 ${K} 必须以大写字母开头` };\n};\n\ntype _ToOriginDefProp<T extends AnyObject> = {\n [K in keyof T as `$${K & string}`]: MergeIntersection<T[K] & { readonly key: K }>;\n};\n\ntype _KVRecord<T> = T extends Record<string, AnyObject>\n ? {\n readonly [K in keyof T]: T[K]['value'];\n }\n : never;\n\ntype _VKRecord<T> = T extends Record<string, AnyObject>\n ? MergeIntersection<\n UnionToIntersection<\n {\n [K in keyof T]: {\n [P in keyof T[K] as P extends 'value' ? T[K][P] & (string | number) : never]: K;\n };\n }[keyof T]\n >\n >\n : never;\n\nexport type EnumExpose<A extends EnumMetaAppend, E extends EnumDescription<A>> = _ToOriginDefProp<E> &\n _KVRecord<E> & {\n readonly definition: E;\n readonly descriptions: MergeIntersection<A & { key: keyof E }>[];\n readonly keys: UnionToTuple<keyof E>;\n readonly length: UnionToTuple<keyof E>['length'];\n readonly values: UnionToTuple<E[keyof E]['value']>;\n readonly kvRecord: _KVRecord<E>;\n readonly vkRecord: _VKRecord<E>;\n toKeyRecord: <P extends keyof A>(prop: P) => Record<keyof E, A[P]>;\n toValRecord: <P extends keyof A>(prop: P) => Record<E[keyof E]['value'], A[P]>;\n };\n\n/**\n * 定义一个枚举类型,如果需要类型提示,需要使用 declareEnum 函数定义枚举。\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @template E - 枚举描述类型,键为枚举键名,值为枚举元数据\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const Status = defineEnum({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n *\n * @property {E} definition - 原始枚举定义对象\n * @property {Array<MergeIntersection<A & { key: keyof E }>>} descriptions - 枚举项的完整描述数组\n * @property {UnionToTuple<keyof E>} keys - 枚举键名的元组\n * @property {\"UnionToTuple<keyof E>[\\\"length\\\"]\"} length - 枚举项的数量\n * @property {UnionToTuple<E[keyof E][\"value\"]>} values - 枚举值的元组\n * @property {Record<keyof E, E[keyof E][\"value\"]>} kvRecord - 键到值的映射记录\n * @property {Record<E[keyof E][\"value\"], E[keyof E]>} vkRecord - 值到键的映射记录\n * @property {function} toKeyRecord - 根据属性名创建键到属性值的映射记录\n * @property {function} toValueRecord - 根据属性名创建值到属性值的映射记录\n */\nfunction defineEnum<A extends EnumMetaAppend, const E extends EnumDescription<A>>(\n definition: _CheckDefinition<E>,\n): EnumExpose<A, E> {\n const keys = Object.keys(definition);\n\n return {\n ...[...Object.entries(definition)].reduce((acc, [key, dfn]) => {\n if (key[0].toUpperCase() !== key[0]) {\n throw new Error(`错误:枚举键名 ${key} 必须以大写字母开头`);\n }\n\n if (key.startsWith('$')) {\n throw new Error(`错误:枚举键名 ${key} 不能以 $ 符号开头`);\n }\n\n // @ts-ignore\n acc[key] = dfn.value;\n // @ts-ignore\n acc[`$${key}`] = { key, ...dfn };\n return acc;\n }, {}),\n definition,\n descriptions: keys.map((key) => ({\n key,\n ...definition[key],\n })),\n keys,\n length: keys.length,\n values: keys.map((key) => definition[key as keyof E].value),\n kvRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key].value;\n return acc;\n }, {}),\n vkRecord: keys.reduce((acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = key;\n return acc;\n }, {}),\n toKeyRecord<P extends keyof A>(prop: P) {\n return keys.reduce((acc, key) => {\n // @ts-ignore\n acc[key] = definition[key][prop];\n return acc;\n }, {});\n },\n toValRecord<P extends keyof A>(prop: P) {\n return keys.reduce(\n (acc, key) => {\n // @ts-ignore\n acc[definition[key].value] = definition[key][prop];\n return acc;\n },\n {} as Record<E[keyof E]['value'], A[P]>,\n );\n },\n } as unknown as EnumExpose<A, E>;\n}\n\n/**\n * 声明一个枚举工厂函数\n * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend\n * @returns {Object} 返回包含 define 方法的对象\n *\n * @property {function} define - 定义枚举的函数\n * @template E - 枚举描述类型\n * @param {_CheckDefinition<E>} definition - 枚举定义对象\n * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象\n * @example\n * ```typescript\n * const createStatusEnum = declareEnum<{ label: string }>();\n * const Status = createStatusEnum.define({\n * Pending: { value: 0, label: '待处理' },\n * Approved: { value: 1, label: '已批准' }\n * });\n * ```\n */\nexport function declareEnum<A extends EnumMetaAppend>() {\n return {\n define<const E extends EnumDescription<A>>(definition: _CheckDefinition<E>): EnumExpose<A, E> {\n return defineEnum(definition);\n },\n };\n}\n"],"names":[],"mappings":"AAuFA,SAAS,WACP,YACkB;AACZ,QAAA,OAAO,OAAO,KAAK,UAAU;AAE5B,SAAA;AAAA,IACL,GAAG,CAAC,GAAG,OAAO,QAAQ,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM;AAC7D,UAAI,IAAI,CAAC,EAAE,kBAAkB,IAAI,CAAC,GAAG;AACnC,cAAM,IAAI,MAAM,WAAW,GAAG,YAAY;AAAA,MAAA;AAGxC,UAAA,IAAI,WAAW,GAAG,GAAG;AACvB,cAAM,IAAI,MAAM,WAAW,GAAG,aAAa;AAAA,MAAA;AAIzC,UAAA,GAAG,IAAI,IAAI;AAEf,UAAI,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI;AACxB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL;AAAA,IACA,cAAc,KAAK,IAAI,CAAC,SAAS;AAAA,MAC/B;AAAA,MACA,GAAG,WAAW,GAAG;AAAA,IAAA,EACjB;AAAA,IACF;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK,IAAI,CAAC,QAAQ,WAAW,GAAc,EAAE,KAAK;AAAA,IAC1D,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,GAAG,IAAI,WAAW,GAAG,EAAE;AACpB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,UAAU,KAAK,OAAO,CAAC,KAAK,QAAQ;AAElC,UAAI,WAAW,GAAG,EAAE,KAAK,IAAI;AACtB,aAAA;AAAA,IACT,GAAG,EAAE;AAAA,IACL,YAA+B,MAAS;AACtC,aAAO,KAAK,OAAO,CAAC,KAAK,QAAQ;AAE/B,YAAI,GAAG,IAAI,WAAW,GAAG,EAAE,IAAI;AACxB,eAAA;AAAA,MACT,GAAG,EAAE;AAAA,IACP;AAAA,IACA,YAA+B,MAAS;AACtC,aAAO,KAAK;AAAA,QACV,CAAC,KAAK,QAAQ;AAER,cAAA,WAAW,GAAG,EAAE,KAAK,IAAI,WAAW,GAAG,EAAE,IAAI;AAC1C,iBAAA;AAAA,QACT;AAAA,QACA,CAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AACF;AAoBO,SAAS,cAAwC;AAC/C,SAAA;AAAA,IACL,OAA2C,YAAmD;AAC5F,aAAO,WAAW,UAAU;AAAA,IAAA;AAAA,EAEhC;AACF;"}