Skip to content

Commit faddc2e

Browse files
authored
Merge pull request #178 from SylarLong/feat-165
Feat: global configuration & plugin support
2 parents 8034c2d + 2f7bfda commit faddc2e

File tree

8 files changed

+232
-22
lines changed

8 files changed

+232
-22
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@
77
- 🛠️ 修复(fix)
88
- 🧹 琐事(Chore)
99

10+
## v2.3.0
11+
12+
- 🪄 功能(feature)
13+
14+
🇨🇳
15+
16+
- 支持全局插件 #165
17+
- 支持全局配置 #165
18+
19+
🇺🇸
20+
21+
- support global plugin #165
22+
- support global configuration #165
23+
1024
## v2.2.3
1125

1226
- 🛠️ 修复(fix)

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "iztro",
3-
"version": "2.2.3",
3+
"version": "2.3.0",
44
"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",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",
@@ -71,6 +71,6 @@
7171
"dependencies": {
7272
"dayjs": "^1.11.10",
7373
"i18next": "^23.5.1",
74-
"lunar-lite": "^0.1.1"
74+
"lunar-lite": "^0.1.2"
7575
}
7676
}

src/__tests__/astro/plugin.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { astro } from '../..';
2+
import FunctionalAstrolabe from '../../astro/FunctionalAstrolabe';
3+
4+
export interface IAstrolabe extends FunctionalAstrolabe {
5+
myNewFunc: () => string;
6+
majorStar: () => string;
7+
}
8+
9+
// 创建一个插件函数
10+
export function myTestPlugin(this: IAstrolabe): void {
11+
// 实现插件应用逻辑
12+
this.myNewFunc = () => {
13+
return this.fiveElementsClass;
14+
};
15+
}
16+
17+
// 创建二个插件函数
18+
export function myTestPlugin2(this: IAstrolabe): void {
19+
// 实现插件应用逻辑
20+
this.majorStar = () => {
21+
let stars = this.palace('命宫')
22+
?.majorStars.filter((item) => item.type === 'major' && !['禄存', '天马'].includes(item.name))
23+
.map((item) => item.name)
24+
.join(',');
25+
26+
if (!stars) {
27+
stars = this.palace('迁移')
28+
?.majorStars.filter((item) => item.type === 'major' && !['禄存', '天马'].includes(item.name))
29+
.map((item) => item.name)
30+
.join(',');
31+
}
32+
33+
return stars ?? '';
34+
};
35+
}
36+
37+
astro.loadPlugins([myTestPlugin]);
38+
astro.loadPlugin(myTestPlugin2);
39+
40+
astro.config({
41+
mutagens: { : ['太阳', '武曲', '天同', '天相'] },
42+
brightness: {
43+
贪狼: ['旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺', '旺'],
44+
},
45+
});
46+
47+
describe('plugin test', () => {
48+
test('plugin', () => {
49+
const astrolabe = astro.bySolar<IAstrolabe>('2023-10-18', 4, 'female');
50+
51+
expect(astrolabe.myNewFunc()).toEqual('火六局');
52+
expect(astrolabe.majorStar()).toEqual('七杀');
53+
});
54+
55+
test('changed configuration', () => {
56+
const astrolabe = astro.bySolar<IAstrolabe>('2010-10-18', 4, 'female');
57+
58+
expect(astrolabe.palace('命宫')?.hasMutagen('忌')).toBeFalsy();
59+
expect(astrolabe.palace('夫妻')?.hasMutagen('忌')).toBeTruthy();
60+
expect(astrolabe.star('贪狼').withBrightness('旺')).toBeTruthy();
61+
});
62+
63+
test('not changed configuration', () => {
64+
const astrolabe = astro.bySolar<IAstrolabe>('2011-10-18', 4, 'female');
65+
66+
expect(astrolabe.palace('命宫')?.hasMutagen('权')).toBeTruthy();
67+
expect(astrolabe.palace('命宫')?.hasMutagen('忌')).toBeTruthy();
68+
expect(astrolabe.palace('福德')?.hasMutagen('科')).toBeTruthy();
69+
expect(astrolabe.palace('田宅')?.hasMutagen('禄')).toBeFalsy();
70+
expect(astrolabe.palace('财帛')?.fliesTo('夫妻', '科')).toBeTruthy();
71+
expect(astrolabe.palace('财帛')?.fliesTo('仆役', '忌')).toBeTruthy();
72+
expect(astrolabe.star('紫微').withBrightness('旺')).toBeTruthy();
73+
});
74+
});

