Skip to content

Commit

Permalink
create FunctionalHoroscope class #31
Browse files Browse the repository at this point in the history
  • Loading branch information
SylarLong committed Oct 8, 2023
1 parent 73897c9 commit 0214f44
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 6 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
- 🛠️ 修复(fix)
- 🧹 琐事(Chore)

## v1.3.0

- 🪄 功能(feature)

🇨🇳

- 创建FunctionalHoroscope类 #31

🇺🇸

- create FunctionalHoroscope class #31

## v1.2.7-alpha

- ✨ 改进(enhancement)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "iztro",
"version": "1.2.7-alpha",
"version": "1.3.0",
"description": "轻量级紫微斗数星盘生成库。可以通过出生年月日获取到紫微斗数星盘信息、生肖、星座等信息。A lightweight kit to astrolabe generator of The Purple Star Astrology (Zi Wei Dou Shu). The Purple Star Astrology(Zi Wei Dou Shu) is a Chinese ancient astrology. You're able to get your horoscope and personality from the astrolabe",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
83 changes: 83 additions & 0 deletions src/__tests__/astro/astro.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,93 @@ describe('Astrolabe', () => {
]);
expect(horoscope.hourly).toHaveProperty('mutagen', ['天同', '天机', '文昌', '廉贞']);

expect(horoscope.hasHoroscopeStars('疾厄', 'decadal', ['流陀', '流曲', '运昌'])).toBe(true);
expect(horoscope.hasHoroscopeStars('财帛', 'yearly', ['流陀', '流曲', '运昌'])).toBe(true);
expect(horoscope.hasHoroscopeStars('迁移', 'monthly', ['流陀', '流曲', '运昌'])).toBe(true);
expect(horoscope.hasHoroscopeStars('田宅', 'daily', ['流陀', '流曲', '运昌'])).toBe(true);

const agePalace = horoscope.agePalace();

expect(agePalace).toHaveProperty('name', '迁移');
expect(agePalace).toHaveProperty('heavenlyStem', '戊');
expect(agePalace).toHaveProperty('earthlyBranch', '子');

const originalPalace = horoscope.palace('命宫', 'origin');

expect(originalPalace).toHaveProperty('name', '命宫');
expect(originalPalace).toHaveProperty('heavenlyStem', '壬');
expect(originalPalace).toHaveProperty('earthlyBranch', '午');

const decadalPalace = horoscope.palace('命宫', 'decadal');

expect(decadalPalace).toHaveProperty('name', '夫妻');
expect(decadalPalace).toHaveProperty('heavenlyStem', '庚');
expect(decadalPalace).toHaveProperty('earthlyBranch', '辰');

const decadalSurpalaces = horoscope.surroundPalaces('命宫', 'decadal');

expect(decadalSurpalaces.target).toHaveProperty('name', '夫妻');
expect(decadalSurpalaces.target).toHaveProperty('heavenlyStem', '庚');
expect(decadalSurpalaces.target).toHaveProperty('earthlyBranch', '辰');
expect(decadalSurpalaces.opposite).toHaveProperty('name', '官禄');
expect(decadalSurpalaces.opposite).toHaveProperty('heavenlyStem', '丙');
expect(decadalSurpalaces.opposite).toHaveProperty('earthlyBranch', '戌');
expect(decadalSurpalaces.career).toHaveProperty('name', '福德');
expect(decadalSurpalaces.career).toHaveProperty('heavenlyStem', '甲');
expect(decadalSurpalaces.career).toHaveProperty('earthlyBranch', '申');
expect(decadalSurpalaces.wealth).toHaveProperty('name', '迁移');
expect(decadalSurpalaces.wealth).toHaveProperty('heavenlyStem', '戊');
expect(decadalSurpalaces.wealth).toHaveProperty('earthlyBranch', '子');

const originalSurpalaces = horoscope.surroundPalaces('夫妻', 'origin');

