@trading-tazos-game/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +132 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +31 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +61 -0
- package/dist/client.js +47 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/battle.d.ts +2 -0
- package/dist/commands/battle.js +154 -0
- package/dist/commands/battle.js.map +1 -0
- package/dist/commands/info.d.ts +2 -0
- package/dist/commands/info.js +51 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.js +39 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/stats.d.ts +2 -0
- package/dist/commands/stats.js +51 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/top.d.ts +2 -0
- package/dist/commands/top.js +44 -0
- package/dist/commands/top.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/format.d.ts +22 -0
- package/dist/lib/format.js +73 -0
- package/dist/lib/format.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Trading Tazos Game
|
|
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,132 @@
|
|
|
1
|
+
# 🎴 @trading-tazos-game/cli
|
|
2
|
+
|
|
3
|
+
> Official CLI for the **Trading Tazos Game** — search, battle, and manage your digital tazo collection from the terminal.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@trading-tazos-game/cli)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
[](https://nodejs.org)
|
|
8
|
+
[](https://github.com/smouj/trading-tazos-game-cli/pulls)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g @trading-tazos-game/cli
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requirements: **Node.js ≥ 18**
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Search your favorite tazo
|
|
24
|
+
tazos search pikachu
|
|
25
|
+
|
|
26
|
+
# Get full battle stats
|
|
27
|
+
tazos info charizard
|
|
28
|
+
|
|
29
|
+
# See collection statistics
|
|
30
|
+
tazos stats
|
|
31
|
+
|
|
32
|
+
# Top 10 by attack power
|
|
33
|
+
tazos top --stat attack
|
|
34
|
+
|
|
35
|
+
# Simulate a battle (deterministic — same seed = same result!)
|
|
36
|
+
tazos battle --player 5 --opponent 5 --seed 42
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
| Command | Description |
|
|
42
|
+
|---------|-------------|
|
|
43
|
+
| `tazos search [query]` | Search tazos by name, slug, or number |
|
|
44
|
+
| `tazos info <name>` | Show detailed 9-stat breakdown with bars |
|
|
45
|
+
| `tazos stats` | Collection statistics by franchise, rarity, condition |
|
|
46
|
+
| `tazos top` | Leaderboard by any stat (attack, defense, bounce...) |
|
|
47
|
+
| `tazos battle` | Simulate a full battle with physics and captures |
|
|
48
|
+
|
|
49
|
+
### Search Options
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
tazos search [query] [options]
|
|
53
|
+
|
|
54
|
+
-f, --franchise <slug> Filter: pokemon, digimon, dragon-ball-z
|
|
55
|
+
-r, --rarity <rarity> Filter: common, uncommon, rare, ultra, legendary
|
|
56
|
+
-s, --stats Show full 9-stat breakdown
|
|
57
|
+
-l, --limit <n> Max results (default: 15)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Battle Options
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
tazos battle [options]
|
|
64
|
+
|
|
65
|
+
-p, --player <n> Your team size (default: 5)
|
|
66
|
+
-o, --opponent <n> Opponent team size (default: 5)
|
|
67
|
+
-s, --seed <n> Random seed for reproducible battles
|
|
68
|
+
-f, --fast Skip detailed turn log
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Authentication
|
|
72
|
+
|
|
73
|
+
Set your API token to access your personal collection:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
export TAZOS_AUTH_TOKEN="your-jwt-token"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Get your token by logging in at [medaclawarena.com](https://medaclawarena.com) and copying it from localStorage (`ttg-token`).
|
|
80
|
+
|
|
81
|
+
## Features
|
|
82
|
+
|
|
83
|
+
- 🎯 **9 Battle Stats** — Attack, Defense, Resistance, Weight, Stability, Spin, Control, Bounce, Precision
|
|
84
|
+
- 🎲 **Deterministic Battles** — Seed-based RNG, same seed = same outcome every time
|
|
85
|
+
- 📊 **Stat Bars** — ASCII bar charts for visual stat comparison
|
|
86
|
+
- 🌈 **Franchise Colors** — Pokémon yellow, DBZ orange, Digimon cyan
|
|
87
|
+
- ⭐ **Rarity Stars** — ★ common through ★★★★★ legendary
|
|
88
|
+
- 🔄 **Reproducible** — Every battle can be replayed with `--seed`
|
|
89
|
+
|
|
90
|
+
## API
|
|
91
|
+
|
|
92
|
+
The CLI connects to the public [Trading Tazos Game API](https://medaclawarena.com):
|
|
93
|
+
|
|
94
|
+
- `GET /api/tazos` — Search, filter, sort tazos
|
|
95
|
+
- `GET /api/stats` — Collection statistics
|
|
96
|
+
|
|
97
|
+
Override the API base URL:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
export TAZOS_API_URL="https://your-instance.com"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Programmatic Usage
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { api } from "@trading-tazos-game/cli"
|
|
107
|
+
|
|
108
|
+
const data = await api.search("pikachu")
|
|
109
|
+
console.log(data.tazos[0].attack) // → 48
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
See `src/index.ts` for the full public API surface.
|
|
113
|
+
|
|
114
|
+
## Development
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
git clone https://github.com/smouj/trading-tazos-game-cli.git
|
|
118
|
+
cd trading-tazos-game-cli
|
|
119
|
+
npm install
|
|
120
|
+
npm run build
|
|
121
|
+
node dist/cli.js --help
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Related
|
|
125
|
+
|
|
126
|
+
- [Trading Tazos Game](https://medaclawarena.com) — Play in your browser
|
|
127
|
+
- [Main Repo](https://github.com/smouj/Trading-Tazos-Game) — Full-stack Next.js game
|
|
128
|
+
- [npm Package](https://www.npmjs.com/package/@trading-tazos-game/cli)
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT © Trading Tazos Game
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { searchCommand } from "./commands/search.js";
|
|
5
|
+
import { infoCommand } from "./commands/info.js";
|
|
6
|
+
import { statsCommand } from "./commands/stats.js";
|
|
7
|
+
import { battleCommand } from "./commands/battle.js";
|
|
8
|
+
import { topCommand } from "./commands/top.js";
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.name("tazos")
|
|
12
|
+
.description(chalk.bold.yellow("🎴 Trading Tazos Game CLI") + chalk.dim(" — Manage your digital tazo collection from the terminal"))
|
|
13
|
+
.version("1.0.0")
|
|
14
|
+
.addHelpText("after", `
|
|
15
|
+
${chalk.dim("Examples:")}
|
|
16
|
+
${chalk.cyan("$ tazos search pikachu")} ${chalk.dim("Search for tazos by name")}
|
|
17
|
+
${chalk.cyan("$ tazos info bulbasaur")} ${chalk.dim("Show detailed stats for a tazo")}
|
|
18
|
+
${chalk.cyan("$ tazos stats")} ${chalk.dim("Show collection statistics")}
|
|
19
|
+
${chalk.cyan("$ tazos top --stat attack")} ${chalk.dim("Top 10 tazos by attack")}
|
|
20
|
+
${chalk.cyan("$ tazos battle --player 5")} ${chalk.dim("Simulate a quick battle")}
|
|
21
|
+
|
|
22
|
+
${chalk.dim("API:")} https://medaclawarena.com
|
|
23
|
+
${chalk.dim("Repo:")} https://github.com/smouj/trading-tazos-game-cli
|
|
24
|
+
`);
|
|
25
|
+
program.addCommand(searchCommand());
|
|
26
|
+
program.addCommand(infoCommand());
|
|
27
|
+
program.addCommand(statsCommand());
|
|
28
|
+
program.addCommand(battleCommand());
|
|
29
|
+
program.addCommand(topCommand());
|
|
30
|
+
program.parse();
|
|
31
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,2BAA2B,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;KACnI,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,OAAO,EAAE;EACtB,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;IACpB,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,YAAY,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACrF,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,aAAa,KAAK,CAAC,GAAG,CAAC,gCAAgC,CAAC;IAC5F,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,sBAAsB,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,UAAU,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC;IACpF,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,UAAU,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC;;EAEvF,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;EACjB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;CACnB,CAAC,CAAA;AAEF,OAAO,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAA;AACnC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAA;AACjC,OAAO,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAA;AACnC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAA;AAEhC,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface Tazo {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string | null;
|
|
4
|
+
displayName: string | null;
|
|
5
|
+
number: string | null;
|
|
6
|
+
slug: string;
|
|
7
|
+
rarity: string;
|
|
8
|
+
condition: string;
|
|
9
|
+
franchise: string | null;
|
|
10
|
+
franchiseSlug: string | null;
|
|
11
|
+
collection: string | null;
|
|
12
|
+
imageUrl: string | null;
|
|
13
|
+
attack: number;
|
|
14
|
+
defense: number;
|
|
15
|
+
resistance: number;
|
|
16
|
+
weight: number;
|
|
17
|
+
stability: number;
|
|
18
|
+
spin: number;
|
|
19
|
+
control: number;
|
|
20
|
+
bounce: number;
|
|
21
|
+
precision: number;
|
|
22
|
+
role: string | null;
|
|
23
|
+
isOwned: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface TazoListResponse {
|
|
26
|
+
tazos: Tazo[];
|
|
27
|
+
total: number;
|
|
28
|
+
}
|
|
29
|
+
export interface StatsResponse {
|
|
30
|
+
totalTazos: number;
|
|
31
|
+
ownedTazos: number;
|
|
32
|
+
totalFranchises: number;
|
|
33
|
+
totalCollections: number;
|
|
34
|
+
byRarity: Record<string, number>;
|
|
35
|
+
byCondition: Record<string, number>;
|
|
36
|
+
byFranchise: Record<string, number>;
|
|
37
|
+
topAttack: Tazo | null;
|
|
38
|
+
topDefense: Tazo | null;
|
|
39
|
+
}
|
|
40
|
+
export interface CollectionResponse {
|
|
41
|
+
items: {
|
|
42
|
+
id: string;
|
|
43
|
+
quantity: number;
|
|
44
|
+
isFavorite: boolean;
|
|
45
|
+
acquiredAt: string;
|
|
46
|
+
tazo: Tazo;
|
|
47
|
+
}[];
|
|
48
|
+
total: number;
|
|
49
|
+
franchiseSummary: Record<string, number>;
|
|
50
|
+
}
|
|
51
|
+
export declare const api: {
|
|
52
|
+
search(query: string, opts?: {
|
|
53
|
+
franchise?: string;
|
|
54
|
+
rarity?: string;
|
|
55
|
+
limit?: number;
|
|
56
|
+
}): Promise<TazoListResponse>;
|
|
57
|
+
getBySlug(slug: string): Promise<Tazo | null>;
|
|
58
|
+
stats(): Promise<StatsResponse>;
|
|
59
|
+
topTazos(stat: string, limit?: number): Promise<TazoListResponse>;
|
|
60
|
+
random(limit?: number): Promise<TazoListResponse>;
|
|
61
|
+
};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const BASE_URL = process.env.TAZOS_API_URL || "https://medaclawarena.com";
|
|
2
|
+
const AUTH_TOKEN = process.env.TAZOS_AUTH_TOKEN || "";
|
|
3
|
+
async function apiGet(path) {
|
|
4
|
+
const headers = { "Accept": "application/json" };
|
|
5
|
+
if (AUTH_TOKEN) {
|
|
6
|
+
headers["Authorization"] = `Bearer ${AUTH_TOKEN}`;
|
|
7
|
+
}
|
|
8
|
+
const url = `${BASE_URL}/api${path}`;
|
|
9
|
+
const res = await fetch(url, { headers });
|
|
10
|
+
if (!res.ok) {
|
|
11
|
+
const body = await res.text().catch(() => "");
|
|
12
|
+
throw new Error(`API ${res.status}: ${body || res.statusText}`);
|
|
13
|
+
}
|
|
14
|
+
return res.json();
|
|
15
|
+
}
|
|
16
|
+
export const api = {
|
|
17
|
+
async search(query, opts) {
|
|
18
|
+
const params = new URLSearchParams();
|
|
19
|
+
if (query)
|
|
20
|
+
params.set("search", query);
|
|
21
|
+
if (opts?.franchise && opts.franchise !== "all")
|
|
22
|
+
params.set("franchise", opts.franchise);
|
|
23
|
+
if (opts?.rarity && opts.rarity !== "all")
|
|
24
|
+
params.set("rarity", opts.rarity);
|
|
25
|
+
params.set("limit", String(opts?.limit || 20));
|
|
26
|
+
return apiGet(`/tazos?${params}`);
|
|
27
|
+
},
|
|
28
|
+
async getBySlug(slug) {
|
|
29
|
+
const params = new URLSearchParams({ search: slug, limit: "1" });
|
|
30
|
+
const data = await apiGet(`/tazos?${params}`);
|
|
31
|
+
return data.tazos.find(t => t.slug === slug || t.slug?.includes(slug)) || data.tazos[0] || null;
|
|
32
|
+
},
|
|
33
|
+
async stats() {
|
|
34
|
+
return apiGet("/stats");
|
|
35
|
+
},
|
|
36
|
+
async topTazos(stat, limit = 10) {
|
|
37
|
+
const params = new URLSearchParams({ sortBy: stat, sortOrder: "desc", limit: String(limit) });
|
|
38
|
+
return apiGet(`/tazos?${params}`);
|
|
39
|
+
},
|
|
40
|
+
async random(limit = 6) {
|
|
41
|
+
const params = new URLSearchParams({ limit: "30" });
|
|
42
|
+
const data = await apiGet(`/tazos?${params}`);
|
|
43
|
+
const shuffled = [...data.tazos].sort(() => Math.random() - 0.5);
|
|
44
|
+
return { tazos: shuffled.slice(0, limit), total: limit };
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { api } from "../client.js";
|
|
4
|
+
import { formatBattleCard, banner } from "../lib/format.js";
|
|
5
|
+
/** Deterministic pseudo-random - same seed = same battle */
|
|
6
|
+
function mulberry32(seed) {
|
|
7
|
+
return () => { seed |= 0; seed = seed + 0x6D2B79F5 | 0; let t = Math.imul(seed ^ seed >>> 15, 1 | seed); t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t; return ((t ^ t >>> 14) >>> 0) / 4294967296; };
|
|
8
|
+
}
|
|
9
|
+
function simulateBattle(playerTazos, opponentTazos, seed) {
|
|
10
|
+
const rng = mulberry32(seed);
|
|
11
|
+
const log = [];
|
|
12
|
+
const p = { tazos: [...playerTazos], captures: 0, totalDamage: 0 };
|
|
13
|
+
const o = { tazos: [...opponentTazos], captures: 0, totalDamage: 0 };
|
|
14
|
+
let turn = 0;
|
|
15
|
+
while (p.tazos.length > 0 && o.tazos.length > 0 && turn < 50) {
|
|
16
|
+
turn++;
|
|
17
|
+
const isPlayerTurn = rng() > 0.5;
|
|
18
|
+
const attacker = isPlayerTurn
|
|
19
|
+
? p.tazos[Math.floor(rng() * p.tazos.length)]
|
|
20
|
+
: o.tazos[Math.floor(rng() * o.tazos.length)];
|
|
21
|
+
const defender = isPlayerTurn
|
|
22
|
+
? o.tazos[Math.floor(rng() * o.tazos.length)]
|
|
23
|
+
: p.tazos[Math.floor(rng() * p.tazos.length)];
|
|
24
|
+
// Calculate damage
|
|
25
|
+
const power = 50 + rng() * 50;
|
|
26
|
+
const accuracy = 0.7 + (attacker.precision / 100) * 0.2 + (attacker.control / 100) * 0.1;
|
|
27
|
+
const hits = rng() < accuracy;
|
|
28
|
+
if (hits) {
|
|
29
|
+
const baseDamage = (attacker.attack * 0.35 + attacker.weight * 0.2 + attacker.spin * 0.1 + power * 0.35);
|
|
30
|
+
const defend = defender.defense * 0.3 + defender.resistance * 0.3 + defender.weight * 0.15 + defender.stability * 0.25;
|
|
31
|
+
const damage = Math.max(1, Math.round(baseDamage - defend * 0.6));
|
|
32
|
+
const critical = rng() < 0.1;
|
|
33
|
+
const finalDamage = critical ? Math.round(damage * 1.8) : damage;
|
|
34
|
+
const atkName = attacker.name || "?";
|
|
35
|
+
const defName = defender.name || "?";
|
|
36
|
+
const critStr = critical ? chalk.yellow(" CRIT!") : "";
|
|
37
|
+
if (isPlayerTurn) {
|
|
38
|
+
o.totalDamage += finalDamage;
|
|
39
|
+
log.push(chalk.cyan(` ${atkName}`) + chalk.dim(" → ") + chalk.red(`${defName}`) + chalk.dim(` ${finalDamage} dmg`) + critStr);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
p.totalDamage += finalDamage;
|
|
43
|
+
log.push(chalk.red(` ${atkName}`) + chalk.dim(" → ") + chalk.cyan(`${defName}`) + chalk.dim(` ${finalDamage} dmg`) + critStr);
|
|
44
|
+
}
|
|
45
|
+
// Capture check (high damage or low stability)
|
|
46
|
+
const captureChance = (finalDamage / 150) * (1 - defender.stability / 100);
|
|
47
|
+
if (rng() < captureChance) {
|
|
48
|
+
if (isPlayerTurn) {
|
|
49
|
+
const idx = o.tazos.indexOf(defender);
|
|
50
|
+
if (idx >= 0) {
|
|
51
|
+
o.tazos.splice(idx, 1);
|
|
52
|
+
p.captures++;
|
|
53
|
+
log.push(chalk.green(` CAPTURE! ${defName} joins your collection`));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const idx = p.tazos.indexOf(defender);
|
|
58
|
+
if (idx >= 0) {
|
|
59
|
+
p.tazos.splice(idx, 1);
|
|
60
|
+
o.captures++;
|
|
61
|
+
log.push(chalk.red(` LOST! ${defName} captured by opponent`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Self-flip check (high power with low precision)
|
|
66
|
+
const selfFlipChance = (power / 100) * (1 - attacker.precision / 100) * 0.2;
|
|
67
|
+
if (rng() < selfFlipChance) {
|
|
68
|
+
const flipDamage = Math.round(finalDamage * 0.3);
|
|
69
|
+
const selfName = attacker.name || "?";
|
|
70
|
+
if (isPlayerTurn) {
|
|
71
|
+
p.totalDamage += flipDamage;
|
|
72
|
+
log.push(chalk.redBright(` SELF-FLIP! ${selfName} takes ${flipDamage} recoil damage`));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
o.totalDamage += flipDamage;
|
|
76
|
+
log.push(chalk.redBright(` SELF-FLIP! ${selfName} takes ${flipDamage} recoil damage`));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const atkName = attacker.name || "?";
|
|
82
|
+
log.push(chalk.dim(` ${atkName} misses completely!`));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const winner = p.tazos.length > o.tazos.length ? "player"
|
|
86
|
+
: o.tazos.length > p.tazos.length ? "opponent"
|
|
87
|
+
: p.captures > o.captures ? "player"
|
|
88
|
+
: o.captures > p.captures ? "opponent"
|
|
89
|
+
: "draw";
|
|
90
|
+
return { player: p, opponent: o, turns: turn, winner, log };
|
|
91
|
+
}
|
|
92
|
+
export function battleCommand() {
|
|
93
|
+
return new Command("battle")
|
|
94
|
+
.description("Simulate a battle between two teams of tazos")
|
|
95
|
+
.option("-p, --player <n>", "Player team size", "5")
|
|
96
|
+
.option("-o, --opponent <n>", "Opponent team size", "5")
|
|
97
|
+
.option("-s, --seed <n>", "Random seed for reproducible battles")
|
|
98
|
+
.option("-f, --fast", "Skip detailed turn log")
|
|
99
|
+
.action(async (opts) => {
|
|
100
|
+
try {
|
|
101
|
+
const pSize = Math.min(Math.max(parseInt(opts.player), 2), 10);
|
|
102
|
+
const oSize = Math.min(Math.max(parseInt(opts.opponent), 2), 10);
|
|
103
|
+
const seed = parseInt(opts.seed) || Math.floor(Math.random() * 99999);
|
|
104
|
+
// Fetch random tazos
|
|
105
|
+
const [playerData, opponentData] = await Promise.all([
|
|
106
|
+
api.random(pSize),
|
|
107
|
+
api.random(oSize),
|
|
108
|
+
]);
|
|
109
|
+
const playerTazos = playerData.tazos;
|
|
110
|
+
const opponentTazos = opponentData.tazos;
|
|
111
|
+
console.log(banner(`Battle! Seed: ${seed}`));
|
|
112
|
+
console.log("");
|
|
113
|
+
// Teams
|
|
114
|
+
console.log(chalk.cyan.bold(" YOUR TEAM:"));
|
|
115
|
+
for (let i = 0; i < playerTazos.length; i++) {
|
|
116
|
+
console.log(formatBattleCard(playerTazos[i], i));
|
|
117
|
+
}
|
|
118
|
+
console.log("");
|
|
119
|
+
console.log(chalk.red.bold(" OPPONENT TEAM:"));
|
|
120
|
+
for (let i = 0; i < opponentTazos.length; i++) {
|
|
121
|
+
console.log(formatBattleCard(opponentTazos[i], i));
|
|
122
|
+
}
|
|
123
|
+
// Run battle
|
|
124
|
+
console.log(chalk.bold.yellow("\n══════════ BATTLE LOG ══════════"));
|
|
125
|
+
const result = simulateBattle(playerTazos, opponentTazos, seed);
|
|
126
|
+
if (!opts.fast) {
|
|
127
|
+
for (const line of result.log) {
|
|
128
|
+
console.log(line);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
console.log(chalk.dim(` (${result.turns} turns, ${result.log.length} events)`));
|
|
133
|
+
}
|
|
134
|
+
// Result
|
|
135
|
+
console.log(chalk.bold.yellow("\n══════════ RESULT ══════════"));
|
|
136
|
+
const winEmoji = result.winner === "player" ? "🏆" : result.winner === "opponent" ? "💀" : "🤝";
|
|
137
|
+
const winColor = result.winner === "player" ? chalk.greenBright : result.winner === "opponent" ? chalk.redBright : chalk.yellow;
|
|
138
|
+
console.log(winColor(` ${winEmoji} ${result.winner === "player" ? "YOU WIN!" : result.winner === "opponent" ? "Opponent wins!" : "DRAW!"}`));
|
|
139
|
+
console.log("");
|
|
140
|
+
console.log(` ${chalk.cyan("Your captures:")} ${chalk.greenBright(result.player.captures)} Damage dealt: ${chalk.yellow(result.opponent.totalDamage)}`);
|
|
141
|
+
console.log(` ${chalk.red("Opponent captures:")} ${chalk.redBright(result.opponent.captures)} Damage dealt: ${chalk.yellow(result.player.totalDamage)}`);
|
|
142
|
+
console.log(` ${chalk.dim("Turns:")} ${result.turns}`);
|
|
143
|
+
console.log(` ${chalk.dim("Your team left:")} ${result.player.tazos.length} / ${playerTazos.length}`);
|
|
144
|
+
console.log(` ${chalk.dim("Opponent team left:")} ${result.opponent.tazos.length} / ${opponentTazos.length}`);
|
|
145
|
+
console.log(` ${chalk.dim("Seed:")} ${seed} (replay with: tazos battle -s ${seed})`);
|
|
146
|
+
console.log("");
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
console.error(chalk.red(`\n Error: ${err.message}`));
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=battle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"battle.js","sourceRoot":"","sources":["../../src/commands/battle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { api } from "../client.js";
|
|
4
|
+
import { STAT_CONFIG, RARITY_STYLE, FRANCHISE_COLOR, statBar, banner } from "../lib/format.js";
|
|
5
|
+
export function infoCommand() {
|
|
6
|
+
return new Command("info")
|
|
7
|
+
.description("Show detailed stats for a tazo by name or slug")
|
|
8
|
+
.argument("<name>", "Tazo name or slug")
|
|
9
|
+
.action(async (name) => {
|
|
10
|
+
try {
|
|
11
|
+
const t = await api.getBySlug(name.toLowerCase());
|
|
12
|
+
if (!t) {
|
|
13
|
+
console.log(chalk.yellow(`\n No tazo found matching "${name}"`));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const displayName = t.name || t.displayName || `#${t.number || "?"}`;
|
|
17
|
+
const franchiseName = typeof t.franchise === "object" && t.franchise
|
|
18
|
+
? t.franchise.name || t.franchise.slug : t.franchise;
|
|
19
|
+
const franchiseSlug = typeof t.franchise === "object" && t.franchise
|
|
20
|
+
? t.franchise.slug : t.franchise;
|
|
21
|
+
const collectionName = typeof t.collection === "object" && t.collection
|
|
22
|
+
? t.collection.name || "Base Set" : t.collection;
|
|
23
|
+
const fc = FRANCHISE_COLOR[franchiseSlug || "unknown"] || chalk.white;
|
|
24
|
+
const rarityStyle = RARITY_STYLE[t.rarity] || { color: chalk.gray, stars: "?" };
|
|
25
|
+
console.log(banner(displayName));
|
|
26
|
+
console.log("");
|
|
27
|
+
console.log(` ${chalk.bold("Franchise:")} ${fc(franchiseName || "Unknown")}`);
|
|
28
|
+
console.log(` ${chalk.bold("Collection:")} ${chalk.dim(collectionName || "Base Set")}`);
|
|
29
|
+
console.log(` ${chalk.bold("Rarity:")} ${rarityStyle.color(rarityStyle.stars)} ${rarityStyle.color(t.rarity)}`);
|
|
30
|
+
console.log(` ${chalk.bold("Role:")} ${chalk.cyanBright((t.role || "balanced").toUpperCase())}`);
|
|
31
|
+
console.log(` ${chalk.bold("Owned:")} ${t.isOwned ? chalk.green("✓ Yes") : chalk.dim("✗ No")}`);
|
|
32
|
+
console.log(` ${chalk.bold("Slug:")} ${chalk.dim(t.slug)}`);
|
|
33
|
+
// Stat bars
|
|
34
|
+
const stats = ["attack", "defense", "resistance", "weight", "stability", "spin", "control", "bounce", "precision"];
|
|
35
|
+
const maxStat = Math.max(...stats.map(s => t[s]), 100);
|
|
36
|
+
console.log(chalk.bold("\n Battle Stats:"));
|
|
37
|
+
for (const stat of stats) {
|
|
38
|
+
const value = t[stat];
|
|
39
|
+
const cfg = STAT_CONFIG[stat];
|
|
40
|
+
const bar = statBar(value, maxStat, 25);
|
|
41
|
+
console.log(` ${cfg.color(cfg.label.padEnd(5))} ${chalk.bold(String(value).padStart(3))} ${chalk.dim(bar)}`);
|
|
42
|
+
}
|
|
43
|
+
console.log("");
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error(chalk.red(`\n Error: ${err.message}`));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/commands/info.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { api } from "../client.js";
|
|
4
|
+
import { formatTazo, banner } from "../lib/format.js";
|
|
5
|
+
export function searchCommand() {
|
|
6
|
+
return new Command("search")
|
|
7
|
+
.description("Search tazos by name or slug")
|
|
8
|
+
.argument("[query]", "Search term (partial name, slug, or number)")
|
|
9
|
+
.option("-f, --franchise <slug>", "Filter by franchise (pokemon, digimon, dragon-ball-z)")
|
|
10
|
+
.option("-r, --rarity <rarity>", "Filter by rarity (common, uncommon, rare, ultra, legendary)")
|
|
11
|
+
.option("-s, --stats", "Show full 9-stat breakdown")
|
|
12
|
+
.option("-l, --limit <n>", "Max results", "15")
|
|
13
|
+
.action(async (query, opts) => {
|
|
14
|
+
try {
|
|
15
|
+
const data = await api.search(query || "", {
|
|
16
|
+
franchise: opts.franchise,
|
|
17
|
+
rarity: opts.rarity,
|
|
18
|
+
limit: parseInt(opts.limit),
|
|
19
|
+
});
|
|
20
|
+
const q = query || "all";
|
|
21
|
+
console.log(banner(`Search: "${q}" — ${data.total} results`));
|
|
22
|
+
if (data.tazos.length === 0) {
|
|
23
|
+
console.log(chalk.dim("\n No tazos found. Try a different query or filter."));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
for (const t of data.tazos) {
|
|
27
|
+
console.log(formatTazo(t, opts.stats));
|
|
28
|
+
}
|
|
29
|
+
if (data.total > data.tazos.length) {
|
|
30
|
+
console.log(chalk.dim(`\n ...and ${data.total - data.tazos.length} more. Use --limit to see more.`));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
console.error(chalk.red(`\n Error: ${err.message}`));
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAErD,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,8BAA8B,CAAC;SAC3C,QAAQ,CAAC,SAAS,EAAE,6CAA6C,CAAC;SAClE,MAAM,CAAC,wBAAwB,EAAE,uDAAuD,CAAC;SACzF,MAAM,CAAC,uBAAuB,EAAE,6DAA6D,CAAC;SAC9F,MAAM,CAAC,aAAa,EAAE,4BAA4B,CAAC;SACnD,MAAM,CAAC,iBAAiB,EAAE,aAAa,EAAE,IAAI,CAAC;SAC9C,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE;gBACzC,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;aAC5B,CAAC,CAAA;YAEF,MAAM,CAAC,GAAG,KAAK,IAAI,KAAK,CAAA;YACxB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC,CAAA;YAE7D,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC,CAAA;gBAC9E,OAAM;YACR,CAAC;YAED,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;YACxC,CAAC;YAED,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,iCAAiC,CAAC,CAAC,CAAA;YACvG,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { api } from "../client.js";
|
|
4
|
+
import { RARITY_STYLE, banner, fmt } from "../lib/format.js";
|
|
5
|
+
export function statsCommand() {
|
|
6
|
+
return new Command("stats")
|
|
7
|
+
.description("Show collection statistics and breakdowns")
|
|
8
|
+
.action(async () => {
|
|
9
|
+
try {
|
|
10
|
+
const s = await api.stats();
|
|
11
|
+
console.log(banner("Collection Statistics"));
|
|
12
|
+
console.log("");
|
|
13
|
+
// KPI cards
|
|
14
|
+
const completionPct = s.totalTazos > 0 ? ((s.ownedTazos / s.totalTazos) * 100).toFixed(1) : "0";
|
|
15
|
+
console.log(` ${chalk.bold("Total Tazos:")} ${chalk.yellowBright(s.totalTazos)}`);
|
|
16
|
+
console.log(` ${chalk.bold("Owned:")} ${chalk.green(fmt(s.ownedTazos))} (${completionPct}%)`);
|
|
17
|
+
console.log(` ${chalk.bold("Franchises:")} ${chalk.cyan(s.totalFranchises)}`);
|
|
18
|
+
console.log(` ${chalk.bold("Collections:")} ${chalk.magenta(s.totalCollections)}`);
|
|
19
|
+
// By franchise
|
|
20
|
+
if (s.byFranchise && Object.keys(s.byFranchise).length > 0) {
|
|
21
|
+
console.log(chalk.bold("\n By Franchise:"));
|
|
22
|
+
const maxF = Math.max(...Object.values(s.byFranchise), 1);
|
|
23
|
+
for (const [name, count] of Object.entries(s.byFranchise)) {
|
|
24
|
+
const bar = "█".repeat(Math.round((count / maxF) * 20));
|
|
25
|
+
console.log(` ${chalk.bold(name.padEnd(18))} ${chalk.yellowBright(String(count).padStart(4))} ${chalk.dim(bar)}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// By rarity
|
|
29
|
+
if (s.byRarity && Object.keys(s.byRarity).length > 0) {
|
|
30
|
+
console.log(chalk.bold("\n By Rarity:"));
|
|
31
|
+
for (const [rarity, count] of Object.entries(s.byRarity)) {
|
|
32
|
+
const style = RARITY_STYLE[rarity] || { color: chalk.gray, stars: "?" };
|
|
33
|
+
console.log(` ${style.color(style.stars)} ${style.color(rarity.padEnd(14))} ${chalk.bold(String(count))}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// By condition
|
|
37
|
+
if (s.byCondition && Object.keys(s.byCondition).length > 0) {
|
|
38
|
+
console.log(chalk.bold("\n By Condition:"));
|
|
39
|
+
for (const [cond, count] of Object.entries(s.byCondition)) {
|
|
40
|
+
console.log(` ${chalk.dim("■")} ${cond.padEnd(16)} ${chalk.bold(String(count))}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
console.log("");
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error(chalk.red(`\n Error: ${err.message}`));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/commands/stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { api } from "../client.js";
|
|
4
|
+
import { banner } from "../lib/format.js";
|
|
5
|
+
export function topCommand() {
|
|
6
|
+
return new Command("top")
|
|
7
|
+
.description("Show top tazos by stat")
|
|
8
|
+
.option("-s, --stat <stat>", "Stat to rank by (attack, defense, spin, etc.)", "attack")
|
|
9
|
+
.option("-l, --limit <n>", "Number to show", "10")
|
|
10
|
+
.option("-f, --franchise <slug>", "Filter by franchise")
|
|
11
|
+
.action(async (opts) => {
|
|
12
|
+
try {
|
|
13
|
+
const stat = opts.stat.toLowerCase();
|
|
14
|
+
const validStats = ["attack", "defense", "resistance", "weight", "stability", "spin", "control", "bounce", "precision"];
|
|
15
|
+
if (!validStats.includes(stat)) {
|
|
16
|
+
console.error(chalk.red(`\n Invalid stat: "${stat}". Choices: ${validStats.join(", ")}`));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const data = await api.topTazos(stat, parseInt(opts.limit));
|
|
20
|
+
console.log(banner(`Top ${opts.limit} by ${stat.toUpperCase()}`));
|
|
21
|
+
if (opts.franchise) {
|
|
22
|
+
console.log(chalk.dim(` Franchise filter: ${opts.franchise}`));
|
|
23
|
+
}
|
|
24
|
+
for (let i = 0; i < data.tazos.length; i++) {
|
|
25
|
+
const t = data.tazos[i];
|
|
26
|
+
const name = t.name || t.displayName || `#${t.number || "?"}`;
|
|
27
|
+
const value = t[stat];
|
|
28
|
+
const rank = chalk.bold(String(i + 1).padStart(2));
|
|
29
|
+
const statName = stat.toUpperCase().padEnd(5);
|
|
30
|
+
const statVal = chalk.yellowBright(String(value).padStart(3));
|
|
31
|
+
const tazoName = chalk.bold(name.padEnd(24));
|
|
32
|
+
const franchiseSlug = typeof t.franchise === "object" && t.franchise ? t.franchise.slug : t.franchise;
|
|
33
|
+
const franchise = chalk.dim(`[${(franchiseSlug || "?").slice(0, 4).toUpperCase()}]`);
|
|
34
|
+
console.log(` ${rank}. ${statName} ${statVal} ${tazoName} ${franchise}`);
|
|
35
|
+
}
|
|
36
|
+
console.log("");
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
console.error(chalk.red(`\n Error: ${err.message}`));
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=top.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"top.js","sourceRoot":"","sources":["../../src/commands/top.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEjC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Tazo } from "../client.js";
|
|
2
|
+
/** Stat name → display label + color */
|
|
3
|
+
export declare const STAT_CONFIG: Record<string, {
|
|
4
|
+
label: string;
|
|
5
|
+
color: (s: string) => string;
|
|
6
|
+
}>;
|
|
7
|
+
/** Rarity → color + stars */
|
|
8
|
+
export declare const RARITY_STYLE: Record<string, {
|
|
9
|
+
color: (s: string) => string;
|
|
10
|
+
stars: string;
|
|
11
|
+
}>;
|
|
12
|
+
export declare const FRANCHISE_COLOR: Record<string, (s: string) => string>;
|
|
13
|
+
/** Draw a horizontal stat bar */
|
|
14
|
+
export declare function statBar(value: number, max: number, width?: number): string;
|
|
15
|
+
/** Format a single tazo for terminal display */
|
|
16
|
+
export declare function formatTazo(t: Tazo, showStats?: boolean): string;
|
|
17
|
+
/** Format a mini battle card for tazos */
|
|
18
|
+
export declare function formatBattleCard(t: Tazo, index: number): string;
|
|
19
|
+
/** Header banner for output */
|
|
20
|
+
export declare function banner(title: string): string;
|
|
21
|
+
/** Format a number with commas */
|
|
22
|
+
export declare function fmt(n: number): string;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
/** Stat name → display label + color */
|
|
3
|
+
export const STAT_CONFIG = {
|
|
4
|
+
attack: { label: "ATK", color: chalk.redBright },
|
|
5
|
+
defense: { label: "DEF", color: chalk.blueBright },
|
|
6
|
+
resistance: { label: "RES", color: chalk.magentaBright },
|
|
7
|
+
weight: { label: "WGT", color: chalk.yellowBright },
|
|
8
|
+
stability: { label: "STB", color: chalk.cyanBright },
|
|
9
|
+
spin: { label: "SPN", color: chalk.greenBright },
|
|
10
|
+
control: { label: "CTL", color: chalk.magenta },
|
|
11
|
+
bounce: { label: "BNC", color: chalk.yellow },
|
|
12
|
+
precision: { label: "PRC", color: chalk.cyan },
|
|
13
|
+
};
|
|
14
|
+
/** Rarity → color + stars */
|
|
15
|
+
export const RARITY_STYLE = {
|
|
16
|
+
common: { color: chalk.gray, stars: "★" },
|
|
17
|
+
uncommon: { color: chalk.green, stars: "★★" },
|
|
18
|
+
rare: { color: chalk.blue, stars: "★★★" },
|
|
19
|
+
ultra: { color: chalk.magenta, stars: "★★★★" },
|
|
20
|
+
legendary: { color: chalk.yellow, stars: "★★★★★" },
|
|
21
|
+
};
|
|
22
|
+
export const FRANCHISE_COLOR = {
|
|
23
|
+
pokemon: chalk.yellowBright,
|
|
24
|
+
"dragon-ball-z": chalk.redBright,
|
|
25
|
+
digimon: chalk.cyanBright,
|
|
26
|
+
};
|
|
27
|
+
/** Draw a horizontal stat bar */
|
|
28
|
+
export function statBar(value, max, width = 20) {
|
|
29
|
+
const filled = Math.round((value / max) * width);
|
|
30
|
+
const bar = "█".repeat(filled) + "░".repeat(width - filled);
|
|
31
|
+
return bar;
|
|
32
|
+
}
|
|
33
|
+
/** Format a single tazo for terminal display */
|
|
34
|
+
export function formatTazo(t, showStats = false) {
|
|
35
|
+
const name = t.name || t.displayName || `#${t.number || "?"}`;
|
|
36
|
+
const slug = chalk.dim(`(${t.slug})`);
|
|
37
|
+
const franchiseName = typeof t.franchise === "object" && t.franchise ? t.franchise.name || t.franchise.slug : t.franchise;
|
|
38
|
+
const franchise = franchiseName || "unknown";
|
|
39
|
+
const fc = FRANCHISE_COLOR[franchise] || chalk.white;
|
|
40
|
+
const rarityStyle = RARITY_STYLE[t.rarity] || { color: chalk.gray, stars: "?" };
|
|
41
|
+
const rarityStr = rarityStyle.color(rarityStyle.stars);
|
|
42
|
+
const owned = t.isOwned ? chalk.green(" ✓") : "";
|
|
43
|
+
let out = ` ${chalk.bold(fc(name.padEnd(22)))} ${slug.padEnd(28)} ${rarityStr} ${chalk.dim(t.rarity.padEnd(10))}${owned}`;
|
|
44
|
+
if (showStats) {
|
|
45
|
+
out += "\n ";
|
|
46
|
+
for (const [key, cfg] of Object.entries(STAT_CONFIG)) {
|
|
47
|
+
const val = t[key];
|
|
48
|
+
out += cfg.color(`${cfg.label} ${String(val).padStart(3)}`) + " ";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
/** Format a mini battle card for tazos */
|
|
54
|
+
export function formatBattleCard(t, index) {
|
|
55
|
+
const name = t.name || t.displayName || "?";
|
|
56
|
+
const fc = FRANCHISE_COLOR[t.franchise || "unknown"] || chalk.white;
|
|
57
|
+
return [
|
|
58
|
+
` ${chalk.bold(`[${index + 1}]`)} ${fc(name.padEnd(20))}`,
|
|
59
|
+
` ${chalk.red(`ATK ${String(t.attack).padStart(3)}`)} ${chalk.blue(`DEF ${String(t.defense).padStart(3)}`)} ${chalk.cyan(`PRC ${String(t.precision).padStart(3)}`)} ${chalk.yellow(`BNC ${String(t.bounce).padStart(3)}`)}`,
|
|
60
|
+
` ${chalk.magenta(`RES ${String(t.resistance).padStart(3)}`)} ${chalk.yellowBright(`WGT ${String(t.weight).padStart(3)}`)} ${chalk.cyanBright(`STB ${String(t.stability).padStart(3)}`)} ${chalk.green(`SPN ${String(t.spin).padStart(3)}`)} ${chalk.magentaBright(`CTL ${String(t.control).padStart(3)}`)}`,
|
|
61
|
+
].join("\n");
|
|
62
|
+
}
|
|
63
|
+
/** Header banner for output */
|
|
64
|
+
export function banner(title) {
|
|
65
|
+
const width = 60;
|
|
66
|
+
const pad = Math.max(0, width - title.length - 4);
|
|
67
|
+
return chalk.bold.yellow("\n" + "═".repeat(2) + " " + title + " " + "═".repeat(pad));
|
|
68
|
+
}
|
|
69
|
+
/** Format a number with commas */
|
|
70
|
+
export function fmt(n) {
|
|
71
|
+
return n.toLocaleString("en-US");
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trading-tazos-game/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official CLI for the Trading Tazos Game — search, battle, and manage your digital tazo collection from the terminal",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Trading Tazos Game <support@medaclawarena.com>",
|
|
7
|
+
"homepage": "https://medaclawarena.com",
|
|
8
|
+
"repository": "github:smouj/trading-tazos-game-cli",
|
|
9
|
+
"bugs": "https://github.com/smouj/trading-tazos-game-cli/issues",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"tazos",
|
|
12
|
+
"pogs",
|
|
13
|
+
"trading-card-game",
|
|
14
|
+
"cli",
|
|
15
|
+
"collectibles",
|
|
16
|
+
"pokemon",
|
|
17
|
+
"dragon-ball-z",
|
|
18
|
+
"digimon",
|
|
19
|
+
"nostalgia",
|
|
20
|
+
"retro-gaming",
|
|
21
|
+
"battle-game",
|
|
22
|
+
"collection-manager"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"bin": {
|
|
28
|
+
"tazos": "./dist/cli.js"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist/",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc",
|
|
37
|
+
"dev": "tsc --watch",
|
|
38
|
+
"prepublishOnly": "npm run build",
|
|
39
|
+
"start": "node dist/cli.js",
|
|
40
|
+
"lint": "eslint src/"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"chalk": "^5.4.1",
|
|
44
|
+
"commander": "^13.1.0",
|
|
45
|
+
"table": "^6.9.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^22.0.0",
|
|
49
|
+
"typescript": "^5.8.0"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18.0.0"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public"
|
|
56
|
+
}
|
|
57
|
+
}
|