src/astro/FunctionalAstrolabe.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import dayjs from 'dayjs';
22
import { getHeavenlyStemAndEarthlyBranchBySolarDate, normalizeDateStr, solar2lunar } from 'lunar-lite';
33
import { EARTHLY_BRANCHES } from '../data';
4-
import { Astrolabe, Horoscope } from '../data/types';
4+
import { Astrolabe, Horoscope, Plugin } from '../data/types';
55
import { EarthlyBranchKey, EarthlyBranchName, HeavenlyStemName, kot, PalaceName, StarKey, StarName, t } from '../i18n';
66
import { getHoroscopeStar, getYearly12 } from '../star';
77
import { IFunctionalStar } from '../star/FunctionalStar';
@@ -192,6 +192,14 @@ const _getHoroscopeBySolarDate = (
192192
* 文档地址:https://docs.iztro.com/posts/astrolabe.html#functionalastrolabe
193193
*/
194194
export interface IFunctionalAstrolabe extends Astrolabe {
195+
/**
196+
* 插件注入方法
197+
*
198+
* @version v2.3.0
199+
*
200+
* @param plugin 插件函数
201+
*/
202+
use(plugin: Plugin): void;
195203
/**
196204
* 获取运限数据
197205
*
@@ -292,6 +300,9 @@ export default class FunctionalAstrolabe implements IFunctionalAstrolabe {
292300
fiveElementsClass;
293301
palaces;
294302

303+
// 保存插件列表
304+
private plugins: Plugin[] = [];
305+
295306
constructor(data: Astrolabe) {
296307
this.gender = data.gender;
297308
this.solarDate = data.solarDate;
@@ -312,6 +323,11 @@ export default class FunctionalAstrolabe implements IFunctionalAstrolabe {
312323
return this;
313324
}
314325

326+
use(plugin: Plugin): void {
327+
this.plugins.push(plugin);
328+
plugin.apply(this);
329+
}
330+
315331
star = (starName: StarName): IFunctionalStar => {
316332
let targetStar: IFunctionalStar | undefined;
317333

src/astro/astro.ts

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,75 @@
11
import { getHeavenlyStemAndEarthlyBranchBySolarDate, getSign, getZodiac, lunar2solar, solar2lunar } from 'lunar-lite';
22
import { CHINESE_TIME, EARTHLY_BRANCHES, HEAVENLY_STEMS, TIME_RANGE, earthlyBranches } from '../data';
3-
import { Language } from '../data/types';
4-
import { EarthlyBranchKey, EarthlyBranchName, GenderName, HeavenlyStemKey, kot, setLanguage, t } from '../i18n';
3+
import { Config, Language, Plugin } from '../data/types';
4+
import {
5+
BrightnessKey,
6+
EarthlyBranchKey,
7+
EarthlyBranchName,
8+
GenderName,
9+
HeavenlyStemKey,
10+
StarKey,
11+
kot,
12+
setLanguage,
13+
t,
14+
} from '../i18n';
515
import { getAdjectiveStar, getBoShi12, getchangsheng12, getMajorStar, getMinorStar, getYearly12 } from '../star';
616
import { fixIndex, translateChineseDate } from '../utils';
717
import FunctionalAstrolabe from './FunctionalAstrolabe';
818
import FunctionalPalace, { IFunctionalPalace } from './FunctionalPalace';
919
import { getPalaceNames, getSoulAndBody, getHoroscope, getFiveElementsClass } from './palace';
1020

21+
const _plugins = [] as Plugin[];
22+
const _mutagens: Partial<Record<HeavenlyStemKey, StarKey[]>> = {};
23+
const _brightness: Partial<Record<StarKey, BrightnessKey[]>> = {};
24+
25+
/**
26+
* 批量加载插件
27+
*
28+
* @version v2.3.0
29+
*
30+
* @param plugins 插件方法数组
31+
*/
32+
export const loadPlugins = (plugins: Plugin[]) => {
33+
Array.prototype.push.apply(_plugins, plugins);
34+
};
35+
36+
/**
37+
* 加载单个插件
38+
*
39+
* @version v2.3.0
40+
*
41+
* @param plugin 插件方法
42+
*/
43+
export const loadPlugin = (plugin: Plugin) => {
44+
_plugins.push(plugin);
45+
};
46+
47+
/**
48+
* 全局配置四化和亮度
49+
*
50+
* 由于key和value都有可能是不同语言传进来的,
51+
* 所以需会将key和value转化为对应的i18n key。
52+
*
53+
* @version 2.3.0
54+
*
55+
* @param {Config} param0 自定义配置
56+
*/
57+
export const config = ({ mutagens, brightness }: Config) => {
58+
if (mutagens) {
59+
Object.entries(mutagens).forEach(([key, value]) => {
60+
_mutagens[kot<HeavenlyStemKey>(key)] = value.map((item) => kot<StarKey>(item)) ?? [];
61+
});
62+
}
63+
64+
if (brightness) {
65+
Object.entries(brightness).forEach(([key, value]) => {
66+
_brightness[kot<StarKey>(key)] = value.map((item) => kot<BrightnessKey>(item)) ?? [];
67+
});
68+
}
69+
};
70+
71+
export const getConfig = () => ({ mutagens: _mutagens, brightness: _brightness });
72+
1173
/**
1274
* 通过阳历获取星盘信息
1375
*
@@ -40,13 +102,13 @@ export const astrolabeBySolarDate = (
40102
* @param language 输出语言
41103
* @returns 星盘信息
42104
*/
43-
export const bySolar = (
105+
export function bySolar<T extends FunctionalAstrolabe>(
44106
solarDateStr: string,
45107
timeIndex: number,
46108
gender: GenderName,
47109
fixLeap: boolean = true,
48110
language?: Language,
49-
) => {
111+
): T {
50112
language && setLanguage(language);
51113

52114
const palaces: IFunctionalPalace[] = [];
@@ -121,8 +183,10 @@ export const bySolar = (
121183
palaces,
122184
});
123185

124-
return result;
125-
};
186+
_plugins.map((plugin) => result.use(plugin));
187+
188+
return result as T;
189+
}
126190

127191
/**
128192
* 通过农历获取星盘信息

src/data/types/astro.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { IFunctionalPalace } from '../../astro/FunctionalPalace';
2-
import { EarthlyBranchName, FiveElementsClassName, HeavenlyStemName, PalaceName, StarName } from '../../i18n';
2+
import {
3+
Brightness,
4+
EarthlyBranchName,
5+
FiveElementsClassName,
6+
HeavenlyStemName,
7+
PalaceName,
8+
StarName,
9+
} from '../../i18n';
310
import FunctionalStar from '../../star/FunctionalStar';
411
import { HeavenlyStemAndEarthlyBranchDate, LunarDate } from 'lunar-lite/lib/types';
512

@@ -150,3 +157,16 @@ export type Astrolabe = {
150157
/** 十二宫数据 */
151158
palaces: IFunctionalPalace[];
152159
};
160+
161+
/**
162+
* 定义一个接口,表示插件函数的类型
163+
* */
164+
export type Plugin = () => void;
165+
166+
export type ConfigMutagens = Partial<Record<HeavenlyStemName, StarName[]>>;
167+
export type ConfigBrightness = Partial<Record<StarName, Brightness[]>>;
168+
169+
export type Config = {
170+
mutagens?: ConfigMutagens;
171+
brightness?: ConfigBrightness;
172+
};