expect(originalSurpalaces.target).toHaveProperty('name', '夫妻');
expect(originalSurpalaces.target).toHaveProperty('heavenlyStem', '庚');
expect(originalSurpalaces.target).toHaveProperty('earthlyBranch', '辰');
expect(originalSurpalaces.opposite).toHaveProperty('name', '官禄');
expect(originalSurpalaces.opposite).toHaveProperty('heavenlyStem', '丙');
expect(originalSurpalaces.opposite).toHaveProperty('earthlyBranch', '戌');
expect(originalSurpalaces.career).toHaveProperty('name', '福德');
expect(originalSurpalaces.career).toHaveProperty('heavenlyStem', '甲');
expect(originalSurpalaces.career).toHaveProperty('earthlyBranch', '申');
expect(originalSurpalaces.wealth).toHaveProperty('name', '迁移');
expect(originalSurpalaces.wealth).toHaveProperty('heavenlyStem', '戊');
expect(originalSurpalaces.wealth).toHaveProperty('earthlyBranch', '子');

const yearlyPalace = horoscope.palace('命宫', 'yearly');

expect(yearlyPalace).toHaveProperty('name', '子女');
expect(yearlyPalace).toHaveProperty('heavenlyStem', '己');
expect(yearlyPalace).toHaveProperty('earthlyBranch', '卯');

const monthlyPalace = horoscope.palace('命宫', 'monthly');

expect(monthlyPalace).toHaveProperty('name', '兄弟');
expect(monthlyPalace).toHaveProperty('heavenlyStem', '辛');
expect(monthlyPalace).toHaveProperty('earthlyBranch', '巳');

const dailyPalace = horoscope.palace('命宫', 'daily');

expect(dailyPalace).toHaveProperty('name', '福德');
expect(dailyPalace).toHaveProperty('heavenlyStem', '甲');
expect(dailyPalace).toHaveProperty('earthlyBranch', '申');

const hourlyPalace = horoscope.palace('命宫', 'hourly');

expect(hourlyPalace).toHaveProperty('name', '官禄');
expect(hourlyPalace).toHaveProperty('heavenlyStem', '丙');
expect(hourlyPalace).toHaveProperty('earthlyBranch', '戌');

const horoscope2 = result.horoscope('2023-10-19 3:12');

expect(horoscope2.age).toHaveProperty('index', 9);
expect(horoscope2.age).toHaveProperty('nominalAge', 24);

const agePalace2 = horoscope2.agePalace();

expect(agePalace2).toHaveProperty('name', '仆役');
expect(agePalace2).toHaveProperty('heavenlyStem', '丁');
expect(agePalace2).toHaveProperty('earthlyBranch', '亥');
});

test('astrolabeBySolarDate() Korean', () => {
Expand Down
7 changes: 4 additions & 3 deletions src/astro/FunctionalAstrolabe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getPalace, getSurroundedPalaces } from './analyzer';
import { IFunctionalPalace } from './FunctionalPalace';
import { IFunctionalSurpalaces } from './FunctionalSurpalaces';
import { getPalaceNames } from './palace';
import FunctionalHoroscope from './FunctionalHoroscope';

/**
* 获取运限数据
Expand All @@ -24,10 +25,10 @@ import { getPalaceNames } from './palace';
* @returns 运限数据
*/
const _getHoroscopeBySolarDate = (
$: Astrolabe,
$: FunctionalAstrolabe,
targetDate: string | Date = new Date(),
timeIndex?: number,
): Horoscope => {
): FunctionalHoroscope => {
const _birthday = solar2lunar($.solarDate);
const _date = solar2lunar(targetDate);
const convertTimeIndex = timeToIndex(dayjs(targetDate).hour());
Expand Down Expand Up @@ -152,7 +153,7 @@ const _getHoroscopeBySolarDate = (
},
};

return scope;
return new FunctionalHoroscope(scope, $);
};

/**
Expand Down
129 changes: 129 additions & 0 deletions src/astro/FunctionalHoroscope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { Horoscope, Scope } from '../data/types';
import { PalaceName, StarKey, StarName, kot } from '../i18n';
import { IFunctionalAstrolabe } from './FunctionalAstrolabe';
import { FunctionalSurpalaces } from './FunctionalSurpalaces';
import FunctionalPalace from './FunctionalPalace';
import { mergeStars } from '../utils';

export interface IFunctionalHoroscope extends Horoscope {
/**
* 获取小限宫位
*
* @version v1.3.0
*
* @returns {FunctionalPalace | undefined} 小限宫位
*/
agePalace: () => FunctionalPalace | undefined;

