@kiznavierr/kirara 1.0.1

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.
@@ -0,0 +1,46 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths: ["package.json"]
7
+ pull_request:
8
+ branches: [main]
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+
15
+ strategy:
16
+ matrix:
17
+ node-version: [18.x, 20.x]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - name: Use Node.js ${{ matrix.node-version }}
22
+ uses: actions/setup-node@v4
23
+ with:
24
+ node-version: ${{ matrix.node-version }}
25
+ cache: "npm"
26
+ - run: npm ci
27
+ - run: npm run build
28
+
29
+ publish:
30
+ needs: build
31
+ runs-on: ubuntu-latest
32
+ if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
33
+
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+ - name: Use Node.js
37
+ uses: actions/setup-node@v4
38
+ with:
39
+ node-version: "20.x"
40
+ cache: "npm"
41
+ registry-url: "https://registry.npmjs.org"
42
+ - run: npm ci
43
+ - run: npm run build
44
+ - run: npm publish --access public
45
+ env:
46
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kiznaiverr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Kirara
2
+
3
+ A TypeScript library for fetching Genshin Impact character data from the Enka API and generating card images using enka.cards. (HSR and ZZZ support coming soon)
4
+
5
+ ## Features
6
+
7
+ - Fetch player profile data from Enka API
8
+ - Retrieve list of character IDs
9
+ - Generate image URLs for character cards
10
+ - Download card images as Buffers
11
+ - Support for customization options (language, substats, etc.)
12
+ - Simple and modular design
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @kiznavierr/kirara
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ Import the library and create an instance:
23
+
24
+ ```typescript
25
+ import { Kirara } from "@kiznavierr/kirara";
26
+
27
+ const kirara = new Kirara();
28
+ ```
29
+
30
+ Fetch player data:
31
+
32
+ ```typescript
33
+ const playerData = await kirara.getPlayerData("856012067");
34
+ console.log(playerData.playerInfo.nickname); // Output: Kiznavierr
35
+ ```
36
+
37
+ Get list of character IDs:
38
+
39
+ ```typescript
40
+ const avatars = await kirara.getAvatarList("856012067");
41
+ console.log(avatars); // Output: ['10000047', '10000096', ...]
42
+ ```
43
+
44
+ Generate image URL for the first character:
45
+
46
+ ```typescript
47
+ const cardUrl = await kirara.generateDefaultCardUrl("856012067", {
48
+ lang: "en",
49
+ });
50
+ console.log(cardUrl); // Output: https://cards.enka.network/u/856012067/10000047/image?lang=en
51
+ ```
52
+
53
+ Fetch image as Buffer:
54
+
55
+ ```typescript
56
+ const imageBuffer = await kirara.generateDefaultCardImage("856012067");
57
+ ```
58
+
59
+ ```
60
+
61
+ ## API
62
+
63
+ - `getPlayerData(uid: string)`: Fetch player data.
64
+ - `getAvatarList(uid: string)`: Get list of avatar IDs.
65
+ - `getDefaultAvatarId(uid: string)`: Get first avatar ID.
66
+ - `generateCardUrl(uid: string, avatarId: string, options?)`: Generate image URL.
67
+ - `generateCardImage(uid: string, avatarId: string, options?)`: Fetch image as Buffer.
68
+ - `generateDefaultCardUrl(uid: string, options?)`: Generate URL for default avatar.
69
+ - `generateDefaultCardImage(uid: string, options?)`: Fetch image for default avatar.
70
+
71
+
72
+ ```
@@ -0,0 +1,6 @@
1
+ import { CardOptions } from "../types";
2
+ export declare class CardsClient {
3
+ generateCardUrl(uid: string, avatarId: string, options?: CardOptions): string;
4
+ generateCardImage(uid: string, avatarId: string, options?: CardOptions): Promise<Buffer>;
5
+ }
6
+ //# sourceMappingURL=cardsClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cardsClient.d.ts","sourceRoot":"","sources":["../../src/client/cardsClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,qBAAa,WAAW;IACtB,eAAe,CACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,WAAW,GACpB,MAAM;IAmBH,iBAAiB,CACrB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC;CAKnB"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CardsClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ class CardsClient {
9
+ generateCardUrl(uid, avatarId, options) {
10
+ let url = `https://cards.enka.network/u/${uid}/${avatarId}/image`;
11
+ if (options) {
12
+ const params = new URLSearchParams();
13
+ if (options.lang)
14
+ params.append("lang", options.lang);
15
+ if (options.substats !== undefined)
16
+ params.append("substats", options.substats.toString());
17
+ if (options.subsBreakdown !== undefined)
18
+ params.append("subsBreakdown", options.subsBreakdown.toString());
19
+ if (options.uid !== undefined)
20
+ params.append("uid", options.uid.toString());
21
+ if (options.hideNames !== undefined)
22
+ params.append("hideNames", options.hideNames.toString());
23
+ const query = params.toString();
24
+ if (query)
25
+ url += `?${query}`;
26
+ }
27
+ return url;
28
+ }
29
+ async generateCardImage(uid, avatarId, options) {
30
+ const url = this.generateCardUrl(uid, avatarId, options);
31
+ const response = await axios_1.default.get(url, { responseType: "arraybuffer" });
32
+ return Buffer.from(response.data);
33
+ }
34
+ }
35
+ exports.CardsClient = CardsClient;
36
+ //# sourceMappingURL=cardsClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cardsClient.js","sourceRoot":"","sources":["../../src/client/cardsClient.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAG1B,MAAa,WAAW;IACtB,eAAe,CACb,GAAW,EACX,QAAgB,EAChB,OAAqB;QAErB,IAAI,GAAG,GAAG,gCAAgC,GAAG,IAAI,QAAQ,QAAQ,CAAC;QAClE,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,IAAI,OAAO,CAAC,IAAI;gBAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACtD,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS;gBAChC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzD,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS;gBACrC,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,OAAO,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC;YACnE,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS;gBAC3B,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/C,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;gBACjC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,KAAK;gBAAE,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;QAChC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,GAAW,EACX,QAAgB,EAChB,OAAqB;QAErB,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC;QACvE,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;CACF;AAjCD,kCAiCC"}
@@ -0,0 +1,5 @@
1
+ import { PlayerData } from "../types";
2
+ export declare class EnkaClient {
3
+ getPlayerData(uid: string): Promise<PlayerData>;
4
+ }
5
+ //# sourceMappingURL=enkaClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enkaClient.d.ts","sourceRoot":"","sources":["../../src/client/enkaClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,qBAAa,UAAU;IACf,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAKtD"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EnkaClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ class EnkaClient {
9
+ async getPlayerData(uid) {
10
+ const url = `https://enka.network/api/uid/${uid}?info`;
11
+ const response = await axios_1.default.get(url);
12
+ return response.data;
13
+ }
14
+ }
15
+ exports.EnkaClient = EnkaClient;
16
+ //# sourceMappingURL=enkaClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enkaClient.js","sourceRoot":"","sources":["../../src/client/enkaClient.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAG1B,MAAa,UAAU;IACrB,KAAK,CAAC,aAAa,CAAC,GAAW;QAC7B,MAAM,GAAG,GAAG,gCAAgC,GAAG,OAAO,CAAC;QACvD,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,GAAG,CAAa,GAAG,CAAC,CAAC;QAClD,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF;AAND,gCAMC"}
@@ -0,0 +1,4 @@
1
+ export type Game = "genshin";
2
+ export declare function getApiBaseUrl(game: Game): string;
3
+ export declare function getCardsBaseUrl(game: Game): string;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/game/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GAAG,SAAS,CAAC;AAE7B,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEhD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAElD"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getApiBaseUrl = getApiBaseUrl;
4
+ exports.getCardsBaseUrl = getCardsBaseUrl;
5
+ function getApiBaseUrl(game) {
6
+ return "https://enka.network/api/uid";
7
+ }
8
+ function getCardsBaseUrl(game) {
9
+ return "https://cards.enka.network/u";
10
+ }
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/game/index.ts"],"names":[],"mappings":";;AAEA,sCAEC;AAED,0CAEC;AAND,SAAgB,aAAa,CAAC,IAAU;IACtC,OAAO,8BAA8B,CAAC;AACxC,CAAC;AAED,SAAgB,eAAe,CAAC,IAAU;IACxC,OAAO,8BAA8B,CAAC;AACxC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { Kirara } from "./kirara.js";
2
+ export * from "./types";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Kirara = void 0;
18
+ var kirara_js_1 = require("./kirara.js");
19
+ Object.defineProperty(exports, "Kirara", { enumerable: true, get: function () { return kirara_js_1.Kirara; } });
20
+ __exportStar(require("./types"), exports);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AACf,0CAAwB"}
@@ -0,0 +1,13 @@
1
+ import { PlayerData, CardOptions } from "./types";
2
+ export declare class Kirara {
3
+ private enkaClient;
4
+ private cardsClient;
5
+ getPlayerData(uid: string): Promise<PlayerData>;
6
+ getAvatarList(uid: string): Promise<string[]>;
7
+ getDefaultAvatarId(uid: string): Promise<string | null>;
8
+ generateCardUrl(uid: string, avatarId: string, options?: CardOptions): string;
9
+ generateCardImage(uid: string, avatarId: string, options?: CardOptions): Promise<Buffer>;
10
+ generateDefaultCardUrl(uid: string, options?: CardOptions): Promise<string | null>;
11
+ generateDefaultCardImage(uid: string, options?: CardOptions): Promise<Buffer | null>;
12
+ }
13
+ //# sourceMappingURL=kirara.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kirara.d.ts","sourceRoot":"","sources":["../src/kirara.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAElD,qBAAa,MAAM;IACjB,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,WAAW,CAAqB;IAElC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAI/C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAO7C,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAK7D,eAAe,CACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,WAAW,GACpB,MAAM;IAIH,iBAAiB,CACrB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC;IAIZ,sBAAsB,CAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKnB,wBAAwB,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAI1B"}
package/dist/kirara.js ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Kirara = void 0;
4
+ const enkaClient_1 = require("./client/enkaClient");
5
+ const cardsClient_1 = require("./client/cardsClient");
6
+ class Kirara {
7
+ constructor() {
8
+ this.enkaClient = new enkaClient_1.EnkaClient();
9
+ this.cardsClient = new cardsClient_1.CardsClient();
10
+ }
11
+ async getPlayerData(uid) {
12
+ return this.enkaClient.getPlayerData(uid);
13
+ }
14
+ async getAvatarList(uid) {
15
+ const data = await this.getPlayerData(uid);
16
+ return data.playerInfo.showAvatarInfoList.map((avatar) => avatar.avatarId.toString());
17
+ }
18
+ async getDefaultAvatarId(uid) {
19
+ const avatars = await this.getAvatarList(uid);
20
+ return avatars.length > 0 ? avatars[0] : null;
21
+ }
22
+ generateCardUrl(uid, avatarId, options) {
23
+ return this.cardsClient.generateCardUrl(uid, avatarId, options);
24
+ }
25
+ async generateCardImage(uid, avatarId, options) {
26
+ return this.cardsClient.generateCardImage(uid, avatarId, options);
27
+ }
28
+ async generateDefaultCardUrl(uid, options) {
29
+ const avatarId = await this.getDefaultAvatarId(uid);
30
+ return avatarId ? this.generateCardUrl(uid, avatarId, options) : null;
31
+ }
32
+ async generateDefaultCardImage(uid, options) {
33
+ const avatarId = await this.getDefaultAvatarId(uid);
34
+ return avatarId ? this.generateCardImage(uid, avatarId, options) : null;
35
+ }
36
+ }
37
+ exports.Kirara = Kirara;
38
+ //# sourceMappingURL=kirara.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kirara.js","sourceRoot":"","sources":["../src/kirara.ts"],"names":[],"mappings":";;;AAAA,oDAAiD;AACjD,sDAAmD;AAGnD,MAAa,MAAM;IAAnB;QACU,eAAU,GAAG,IAAI,uBAAU,EAAE,CAAC;QAC9B,gBAAW,GAAG,IAAI,yBAAW,EAAE,CAAC;IAiD1C,CAAC;IA/CC,KAAK,CAAC,aAAa,CAAC,GAAW;QAC7B,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAW;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACvD,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAC3B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,GAAW;QAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC9C,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChD,CAAC;IAED,eAAe,CACb,GAAW,EACX,QAAgB,EAChB,OAAqB;QAErB,OAAO,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,GAAW,EACX,QAAgB,EAChB,OAAqB;QAErB,OAAO,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,GAAW,EACX,OAAqB;QAErB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,wBAAwB,CAC5B,GAAW,EACX,OAAqB;QAErB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,CAAC;CACF;AAnDD,wBAmDC"}
@@ -0,0 +1,38 @@
1
+ export type Game = "genshin";
2
+ export interface Avatar {
3
+ avatarId: string;
4
+ level: number;
5
+ talentLevel?: number;
6
+ energyType?: number;
7
+ }
8
+ export interface PlayerInfo {
9
+ nickname: string;
10
+ level: number;
11
+ signature: string;
12
+ worldLevel: number;
13
+ nameCardId: number;
14
+ finishAchievementNum: number;
15
+ towerFloorIndex: number;
16
+ towerLevelIndex: number;
17
+ isShowAvatarTalent?: boolean;
18
+ theaterActIndex?: number;
19
+ theaterModeIndex?: number;
20
+ theaterStarIndex?: number;
21
+ fetterCount?: number;
22
+ towerStarIndex?: number;
23
+ stygianIndex?: number;
24
+ stygianSeconds?: number;
25
+ stygianId?: number;
26
+ showAvatarInfoList: Avatar[];
27
+ }
28
+ export interface PlayerData {
29
+ playerInfo: PlayerInfo;
30
+ }
31
+ export interface CardOptions {
32
+ lang?: string;
33
+ substats?: boolean;
34
+ subsBreakdown?: boolean;
35
+ uid?: boolean;
36
+ hideNames?: boolean;
37
+ }
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GAAG,SAAS,CAAC;AAE7B,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@kiznavierr/kirara",
3
+ "version": "1.0.1",
4
+ "description": "A TypeScript library for fetching character data from Enka API and generating card images using enka.cards. Supports Genshin Impact, Honkai: Star Rail, and Zenless Zone Zero.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepublishOnly": "npm run build"
10
+ },
11
+ "keywords": [
12
+ "genshin",
13
+ "enka",
14
+ "api",
15
+ "cards",
16
+ "typescript"
17
+ ],
18
+ "author": "Kiznaiverr",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/Kiznaiverr/kirara.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/Kiznaiverr/kirara/issues"
26
+ },
27
+ "homepage": "https://github.com/Kiznaiverr/kirara#readme",
28
+ "devDependencies": {
29
+ "@types/node": "^20.0.0",
30
+ "ts-node": "^10.9.0",
31
+ "typescript": "^5.0.0"
32
+ },
33
+ "dependencies": {
34
+ "axios": "^1.6.0"
35
+ }
36
+ }
@@ -0,0 +1,37 @@
1
+ import axios from "axios";
2
+ import { CardOptions } from "../types";
3
+
4
+ export class CardsClient {
5
+ generateCardUrl(
6
+ uid: string,
7
+ avatarId: string,
8
+ options?: CardOptions,
9
+ ): string {
10
+ let url = `https://cards.enka.network/u/${uid}/${avatarId}/image`;
11
+ if (options) {
12
+ const params = new URLSearchParams();
13
+ if (options.lang) params.append("lang", options.lang);
14
+ if (options.substats !== undefined)
15
+ params.append("substats", options.substats.toString());
16
+ if (options.subsBreakdown !== undefined)
17
+ params.append("subsBreakdown", options.subsBreakdown.toString());
18
+ if (options.uid !== undefined)
19
+ params.append("uid", options.uid.toString());
20
+ if (options.hideNames !== undefined)
21
+ params.append("hideNames", options.hideNames.toString());
22
+ const query = params.toString();
23
+ if (query) url += `?${query}`;
24
+ }
25
+ return url;
26
+ }
27
+
28
+ async generateCardImage(
29
+ uid: string,
30
+ avatarId: string,
31
+ options?: CardOptions,
32
+ ): Promise<Buffer> {
33
+ const url = this.generateCardUrl(uid, avatarId, options);
34
+ const response = await axios.get(url, { responseType: "arraybuffer" });
35
+ return Buffer.from(response.data);
36
+ }
37
+ }
@@ -0,0 +1,10 @@
1
+ import axios from "axios";
2
+ import { PlayerData } from "../types";
3
+
4
+ export class EnkaClient {
5
+ async getPlayerData(uid: string): Promise<PlayerData> {
6
+ const url = `https://enka.network/api/uid/${uid}?info`;
7
+ const response = await axios.get<PlayerData>(url);
8
+ return response.data;
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ export type Game = "genshin";
2
+
3
+ export function getApiBaseUrl(game: Game): string {
4
+ return "https://enka.network/api/uid";
5
+ }
6
+
7
+ export function getCardsBaseUrl(game: Game): string {
8
+ return "https://cards.enka.network/u";
9
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { Kirara } from "./kirara.js";
2
+ export * from "./types";
package/src/kirara.ts ADDED
@@ -0,0 +1,56 @@
1
+ import { EnkaClient } from "./client/enkaClient";
2
+ import { CardsClient } from "./client/cardsClient";
3
+ import { PlayerData, CardOptions } from "./types";
4
+
5
+ export class Kirara {
6
+ private enkaClient = new EnkaClient();
7
+ private cardsClient = new CardsClient();
8
+
9
+ async getPlayerData(uid: string): Promise<PlayerData> {
10
+ return this.enkaClient.getPlayerData(uid);
11
+ }
12
+
13
+ async getAvatarList(uid: string): Promise<string[]> {
14
+ const data = await this.getPlayerData(uid);
15
+ return data.playerInfo.showAvatarInfoList.map((avatar) =>
16
+ avatar.avatarId.toString(),
17
+ );
18
+ }
19
+
20
+ async getDefaultAvatarId(uid: string): Promise<string | null> {
21
+ const avatars = await this.getAvatarList(uid);
22
+ return avatars.length > 0 ? avatars[0] : null;
23
+ }
24
+
25
+ generateCardUrl(
26
+ uid: string,
27
+ avatarId: string,
28
+ options?: CardOptions,
29
+ ): string {
30
+ return this.cardsClient.generateCardUrl(uid, avatarId, options);
31
+ }
32
+
33
+ async generateCardImage(
34
+ uid: string,
35
+ avatarId: string,
36
+ options?: CardOptions,
37
+ ): Promise<Buffer> {
38
+ return this.cardsClient.generateCardImage(uid, avatarId, options);
39
+ }
40
+
41
+ async generateDefaultCardUrl(
42
+ uid: string,
43
+ options?: CardOptions,
44
+ ): Promise<string | null> {
45
+ const avatarId = await this.getDefaultAvatarId(uid);
46
+ return avatarId ? this.generateCardUrl(uid, avatarId, options) : null;
47
+ }
48
+
49
+ async generateDefaultCardImage(
50
+ uid: string,
51
+ options?: CardOptions,
52
+ ): Promise<Buffer | null> {
53
+ const avatarId = await this.getDefaultAvatarId(uid);
54
+ return avatarId ? this.generateCardImage(uid, avatarId, options) : null;
55
+ }
56
+ }
@@ -0,0 +1,41 @@
1
+ export type Game = "genshin";
2
+
3
+ export interface Avatar {
4
+ avatarId: string;
5
+ level: number;
6
+ talentLevel?: number;
7
+ energyType?: number;
8
+ }
9
+
10
+ export interface PlayerInfo {
11
+ nickname: string;
12
+ level: number;
13
+ signature: string;
14
+ worldLevel: number;
15
+ nameCardId: number;
16
+ finishAchievementNum: number;
17
+ towerFloorIndex: number;
18
+ towerLevelIndex: number;
19
+ isShowAvatarTalent?: boolean;
20
+ theaterActIndex?: number;
21
+ theaterModeIndex?: number;
22
+ theaterStarIndex?: number;
23
+ fetterCount?: number;
24
+ towerStarIndex?: number;
25
+ stygianIndex?: number;
26
+ stygianSeconds?: number;
27
+ stygianId?: number;
28
+ showAvatarInfoList: Avatar[];
29
+ }
30
+
31
+ export interface PlayerData {
32
+ playerInfo: PlayerInfo;
33
+ }
34
+
35
+ export interface CardOptions {
36
+ lang?: string;
37
+ substats?: boolean;
38
+ subsBreakdown?: boolean;
39
+ uid?: boolean;
40
+ hideNames?: boolean;
41
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
18
+ }