src/utils/index.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ import {
1515
import FunctionalStar from '../star/FunctionalStar';
1616
import { HeavenlyStemAndEarthlyBranchDate } from 'lunar-lite/lib/types';
1717
import { solar2lunar } from 'lunar-lite';
18+
import { getConfig } from '../astro';
19+
20+
const getTargetMutagens = (heavenlyStem: HeavenlyStemKey) => {
21+
const { mutagens } = getConfig();
22+
let result;
23+
24+
if (mutagens && mutagens[heavenlyStem]) {
25+
result = mutagens[heavenlyStem] ?? [];
26+
} else {
27+
result = heavenlyStems[heavenlyStem].mutagen ?? [];
28+
}
29+
30+
return result;
31+
};
1832

1933
/**
2034
* 用于处理索引,将索引锁定在 0~max 范围内
@@ -58,21 +72,29 @@ export const earthlyBranchIndexToPalaceIndex = (earthlyBranchName: EarthlyBranch
5872
*/
5973
export const getBrightness = (starName: StarName, index: number): Brightness => {
6074
const star = kot<keyof typeof STARS_INFO>(starName);
75+
const { brightness } = getConfig();
76+
const targetBrightness = brightness[star] ? brightness[star] : STARS_INFO[star]?.brightness;
77+
78+
if (!targetBrightness) {
79+
return '';
80+
}
6181

62-
return t<Brightness>(STARS_INFO[star]?.brightness[fixIndex(index)]);
82+
return t<Brightness>(targetBrightness[fixIndex(index)]);
6383
};
6484

6585
export const getMutagen = (starName: StarName, heavenlyStemName: HeavenlyStemName): Mutagen => {
6686
const heavenlyStem = kot<HeavenlyStemKey>(heavenlyStemName, 'Heavenly');
6787
const starKey = kot<StarKey>(starName);
88+
const target = getTargetMutagens(heavenlyStem);
6889

69-
return t<Mutagen>(MUTAGEN[heavenlyStems[heavenlyStem].mutagen.indexOf(starKey as never)]);
90+
return t<Mutagen>(MUTAGEN[target.indexOf(starKey as never)]);
7091
};
7192

7293
export const getMutagensByHeavenlyStem = (heavenlyStemName: HeavenlyStemName): StarName[] => {
7394
const heavenlyStem = kot<HeavenlyStemKey>(heavenlyStemName, 'Heavenly');
95+
const target = getTargetMutagens(heavenlyStem);
7496

75-
return heavenlyStems[heavenlyStem].mutagen.map((star) => t<StarName>(star));
97+
return target.map((star) => t<StarName>(star));
7698
};
7799

78100
/**

yarn.lock

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3870,17 +3870,17 @@ lru-cache@^6.0.0:
38703870
dependencies:
38713871
yallist "^4.0.0"
38723872

3873-
lunar-lite@^0.1.1:
3874-
version "0.1.1"
3875-
resolved "https://registry.npmjs.org/lunar-lite/-/lunar-lite-0.1.1.tgz#c2c114b95eae24b84ebc0702f616ed573772c244"
3876-
integrity sha512-ttdkDY4uZg6LtE8r4m/Vt+z48ReT8StYXPY2eXqJ6tOG3C4I11g/f/gAJXplJIRTZd+F1xOFa52tUiP2UIkqzQ==
3873+
lunar-lite@^0.1.2:
3874+
version "0.1.2"
3875+
resolved "https://registry.npmjs.org/lunar-lite/-/lunar-lite-0.1.2.tgz#a66b08cbc6c8df3a31d4e166052593662f489144"
3876+
integrity sha512-3SKo8zTDdbS1Ynn4qHUPNOW9oviqL8d2qdHSMS9jfNbmIdh6DbYKaY9dnXpMS5I1dzG9ztAuwVJ8MBAupv89aA==
38773877
dependencies:
3878-
lunar-typescript "^1.6.13"
3878+
lunar-typescript "^1.7.3"
38793879

3880-
lunar-typescript@^1.6.13:
3881-
version "1.6.13"
3882-
resolved "https://registry.npmjs.org/lunar-typescript/-/lunar-typescript-1.6.13.tgz#99c9975f8ba4bc43af813e0155db0926d024cbcf"
3883-
integrity sha512-6gBJepWWRiCvpbxxeiogsd/ZIggBbH1xmS090Kat/FiM0AGFnso0bmYXL1q/opr8qrMdnjsBlMZqBvNiRKACGA==
3880+
lunar-typescript@^1.7.3:
3881+
version "1.7.3"
3882+
resolved "https://registry.npmjs.org/lunar-typescript/-/lunar-typescript-1.7.3.tgz#841d997687a0145a1fe9f65db735675f66d06660"
3883+
integrity sha512-VXMdgh2Psrn3vtfrai4lPug3Mt7ijYGVTICDARA8tLzqGv3Io/OvS23wxzFi/AbSzxt93u2wWhgv3VGKPSbUgQ==
38843884

38853885
make-dir@^4.0.0:
38863886
version "4.0.0"

0 commit comments

Comments
 (0)