@timecell/cli 0.1.1 → 0.2.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/dist/wizard.d.ts +9 -0
- package/dist/wizard.d.ts.map +1 -1
- package/dist/wizard.js +49 -12
- package/dist/wizard.js.map +1 -1
- package/package.json +3 -3
package/dist/wizard.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { PortfolioInput } from "@timecell/engine";
|
|
2
|
+
export interface CurrencyOption {
|
|
3
|
+
code: string;
|
|
4
|
+
symbol: string;
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
2
7
|
export interface WizardResult {
|
|
3
8
|
portfolio: PortfolioInput;
|
|
9
|
+
currency: {
|
|
10
|
+
code: string;
|
|
11
|
+
symbol: string;
|
|
12
|
+
};
|
|
4
13
|
}
|
|
5
14
|
export declare function runWizard(): Promise<WizardResult>;
|
|
6
15
|
//# sourceMappingURL=wizard.d.ts.map
|
package/dist/wizard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAUD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C;AA0DD,wBAAsB,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,CAyCvD"}
|
package/dist/wizard.js
CHANGED
|
@@ -1,16 +1,46 @@
|
|
|
1
|
-
import { input, number } from "@inquirer/prompts";
|
|
1
|
+
import { input, number, select } from "@inquirer/prompts";
|
|
2
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
const CONFIG_DIR = join(homedir(), ".timecell");
|
|
6
6
|
const PORTFOLIO_PATH = join(CONFIG_DIR, "portfolio.json");
|
|
7
|
+
const CURRENCIES = [
|
|
8
|
+
{ code: "USD", symbol: "$", name: "USD ($)" },
|
|
9
|
+
{ code: "INR", symbol: "\u20B9", name: "INR (\u20B9)" },
|
|
10
|
+
{ code: "EUR", symbol: "\u20AC", name: "EUR (\u20AC)" },
|
|
11
|
+
{ code: "GBP", symbol: "\u00A3", name: "GBP (\u00A3)" },
|
|
12
|
+
{ code: "SGD", symbol: "S$", name: "SGD (S$)" },
|
|
13
|
+
];
|
|
14
|
+
const SUFFIX_MULTIPLIERS = {
|
|
15
|
+
k: 1_000,
|
|
16
|
+
m: 1_000_000,
|
|
17
|
+
b: 1_000_000_000,
|
|
18
|
+
cr: 10_000_000,
|
|
19
|
+
lk: 100_000,
|
|
20
|
+
l: 100_000,
|
|
21
|
+
};
|
|
22
|
+
// Matches optional number (with decimals) followed by optional suffix
|
|
23
|
+
const SHORTHAND_RE = /^([0-9]*\.?[0-9]+)\s*(k|m|b|cr|lk|l)$/i;
|
|
7
24
|
function parseNumber(raw) {
|
|
8
|
-
// Strip commas, currency symbols, whitespace
|
|
9
|
-
const cleaned = raw.replace(/[
|
|
25
|
+
// Strip commas, currency symbols, whitespace (but preserve suffix letters)
|
|
26
|
+
const cleaned = raw.replace(/[$\u20B9\u20AC\u00A3,\s]|S\$/g, "");
|
|
27
|
+
if (cleaned === "")
|
|
28
|
+
return undefined;
|
|
29
|
+
// Try shorthand suffix match first (e.g. "5m", "25k", "1.5b", "50cr", "10l")
|
|
30
|
+
const match = cleaned.match(SHORTHAND_RE);
|
|
31
|
+
if (match) {
|
|
32
|
+
const num = Number.parseFloat(match[1]);
|
|
33
|
+
const suffix = match[2].toLowerCase();
|
|
34
|
+
const multiplier = SUFFIX_MULTIPLIERS[suffix];
|
|
35
|
+
if (Number.isNaN(num) || !multiplier)
|
|
36
|
+
return undefined;
|
|
37
|
+
return num * multiplier;
|
|
38
|
+
}
|
|
39
|
+
// Fall back to standard number parsing
|
|
10
40
|
const num = Number(cleaned);
|
|
11
41
|
return Number.isNaN(num) ? undefined : num;
|
|
12
42
|
}
|
|
13
|
-
async function
|
|
43
|
+
async function askAmount(message, defaultVal, currencySymbol) {
|
|
14
44
|
const formatted = defaultVal.toLocaleString("en-US");
|
|
15
45
|
const raw = await input({
|
|
16
46
|
message,
|
|
@@ -18,7 +48,7 @@ async function askUsd(message, defaultVal) {
|
|
|
18
48
|
validate: (v) => {
|
|
19
49
|
const num = parseNumber(v);
|
|
20
50
|
if (num === undefined || num <= 0)
|
|
21
|
-
return
|
|
51
|
+
return `Enter a positive number (e.g. ${currencySymbol}5,000,000 or 5m or 50cr)`;
|
|
22
52
|
return true;
|
|
23
53
|
},
|
|
24
54
|
});
|
|
@@ -36,17 +66,24 @@ async function fetchBtcPrice() {
|
|
|
36
66
|
}
|
|
37
67
|
export async function runWizard() {
|
|
38
68
|
console.log("\nLet's configure your portfolio.\n");
|
|
39
|
-
|
|
69
|
+
const currencyCode = await select({
|
|
70
|
+
message: "Select your currency:",
|
|
71
|
+
choices: CURRENCIES.map((c) => ({ name: c.name, value: c.code })),
|
|
72
|
+
default: "USD",
|
|
73
|
+
});
|
|
74
|
+
const currency = CURRENCIES.find((c) => c.code === currencyCode);
|
|
75
|
+
const sym = currency.symbol;
|
|
76
|
+
console.log(`\n Your data stays local (~/.timecell/).\n`);
|
|
40
77
|
const btcPrice = await fetchBtcPrice();
|
|
41
|
-
console.log(` Current BTC price:
|
|
42
|
-
const totalValueUsd = await
|
|
78
|
+
console.log(` Current BTC price: ${sym}${btcPrice.toLocaleString("en-US")} (live)\n`);
|
|
79
|
+
const totalValueUsd = await askAmount(`Total portfolio value (${currency.code}):`, 5_000_000, sym);
|
|
43
80
|
const btcPercentage = await number({
|
|
44
81
|
message: "Bitcoin allocation (%):",
|
|
45
82
|
default: 35,
|
|
46
83
|
validate: (v) => (v !== undefined && v >= 0 && v <= 100 ? true : "Must be between 0 and 100"),
|
|
47
84
|
});
|
|
48
|
-
const monthlyBurnUsd = await
|
|
49
|
-
const liquidReserveUsd = await
|
|
85
|
+
const monthlyBurnUsd = await askAmount(`Monthly burn rate (${currency.code}):`, 25_000, sym);
|
|
86
|
+
const liquidReserveUsd = await askAmount(`Liquid reserve (${currency.code}):`, 600_000, sym);
|
|
50
87
|
const portfolio = {
|
|
51
88
|
totalValueUsd,
|
|
52
89
|
btcPercentage,
|
|
@@ -55,8 +92,8 @@ export async function runWizard() {
|
|
|
55
92
|
btcPriceUsd: btcPrice,
|
|
56
93
|
};
|
|
57
94
|
await mkdir(CONFIG_DIR, { recursive: true });
|
|
58
|
-
await writeFile(PORTFOLIO_PATH, JSON.stringify({ portfolio }, null, 2));
|
|
95
|
+
await writeFile(PORTFOLIO_PATH, JSON.stringify({ portfolio, currency: { code: currency.code, symbol: sym } }, null, 2));
|
|
59
96
|
console.log(`\nPortfolio saved to ${PORTFOLIO_PATH}`);
|
|
60
|
-
return { portfolio };
|
|
97
|
+
return { portfolio, currency: { code: currency.code, symbol: sym } };
|
|
61
98
|
}
|
|
62
99
|
//# sourceMappingURL=wizard.js.map
|
package/dist/wizard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timecell/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "TimeCell CLI — Crash Survival Calculator",
|
|
6
6
|
"bin": {
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@inquirer/prompts": "^7",
|
|
21
|
-
"@timecell/api": "
|
|
22
|
-
"@timecell/engine": "
|
|
21
|
+
"@timecell/api": "*",
|
|
22
|
+
"@timecell/engine": "*",
|
|
23
23
|
"open": "^10"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|