/**
* 获取运限宫位
*
* @version v1.3.0
*
* @param palaceName 宫位名称
* @param scope 指定获取哪个运限的宫位
* @returns {FunctionalPalace | undefined} 指定宫位
*/
palace: (palaceName: PalaceName, scope: Scope) => FunctionalPalace | undefined;

/**
* 获取运限指定宫位的三方四正宫位
*
* @version v1.3.0
*
* @param palaceName 宫位名称
* @param scope 指定获取哪个运限的宫位
* @returns {FunctionalSurpalaces | undefined} 指定宫位的三方四正
*/
surroundPalaces: (palaceName: PalaceName, scope: Scope) => FunctionalSurpalaces | undefined;

/**
* 判断在指定运限的宫位内是否包含流耀,需要全部包含才返回true
*
* @version v1.3.0
*
* @param palaceName 宫位名称
* @param scope 指定获取哪个运限的宫位
* @param horoscopeStar
* @returns {boolean} 是否包含指定流耀
*/
hasHoroscopeStars: (palaceName: PalaceName, scope: Scope, horoscopeStar: StarName[]) => boolean;
}

export default class FunctionalHoroscope implements IFunctionalHoroscope {
lunarDate;
solarDate;
decadal;
age;
yearly;
monthly;
daily;
hourly;
astrolabe;

constructor(data: Horoscope, astrolabe: IFunctionalAstrolabe) {
this.lunarDate = data.lunarDate;
this.solarDate = data.solarDate;
this.decadal = data.decadal;
this.age = data.age;
this.yearly = data.yearly;
this.monthly = data.monthly;
this.daily = data.daily;
this.hourly = data.hourly;
this.astrolabe = astrolabe;

return this;
}

agePalace = () => {
return this.astrolabe.palace(this.age.index);
};

palace = (palaceName: PalaceName, scope: Scope) => {
if (scope === 'origin') {
return this.astrolabe.palace(palaceName);
}

const targetPalaceindex = this[scope].palaceNames.indexOf(palaceName);

return this.astrolabe.palace(targetPalaceindex);
};

surroundPalaces = (palaceName: PalaceName, scope: Scope) => {
if (scope === 'origin') {
return this.astrolabe.surroundedPalaces(palaceName);
}

const targetPalaceindex = this[scope].palaceNames.indexOf(palaceName);

return this.astrolabe.surroundedPalaces(targetPalaceindex);
};

hasHoroscopeStars = (palaceName: PalaceName, scope: Scope, horoscopeStar: StarName[]) => {
let palaceIndex = -1;

if (!this.decadal.stars || !this.yearly.stars) {
return false;
}

if (scope === 'origin') {
this.astrolabe.palaces.some((p, idx) => {
if (p.name === palaceName) {
palaceIndex = idx;

return true;
}

return false;
});
} else {
palaceIndex = this[scope].palaceNames.indexOf(palaceName);
}

const stars = mergeStars(this.decadal.stars, this.yearly.stars)[palaceIndex];
const starKeys = stars.map((item) => kot<StarKey>(item.name));
const horoscopeStarKeys = horoscopeStar.map((item) => kot<StarKey>(item));

return horoscopeStarKeys.every((star) => starKeys.includes(star));
};
}
4 changes: 2 additions & 2 deletions src/data/types/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export type ChineseTime = (typeof CHINESE_TIME)[number];
/** 时辰对应的时间段 */
export type TimeRange = (typeof TIME_RANGE)[number];

/** 范围:本命|大限|流年 */
export type Scope = 'origin' | 'decadal' | 'yearly';
/** 范围:本命|大限|流年|流月|流日|流时 */
export type Scope = 'origin' | 'decadal' | 'yearly' | 'monthly' | 'daily' | 'hourly';

/** 星耀类型 */
export type StarType = 'major' | 'soft' | 'tough' | 'adjective' | 'flower' | 'helper' | 'lucun' | 'tianma';

0 comments on commit 0214f44

Please sign in to comment.