star-sdk-cli 0.1.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/cli.mjs +218 -0
- package/package.json +28 -0
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
var VERSION = "0.1.0";
|
|
7
|
+
var API_BASE = process.env.STAR_API_BASE || "https://buildwithstar.com";
|
|
8
|
+
var CONFIG_FILE = ".starrc";
|
|
9
|
+
var colors = {
|
|
10
|
+
reset: "\x1B[0m",
|
|
11
|
+
bright: "\x1B[1m",
|
|
12
|
+
dim: "\x1B[2m",
|
|
13
|
+
green: "\x1B[32m",
|
|
14
|
+
yellow: "\x1B[33m",
|
|
15
|
+
blue: "\x1B[34m",
|
|
16
|
+
red: "\x1B[31m",
|
|
17
|
+
cyan: "\x1B[36m"
|
|
18
|
+
};
|
|
19
|
+
function log(message) {
|
|
20
|
+
console.log(message);
|
|
21
|
+
}
|
|
22
|
+
function success(message) {
|
|
23
|
+
console.log(`${colors.green}\u2713${colors.reset} ${message}`);
|
|
24
|
+
}
|
|
25
|
+
function error(message) {
|
|
26
|
+
console.error(`${colors.red}\u2717${colors.reset} ${message}`);
|
|
27
|
+
}
|
|
28
|
+
function info(message) {
|
|
29
|
+
console.log(`${colors.blue}\u2139${colors.reset} ${message}`);
|
|
30
|
+
}
|
|
31
|
+
function showHelp() {
|
|
32
|
+
log(`
|
|
33
|
+
${colors.bright}Star SDK CLI${colors.reset} v${VERSION}
|
|
34
|
+
|
|
35
|
+
${colors.dim}Commands:${colors.reset}
|
|
36
|
+
${colors.cyan}init <name>${colors.reset} Register a new game
|
|
37
|
+
${colors.cyan}whoami${colors.reset} Show current configuration
|
|
38
|
+
|
|
39
|
+
${colors.dim}Options:${colors.reset}
|
|
40
|
+
--email <email> Email for higher rate limits (optional)
|
|
41
|
+
--help Show this help message
|
|
42
|
+
--version Show version
|
|
43
|
+
|
|
44
|
+
${colors.dim}Examples:${colors.reset}
|
|
45
|
+
${colors.dim}# Register a new game${colors.reset}
|
|
46
|
+
npx star-sdk init "My Awesome Game"
|
|
47
|
+
|
|
48
|
+
${colors.dim}# Register with email for higher limits${colors.reset}
|
|
49
|
+
npx star-sdk init "My Awesome Game" --email user@example.com
|
|
50
|
+
|
|
51
|
+
${colors.dim}# Using environment variable${colors.reset}
|
|
52
|
+
STAR_EMAIL=user@example.com npx star-sdk init "My Awesome Game"
|
|
53
|
+
|
|
54
|
+
${colors.dim}Learn more:${colors.reset} https://buildwithstar.com/docs/sdk
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
function showVersion() {
|
|
58
|
+
log(`star-sdk-cli v${VERSION}`);
|
|
59
|
+
}
|
|
60
|
+
function loadConfig() {
|
|
61
|
+
const configPath = path.join(process.cwd(), CONFIG_FILE);
|
|
62
|
+
if (!fs.existsSync(configPath)) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
67
|
+
return JSON.parse(content);
|
|
68
|
+
} catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function saveConfig(config) {
|
|
73
|
+
const configPath = path.join(process.cwd(), CONFIG_FILE);
|
|
74
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
75
|
+
}
|
|
76
|
+
async function initCommand(name, email) {
|
|
77
|
+
if (!name || name.trim().length === 0) {
|
|
78
|
+
error("Game name is required");
|
|
79
|
+
log('\nUsage: npx star-sdk init "Game Name"');
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
const existing = loadConfig();
|
|
83
|
+
if (existing) {
|
|
84
|
+
info(`Found existing config for "${existing.name}" (${existing.gameId})`);
|
|
85
|
+
log("");
|
|
86
|
+
}
|
|
87
|
+
log(`Registering game: ${colors.bright}${name}${colors.reset}`);
|
|
88
|
+
try {
|
|
89
|
+
const response = await fetch(`${API_BASE}/api/sdk/games`, {
|
|
90
|
+
method: "POST",
|
|
91
|
+
headers: {
|
|
92
|
+
"Content-Type": "application/json"
|
|
93
|
+
},
|
|
94
|
+
body: JSON.stringify({
|
|
95
|
+
name: name.trim(),
|
|
96
|
+
email: email?.trim() || void 0
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const data2 = await response.json().catch(() => ({}));
|
|
101
|
+
if (response.status === 429) {
|
|
102
|
+
error("Rate limit exceeded. Maximum 10 games per hour.");
|
|
103
|
+
log("Try again later or provide an email for higher limits.");
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
error(data2.error || `Failed to register game (HTTP ${response.status})`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
const data = await response.json();
|
|
110
|
+
const config = {
|
|
111
|
+
gameId: data.gameId,
|
|
112
|
+
name: data.name,
|
|
113
|
+
email: email?.trim(),
|
|
114
|
+
dashboardUrl: data.dashboardUrl
|
|
115
|
+
};
|
|
116
|
+
saveConfig(config);
|
|
117
|
+
log("");
|
|
118
|
+
success(`Game registered successfully!`);
|
|
119
|
+
log("");
|
|
120
|
+
log(` ${colors.dim}Game ID:${colors.reset} ${colors.cyan}${data.gameId}${colors.reset}`);
|
|
121
|
+
log(` ${colors.dim}Dashboard:${colors.reset} ${colors.cyan}${data.dashboardUrl}${colors.reset}`);
|
|
122
|
+
log("");
|
|
123
|
+
log(`${colors.dim}Config saved to${colors.reset} ${colors.bright}.starrc${colors.reset}`);
|
|
124
|
+
log("");
|
|
125
|
+
log(`${colors.dim}Next steps:${colors.reset}`);
|
|
126
|
+
log(` 1. Import Star SDK in your game`);
|
|
127
|
+
log(` 2. Use Star.leaderboard.submit(score) to submit scores`);
|
|
128
|
+
log("");
|
|
129
|
+
log(`${colors.dim}Example:${colors.reset}`);
|
|
130
|
+
log(` ${colors.cyan}import Star from 'star-sdk';${colors.reset}`);
|
|
131
|
+
log(` ${colors.cyan}Star.leaderboard.submit(1500);${colors.reset}`);
|
|
132
|
+
log("");
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (err.code === "ECONNREFUSED" || err.code === "ENOTFOUND") {
|
|
135
|
+
error("Could not connect to Star API. Check your internet connection.");
|
|
136
|
+
} else {
|
|
137
|
+
error(err.message || "Failed to register game");
|
|
138
|
+
}
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function whoamiCommand() {
|
|
143
|
+
const config = loadConfig();
|
|
144
|
+
if (!config) {
|
|
145
|
+
info("No .starrc found in current directory");
|
|
146
|
+
log("");
|
|
147
|
+
log('Run "npx star-sdk init <name>" to register a game.');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
log("");
|
|
151
|
+
log(`${colors.bright}Current Configuration${colors.reset}`);
|
|
152
|
+
log("");
|
|
153
|
+
log(` ${colors.dim}Game:${colors.reset} ${config.name}`);
|
|
154
|
+
log(` ${colors.dim}Game ID:${colors.reset} ${colors.cyan}${config.gameId}${colors.reset}`);
|
|
155
|
+
if (config.email) {
|
|
156
|
+
log(` ${colors.dim}Email:${colors.reset} ${config.email}`);
|
|
157
|
+
}
|
|
158
|
+
if (config.dashboardUrl) {
|
|
159
|
+
log(` ${colors.dim}Dashboard:${colors.reset} ${colors.cyan}${config.dashboardUrl}${colors.reset}`);
|
|
160
|
+
}
|
|
161
|
+
log("");
|
|
162
|
+
}
|
|
163
|
+
function parseArgs(args) {
|
|
164
|
+
const flags = {};
|
|
165
|
+
const positional = [];
|
|
166
|
+
let command = "";
|
|
167
|
+
for (let i = 0; i < args.length; i++) {
|
|
168
|
+
const arg = args[i];
|
|
169
|
+
if (arg.startsWith("--")) {
|
|
170
|
+
const key = arg.slice(2);
|
|
171
|
+
const nextArg = args[i + 1];
|
|
172
|
+
if (nextArg && !nextArg.startsWith("--")) {
|
|
173
|
+
flags[key] = nextArg;
|
|
174
|
+
i++;
|
|
175
|
+
} else {
|
|
176
|
+
flags[key] = true;
|
|
177
|
+
}
|
|
178
|
+
} else if (!command) {
|
|
179
|
+
command = arg;
|
|
180
|
+
} else {
|
|
181
|
+
positional.push(arg);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return { command, positional, flags };
|
|
185
|
+
}
|
|
186
|
+
async function main() {
|
|
187
|
+
const args = process.argv.slice(2);
|
|
188
|
+
const { command, positional, flags } = parseArgs(args);
|
|
189
|
+
if (flags.help || flags.h) {
|
|
190
|
+
showHelp();
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (flags.version || flags.v) {
|
|
194
|
+
showVersion();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const email = flags.email || process.env.STAR_EMAIL;
|
|
198
|
+
switch (command) {
|
|
199
|
+
case "init":
|
|
200
|
+
await initCommand(positional[0], email);
|
|
201
|
+
break;
|
|
202
|
+
case "whoami":
|
|
203
|
+
whoamiCommand();
|
|
204
|
+
break;
|
|
205
|
+
case "":
|
|
206
|
+
showHelp();
|
|
207
|
+
break;
|
|
208
|
+
default:
|
|
209
|
+
error(`Unknown command: ${command}`);
|
|
210
|
+
log("");
|
|
211
|
+
log('Run "npx star-sdk --help" for available commands.');
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
main().catch((err) => {
|
|
216
|
+
error(err.message || "An unexpected error occurred");
|
|
217
|
+
process.exit(1);
|
|
218
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "star-sdk-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI tool for Star SDK - register games and manage leaderboards",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"star-sdk": "./dist/cli.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsup",
|
|
14
|
+
"dev": "tsx src/cli.ts"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"star",
|
|
18
|
+
"sdk",
|
|
19
|
+
"cli",
|
|
20
|
+
"games",
|
|
21
|
+
"leaderboard"
|
|
22
|
+
],
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"tsup": "^8.0.0",
|
|
25
|
+
"tsx": "^4.7.0",
|
|
26
|
+
"typescript": "^5.4.5"
|
|
27
|
+
}
|
|
28
|
+
}
|