onflyt-cli 1.0.1-beta.2 → 1.0.1-beta.3

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.
Files changed (67) hide show
  1. package/dist/App.d.ts +3 -0
  2. package/dist/App.js +8 -0
  3. package/dist/commands/credits.d.ts +3 -0
  4. package/dist/commands/credits.js +101 -0
  5. package/dist/commands/delete.d.ts +7 -0
  6. package/dist/commands/delete.js +220 -0
  7. package/dist/commands/deploy.d.ts +6 -0
  8. package/dist/commands/deploy.js +715 -0
  9. package/dist/commands/deployments.d.ts +6 -0
  10. package/dist/commands/deployments.js +225 -0
  11. package/dist/commands/help.d.ts +3 -0
  12. package/dist/commands/help.js +76 -0
  13. package/dist/commands/init.d.ts +11 -0
  14. package/dist/commands/init.js +422 -0
  15. package/dist/commands/login.d.ts +6 -0
  16. package/dist/commands/login.js +150 -0
  17. package/dist/commands/logout.d.ts +3 -0
  18. package/dist/commands/logout.js +19 -0
  19. package/dist/commands/logs.d.ts +7 -0
  20. package/dist/commands/logs.js +307 -0
  21. package/dist/commands/projects.d.ts +3 -0
  22. package/dist/commands/projects.js +203 -0
  23. package/dist/commands/rollback.d.ts +6 -0
  24. package/dist/commands/rollback.js +316 -0
  25. package/dist/commands/teams.d.ts +3 -0
  26. package/dist/commands/teams.js +81 -0
  27. package/dist/commands/whoami.d.ts +3 -0
  28. package/dist/commands/whoami.js +34 -0
  29. package/dist/components/Loading.d.ts +13 -0
  30. package/dist/components/Loading.js +42 -0
  31. package/dist/index.d.ts +1 -0
  32. package/dist/index.js +77 -116
  33. package/dist/lib/api.d.ts +27 -0
  34. package/dist/lib/api.js +109 -0
  35. package/dist/lib/config.d.ts +32 -0
  36. package/dist/lib/config.js +52 -0
  37. package/dist/lib/deploy-api.d.ts +97 -0
  38. package/dist/lib/deploy-api.js +335 -0
  39. package/dist/lib/deploy.d.ts +36 -0
  40. package/dist/lib/deploy.js +181 -0
  41. package/dist/lib/framework.d.ts +27 -0
  42. package/dist/lib/framework.js +184 -0
  43. package/dist/lib/git.d.ts +25 -0
  44. package/dist/lib/git.js +149 -0
  45. package/dist/lib/scaffold.d.ts +21 -0
  46. package/dist/lib/scaffold.js +190 -0
  47. package/dist/shared/frameworks/registry.d.ts +21 -0
  48. package/dist/shared/frameworks/registry.js +196 -0
  49. package/dist/shared/index.d.ts +4 -0
  50. package/dist/shared/index.js +4 -0
  51. package/dist/shared/limits.d.ts +16 -0
  52. package/dist/shared/limits.js +44 -0
  53. package/dist/shared/pricing.d.ts +2 -0
  54. package/dist/shared/pricing.js +7 -0
  55. package/dist/shared/templates/registry.d.ts +9 -0
  56. package/dist/shared/templates/registry.js +47 -0
  57. package/package.json +2 -3
  58. package/src/App.tsx +1 -1
  59. package/src/commands/deploy.tsx +1 -1
  60. package/src/commands/help.tsx +1 -1
  61. package/src/commands/init.tsx +1 -1
  62. package/src/commands/projects.tsx +1 -1
  63. package/src/components/Loading.tsx +1 -1
  64. package/src/index.tsx +1 -1
  65. package/src/lib/deploy-api.ts +3 -3
  66. package/src/lib/framework.ts +2 -2
  67. package/src/lib/shared.ts +350 -0
