commet 0.2.1 → 0.4.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/README.md +216 -20
- package/bin/commet +2 -0
- package/dist/index.js +650 -430
- package/package.json +23 -30
- package/dist/index.d.mts +0 -365
- package/dist/index.d.ts +0 -365
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -455
- package/dist/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
2
4
|
var __defProp = Object.defineProperty;
|
|
3
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
9
|
var __copyProps = (to, from, except, desc) => {
|
|
11
10
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
11
|
for (let key of __getOwnPropNames(from))
|
|
@@ -15,474 +14,695 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
14
|
}
|
|
16
15
|
return to;
|
|
17
16
|
};
|
|
18
|
-
var
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
19
25
|
|
|
20
26
|
// src/index.ts
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
Commet: () => Commet,
|
|
24
|
-
CommetAPIError: () => CommetAPIError,
|
|
25
|
-
CommetError: () => CommetError,
|
|
26
|
-
CommetValidationError: () => CommetValidationError,
|
|
27
|
-
default: () => index_default,
|
|
28
|
-
detectEnvironment: () => detectEnvironment,
|
|
29
|
-
isDevelopment: () => isDevelopment,
|
|
30
|
-
isProduction: () => isProduction
|
|
31
|
-
});
|
|
32
|
-
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
var import_commander10 = require("commander");
|
|
28
|
+
var import_chalk10 = __toESM(require("chalk"));
|
|
33
29
|
|
|
34
|
-
// src/
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
async create(params, options) {
|
|
40
|
-
return this.httpClient.post("/customers", params, options);
|
|
41
|
-
}
|
|
42
|
-
async retrieve(customerId, options) {
|
|
43
|
-
const params = options?.expand ? { expand: options.expand.join(",") } : void 0;
|
|
44
|
-
return this.httpClient.get(`/customers/${customerId}`, params);
|
|
45
|
-
}
|
|
46
|
-
async update(customerId, params, options) {
|
|
47
|
-
return this.httpClient.put(`/customers/${customerId}`, params, options);
|
|
48
|
-
}
|
|
49
|
-
async list(params) {
|
|
50
|
-
return this.httpClient.get("/customers", params);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Deactivate a customer (soft delete)
|
|
54
|
-
*/
|
|
55
|
-
async deactivate(customerId, options) {
|
|
56
|
-
return this.httpClient.put(
|
|
57
|
-
`/customers/${customerId}`,
|
|
58
|
-
{ isActive: false },
|
|
59
|
-
options
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
};
|
|
30
|
+
// src/commands/login.ts
|
|
31
|
+
var import_commander = require("commander");
|
|
32
|
+
var import_chalk = __toESM(require("chalk"));
|
|
33
|
+
var import_ora = __toESM(require("ora"));
|
|
34
|
+
var import_open = __toESM(require("open"));
|
|
63
35
|
|
|
64
|
-
// src/
|
|
65
|
-
var
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
options
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
async bulkUpdate(customerId, seats, options) {
|
|
91
|
-
return this.httpClient.post(
|
|
92
|
-
`/customers/${customerId}/seats/bulk-update`,
|
|
93
|
-
{ seats },
|
|
94
|
-
options
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
async getBalance(customerId, seatType) {
|
|
98
|
-
return this.httpClient.get(
|
|
99
|
-
`/customers/${customerId}/seats/${seatType}/balance`
|
|
100
|
-
);
|
|
36
|
+
// src/utils/config.ts
|
|
37
|
+
var fs = __toESM(require("fs"));
|
|
38
|
+
var os = __toESM(require("os"));
|
|
39
|
+
var path = __toESM(require("path"));
|
|
40
|
+
function getAuthPath() {
|
|
41
|
+
return path.join(os.homedir(), ".commet", "auth.json");
|
|
42
|
+
}
|
|
43
|
+
function getProjectConfigPath() {
|
|
44
|
+
return path.join(process.cwd(), ".commet");
|
|
45
|
+
}
|
|
46
|
+
function authExists() {
|
|
47
|
+
return fs.existsSync(getAuthPath());
|
|
48
|
+
}
|
|
49
|
+
function loadAuth() {
|
|
50
|
+
try {
|
|
51
|
+
const authPath = getAuthPath();
|
|
52
|
+
if (!fs.existsSync(authPath)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const data = fs.readFileSync(authPath, "utf8");
|
|
56
|
+
return JSON.parse(data);
|
|
57
|
+
} catch {
|
|
58
|
+
return null;
|
|
101
59
|
}
|
|
102
|
-
|
|
103
|
-
|
|
60
|
+
}
|
|
61
|
+
function saveAuth(data) {
|
|
62
|
+
const authPath = getAuthPath();
|
|
63
|
+
fs.mkdirSync(path.dirname(authPath), { recursive: true });
|
|
64
|
+
fs.writeFileSync(authPath, JSON.stringify(data, null, 2), "utf8");
|
|
65
|
+
}
|
|
66
|
+
function clearAuth() {
|
|
67
|
+
const authPath = getAuthPath();
|
|
68
|
+
if (fs.existsSync(authPath)) {
|
|
69
|
+
fs.unlinkSync(authPath);
|
|
104
70
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
71
|
+
}
|
|
72
|
+
function projectConfigExists() {
|
|
73
|
+
return fs.existsSync(getProjectConfigPath());
|
|
74
|
+
}
|
|
75
|
+
function loadProjectConfig() {
|
|
76
|
+
try {
|
|
77
|
+
const configPath = getProjectConfigPath();
|
|
78
|
+
if (!fs.existsSync(configPath)) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const data = fs.readFileSync(configPath, "utf8");
|
|
82
|
+
return JSON.parse(data);
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
115
85
|
}
|
|
116
|
-
|
|
117
|
-
|
|
86
|
+
}
|
|
87
|
+
function saveProjectConfig(data) {
|
|
88
|
+
const configPath = getProjectConfigPath();
|
|
89
|
+
fs.writeFileSync(configPath, JSON.stringify(data, null, 2), "utf8");
|
|
90
|
+
}
|
|
91
|
+
function clearProjectConfig() {
|
|
92
|
+
const configPath = getProjectConfigPath();
|
|
93
|
+
if (fs.existsSync(configPath)) {
|
|
94
|
+
fs.unlinkSync(configPath);
|
|
118
95
|
}
|
|
119
|
-
}
|
|
96
|
+
}
|
|
120
97
|
|
|
121
|
-
// src/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
async create(params, options) {
|
|
127
|
-
const eventData = {
|
|
128
|
-
...params,
|
|
129
|
-
ts: params.timestamp || (/* @__PURE__ */ new Date()).toISOString()
|
|
130
|
-
};
|
|
131
|
-
return this.httpClient.post("/usage/events", eventData, options);
|
|
132
|
-
}
|
|
133
|
-
async createBatch(params, options) {
|
|
134
|
-
return this.httpClient.post("/usage/events/batch", params, options);
|
|
135
|
-
}
|
|
136
|
-
async retrieve(eventId) {
|
|
137
|
-
return this.httpClient.get(`/usage/events/${eventId}`);
|
|
138
|
-
}
|
|
139
|
-
async list(params) {
|
|
140
|
-
return this.httpClient.get("/usage/events", params);
|
|
141
|
-
}
|
|
142
|
-
async delete(eventId, options) {
|
|
143
|
-
return this.httpClient.delete(`/usage/events/${eventId}`, options);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
var UsageMetricsResource = class {
|
|
147
|
-
constructor(httpClient) {
|
|
148
|
-
this.httpClient = httpClient;
|
|
98
|
+
// src/utils/api.ts
|
|
99
|
+
function getBaseURL(environment) {
|
|
100
|
+
if (environment === "production") {
|
|
101
|
+
return "https://billing.commet.co";
|
|
149
102
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
};
|
|
157
|
-
var UsageResource = class {
|
|
158
|
-
constructor(httpClient) {
|
|
159
|
-
this.events = new UsageEventsResource(httpClient);
|
|
160
|
-
this.metrics = new UsageMetricsResource(httpClient);
|
|
103
|
+
return "https://billing.commet.co";
|
|
104
|
+
}
|
|
105
|
+
async function apiRequest(endpoint, options = {}) {
|
|
106
|
+
const auth = loadAuth();
|
|
107
|
+
if (!auth) {
|
|
108
|
+
return { error: "Not authenticated. Run `commet login` first." };
|
|
161
109
|
}
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
// src/utils/environment.ts
|
|
165
|
-
function detectEnvironment() {
|
|
166
110
|
try {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const hostname = window.location.hostname;
|
|
174
|
-
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname.startsWith("192.168.") || hostname.startsWith("10.") || hostname.endsWith(".local")) {
|
|
175
|
-
return "development";
|
|
111
|
+
const response = await fetch(endpoint, {
|
|
112
|
+
...options,
|
|
113
|
+
headers: {
|
|
114
|
+
...options.headers,
|
|
115
|
+
Authorization: `Bearer ${auth.token}`,
|
|
116
|
+
"Content-Type": "application/json"
|
|
176
117
|
}
|
|
118
|
+
});
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
const errorData = await response.json().catch(() => ({}));
|
|
121
|
+
return {
|
|
122
|
+
error: errorData.message || errorData.error || `Request failed with status ${response.status}`
|
|
123
|
+
};
|
|
177
124
|
}
|
|
125
|
+
const data = await response.json();
|
|
126
|
+
return { data };
|
|
178
127
|
} catch (error) {
|
|
128
|
+
return {
|
|
129
|
+
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
130
|
+
};
|
|
179
131
|
}
|
|
180
|
-
return "production";
|
|
181
|
-
}
|
|
182
|
-
function isDevelopment(environment) {
|
|
183
|
-
return environment === "development";
|
|
184
|
-
}
|
|
185
|
-
function isProduction(environment) {
|
|
186
|
-
return environment === "production";
|
|
187
132
|
}
|
|
188
133
|
|
|
189
|
-
// src/
|
|
190
|
-
var
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
};
|
|
199
|
-
var CommetAPIError = class extends CommetError {
|
|
200
|
-
constructor(message, statusCode, code, details) {
|
|
201
|
-
super(message, code, statusCode, details);
|
|
202
|
-
this.statusCode = statusCode;
|
|
203
|
-
this.code = code;
|
|
204
|
-
this.details = details;
|
|
205
|
-
this.name = "CommetAPIError";
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
var CommetValidationError = class extends CommetError {
|
|
209
|
-
constructor(message, validationErrors) {
|
|
210
|
-
super(message);
|
|
211
|
-
this.validationErrors = validationErrors;
|
|
212
|
-
this.name = "CommetValidationError";
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
// src/utils/http.ts
|
|
217
|
-
var DEFAULT_RETRY_CONFIG = {
|
|
218
|
-
maxRetries: 3,
|
|
219
|
-
baseDelay: 1e3,
|
|
220
|
-
// 1s
|
|
221
|
-
maxDelay: 8e3,
|
|
222
|
-
// 8s
|
|
223
|
-
retryableStatusCodes: [408, 429, 500, 502, 503, 504]
|
|
224
|
-
};
|
|
225
|
-
var CommetHTTPClient = class {
|
|
226
|
-
constructor(config, environment) {
|
|
227
|
-
this.config = config;
|
|
228
|
-
this.environment = environment;
|
|
229
|
-
this.retryConfig = {
|
|
230
|
-
...DEFAULT_RETRY_CONFIG,
|
|
231
|
-
maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
async get(endpoint, params, options) {
|
|
235
|
-
return this.request("GET", endpoint, void 0, options, params);
|
|
236
|
-
}
|
|
237
|
-
async post(endpoint, data, options) {
|
|
238
|
-
return this.request("POST", endpoint, data, options);
|
|
239
|
-
}
|
|
240
|
-
async put(endpoint, data, options) {
|
|
241
|
-
return this.request("PUT", endpoint, data, options);
|
|
242
|
-
}
|
|
243
|
-
async delete(endpoint, options) {
|
|
244
|
-
return this.request("DELETE", endpoint, void 0, options);
|
|
134
|
+
// src/commands/login.ts
|
|
135
|
+
var loginCommand = new import_commander.Command("login").description("Authenticate with Commet").action(async () => {
|
|
136
|
+
if (authExists()) {
|
|
137
|
+
const auth = loadAuth();
|
|
138
|
+
console.log(import_chalk.default.yellow("\u26A0 You are already logged in."));
|
|
139
|
+
console.log(
|
|
140
|
+
import_chalk.default.dim("Run `commet logout` first if you want to login with a different account.")
|
|
141
|
+
);
|
|
142
|
+
return;
|
|
245
143
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Log request in development mode instead of sending to API
|
|
258
|
-
*/
|
|
259
|
-
logDevRequest(method, url, data) {
|
|
260
|
-
console.log("[Commet SDK] Dev mode");
|
|
261
|
-
console.log(`Method: ${method}`);
|
|
262
|
-
console.log(`Endpoint: ${url}`);
|
|
263
|
-
if (data) {
|
|
264
|
-
console.log("Data:", JSON.stringify(data, null, 2));
|
|
265
|
-
}
|
|
266
|
-
console.log("Request logged, not sent to server");
|
|
267
|
-
if (this.config.debug) {
|
|
268
|
-
console.log("Base URL:", "https://api.commet.co/api");
|
|
269
|
-
console.log("Debug mode enabled");
|
|
270
|
-
}
|
|
271
|
-
return Promise.resolve({
|
|
272
|
-
success: true,
|
|
273
|
-
devMode: true,
|
|
274
|
-
data: { id: `dev_${Date.now()}` }
|
|
144
|
+
const spinner = (0, import_ora.default)("Initiating login flow...").start();
|
|
145
|
+
const baseURL = getBaseURL("sandbox");
|
|
146
|
+
try {
|
|
147
|
+
const deviceResponse = await fetch(`${baseURL}/api/auth/device/code`, {
|
|
148
|
+
method: "POST",
|
|
149
|
+
headers: { "Content-Type": "application/json" },
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
client_id: "commet-cli",
|
|
152
|
+
scope: "openid profile email"
|
|
153
|
+
})
|
|
275
154
|
});
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
155
|
+
if (!deviceResponse.ok) {
|
|
156
|
+
spinner.fail("Failed to initiate login");
|
|
157
|
+
console.error(import_chalk.default.red("Error:"), await deviceResponse.text());
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const deviceData = await deviceResponse.json();
|
|
161
|
+
const {
|
|
162
|
+
device_code,
|
|
163
|
+
user_code,
|
|
164
|
+
verification_uri_complete,
|
|
165
|
+
interval = 5
|
|
166
|
+
} = deviceData;
|
|
167
|
+
spinner.stop();
|
|
168
|
+
console.log(import_chalk.default.bold("\n\u{1F510} Commet CLI Login\n"));
|
|
169
|
+
console.log("Visit the following URL in your browser:");
|
|
170
|
+
console.log(import_chalk.default.cyan.underline(verification_uri_complete));
|
|
171
|
+
console.log("\nOr enter this code manually:");
|
|
172
|
+
console.log(import_chalk.default.bold.green(` ${user_code}`));
|
|
173
|
+
console.log(import_chalk.default.dim("\nOpening browser...\n"));
|
|
281
174
|
try {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
signal: AbortSignal.timeout(
|
|
296
|
-
options?.timeout ?? this.config.timeout ?? 3e4
|
|
297
|
-
)
|
|
298
|
-
};
|
|
299
|
-
if (data) {
|
|
300
|
-
requestConfig.body = JSON.stringify(data);
|
|
301
|
-
}
|
|
302
|
-
if (this.config.debug) {
|
|
303
|
-
console.log(`[Commet SDK] ${method} ${url}`);
|
|
304
|
-
if (data) {
|
|
305
|
-
console.log("Request data:", JSON.stringify(data, null, 2));
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
const response = await fetch(url, requestConfig);
|
|
309
|
-
if (this.config.debug) {
|
|
310
|
-
console.log(
|
|
311
|
-
`[Commet SDK] Response status: ${response.status} ${response.statusText}`
|
|
312
|
-
);
|
|
175
|
+
await (0, import_open.default)(verification_uri_complete);
|
|
176
|
+
} catch {
|
|
177
|
+
console.log(import_chalk.default.yellow("\u26A0 Could not open browser automatically."));
|
|
178
|
+
}
|
|
179
|
+
const pollSpinner = (0, import_ora.default)("Waiting for authorization...").start();
|
|
180
|
+
let pollingInterval = interval;
|
|
181
|
+
let attempts = 0;
|
|
182
|
+
const maxAttempts = 180 / pollingInterval;
|
|
183
|
+
const poll = async () => {
|
|
184
|
+
if (attempts >= maxAttempts) {
|
|
185
|
+
pollSpinner.fail("Login timed out");
|
|
186
|
+
console.log(import_chalk.default.red("Authorization timed out. Please try again."));
|
|
187
|
+
return;
|
|
313
188
|
}
|
|
314
|
-
|
|
315
|
-
let responseText;
|
|
189
|
+
attempts++;
|
|
316
190
|
try {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
`Invalid JSON response: ${response.status} ${response.statusText}`,
|
|
334
|
-
response.status,
|
|
335
|
-
"INVALID_JSON",
|
|
336
|
-
{ responseText }
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
if (!response.ok) {
|
|
340
|
-
if (attempt <= this.retryConfig.maxRetries && this.retryConfig.retryableStatusCodes.includes(response.status)) {
|
|
341
|
-
const delay = Math.min(
|
|
342
|
-
this.retryConfig.baseDelay * 2 ** (attempt - 1),
|
|
343
|
-
this.retryConfig.maxDelay
|
|
344
|
-
);
|
|
345
|
-
if (this.config.debug) {
|
|
346
|
-
console.log(
|
|
347
|
-
`[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`
|
|
348
|
-
);
|
|
191
|
+
const tokenResponse = await fetch(`${baseURL}/api/auth/device/token`, {
|
|
192
|
+
method: "POST",
|
|
193
|
+
headers: { "Content-Type": "application/json" },
|
|
194
|
+
body: JSON.stringify({
|
|
195
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
196
|
+
device_code,
|
|
197
|
+
client_id: "commet-cli"
|
|
198
|
+
})
|
|
199
|
+
});
|
|
200
|
+
const tokenData = await tokenResponse.json();
|
|
201
|
+
if (tokenData.access_token) {
|
|
202
|
+
const authConfig = {
|
|
203
|
+
token: tokenData.access_token
|
|
204
|
+
};
|
|
205
|
+
if (tokenData.refresh_token) {
|
|
206
|
+
authConfig.refreshToken = tokenData.refresh_token;
|
|
349
207
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
208
|
+
if (tokenData.expires_in) {
|
|
209
|
+
authConfig.expiresAt = Date.now() + tokenData.expires_in * 1e3;
|
|
210
|
+
}
|
|
211
|
+
saveAuth(authConfig);
|
|
212
|
+
pollSpinner.succeed("Successfully logged in!");
|
|
213
|
+
console.log(import_chalk.default.green("\n\u2713 Authentication complete"));
|
|
354
214
|
console.log(
|
|
355
|
-
"
|
|
356
|
-
JSON.stringify(responseData, null, 2)
|
|
215
|
+
import_chalk.default.dim("\nNext steps:\n 1. Run `commet link` to connect a project\n 2. Run `commet pull` to generate types\n")
|
|
357
216
|
);
|
|
217
|
+
return;
|
|
358
218
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
219
|
+
if (tokenData.error === "authorization_pending") {
|
|
220
|
+
setTimeout(() => poll(), pollingInterval * 1e3);
|
|
221
|
+
} else if (tokenData.error === "slow_down") {
|
|
222
|
+
pollingInterval += 5;
|
|
223
|
+
setTimeout(() => poll(), pollingInterval * 1e3);
|
|
224
|
+
} else if (tokenData.error === "access_denied") {
|
|
225
|
+
pollSpinner.fail("Authorization denied");
|
|
226
|
+
console.log(
|
|
227
|
+
import_chalk.default.red("\n\u2717 You denied the authorization request.")
|
|
367
228
|
);
|
|
229
|
+
return;
|
|
230
|
+
} else if (tokenData.error === "expired_token") {
|
|
231
|
+
pollSpinner.fail("Code expired");
|
|
232
|
+
console.log(import_chalk.default.red("\n\u2717 The authorization code expired. Please try again."));
|
|
233
|
+
return;
|
|
234
|
+
} else {
|
|
235
|
+
pollSpinner.fail("Authorization failed");
|
|
236
|
+
console.log(import_chalk.default.red("\n\u2717 Error:"), tokenData.error || "Unknown error");
|
|
237
|
+
return;
|
|
368
238
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
239
|
+
} catch (error) {
|
|
240
|
+
pollSpinner.fail("Network error");
|
|
241
|
+
console.error(
|
|
242
|
+
import_chalk.default.red("Error:"),
|
|
243
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
374
244
|
);
|
|
375
245
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
246
|
+
};
|
|
247
|
+
poll();
|
|
248
|
+
} catch (error) {
|
|
249
|
+
spinner.fail("Login failed");
|
|
250
|
+
console.error(
|
|
251
|
+
import_chalk.default.red("Error:"),
|
|
252
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// src/commands/logout.ts
|
|
258
|
+
var import_commander2 = require("commander");
|
|
259
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
260
|
+
var logoutCommand = new import_commander2.Command("logout").description("Log out of Commet").action(async () => {
|
|
261
|
+
if (!authExists()) {
|
|
262
|
+
console.log(import_chalk2.default.yellow("\u26A0 You are not logged in."));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
clearAuth();
|
|
266
|
+
console.log(import_chalk2.default.green("\u2713 Successfully logged out"));
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// src/commands/whoami.ts
|
|
270
|
+
var import_commander3 = require("commander");
|
|
271
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
272
|
+
var whoamiCommand = new import_commander3.Command("whoami").description("Display current authentication and project status").action(async () => {
|
|
273
|
+
if (!authExists()) {
|
|
274
|
+
console.log(import_chalk3.default.yellow("\u26A0 Not logged in"));
|
|
275
|
+
console.log(import_chalk3.default.dim("Run `commet login` to authenticate"));
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
console.log(import_chalk3.default.green("\u2713 Logged in"));
|
|
279
|
+
const projectConfig = loadProjectConfig();
|
|
280
|
+
if (projectConfig) {
|
|
281
|
+
console.log(import_chalk3.default.bold("\nProject:"));
|
|
282
|
+
console.log(import_chalk3.default.dim("Organization:"), projectConfig.orgName);
|
|
283
|
+
console.log(import_chalk3.default.dim("Environment:"), projectConfig.environment);
|
|
284
|
+
} else {
|
|
285
|
+
console.log(import_chalk3.default.yellow("\n\u26A0 No project linked"));
|
|
286
|
+
console.log(import_chalk3.default.dim("Run `commet link` to connect this directory to an organization"));
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// src/commands/link.ts
|
|
291
|
+
var import_commander4 = require("commander");
|
|
292
|
+
var import_chalk4 = __toESM(require("chalk"));
|
|
293
|
+
var import_inquirer = __toESM(require("inquirer"));
|
|
294
|
+
var import_ora2 = __toESM(require("ora"));
|
|
295
|
+
var linkCommand = new import_commander4.Command("link").description("Link this project to a Commet organization").action(async () => {
|
|
296
|
+
if (!authExists()) {
|
|
297
|
+
console.log(import_chalk4.default.red("\u2717 Not authenticated"));
|
|
298
|
+
console.log(import_chalk4.default.dim("Run `commet login` first"));
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (projectConfigExists()) {
|
|
302
|
+
const config = loadProjectConfig();
|
|
303
|
+
console.log(import_chalk4.default.yellow("\u26A0 This project is already linked"));
|
|
304
|
+
console.log(
|
|
305
|
+
import_chalk4.default.dim(`Organization: ${config?.orgName} (${config?.environment})`)
|
|
306
|
+
);
|
|
307
|
+
console.log(
|
|
308
|
+
import_chalk4.default.dim("\nRun `commet unlink` first if you want to change the organization")
|
|
309
|
+
);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const spinner = (0, import_ora2.default)("Fetching organizations...").start();
|
|
313
|
+
const baseURL = getBaseURL("sandbox");
|
|
314
|
+
const result = await apiRequest(
|
|
315
|
+
`${baseURL}/api/cli/organizations`
|
|
316
|
+
);
|
|
317
|
+
if (result.error || !result.data) {
|
|
318
|
+
spinner.fail("Failed to fetch organizations");
|
|
319
|
+
console.error(import_chalk4.default.red("Error:"), result.error);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const { organizations } = result.data;
|
|
323
|
+
if (organizations.length === 0) {
|
|
324
|
+
spinner.stop();
|
|
325
|
+
console.log(import_chalk4.default.yellow("\u26A0 No organizations found"));
|
|
326
|
+
console.log(
|
|
327
|
+
import_chalk4.default.dim("Create an organization at https://billing.commet.co first")
|
|
328
|
+
);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
spinner.stop();
|
|
332
|
+
const answers = await import_inquirer.default.prompt([
|
|
333
|
+
{
|
|
334
|
+
type: "list",
|
|
335
|
+
name: "orgId",
|
|
336
|
+
message: "Select organization:",
|
|
337
|
+
choices: organizations.map((org) => ({
|
|
338
|
+
name: `${org.name} (${org.slug})`,
|
|
339
|
+
value: org.id
|
|
340
|
+
}))
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
type: "list",
|
|
344
|
+
name: "environment",
|
|
345
|
+
message: "Select environment:",
|
|
346
|
+
choices: [
|
|
347
|
+
{ name: "Sandbox (Development)", value: "sandbox" },
|
|
348
|
+
{ name: "Production", value: "production" }
|
|
349
|
+
],
|
|
350
|
+
default: "sandbox"
|
|
351
|
+
}
|
|
352
|
+
]);
|
|
353
|
+
const selectedOrg = organizations.find((org) => org.id === answers.orgId);
|
|
354
|
+
if (!selectedOrg) {
|
|
355
|
+
console.log(import_chalk4.default.red("\u2717 Organization not found"));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
saveProjectConfig({
|
|
359
|
+
orgId: selectedOrg.id,
|
|
360
|
+
orgName: selectedOrg.name,
|
|
361
|
+
environment: answers.environment
|
|
362
|
+
});
|
|
363
|
+
console.log(import_chalk4.default.green("\n\u2713 Project linked successfully!"));
|
|
364
|
+
console.log(import_chalk4.default.dim("\nProject configuration:"));
|
|
365
|
+
console.log(import_chalk4.default.dim(` Organization: ${selectedOrg.name}`));
|
|
366
|
+
console.log(import_chalk4.default.dim(` Environment: ${answers.environment}`));
|
|
367
|
+
console.log(
|
|
368
|
+
import_chalk4.default.dim("\nNext step:\n Run `commet pull` to generate TypeScript types")
|
|
369
|
+
);
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// src/commands/unlink.ts
|
|
373
|
+
var import_commander5 = require("commander");
|
|
374
|
+
var import_chalk5 = __toESM(require("chalk"));
|
|
375
|
+
var unlinkCommand = new import_commander5.Command("unlink").description("Unlink this project from Commet").action(async () => {
|
|
376
|
+
if (!projectConfigExists()) {
|
|
377
|
+
console.log(import_chalk5.default.yellow("\u26A0 This project is not linked to any organization"));
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
clearProjectConfig();
|
|
381
|
+
console.log(import_chalk5.default.green("\u2713 Project unlinked successfully"));
|
|
382
|
+
console.log(import_chalk5.default.dim("Run `commet link` to connect to an organization"));
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// src/commands/switch.ts
|
|
386
|
+
var import_commander6 = require("commander");
|
|
387
|
+
var import_chalk6 = __toESM(require("chalk"));
|
|
388
|
+
var import_inquirer2 = __toESM(require("inquirer"));
|
|
389
|
+
var import_ora3 = __toESM(require("ora"));
|
|
390
|
+
var switchCommand = new import_commander6.Command("switch").description("Switch to a different organization").action(async () => {
|
|
391
|
+
if (!authExists()) {
|
|
392
|
+
console.log(import_chalk6.default.red("\u2717 Not authenticated"));
|
|
393
|
+
console.log(import_chalk6.default.dim("Run `commet login` first"));
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (!projectConfigExists()) {
|
|
397
|
+
console.log(import_chalk6.default.yellow("\u26A0 Project not linked"));
|
|
398
|
+
console.log(
|
|
399
|
+
import_chalk6.default.dim("Run `commet link` first to connect to an organization")
|
|
400
|
+
);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
const spinner = (0, import_ora3.default)("Fetching organizations...").start();
|
|
404
|
+
const baseURL = getBaseURL("sandbox");
|
|
405
|
+
const result = await apiRequest(
|
|
406
|
+
`${baseURL}/api/cli/organizations`
|
|
407
|
+
);
|
|
408
|
+
if (result.error || !result.data) {
|
|
409
|
+
spinner.fail("Failed to fetch organizations");
|
|
410
|
+
console.error(import_chalk6.default.red("Error:"), result.error);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const { organizations } = result.data;
|
|
414
|
+
if (organizations.length === 0) {
|
|
415
|
+
spinner.stop();
|
|
416
|
+
console.log(import_chalk6.default.yellow("\u26A0 No organizations found"));
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
spinner.stop();
|
|
420
|
+
const answers = await import_inquirer2.default.prompt([
|
|
421
|
+
{
|
|
422
|
+
type: "list",
|
|
423
|
+
name: "orgId",
|
|
424
|
+
message: "Select organization:",
|
|
425
|
+
choices: organizations.map((org) => ({
|
|
426
|
+
name: `${org.name} (${org.slug})`,
|
|
427
|
+
value: org.id
|
|
428
|
+
}))
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
type: "list",
|
|
432
|
+
name: "environment",
|
|
433
|
+
message: "Select environment:",
|
|
434
|
+
choices: [
|
|
435
|
+
{ name: "Sandbox (Development)", value: "sandbox" },
|
|
436
|
+
{ name: "Production", value: "production" }
|
|
437
|
+
],
|
|
438
|
+
default: "sandbox"
|
|
395
439
|
}
|
|
440
|
+
]);
|
|
441
|
+
const selectedOrg = organizations.find((org) => org.id === answers.orgId);
|
|
442
|
+
if (!selectedOrg) {
|
|
443
|
+
console.log(import_chalk6.default.red("\u2717 Organization not found"));
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
saveProjectConfig({
|
|
447
|
+
orgId: selectedOrg.id,
|
|
448
|
+
orgName: selectedOrg.name,
|
|
449
|
+
environment: answers.environment
|
|
450
|
+
});
|
|
451
|
+
console.log(import_chalk6.default.green("\n\u2713 Switched organization successfully!"));
|
|
452
|
+
console.log(import_chalk6.default.dim("\nNew configuration:"));
|
|
453
|
+
console.log(import_chalk6.default.dim(` Organization: ${selectedOrg.name}`));
|
|
454
|
+
console.log(import_chalk6.default.dim(` Environment: ${answers.environment}`));
|
|
455
|
+
console.log(
|
|
456
|
+
import_chalk6.default.dim("\nRun `commet pull` to update TypeScript types for this organization")
|
|
457
|
+
);
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// src/commands/pull.ts
|
|
461
|
+
var fs2 = __toESM(require("fs"));
|
|
462
|
+
var path2 = __toESM(require("path"));
|
|
463
|
+
var import_commander7 = require("commander");
|
|
464
|
+
var import_chalk7 = __toESM(require("chalk"));
|
|
465
|
+
var import_ora4 = __toESM(require("ora"));
|
|
466
|
+
|
|
467
|
+
// src/utils/generator.ts
|
|
468
|
+
function generateTypes(eventTypes, seatTypes) {
|
|
469
|
+
const eventTypeUnion = eventTypes.length > 0 ? eventTypes.map((e) => `"${e.code}"`).join(" | ") : "string";
|
|
470
|
+
const seatTypeUnion = seatTypes.length > 0 ? seatTypes.map((s) => `"${s.code}"`).join(" | ") : "string";
|
|
471
|
+
const eventComments = eventTypes.map((e) => ` * - "${e.code}": ${e.name}${e.description ? ` - ${e.description}` : ""}`).join("\n");
|
|
472
|
+
const seatComments = seatTypes.map(
|
|
473
|
+
(s) => ` * - "${s.code}": ${s.name}${s.description ? ` - ${s.description}` : ""} ${s.isFree ? "(Free)" : ""}`
|
|
474
|
+
).join("\n");
|
|
475
|
+
return `// Auto-generated by Commet CLI
|
|
476
|
+
// Do not edit this file manually - run 'commet pull' to update
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Event types available in your organization
|
|
480
|
+
${eventComments}
|
|
481
|
+
*/
|
|
482
|
+
export type CommetEventType = ${eventTypeUnion};
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Seat types available in your organization
|
|
486
|
+
${seatComments}
|
|
487
|
+
*/
|
|
488
|
+
export type CommetSeatType = ${seatTypeUnion};
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Use these types with the Commet SDK for type-safe event and seat tracking
|
|
492
|
+
*
|
|
493
|
+
* @example
|
|
494
|
+
* import { Commet } from 'commet';
|
|
495
|
+
* import type { CommetEventType, CommetSeatType } from './.commet';
|
|
496
|
+
*
|
|
497
|
+
* const commet = new Commet({ apiKey: 'your-api-key' });
|
|
498
|
+
*
|
|
499
|
+
* // Type-safe event tracking
|
|
500
|
+
* await commet.usage.sendEvent<CommetEventType>({
|
|
501
|
+
* customerId: 'cust_123',
|
|
502
|
+
* eventType: 'api_call', // Autocomplete works!
|
|
503
|
+
* timestamp: new Date(),
|
|
504
|
+
* });
|
|
505
|
+
*
|
|
506
|
+
* // Type-safe seat management
|
|
507
|
+
* await commet.seats.updateSeats<CommetSeatType>({
|
|
508
|
+
* customerId: 'cust_123',
|
|
509
|
+
* seatType: 'admin_seat', // Autocomplete works!
|
|
510
|
+
* totalSeats: 5,
|
|
511
|
+
* });
|
|
512
|
+
*/
|
|
513
|
+
`;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// src/commands/pull.ts
|
|
517
|
+
var pullCommand = new import_commander7.Command("pull").description("Pull type definitions from Commet").option(
|
|
518
|
+
"-o, --output <file>",
|
|
519
|
+
"Output file path",
|
|
520
|
+
".commet.d.ts"
|
|
521
|
+
).action(async (options) => {
|
|
522
|
+
if (!authExists()) {
|
|
523
|
+
console.log(import_chalk7.default.red("\u2717 Not authenticated"));
|
|
524
|
+
console.log(import_chalk7.default.dim("Run `commet login` first"));
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
if (!projectConfigExists()) {
|
|
528
|
+
console.log(import_chalk7.default.red("\u2717 Project not linked"));
|
|
529
|
+
console.log(import_chalk7.default.dim("Run `commet link` first to connect to an organization"));
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
const projectConfig = loadProjectConfig();
|
|
533
|
+
if (!projectConfig) {
|
|
534
|
+
console.log(import_chalk7.default.red("\u2717 Invalid project configuration"));
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
const spinner = (0, import_ora4.default)("Fetching type definitions...").start();
|
|
538
|
+
const baseURL = getBaseURL(projectConfig.environment);
|
|
539
|
+
const result = await apiRequest(
|
|
540
|
+
`${baseURL}/api/cli/types?orgId=${projectConfig.orgId}`
|
|
541
|
+
);
|
|
542
|
+
if (result.error || !result.data) {
|
|
543
|
+
spinner.fail("Failed to fetch types");
|
|
544
|
+
console.error(import_chalk7.default.red("Error:"), result.error);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
const { eventTypes, seatTypes } = result.data;
|
|
548
|
+
const typeDefinitions = generateTypes(eventTypes, seatTypes);
|
|
549
|
+
const outputPath = path2.resolve(process.cwd(), options.output);
|
|
550
|
+
fs2.writeFileSync(outputPath, typeDefinitions, "utf8");
|
|
551
|
+
spinner.succeed("Type definitions generated!");
|
|
552
|
+
console.log(import_chalk7.default.green("\n\u2713 Success"));
|
|
553
|
+
console.log(import_chalk7.default.dim("\nGenerated types:"));
|
|
554
|
+
console.log(
|
|
555
|
+
import_chalk7.default.dim(` Event types: ${eventTypes.length > 0 ? eventTypes.map((e) => e.code).join(", ") : "none"}`)
|
|
556
|
+
);
|
|
557
|
+
console.log(
|
|
558
|
+
import_chalk7.default.dim(` Seat types: ${seatTypes.length > 0 ? seatTypes.map((s) => s.code).join(", ") : "none"}`)
|
|
559
|
+
);
|
|
560
|
+
console.log(import_chalk7.default.dim(`
|
|
561
|
+
Output file: ${outputPath}`));
|
|
562
|
+
if (eventTypes.length === 0 && seatTypes.length === 0) {
|
|
563
|
+
console.log(
|
|
564
|
+
import_chalk7.default.yellow("\n\u26A0 No types found. Create event types and seat types in your Commet dashboard.")
|
|
565
|
+
);
|
|
396
566
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
// src/commands/list.ts
|
|
570
|
+
var import_commander8 = require("commander");
|
|
571
|
+
var import_chalk8 = __toESM(require("chalk"));
|
|
572
|
+
var import_ora5 = __toESM(require("ora"));
|
|
573
|
+
var listCommand = new import_commander8.Command("list").description("List event types or seat types").argument("<type>", "Type to list (events or seats)").action(async (type) => {
|
|
574
|
+
if (type !== "events" && type !== "seats") {
|
|
575
|
+
console.log(import_chalk8.default.red('\u2717 Invalid type. Use "events" or "seats"'));
|
|
576
|
+
console.log(import_chalk8.default.dim("\nExamples:"));
|
|
577
|
+
console.log(import_chalk8.default.dim(" commet list events"));
|
|
578
|
+
console.log(import_chalk8.default.dim(" commet list seats"));
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
if (!authExists()) {
|
|
582
|
+
console.log(import_chalk8.default.red("\u2717 Not authenticated"));
|
|
583
|
+
console.log(import_chalk8.default.dim("Run `commet login` first"));
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
if (!projectConfigExists()) {
|
|
587
|
+
console.log(import_chalk8.default.red("\u2717 Project not linked"));
|
|
588
|
+
console.log(import_chalk8.default.dim("Run `commet link` first to connect to an organization"));
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
const projectConfig = loadProjectConfig();
|
|
592
|
+
if (!projectConfig) {
|
|
593
|
+
console.log(import_chalk8.default.red("\u2717 Invalid project configuration"));
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
const spinner = (0, import_ora5.default)(`Fetching ${type}...`).start();
|
|
597
|
+
const baseURL = getBaseURL(projectConfig.environment);
|
|
598
|
+
const result = await apiRequest(
|
|
599
|
+
`${baseURL}/api/cli/types?orgId=${projectConfig.orgId}`
|
|
600
|
+
);
|
|
601
|
+
if (result.error || !result.data) {
|
|
602
|
+
spinner.fail(`Failed to fetch ${type}`);
|
|
603
|
+
console.error(import_chalk8.default.red("Error:"), result.error);
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
spinner.stop();
|
|
607
|
+
if (type === "events") {
|
|
608
|
+
const { eventTypes } = result.data;
|
|
609
|
+
if (eventTypes.length === 0) {
|
|
610
|
+
console.log(import_chalk8.default.yellow("\u26A0 No event types found"));
|
|
404
611
|
console.log(
|
|
405
|
-
|
|
612
|
+
import_chalk8.default.dim("Create event types in your Commet dashboard first")
|
|
406
613
|
);
|
|
614
|
+
return;
|
|
407
615
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
616
|
+
console.log(import_chalk8.default.bold(`
|
|
617
|
+
\u{1F4CA} Event Types (${eventTypes.length})
|
|
618
|
+
`));
|
|
619
|
+
for (const eventType of eventTypes) {
|
|
620
|
+
console.log(import_chalk8.default.green(`\u2022 ${eventType.code}`));
|
|
621
|
+
console.log(import_chalk8.default.dim(` ${eventType.name}`));
|
|
622
|
+
if (eventType.description) {
|
|
623
|
+
console.log(import_chalk8.default.dim(` ${eventType.description}`));
|
|
414
624
|
}
|
|
625
|
+
console.log("");
|
|
415
626
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Generate idempotency key
|
|
424
|
-
*/
|
|
425
|
-
generateIdempotencyKey() {
|
|
426
|
-
return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Sleep for specified milliseconds
|
|
430
|
-
*/
|
|
431
|
-
sleep(ms) {
|
|
432
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
433
|
-
}
|
|
434
|
-
};
|
|
435
|
-
|
|
436
|
-
// src/client.ts
|
|
437
|
-
var Commet = class {
|
|
438
|
-
constructor(config) {
|
|
439
|
-
if (!config.apiKey) {
|
|
440
|
-
throw new Error("Commet SDK: API key is required");
|
|
441
|
-
}
|
|
442
|
-
if (!config.apiKey.startsWith("ck_")) {
|
|
443
|
-
throw new Error(
|
|
444
|
-
"Commet SDK: Invalid API key format. Expected format: ck_xxx..."
|
|
627
|
+
} else {
|
|
628
|
+
const { seatTypes } = result.data;
|
|
629
|
+
if (seatTypes.length === 0) {
|
|
630
|
+
console.log(import_chalk8.default.yellow("\u26A0 No seat types found"));
|
|
631
|
+
console.log(
|
|
632
|
+
import_chalk8.default.dim("Create seat types in your Commet dashboard first")
|
|
445
633
|
);
|
|
634
|
+
return;
|
|
446
635
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
console.log(
|
|
457
|
-
if (this.environment === "development") {
|
|
458
|
-
console.log(
|
|
459
|
-
"Dev mode: Events will be logged to console, not sent to server"
|
|
460
|
-
);
|
|
461
|
-
}
|
|
636
|
+
console.log(import_chalk8.default.bold(`
|
|
637
|
+
\u{1F4BA} Seat Types (${seatTypes.length})
|
|
638
|
+
`));
|
|
639
|
+
for (const seatType of seatTypes) {
|
|
640
|
+
console.log(
|
|
641
|
+
import_chalk8.default.green(`\u2022 ${seatType.code}${seatType.isFree ? " (Free)" : ""}`)
|
|
642
|
+
);
|
|
643
|
+
console.log(import_chalk8.default.dim(` ${seatType.name}`));
|
|
644
|
+
if (seatType.description) {
|
|
645
|
+
console.log(import_chalk8.default.dim(` ${seatType.description}`));
|
|
462
646
|
}
|
|
647
|
+
console.log("");
|
|
463
648
|
}
|
|
464
649
|
}
|
|
465
|
-
|
|
466
|
-
return this.environment;
|
|
467
|
-
}
|
|
468
|
-
isDevelopment() {
|
|
469
|
-
return this.environment === "development";
|
|
470
|
-
}
|
|
471
|
-
isProduction() {
|
|
472
|
-
return this.environment === "production";
|
|
473
|
-
}
|
|
474
|
-
};
|
|
650
|
+
});
|
|
475
651
|
|
|
476
|
-
// src/
|
|
477
|
-
var
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
652
|
+
// src/commands/info.ts
|
|
653
|
+
var import_commander9 = require("commander");
|
|
654
|
+
var import_chalk9 = __toESM(require("chalk"));
|
|
655
|
+
var infoCommand = new import_commander9.Command("info").description("Display information about the current project").action(async () => {
|
|
656
|
+
console.log(import_chalk9.default.bold("\n\u{1F4E6} Project Information\n"));
|
|
657
|
+
if (!authExists()) {
|
|
658
|
+
console.log(import_chalk9.default.yellow("Authentication: Not logged in"));
|
|
659
|
+
console.log(import_chalk9.default.dim("Run `commet login` to authenticate\n"));
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
console.log(import_chalk9.default.green("Authentication: Logged in \u2713"));
|
|
663
|
+
if (!projectConfigExists()) {
|
|
664
|
+
console.log(import_chalk9.default.yellow("\nProject: Not linked"));
|
|
665
|
+
console.log(import_chalk9.default.dim("Run `commet link` to connect to an organization\n"));
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
const projectConfig = loadProjectConfig();
|
|
669
|
+
if (!projectConfig) {
|
|
670
|
+
console.log(import_chalk9.default.red("\nProject: Invalid configuration"));
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
console.log(import_chalk9.default.green("\nProject: Linked \u2713"));
|
|
674
|
+
console.log(import_chalk9.default.dim(" Organization:"), projectConfig.orgName);
|
|
675
|
+
console.log(import_chalk9.default.dim(" Organization ID:"), projectConfig.orgId);
|
|
676
|
+
console.log(import_chalk9.default.dim(" Environment:"), projectConfig.environment);
|
|
677
|
+
console.log(
|
|
678
|
+
import_chalk9.default.dim("\nRun `commet pull` to generate type definitions\n")
|
|
679
|
+
);
|
|
487
680
|
});
|
|
488
|
-
|
|
681
|
+
|
|
682
|
+
// src/index.ts
|
|
683
|
+
var program = new import_commander10.Command();
|
|
684
|
+
program.name("commet").description("Commet CLI - Manage your billing platform from the command line").version("0.3.0");
|
|
685
|
+
program.addCommand(loginCommand);
|
|
686
|
+
program.addCommand(logoutCommand);
|
|
687
|
+
program.addCommand(whoamiCommand);
|
|
688
|
+
program.addCommand(linkCommand);
|
|
689
|
+
program.addCommand(unlinkCommand);
|
|
690
|
+
program.addCommand(switchCommand);
|
|
691
|
+
program.addCommand(infoCommand);
|
|
692
|
+
program.addCommand(pullCommand);
|
|
693
|
+
program.addCommand(listCommand);
|
|
694
|
+
program.exitOverride();
|
|
695
|
+
try {
|
|
696
|
+
program.parse(process.argv);
|
|
697
|
+
} catch (error) {
|
|
698
|
+
if (error instanceof Error) {
|
|
699
|
+
if (error.message.includes("outputHelp")) {
|
|
700
|
+
process.exit(0);
|
|
701
|
+
}
|
|
702
|
+
console.error(import_chalk10.default.red("Error:"), error.message);
|
|
703
|
+
}
|
|
704
|
+
process.exit(1);
|
|
705
|
+
}
|
|
706
|
+
if (!process.argv.slice(2).length) {
|
|
707
|
+
program.outputHelp();
|
|
708
|
+
}
|