quvur-dev 1.0.1 → 1.0.2
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/{index.cjs → index.js} +148 -118
- package/package.json +21 -4
- package/dist/index.d.cts +0 -1
|
@@ -1,61 +1,92 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
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
|
-
));
|
|
25
2
|
|
|
26
3
|
// src/commands/index.ts
|
|
27
|
-
|
|
4
|
+
import { Command as Command6 } from "commander";
|
|
28
5
|
|
|
29
6
|
// src/core/ws-client.ts
|
|
30
|
-
|
|
7
|
+
import { WebSocket } from "ws";
|
|
31
8
|
|
|
32
9
|
// src/utils/config.ts
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
10
|
+
import * as path from "path";
|
|
11
|
+
import * as fs from "fs";
|
|
12
|
+
import * as os from "os";
|
|
36
13
|
|
|
37
14
|
// src/utils/logger.ts
|
|
38
|
-
|
|
15
|
+
import chalk from "chalk";
|
|
39
16
|
var logger = {
|
|
40
|
-
info: (...msg) => console.log(
|
|
41
|
-
next: (...msg) => console.log(
|
|
42
|
-
success: (...msg) => console.log(
|
|
43
|
-
error: (...msg) => console.error(
|
|
44
|
-
debug: (...msg) => console.debug(
|
|
45
|
-
warn: (...msg) => console.warn(
|
|
17
|
+
info: (...msg) => console.log(chalk.blue("[\u2139]"), ...msg),
|
|
18
|
+
next: (...msg) => console.log(chalk.green("[\u2192]"), ...msg),
|
|
19
|
+
success: (...msg) => console.log(chalk.green("[\u2714]"), ...msg),
|
|
20
|
+
error: (...msg) => console.error(chalk.red("[\u2716]"), ...msg),
|
|
21
|
+
debug: (...msg) => console.debug(chalk.bgRed("[debug]"), ...msg),
|
|
22
|
+
warn: (...msg) => console.warn(chalk.bgYellowBright("[warn]"), ...msg),
|
|
46
23
|
log: (...msg) => console.log(...msg)
|
|
47
24
|
};
|
|
48
25
|
|
|
26
|
+
// src/utils/default-config.ts
|
|
27
|
+
var defaultConfig = {
|
|
28
|
+
name: "quvur",
|
|
29
|
+
description: "Quvur CLI \u2014 simple and fast HTTP/TCP tunneling tool for exposing local services to the internet.",
|
|
30
|
+
version: "1.0.2",
|
|
31
|
+
wsBaseUrl: "wss://ws.livee.uz",
|
|
32
|
+
apiBaseUrl: "https://livee.uz",
|
|
33
|
+
auth: {
|
|
34
|
+
accessToken: null,
|
|
35
|
+
refreshToken: null
|
|
36
|
+
},
|
|
37
|
+
defaults: {
|
|
38
|
+
protocol: "http",
|
|
39
|
+
autoReconnect: true
|
|
40
|
+
},
|
|
41
|
+
usage: "<command> [options]",
|
|
42
|
+
help: {
|
|
43
|
+
intro: "Expose your local development server to the internet in seconds.",
|
|
44
|
+
examples: [
|
|
45
|
+
"quvur http 3000",
|
|
46
|
+
"quvur tcp 22",
|
|
47
|
+
"quvur http 3000 -s myapp",
|
|
48
|
+
"quvur auth",
|
|
49
|
+
"quvur config --reset"
|
|
50
|
+
],
|
|
51
|
+
commands: {
|
|
52
|
+
http: {
|
|
53
|
+
description: "Start an HTTP tunnel to expose a local web server.",
|
|
54
|
+
usage: "http <port> [options]",
|
|
55
|
+
examples: ["quvur http 3000", "quvur http 5173 -s myapp"]
|
|
56
|
+
},
|
|
57
|
+
tcp: {
|
|
58
|
+
description: "Start a raw TCP tunnel to expose any TCP service.",
|
|
59
|
+
usage: "tcp <port> [options]",
|
|
60
|
+
examples: ["quvur tcp 22", "quvur tcp 5432"]
|
|
61
|
+
},
|
|
62
|
+
auth: {
|
|
63
|
+
description: "Authenticate with Quvur server and store access token locally.",
|
|
64
|
+
usage: "auth",
|
|
65
|
+
examples: ["quvur auth"]
|
|
66
|
+
},
|
|
67
|
+
logout: {
|
|
68
|
+
description: "Remove stored authentication token.",
|
|
69
|
+
usage: "logout",
|
|
70
|
+
examples: ["quvur logout"]
|
|
71
|
+
},
|
|
72
|
+
config: {
|
|
73
|
+
description: "Load config file.",
|
|
74
|
+
usage: "config",
|
|
75
|
+
examples: ["quvur config", "quvur config --reset"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
telemetry: {
|
|
80
|
+
enabled: false
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
49
84
|
// src/utils/config.ts
|
|
50
|
-
var localConfigPath = path.join(process.cwd(), "config.json");
|
|
51
85
|
var configDir = path.join(os.homedir(), ".quvur");
|
|
52
86
|
var configPath = path.join(os.homedir(), ".quvur", "config.json");
|
|
53
87
|
var loadConfig = () => {
|
|
54
88
|
if (!fs.existsSync(configPath)) {
|
|
55
|
-
|
|
56
|
-
return loadConfigFromLocal();
|
|
57
|
-
}
|
|
58
|
-
throw new Error("Config file not found. Run `quvur auth` first.");
|
|
89
|
+
return loadConfigFromLocal();
|
|
59
90
|
}
|
|
60
91
|
const raw = fs.readFileSync(configPath, "utf-8");
|
|
61
92
|
try {
|
|
@@ -66,15 +97,14 @@ var loadConfig = () => {
|
|
|
66
97
|
}
|
|
67
98
|
};
|
|
68
99
|
var loadConfigFromLocal = () => {
|
|
69
|
-
const raw = fs.readFileSync(localConfigPath, "utf-8");
|
|
70
100
|
try {
|
|
71
|
-
const
|
|
101
|
+
const raw = JSON.stringify(defaultConfig, null, 2);
|
|
72
102
|
fs.mkdirSync(configDir, { recursive: true });
|
|
73
103
|
fs.writeFileSync(configPath, raw);
|
|
74
|
-
return
|
|
104
|
+
return defaultConfig;
|
|
75
105
|
} catch (error) {
|
|
76
106
|
logger.error(error);
|
|
77
|
-
throw new Error("
|
|
107
|
+
throw new Error("Failed to load default config file");
|
|
78
108
|
}
|
|
79
109
|
};
|
|
80
110
|
var saveConfig = (config2) => {
|
|
@@ -83,7 +113,7 @@ var saveConfig = (config2) => {
|
|
|
83
113
|
var config = loadConfig();
|
|
84
114
|
|
|
85
115
|
// src/auth/token-manager.ts
|
|
86
|
-
|
|
116
|
+
import axios, { AxiosError } from "axios";
|
|
87
117
|
var TokenManager = class {
|
|
88
118
|
async getValidAccessToken() {
|
|
89
119
|
const { accessToken, refreshToken } = config.auth;
|
|
@@ -129,7 +159,7 @@ var TokenManager = class {
|
|
|
129
159
|
}
|
|
130
160
|
async refreshTokens(refreshToken) {
|
|
131
161
|
try {
|
|
132
|
-
const response = await
|
|
162
|
+
const response = await axios.post(
|
|
133
163
|
`${config.apiBaseUrl}/auth/refresh-token`,
|
|
134
164
|
{ refresh_token: refreshToken }
|
|
135
165
|
);
|
|
@@ -141,7 +171,7 @@ var TokenManager = class {
|
|
|
141
171
|
saveConfig(config);
|
|
142
172
|
return tokens.access_token;
|
|
143
173
|
} catch (error) {
|
|
144
|
-
if (error instanceof
|
|
174
|
+
if (error instanceof AxiosError) {
|
|
145
175
|
const errorData = error.response?.data;
|
|
146
176
|
if (!errorData) throw error;
|
|
147
177
|
throw new Error(errorData.error);
|
|
@@ -151,7 +181,7 @@ var TokenManager = class {
|
|
|
151
181
|
}
|
|
152
182
|
async tokenExchange(accessToken) {
|
|
153
183
|
try {
|
|
154
|
-
const response = await
|
|
184
|
+
const response = await axios.post(
|
|
155
185
|
`${config.apiBaseUrl}/auth/token-exchange`,
|
|
156
186
|
{
|
|
157
187
|
access_token: accessToken
|
|
@@ -160,7 +190,7 @@ var TokenManager = class {
|
|
|
160
190
|
const { data } = response;
|
|
161
191
|
return data.access_token;
|
|
162
192
|
} catch (error) {
|
|
163
|
-
if (error instanceof
|
|
193
|
+
if (error instanceof AxiosError) {
|
|
164
194
|
const errorData = error.response?.data;
|
|
165
195
|
if (!errorData) throw error;
|
|
166
196
|
throw new Error(errorData.error);
|
|
@@ -179,7 +209,7 @@ var connectWebSocket = async (data) => {
|
|
|
179
209
|
});
|
|
180
210
|
const accessToken = await tokenManager.getValidAccessToken();
|
|
181
211
|
if (!accessToken) return null;
|
|
182
|
-
const ws = new
|
|
212
|
+
const ws = new WebSocket(url, {
|
|
183
213
|
headers: {
|
|
184
214
|
Authorization: `Bearer ${accessToken}`
|
|
185
215
|
}
|
|
@@ -188,8 +218,8 @@ var connectWebSocket = async (data) => {
|
|
|
188
218
|
};
|
|
189
219
|
|
|
190
220
|
// src/transport/http-tunnel.ts
|
|
191
|
-
|
|
192
|
-
|
|
221
|
+
import http from "http";
|
|
222
|
+
import "ws";
|
|
193
223
|
|
|
194
224
|
// src/@protocol/binary-frame.ts
|
|
195
225
|
var encodeBinaryFrame = (frame) => {
|
|
@@ -209,13 +239,13 @@ var decodeBinaryFrame = (buffer) => {
|
|
|
209
239
|
};
|
|
210
240
|
|
|
211
241
|
// src/@protocol/schemas/index.ts
|
|
212
|
-
|
|
242
|
+
import z6 from "zod";
|
|
213
243
|
|
|
214
244
|
// src/@protocol/schemas/request.schema.ts
|
|
215
|
-
|
|
245
|
+
import z2 from "zod";
|
|
216
246
|
|
|
217
247
|
// src/@protocol/schemas/base.schema.ts
|
|
218
|
-
|
|
248
|
+
import z from "zod";
|
|
219
249
|
|
|
220
250
|
// src/@protocol/constants.ts
|
|
221
251
|
var PROTOCOL_VERSION = "1.0.0";
|
|
@@ -233,55 +263,55 @@ var JsonMessageType = /* @__PURE__ */ ((JsonMessageType2) => {
|
|
|
233
263
|
})(JsonMessageType || {});
|
|
234
264
|
|
|
235
265
|
// src/@protocol/schemas/base.schema.ts
|
|
236
|
-
var baseSchema =
|
|
237
|
-
version:
|
|
238
|
-
type:
|
|
266
|
+
var baseSchema = z.object({
|
|
267
|
+
version: z.string().default(PROTOCOL_VERSION),
|
|
268
|
+
type: z.enum(JsonMessageType)
|
|
239
269
|
});
|
|
240
270
|
|
|
241
271
|
// src/@protocol/schemas/request.schema.ts
|
|
242
272
|
var requestStartSchema = baseSchema.extend({
|
|
243
|
-
type:
|
|
244
|
-
requestId:
|
|
245
|
-
method:
|
|
246
|
-
url:
|
|
247
|
-
headers:
|
|
273
|
+
type: z2.literal("request-start" /* RequestStart */),
|
|
274
|
+
requestId: z2.string(),
|
|
275
|
+
method: z2.string(),
|
|
276
|
+
url: z2.string(),
|
|
277
|
+
headers: z2.record(z2.string(), z2.string())
|
|
248
278
|
});
|
|
249
279
|
var requestEndSchema = baseSchema.extend({
|
|
250
|
-
type:
|
|
251
|
-
requestId:
|
|
280
|
+
type: z2.literal("request-end" /* RequestEnd */),
|
|
281
|
+
requestId: z2.string()
|
|
252
282
|
});
|
|
253
283
|
|
|
254
284
|
// src/@protocol/schemas/response.schema.ts
|
|
255
|
-
|
|
285
|
+
import z3 from "zod";
|
|
256
286
|
var responseStartSchema = baseSchema.extend({
|
|
257
|
-
type:
|
|
258
|
-
requestId:
|
|
259
|
-
statusCode:
|
|
260
|
-
headers:
|
|
287
|
+
type: z3.literal("response-start" /* ResponseStart */),
|
|
288
|
+
requestId: z3.string(),
|
|
289
|
+
statusCode: z3.number().int().min(100).max(599),
|
|
290
|
+
headers: z3.record(z3.string(), z3.string())
|
|
261
291
|
});
|
|
262
292
|
var responseEndSchema = baseSchema.extend({
|
|
263
|
-
type:
|
|
264
|
-
requestId:
|
|
293
|
+
type: z3.literal("response-end" /* ResponseEnd */),
|
|
294
|
+
requestId: z3.string()
|
|
265
295
|
});
|
|
266
296
|
|
|
267
297
|
// src/@protocol/schemas/tunnel.schema.ts
|
|
268
|
-
|
|
298
|
+
import z4 from "zod";
|
|
269
299
|
var tunnelCreatedSchema = baseSchema.extend({
|
|
270
|
-
type:
|
|
271
|
-
tunnelId:
|
|
272
|
-
subdomain:
|
|
273
|
-
host:
|
|
300
|
+
type: z4.literal("tunnel-created" /* TunnelCreated */),
|
|
301
|
+
tunnelId: z4.string(),
|
|
302
|
+
subdomain: z4.string(),
|
|
303
|
+
host: z4.string()
|
|
274
304
|
});
|
|
275
305
|
|
|
276
306
|
// src/@protocol/schemas/error-schema.ts
|
|
277
|
-
|
|
307
|
+
import z5 from "zod";
|
|
278
308
|
var errorSchema = baseSchema.extend({
|
|
279
|
-
type:
|
|
280
|
-
message:
|
|
309
|
+
type: z5.literal("error" /* Error */),
|
|
310
|
+
message: z5.string()
|
|
281
311
|
});
|
|
282
312
|
|
|
283
313
|
// src/@protocol/schemas/index.ts
|
|
284
|
-
var jsonMessageSchema =
|
|
314
|
+
var jsonMessageSchema = z6.discriminatedUnion("type", [
|
|
285
315
|
requestStartSchema,
|
|
286
316
|
requestEndSchema,
|
|
287
317
|
responseStartSchema,
|
|
@@ -291,40 +321,40 @@ var jsonMessageSchema = import_zod6.default.discriminatedUnion("type", [
|
|
|
291
321
|
]);
|
|
292
322
|
|
|
293
323
|
// src/@protocol/logger/index.ts
|
|
294
|
-
|
|
324
|
+
import chalk2 from "chalk";
|
|
295
325
|
var protoLogger = {
|
|
296
326
|
info: (...msg) => console.log(
|
|
297
|
-
|
|
327
|
+
chalk2.blue("[protocol:info]"),
|
|
298
328
|
...msg,
|
|
299
329
|
(/* @__PURE__ */ new Date()).toLocaleString(),
|
|
300
330
|
"\n"
|
|
301
331
|
),
|
|
302
332
|
next: (...msg) => console.log(
|
|
303
|
-
|
|
333
|
+
chalk2.green("[protocol:next]"),
|
|
304
334
|
...msg,
|
|
305
335
|
(/* @__PURE__ */ new Date()).toLocaleString(),
|
|
306
336
|
"\n"
|
|
307
337
|
),
|
|
308
338
|
success: (...msg) => console.log(
|
|
309
|
-
|
|
339
|
+
chalk2.green("[protocol:success]"),
|
|
310
340
|
...msg,
|
|
311
341
|
(/* @__PURE__ */ new Date()).toLocaleString(),
|
|
312
342
|
"\n"
|
|
313
343
|
),
|
|
314
344
|
error: (...msg) => console.error(
|
|
315
|
-
|
|
345
|
+
chalk2.red("[protocol:error]"),
|
|
316
346
|
...msg,
|
|
317
347
|
(/* @__PURE__ */ new Date()).toLocaleString(),
|
|
318
348
|
"\n"
|
|
319
349
|
),
|
|
320
350
|
debug: (...msg) => console.debug(
|
|
321
|
-
|
|
351
|
+
chalk2.bgRed("[protocol:debug]"),
|
|
322
352
|
...msg,
|
|
323
353
|
(/* @__PURE__ */ new Date()).toLocaleString(),
|
|
324
354
|
"\n"
|
|
325
355
|
),
|
|
326
356
|
warn: (...msg) => console.warn(
|
|
327
|
-
|
|
357
|
+
chalk2.bgYellowBright("[protocol:warn]"),
|
|
328
358
|
...msg,
|
|
329
359
|
(/* @__PURE__ */ new Date()).toLocaleString(),
|
|
330
360
|
"\n"
|
|
@@ -353,7 +383,7 @@ var parseFrame = (data, isBinary) => {
|
|
|
353
383
|
};
|
|
354
384
|
|
|
355
385
|
// src/@protocol/contract.ts
|
|
356
|
-
|
|
386
|
+
import "ws";
|
|
357
387
|
function createProtocolSide(incomingSchema, outgoingSchema) {
|
|
358
388
|
return {
|
|
359
389
|
validateIncoming: (data) => {
|
|
@@ -380,16 +410,16 @@ function createProtocolSide(incomingSchema, outgoingSchema) {
|
|
|
380
410
|
}
|
|
381
411
|
|
|
382
412
|
// src/@protocol/directions/client-to-server.ts
|
|
383
|
-
|
|
384
|
-
var clientToServerSchema =
|
|
413
|
+
import z7 from "zod";
|
|
414
|
+
var clientToServerSchema = z7.discriminatedUnion("type", [
|
|
385
415
|
responseStartSchema,
|
|
386
416
|
responseEndSchema,
|
|
387
417
|
errorSchema
|
|
388
418
|
]);
|
|
389
419
|
|
|
390
420
|
// src/@protocol/directions/server-to-client.ts
|
|
391
|
-
|
|
392
|
-
var serverToClientSchema =
|
|
421
|
+
import z8 from "zod";
|
|
422
|
+
var serverToClientSchema = z8.discriminatedUnion("type", [
|
|
393
423
|
tunnelCreatedSchema,
|
|
394
424
|
requestStartSchema,
|
|
395
425
|
requestEndSchema,
|
|
@@ -443,7 +473,7 @@ var startHttpTransport = (ws, localPort) => {
|
|
|
443
473
|
return;
|
|
444
474
|
}
|
|
445
475
|
if (message.type === "request-start" /* RequestStart */) {
|
|
446
|
-
const localRequest =
|
|
476
|
+
const localRequest = http.request({
|
|
447
477
|
hostname: "127.0.0.1",
|
|
448
478
|
port: localPort,
|
|
449
479
|
method: message.method,
|
|
@@ -511,29 +541,29 @@ async function startHttpTunnel(data) {
|
|
|
511
541
|
}
|
|
512
542
|
|
|
513
543
|
// src/commands/validators/http.validator.ts
|
|
514
|
-
|
|
544
|
+
import { InvalidArgumentError } from "commander";
|
|
515
545
|
var validatePort = (value) => {
|
|
516
546
|
const parsed = Number(value);
|
|
517
547
|
if (!Number.isInteger(parsed)) {
|
|
518
|
-
throw new
|
|
548
|
+
throw new InvalidArgumentError("port must be an integer");
|
|
519
549
|
}
|
|
520
550
|
if (parsed <= 0 || parsed > 65535) {
|
|
521
|
-
throw new
|
|
551
|
+
throw new InvalidArgumentError("port must be between 1 and 65535");
|
|
522
552
|
}
|
|
523
553
|
return parsed;
|
|
524
554
|
};
|
|
525
555
|
var validateSubdomain = (value) => {
|
|
526
556
|
if (value.length < 3) {
|
|
527
|
-
throw new
|
|
557
|
+
throw new InvalidArgumentError(
|
|
528
558
|
"subdomain must be at least 3 characters long"
|
|
529
559
|
);
|
|
530
560
|
}
|
|
531
561
|
if (value.length > 63) {
|
|
532
|
-
throw new
|
|
562
|
+
throw new InvalidArgumentError("subdomain must be less than 63 characters");
|
|
533
563
|
}
|
|
534
564
|
const regex = /^[a-z0-9][a-z0-9-]*$/;
|
|
535
565
|
if (!regex.test(value)) {
|
|
536
|
-
throw new
|
|
566
|
+
throw new InvalidArgumentError(
|
|
537
567
|
"subdomain must contain only lowercase letters, numbers, and hyphens"
|
|
538
568
|
);
|
|
539
569
|
}
|
|
@@ -557,7 +587,7 @@ var registerHttpCommand = (program2, config2) => {
|
|
|
557
587
|
};
|
|
558
588
|
|
|
559
589
|
// src/commands/help.ts
|
|
560
|
-
|
|
590
|
+
import "commander";
|
|
561
591
|
var registerHelpSubcommand = (program2) => {
|
|
562
592
|
program2.addHelpText(
|
|
563
593
|
"after",
|
|
@@ -570,17 +600,17 @@ Examples:
|
|
|
570
600
|
};
|
|
571
601
|
|
|
572
602
|
// src/commands/tcp.ts
|
|
573
|
-
|
|
603
|
+
import "commander";
|
|
574
604
|
|
|
575
605
|
// src/commands/auth.ts
|
|
576
|
-
|
|
606
|
+
import "commander";
|
|
577
607
|
|
|
578
608
|
// src/auth/auth-service.ts
|
|
579
|
-
|
|
609
|
+
import axios2, { AxiosError as AxiosError2 } from "axios";
|
|
580
610
|
|
|
581
611
|
// src/events/auth-emitter.ts
|
|
582
|
-
|
|
583
|
-
var AuthEventEmitter = class extends
|
|
612
|
+
import { EventEmitter } from "events";
|
|
613
|
+
var AuthEventEmitter = class extends EventEmitter {
|
|
584
614
|
emit(event, payload) {
|
|
585
615
|
return super.emit(event, payload);
|
|
586
616
|
}
|
|
@@ -595,7 +625,7 @@ var AuthService = class {
|
|
|
595
625
|
async startLogin() {
|
|
596
626
|
try {
|
|
597
627
|
authEmitter.emit("auth:start");
|
|
598
|
-
const response = await
|
|
628
|
+
const response = await axios2.post(
|
|
599
629
|
`${config.apiBaseUrl}/auth/github/device-start`
|
|
600
630
|
);
|
|
601
631
|
const { data } = response;
|
|
@@ -613,7 +643,7 @@ var AuthService = class {
|
|
|
613
643
|
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
|
|
614
644
|
while (Date.now() < expiresAt.getTime()) {
|
|
615
645
|
try {
|
|
616
|
-
const response = await
|
|
646
|
+
const response = await axios2.post(
|
|
617
647
|
`${config.apiBaseUrl}/auth/github/device-poll`,
|
|
618
648
|
{ device_code: deviceCode }
|
|
619
649
|
);
|
|
@@ -625,7 +655,7 @@ var AuthService = class {
|
|
|
625
655
|
});
|
|
626
656
|
return authEmitter.emit("auth:completed");
|
|
627
657
|
} catch (error) {
|
|
628
|
-
if (error instanceof
|
|
658
|
+
if (error instanceof AxiosError2) {
|
|
629
659
|
const errorData = error.response?.data;
|
|
630
660
|
if (!errorData) {
|
|
631
661
|
authEmitter.emit("auth:error", error);
|
|
@@ -659,7 +689,7 @@ var AuthService = class {
|
|
|
659
689
|
}
|
|
660
690
|
async logout(refreshToken) {
|
|
661
691
|
try {
|
|
662
|
-
const response = await
|
|
692
|
+
const response = await axios2.post(
|
|
663
693
|
`${config.apiBaseUrl}/auth/logout`,
|
|
664
694
|
{
|
|
665
695
|
refresh_token: refreshToken
|
|
@@ -672,7 +702,7 @@ var AuthService = class {
|
|
|
672
702
|
);
|
|
673
703
|
return true;
|
|
674
704
|
} catch (error) {
|
|
675
|
-
if (error instanceof
|
|
705
|
+
if (error instanceof AxiosError2) {
|
|
676
706
|
const errorData = error.response?.data;
|
|
677
707
|
if (!errorData) throw error;
|
|
678
708
|
throw new Error(`Logout failed: ${errorData.error}`);
|
|
@@ -684,7 +714,7 @@ var AuthService = class {
|
|
|
684
714
|
var authService = new AuthService();
|
|
685
715
|
|
|
686
716
|
// src/commands/auth.ts
|
|
687
|
-
|
|
717
|
+
import chalk3 from "chalk";
|
|
688
718
|
var registerAuthCommand = (program2, commandConfig) => {
|
|
689
719
|
program2.command("auth").description(commandConfig.description).usage(commandConfig.usage).addHelpText(
|
|
690
720
|
"after",
|
|
@@ -697,13 +727,13 @@ Examples:
|
|
|
697
727
|
});
|
|
698
728
|
authEmitter.on("auth:code", ({ user_code, verification_uri }) => {
|
|
699
729
|
logger.info("Please visit the following URL to authorize the CLI:");
|
|
700
|
-
logger.log(
|
|
701
|
-
logger.info(`Enter the code: ${
|
|
730
|
+
logger.log(chalk3.bold.cyan(verification_uri));
|
|
731
|
+
logger.info(`Enter the code: ${chalk3.bold.yellow(user_code)}`);
|
|
702
732
|
});
|
|
703
733
|
authEmitter.on("auth:success", ({ accessToken, refreshToken, user }) => {
|
|
704
734
|
tokenManager.saveTokens(accessToken, refreshToken);
|
|
705
735
|
logger.success(
|
|
706
|
-
`Successfully authenticated as ${
|
|
736
|
+
`Successfully authenticated as ${chalk3.bold.green(`${user.name} (${user.username})`)}!`
|
|
707
737
|
);
|
|
708
738
|
});
|
|
709
739
|
authEmitter.on("auth:error", (error) => {
|
|
@@ -722,7 +752,7 @@ Examples:
|
|
|
722
752
|
};
|
|
723
753
|
|
|
724
754
|
// src/commands/logout.ts
|
|
725
|
-
|
|
755
|
+
import "commander";
|
|
726
756
|
var registerLogoutCommand = (program2, commandConfig) => {
|
|
727
757
|
program2.command("logout").description(commandConfig.description).usage(commandConfig.usage).addHelpText("after", `Examples:
|
|
728
758
|
${commandConfig.examples.join("\n ")}`).action(async () => {
|
|
@@ -745,7 +775,7 @@ var registerLogoutCommand = (program2, commandConfig) => {
|
|
|
745
775
|
};
|
|
746
776
|
|
|
747
777
|
// src/commands/config.ts
|
|
748
|
-
|
|
778
|
+
import "commander";
|
|
749
779
|
var registerConfigCommand = (program2, config2) => {
|
|
750
780
|
program2.command("config").description(config2.description).usage(config2.usage).addHelpText("after", `Examples:
|
|
751
781
|
${config2.examples.join("\n ")}`).option("-r, --reset", "Reset config file options to default.").action((options) => {
|
|
@@ -760,7 +790,7 @@ var registerConfigCommand = (program2, config2) => {
|
|
|
760
790
|
};
|
|
761
791
|
|
|
762
792
|
// src/commands/index.ts
|
|
763
|
-
var program = new
|
|
793
|
+
var program = new Command6();
|
|
764
794
|
program.name(config.name).version(config.version).description(config.description).usage(config.usage).configureOutput({
|
|
765
795
|
writeOut: (message) => logger.info(message),
|
|
766
796
|
writeErr: (message) => logger.error(message)
|
package/package.json
CHANGED
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quvur-dev",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "A lightweight developer tunneling CLI that securely exposes local HTTP and TCP services to the internet via a remote gateway.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "Muhammadali Yuldoshev <mukhammadaliweb@gmail.com>",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"cli",
|
|
12
|
+
"tunnel",
|
|
13
|
+
"tcp-tunnel",
|
|
14
|
+
"http-tunnel",
|
|
15
|
+
"reverse-proxy",
|
|
16
|
+
"port-forwarding",
|
|
17
|
+
"local-development",
|
|
18
|
+
"developer-tools",
|
|
19
|
+
"devops",
|
|
20
|
+
"networking",
|
|
21
|
+
"websocket-tunnel"
|
|
22
|
+
],
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20"
|
|
25
|
+
},
|
|
9
26
|
"bin": {
|
|
10
|
-
"quvur": "dist/index.
|
|
27
|
+
"quvur": "dist/index.js"
|
|
11
28
|
},
|
|
12
29
|
"files": [
|
|
13
30
|
"dist"
|
|
14
31
|
],
|
|
15
32
|
"scripts": {
|
|
16
|
-
"build": "npx tsup src/index.ts --dts",
|
|
33
|
+
"build": "npx tsup src/index.ts --format esm --dts",
|
|
17
34
|
"start:dev": "tsx --watch src/index.ts",
|
|
18
35
|
"prepublishOnly": "npm run build"
|
|
19
36
|
},
|
package/dist/index.d.cts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|