package/dist/App.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const App: () => React.JSX.Element;
3
+ export default App;
package/dist/App.js ADDED
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import { Text, Box } from "ink";
3
+ const App = () => {
4
+ return (React.createElement(Box, { flexDirection: "column" },
5
+ React.createElement(Text, { bold: true }, "Onflyt CLI v1.0.1-beta.1"),
6
+ React.createElement(Text, null, "Type onflyt --help for available commands")));
7
+ };
8
+ export default App;
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const Credits: () => React.JSX.Element | null;
3
+ export default Credits;
@@ -0,0 +1,101 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { api } from "../lib/api.js";
3
+ import { getConfig, isLoggedIn } from "../lib/config.js";
4
+ import { ErrorDisplay } from "../components/Loading.js";
5
+ const MAX_RETRIES = 3;
6
+ const Credits = () => {
7
+ const [state, setState] = useState("loading");
8
+ const [errorMsg, setErrorMsg] = useState("");
9
+ const [retryCount, setRetryCount] = useState(0);
10
+ const [credits, setCredits] = useState([]);
11
+ useEffect(() => {
12
+ if (state !== "done")
13
+ return;
14
+ console.log("\n Credits Balance\n");
15
+ console.log(" " + "─".repeat(50));
16
+ credits.forEach((item) => {
17
+ const { team, balance } = item;
18
+ const isLow = balance.balanceUSD < 5;
19
+ const plan = team.team.plan || "free";
20
+ console.log(`\n ${team.team.name} (${plan})`);
21
+ if (isLow) {
22
+ console.log(` \x1b[33m Credits: ${balance.balanceFormatted} ⚠ Low credits\x1b[0m`);
23
+ }
24
+ else {
25
+ console.log(` \x1b[32m Credits: ${balance.balanceFormatted} ✓\x1b[0m`);
26
+ }
27
+ });
28
+ console.log("\n " + "─".repeat(50));
29
+ console.log("\n Run 'onflyt add-credits' to add more credits.\n");
30
+ }, [state, credits]);
31
+ useEffect(() => {
32
+ if (!isLoggedIn()) {
33
+ setErrorMsg("Not logged in. Run 'onflyt login' first.");
34
+ setState("error");
35
+ return;
36
+ }
37
+ const fetchCredits = async () => {
38
+ let attempt = 0;
39
+ const attemptFetch = async () => {
40
+ attempt++;
41
+ try {
42
+ console.log(`\n Fetching credits...${attempt > 1 ? ` (retry ${attempt}/${MAX_RETRIES})` : ""}\n`);
43
+ const config = getConfig();
44
+ api.setToken(config.token);
45
+ const meData = await api.get("/auth/me");
46
+ const userTeams = meData.teams || [];
47
+ if (userTeams.length === 0) {
48
+ console.log("\n No teams found.\n");
49
+ console.log(" You don't have any teams yet.\n");
50
+ return;
51
+ }
52
+ const balancesData = {};
53
+ await Promise.all(userTeams.map(async (team) => {
54
+ try {
55
+ const balanceData = await api.get(`/billing/balance?teamId=${team.team.id}`);
56
+ balancesData[team.team.id] = balanceData.data || balanceData;
57
+ }
58
+ catch {
59
+ balancesData[team.team.id] = {
60
+ balanceUSD: 0,
61
+ balanceFormatted: "$0.00",
62
+ };
63
+ }
64
+ }));
65
+ const creditDisplay = userTeams.map((team) => ({
66
+ team,
67
+ balance: balancesData[team.team.id] || {
68
+ balanceUSD: 0,
69
+ balanceFormatted: "$0.00",
70
+ },
71
+ }));
72
+ setCredits(creditDisplay);
73
+ setState("done");
74
+ }
75
+ catch (err) {
76
+ if (attempt < MAX_RETRIES) {
77
+ setRetryCount(attempt);
78
+ return attemptFetch();
79
+ }
80
+ throw err;
81
+ }
82
+ };
83
+ try {
84
+ await attemptFetch();
85
+ }
86
+ catch (err) {
87
+ setErrorMsg(err.message || "Failed to fetch credits");
88
+ setState("error");
89
+ }
90
+ };
91
+ fetchCredits();
92
+ }, []);
93
+ if (state === "loading") {
94
+ return null;
95
+ }
96
+ if (state === "error") {
97
+ return React.createElement(ErrorDisplay, { message: errorMsg });
98
+ }
99
+ return null;
100
+ };
101
+ export default Credits;
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ interface DeleteProps {
3
+ projectId?: string;
4
+ projectName?: string;
5
+ }
6
+ declare const Delete: React.FC<DeleteProps>;
7
+ export default Delete;
@@ -0,0 +1,220 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { Text, Box, useInput } from "ink";
3
+ import { isLoggedIn, getConfig } from "../lib/config.js";
4
+ import { api } from "../lib/api.js";
5
+ import { Logo } from "../components/Loading.js";
6
+ import Spinner from "ink-spinner";
7
+ const Delete = ({ projectId, projectName }) => {
8
+ const [step, setStep] = useState("loading");
9
+ const [teams, setTeams] = useState([]);
10
+ const [projects, setProjects] = useState([]);
11
+ const [selectedTeamIndex, setSelectedTeamIndex] = useState(0);
12
+ const [selectedProjectIndex, setSelectedProjectIndex] = useState(0);
13
+ const [targetProject, setTargetProject] = useState(null);
14
+ const [errorMsg, setErrorMsg] = useState("");
15
+ useEffect(() => {
16
+ const handleSigInt = () => process.exit(0);
17
+ process.on("SIGINT", handleSigInt);
18
+ return () => {
19
+ process.off("SIGINT", handleSigInt);
20
+ };
21
+ }, []);
22
+ useEffect(() => {
23
+ if (step === "done" || step === "error") {
24
+ const timer = setTimeout(() => process.exit(0), 500);
25
+ return () => clearTimeout(timer);
26
+ }
27
+ }, [step]);
28
+ useInput((input, key) => {
29
+ if (input === "q" || input === "Q" || (key.ctrl && input === "c")) {
30
+ process.exit(0);
31
+ }
32
+ if (step === "team") {
33
+ if (key.upArrow) {
34
+ setSelectedTeamIndex((i) => Math.max(0, i - 1));
35
+ }
36
+ else if (key.downArrow) {
37
+ setSelectedTeamIndex((i) => Math.min(teams.length - 1, i + 1));
38
+ }
39
+ else if (key.return) {
40
+ setStep("loading-projects");
41
+ loadProjects(teams[selectedTeamIndex].team.id);
42
+ }
43
+ }
44
+ if (step === "select") {
45
+ if (key.upArrow) {
46
+ setSelectedProjectIndex((i) => Math.max(0, i - 1));
47
+ }
48
+ else if (key.downArrow) {
49
+ setSelectedProjectIndex((i) => Math.min(projects.length - 1, i + 1));
50
+ }
51
+ else if (key.return) {
52
+ setTargetProject(projects[selectedProjectIndex]);
53
+ setStep("confirm");
54
+ }
55
+ else if (key.escape) {
56
+ setStep("team");
57
+ }
58
+ }
59
+ if (step === "confirm") {
60
+ if (input === "y" || input === "Y" || key.return) {
61
+ deleteProject(targetProject.id);
62
+ }
63
+ else if (input === "n" || input === "N" || key.escape) {
64
+ setStep("select");
65
+ }
66
+ }
67
+ });
68
+ useEffect(() => {
69
+ if (!isLoggedIn()) {
70
+ setErrorMsg("Not logged in. Run 'onflyt login' first.");
71
+ setStep("error");
72
+ return;
73
+ }
74
+ if (projectId) {
75
+ setTargetProject({ id: projectId, name: projectName || projectId });
76
+ setStep("confirm");
77
+ return;
78
+ }
79
+ loadTeams();
80
+ }, []);
81
+ const loadTeams = async () => {
82
+ try {
83
+ const config = getConfig();
84
+ api.setToken(config.token);
85
+ const meData = await api.get("/auth/me");
86
+ const userTeams = meData.teams || [];
87
+ if (userTeams.length === 0) {
88
+ setErrorMsg("No teams found");
89
+ setStep("error");
90
+ return;
91
+ }
92
+ setTeams(userTeams);
93
+ if (userTeams.length === 1) {
94
+ setSelectedTeamIndex(0);
95
+ setStep("loading-projects");
96
+ loadProjects(userTeams[0].team.id);
97
+ }
98
+ else {
99
+ setStep("team");
100
+ }
101
+ }
102
+ catch (err) {
103
+ setErrorMsg(err.message);
104
+ setStep("error");
105
+ }
106
+ };
107
+ const loadProjects = async (teamId) => {
108
+ try {
109
+ const projectsRes = await api.get(`/projects/team/${teamId}`);
110
+ const teamProjects = projectsRes.projects || [];
111
+ if (teamProjects.length === 0) {
112
+ setErrorMsg("No projects found in this team");
113
+ setStep("error");
114
+ return;
115
+ }
116
+ setProjects(teamProjects);
117
+ setSelectedProjectIndex(0);
118
+ setStep("select");
119
+ }
120
+ catch (err) {
121
+ setErrorMsg(err.message);
122
+ setStep("error");
123
+ }
124
+ };
125
+ const deleteProject = async (projId) => {
126
+ setStep("deleting");
127
+ try {
128
+ await api.delete(`/projects/${projId}`);
129
+ setStep("done");
130
+ }
131
+ catch (err) {
132
+ setErrorMsg(err.message);
133
+ setStep("error");
134
+ }
135
+ };
136
+ if (step === "loading") {
137
+ return (React.createElement(Box, { flexDirection: "column" },
138
+ React.createElement(Logo, null),
139
+ React.createElement(Box, { marginTop: 1 },
140
+ React.createElement(Text, null, "Loading..."))));
141
+ }
142
+ if (step === "loading-projects") {
143
+ return (React.createElement(Box, { flexDirection: "column", padding: 1 },
144
+ React.createElement(Logo, null),
145
+ React.createElement(Box, { marginTop: 1 },
146
+ React.createElement(Text, { bold: true }, "Delete Project")),
147
+ React.createElement(Box, { marginTop: 1 },
148
+ React.createElement(Text, { dimColor: true }, "Loading projects...")),
149
+ React.createElement(Box, { marginTop: 1 },
150
+ React.createElement(Text, null,
151
+ React.createElement(Spinner, null)))));
152
+ }
153
+ if (step === "error") {
154
+ return (React.createElement(Box, { flexDirection: "column" },
155
+ React.createElement(Logo, null),
156
+ React.createElement(Box, { marginTop: 1 },
157
+ React.createElement(Text, { bold: true, color: "red" }, "\u2716 Error")),
158
+ React.createElement(Box, { marginTop: 1 },
159
+ React.createElement(Text, { color: "red" }, errorMsg))));
160
+ }
161
+ if (step === "deleting") {
162
+ return (React.createElement(Box, { flexDirection: "column" },
163
+ React.createElement(Logo, null),
164
+ React.createElement(Box, { marginTop: 1 },
165
+ React.createElement(Text, null, "Deleting project..."))));
166
+ }
167
+ if (step === "done") {
168
+ return (React.createElement(Box, { flexDirection: "column" },
169
+ React.createElement(Logo, null),
170
+ React.createElement(Box, { marginTop: 1 },
171
+ React.createElement(Text, { bold: true, color: "green" }, "\u2713 Project deleted successfully"))));
172
+ }
173
+ if (step === "team") {
174
+ return (React.createElement(Box, { flexDirection: "column", padding: 1 },
175
+ React.createElement(Logo, null),
176
+ React.createElement(Box, { marginTop: 1 },
177
+ React.createElement(Text, { bold: true }, "Delete Project")),
178
+ React.createElement(Box, { marginTop: 1 },
179
+ React.createElement(Text, { dimColor: true }, "Step 1/2: Select Team (\u2191\u2193 navigate, Enter select)")),
180
+ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, teams.map((t, idx) => (React.createElement(Box, { key: t.team.id, marginTop: 1 },
181
+ React.createElement(Text, { color: idx === selectedTeamIndex ? "cyan" : "gray" }, idx === selectedTeamIndex ? "▶ " : " "),
182
+ React.createElement(Text, { bold: idx === selectedTeamIndex }, t.team.name)))))));
183
+ }
184
+ if (step === "select") {
185
+ return (React.createElement(Box, { flexDirection: "column", padding: 1 },
186
+ React.createElement(Logo, null),
187
+ React.createElement(Box, { marginTop: 1 },
188
+ React.createElement(Text, { bold: true }, "Delete Project")),
189
+ React.createElement(Box, { marginTop: 1 },
190
+ React.createElement(Text, { dimColor: true },
191
+ "Step 2/2: Select Project - ",
192
+ teams[selectedTeamIndex]?.team.name)),
193
+ React.createElement(Box, null,
194
+ React.createElement(Text, { dimColor: true }, "(\u2191\u2193 navigate, Enter select, Esc go back)")),
195
+ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, projects.map((p, idx) => (React.createElement(Box, { key: p.id, marginTop: 1 },
196
+ React.createElement(Text, { color: idx === selectedProjectIndex ? "cyan" : "gray" }, idx === selectedProjectIndex ? "▶ " : " "),
197
+ React.createElement(Text, { bold: idx === selectedProjectIndex }, p.name),
198
+ React.createElement(Text, { dimColor: true },
199
+ " (",
200
+ p.framework,
201
+ ")")))))));
202
+ }
203
+ if (step === "confirm") {
204
+ return (React.createElement(Box, { flexDirection: "column", padding: 1 },
205
+ React.createElement(Logo, null),
206
+ React.createElement(Box, { marginTop: 1 },
207
+ React.createElement(Text, { bold: true, color: "red" }, "\u26A0 Confirm Delete")),
208
+ React.createElement(Box, { marginTop: 1 },
209
+ React.createElement(Text, null,
210
+ "Delete project: ",
211
+ React.createElement(Text, { bold: true }, targetProject?.name),
212
+ "?")),
213
+ React.createElement(Box, { marginTop: 1 },
214
+ React.createElement(Text, { color: "red" }, "This action cannot be undone!")),
215
+ React.createElement(Box, { marginTop: 2 },
216
+ React.createElement(Text, null, "[Y] Yes, delete [N] Cancel"))));
217
+ }
218
+ return null;
219
+ };
220
+ export default Delete;
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ interface Props {
3
+ teamFlag?: string;
4
+ }
5
+ declare const Deploy: React.FC<Props>;
6
+ export default Deploy;