terminalmarket 0.5.1 → 0.6.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.
- package/bin/tm.js +216 -2
- package/package.json +1 -1
package/bin/tm.js
CHANGED
|
@@ -13,7 +13,7 @@ const program = new Command();
|
|
|
13
13
|
program
|
|
14
14
|
.name("tm")
|
|
15
15
|
.description("TerminalMarket CLI — marketplace for developers")
|
|
16
|
-
.version("0.
|
|
16
|
+
.version("0.6.0");
|
|
17
17
|
|
|
18
18
|
// -----------------
|
|
19
19
|
// config
|
|
@@ -54,12 +54,15 @@ program
|
|
|
54
54
|
.command("register <email> <password>")
|
|
55
55
|
.description("Create a new account")
|
|
56
56
|
.option("-n, --name <name>", "Your name")
|
|
57
|
+
.option("-u, --username <username>", "Username")
|
|
57
58
|
.action(async (email, password, opts) => {
|
|
58
59
|
try {
|
|
60
|
+
const username = opts.username || email.split("@")[0];
|
|
59
61
|
const result = await apiPost("/auth/register", {
|
|
60
62
|
email,
|
|
61
63
|
password,
|
|
62
|
-
|
|
64
|
+
username,
|
|
65
|
+
name: opts.name || username
|
|
63
66
|
});
|
|
64
67
|
|
|
65
68
|
if (result.user) {
|
|
@@ -110,6 +113,45 @@ program
|
|
|
110
113
|
}
|
|
111
114
|
});
|
|
112
115
|
|
|
116
|
+
// GitHub auth - opens browser
|
|
117
|
+
program
|
|
118
|
+
.command("auth")
|
|
119
|
+
.description("Authenticate with GitHub (opens browser)")
|
|
120
|
+
.argument("[provider]", "Auth provider (github)")
|
|
121
|
+
.action(async (provider) => {
|
|
122
|
+
if (!provider || provider === "github") {
|
|
123
|
+
const apiBase = getApiBase();
|
|
124
|
+
const authUrl = `${apiBase}/auth/github`;
|
|
125
|
+
console.log(chalk.green("Opening GitHub authentication..."));
|
|
126
|
+
console.log(chalk.dim(authUrl));
|
|
127
|
+
try {
|
|
128
|
+
await open(authUrl);
|
|
129
|
+
console.log(chalk.dim("Complete login in browser, then run 'tm whoami' to verify."));
|
|
130
|
+
} catch {
|
|
131
|
+
console.log(chalk.yellow("Could not open browser. Visit manually:"));
|
|
132
|
+
console.log(authUrl);
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
console.error(chalk.red(`Unknown provider: ${provider}. Use 'github'.`));
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
program
|
|
140
|
+
.command("github")
|
|
141
|
+
.description("Login with GitHub (opens browser)")
|
|
142
|
+
.action(async () => {
|
|
143
|
+
const apiBase = getApiBase();
|
|
144
|
+
const authUrl = `${apiBase}/auth/github`;
|
|
145
|
+
console.log(chalk.green("Opening GitHub authentication..."));
|
|
146
|
+
try {
|
|
147
|
+
await open(authUrl);
|
|
148
|
+
console.log(chalk.dim("Complete login in browser, then run 'tm whoami' to verify."));
|
|
149
|
+
} catch {
|
|
150
|
+
console.log(chalk.yellow("Could not open browser. Visit:"));
|
|
151
|
+
console.log(authUrl);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
113
155
|
program
|
|
114
156
|
.command("whoami")
|
|
115
157
|
.alias("me")
|
|
@@ -685,6 +727,178 @@ program
|
|
|
685
727
|
}
|
|
686
728
|
});
|
|
687
729
|
|
|
730
|
+
// -----------------
|
|
731
|
+
// alias commands
|
|
732
|
+
// -----------------
|
|
733
|
+
const alias = program
|
|
734
|
+
.command("alias")
|
|
735
|
+
.description("Manage custom command aliases");
|
|
736
|
+
|
|
737
|
+
alias
|
|
738
|
+
.command("list")
|
|
739
|
+
.alias("ls")
|
|
740
|
+
.description("List your aliases")
|
|
741
|
+
.action(async () => {
|
|
742
|
+
try {
|
|
743
|
+
const aliases = await apiGet("/aliases");
|
|
744
|
+
|
|
745
|
+
if (!aliases || aliases.length === 0) {
|
|
746
|
+
console.log(chalk.yellow("No aliases defined."));
|
|
747
|
+
console.log(chalk.dim("Create one: tm alias add <name> <command>"));
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
console.log(chalk.bold("Your Aliases"));
|
|
752
|
+
console.log("");
|
|
753
|
+
aliases.forEach(a => {
|
|
754
|
+
console.log(` ${chalk.cyan(a.name)} → ${a.command}`);
|
|
755
|
+
});
|
|
756
|
+
} catch (e) {
|
|
757
|
+
if (e?.message?.includes("401")) {
|
|
758
|
+
console.log(chalk.yellow("Please login first."));
|
|
759
|
+
} else {
|
|
760
|
+
console.error(chalk.red(e?.message || String(e)));
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
alias
|
|
766
|
+
.command("add <name> <command...>")
|
|
767
|
+
.description("Create an alias")
|
|
768
|
+
.action(async (name, command) => {
|
|
769
|
+
try {
|
|
770
|
+
const commandStr = command.join(" ");
|
|
771
|
+
await apiPost("/aliases", { name, command: commandStr });
|
|
772
|
+
console.log(chalk.green(`Alias created: ${name} → ${commandStr}`));
|
|
773
|
+
} catch (e) {
|
|
774
|
+
console.error(chalk.red(e?.message || String(e)));
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
alias
|
|
779
|
+
.command("remove <name>")
|
|
780
|
+
.alias("rm")
|
|
781
|
+
.description("Remove an alias")
|
|
782
|
+
.action(async (name) => {
|
|
783
|
+
try {
|
|
784
|
+
await apiDelete(`/aliases/${encodeURIComponent(name)}`);
|
|
785
|
+
console.log(chalk.green(`Alias '${name}' removed.`));
|
|
786
|
+
} catch (e) {
|
|
787
|
+
console.error(chalk.red(e?.message || String(e)));
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
program
|
|
792
|
+
.command("aliases")
|
|
793
|
+
.description("List your aliases (shortcut)")
|
|
794
|
+
.action(async () => {
|
|
795
|
+
try {
|
|
796
|
+
const aliases = await apiGet("/aliases");
|
|
797
|
+
if (!aliases || aliases.length === 0) {
|
|
798
|
+
console.log(chalk.yellow("No aliases. Create: tm alias add <name> <command>"));
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
aliases.forEach(a => {
|
|
802
|
+
console.log(`${chalk.cyan(a.name)} → ${a.command}`);
|
|
803
|
+
});
|
|
804
|
+
} catch (e) {
|
|
805
|
+
if (e?.message?.includes("401")) {
|
|
806
|
+
console.log(chalk.yellow("Please login first."));
|
|
807
|
+
} else {
|
|
808
|
+
console.error(chalk.red(e?.message || String(e)));
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
// -----------------
|
|
814
|
+
// reward commands (Push Rewards)
|
|
815
|
+
// -----------------
|
|
816
|
+
const reward = program
|
|
817
|
+
.command("reward")
|
|
818
|
+
.description("Manage push rewards (auto-order after GitHub pushes)");
|
|
819
|
+
|
|
820
|
+
reward
|
|
821
|
+
.command("list")
|
|
822
|
+
.alias("ls")
|
|
823
|
+
.description("List your reward rules")
|
|
824
|
+
.action(async () => {
|
|
825
|
+
try {
|
|
826
|
+
const rules = await apiGet("/rewards");
|
|
827
|
+
|
|
828
|
+
if (!rules || rules.length === 0) {
|
|
829
|
+
console.log(chalk.yellow("No reward rules defined."));
|
|
830
|
+
console.log(chalk.dim("Create one: tm reward add <productId> <pushCount>"));
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
console.log(chalk.bold("Your Reward Rules"));
|
|
835
|
+
console.log("");
|
|
836
|
+
rules.forEach(r => {
|
|
837
|
+
const status = r.active ? chalk.green("active") : chalk.dim("paused");
|
|
838
|
+
console.log(` Product #${r.productId}: every ${r.pushCount} pushes [${status}]`);
|
|
839
|
+
console.log(` ${chalk.dim(`progress: ${r.currentPushes || 0}/${r.pushCount}`)}`);
|
|
840
|
+
});
|
|
841
|
+
} catch (e) {
|
|
842
|
+
if (e?.message?.includes("401")) {
|
|
843
|
+
console.log(chalk.yellow("Please login first."));
|
|
844
|
+
} else {
|
|
845
|
+
console.error(chalk.red(e?.message || String(e)));
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
reward
|
|
851
|
+
.command("add <productId> <pushCount>")
|
|
852
|
+
.description("Create a reward rule (auto-order after N pushes)")
|
|
853
|
+
.action(async (productId, pushCount) => {
|
|
854
|
+
try {
|
|
855
|
+
await apiPost("/rewards", {
|
|
856
|
+
productId: parseInt(productId),
|
|
857
|
+
pushCount: parseInt(pushCount)
|
|
858
|
+
});
|
|
859
|
+
console.log(chalk.green(`Reward rule created! Product #${productId} every ${pushCount} pushes.`));
|
|
860
|
+
console.log(chalk.dim("Connect GitHub webhook to start tracking pushes."));
|
|
861
|
+
} catch (e) {
|
|
862
|
+
console.error(chalk.red(e?.message || String(e)));
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
reward
|
|
867
|
+
.command("remove <productId>")
|
|
868
|
+
.alias("rm")
|
|
869
|
+
.description("Remove a reward rule")
|
|
870
|
+
.action(async (productId) => {
|
|
871
|
+
try {
|
|
872
|
+
await apiDelete(`/rewards/${productId}`);
|
|
873
|
+
console.log(chalk.green(`Reward rule for product #${productId} removed.`));
|
|
874
|
+
} catch (e) {
|
|
875
|
+
console.error(chalk.red(e?.message || String(e)));
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
program
|
|
880
|
+
.command("rewards")
|
|
881
|
+
.description("List reward rules (shortcut)")
|
|
882
|
+
.action(async () => {
|
|
883
|
+
try {
|
|
884
|
+
const rules = await apiGet("/rewards");
|
|
885
|
+
if (!rules || rules.length === 0) {
|
|
886
|
+
console.log(chalk.yellow("No reward rules. Create: tm reward add <productId> <pushCount>"));
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
rules.forEach(r => {
|
|
890
|
+
const status = r.active ? chalk.green("✓") : chalk.dim("○");
|
|
891
|
+
console.log(`${status} Product #${r.productId}: every ${r.pushCount} pushes (${r.currentPushes || 0}/${r.pushCount})`);
|
|
892
|
+
});
|
|
893
|
+
} catch (e) {
|
|
894
|
+
if (e?.message?.includes("401")) {
|
|
895
|
+
console.log(chalk.yellow("Please login first."));
|
|
896
|
+
} else {
|
|
897
|
+
console.error(chalk.red(e?.message || String(e)));
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
|
|
688
902
|
// -----------------
|
|
689
903
|
// categories
|
|
690
904
|
// -----------------
|