@stacksjs/bun-router 0.0.13 → 0.0.14
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/CHANGELOG.md +770 -0
- package/README.md +584 -261
- package/package.json +43 -47
- package/bin/cli.ts +0 -9
- package/dist/auth.d.ts +0 -134
- package/dist/cache/lru-cache.d.ts +0 -139
- package/dist/cache/middleware-memoization.d.ts +0 -151
- package/dist/cache/route-cache-warmer.d.ts +0 -161
- package/dist/cache/sqlite-cache.d.ts +0 -209
- package/dist/cache/streaming-cache.d.ts +0 -132
- package/dist/chunk-1mvtv6jw.js +0 -13012
- package/dist/cli/colors.d.ts +0 -15
- package/dist/cli/index.d.ts +0 -10
- package/dist/cli/middleware.d.ts +0 -31
- package/dist/cli/openapi.d.ts +0 -17
- package/dist/cli/router.d.ts +0 -15
- package/dist/cli/routes.d.ts +0 -29
- package/dist/cli/utils.d.ts +0 -74
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -3195
- package/dist/config.d.ts +0 -7
- package/dist/container/container.d.ts +0 -273
- package/dist/container/contextual-binding.d.ts +0 -240
- package/dist/container/decorators.d.ts +0 -141
- package/dist/container/service-provider.d.ts +0 -285
- package/dist/development/hot-reload.d.ts +0 -187
- package/dist/development/index.d.ts +0 -167
- package/dist/development/performance-profiler.d.ts +0 -217
- package/dist/development/route-debugger.d.ts +0 -154
- package/dist/development/route-inspector.d.ts +0 -211
- package/dist/development/typescript-utilities.d.ts +0 -209
- package/dist/docs.d.ts +0 -11
- package/dist/errors/circuit-breaker.d.ts +0 -195
- package/dist/errors/error-handler.d.ts +0 -88
- package/dist/errors/error-reporting.d.ts +0 -144
- package/dist/errors/exceptions.d.ts +0 -184
- package/dist/errors/graceful-degradation.d.ts +0 -154
- package/dist/errors/index.d.ts +0 -9
- package/dist/errors/router-errors.d.ts +0 -110
- package/dist/file-serving/static-files.d.ts +0 -143
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -13933
- package/dist/middleware/auth.d.ts +0 -63
- package/dist/middleware/content_security_policy.d.ts +0 -53
- package/dist/middleware/cors.d.ts +0 -5
- package/dist/middleware/csrf.d.ts +0 -7
- package/dist/middleware/ddos_protection.d.ts +0 -39
- package/dist/middleware/file_security.d.ts +0 -26
- package/dist/middleware/file_upload.d.ts +0 -38
- package/dist/middleware/helmet.d.ts +0 -54
- package/dist/middleware/index.d.ts +0 -44
- package/dist/middleware/input_validation.d.ts +0 -45
- package/dist/middleware/json_body.d.ts +0 -4
- package/dist/middleware/performance_alerting.d.ts +0 -87
- package/dist/middleware/performance_dashboard.d.ts +0 -87
- package/dist/middleware/performance_monitor.d.ts +0 -209
- package/dist/middleware/pipeline.d.ts +0 -131
- package/dist/middleware/rate_limit.d.ts +0 -36
- package/dist/middleware/request_id.d.ts +0 -4
- package/dist/middleware/request_signing.d.ts +0 -153
- package/dist/middleware/request_tracer.d.ts +0 -72
- package/dist/middleware/response_cache.d.ts +0 -97
- package/dist/middleware/security.d.ts +0 -69
- package/dist/middleware/security_suite.d.ts +0 -46
- package/dist/middleware/session.d.ts +0 -23
- package/dist/model-binding/index.d.ts +0 -2
- package/dist/model-binding/model-middleware.d.ts +0 -118
- package/dist/model-binding/model-registry.d.ts +0 -164
- package/dist/model-binding.d.ts +0 -185
- package/dist/model-resolver-factory.d.ts +0 -31
- package/dist/observability/correlation.d.ts +0 -187
- package/dist/observability/health-checks.d.ts +0 -186
- package/dist/observability/index.d.ts +0 -60
- package/dist/observability/integration.d.ts +0 -147
- package/dist/observability/metrics.d.ts +0 -184
- package/dist/observability/tracing.d.ts +0 -187
- package/dist/optimization/bun-utilities.d.ts +0 -224
- package/dist/query-builder-integration.d.ts +0 -36
- package/dist/request/context.d.ts +0 -34
- package/dist/request/enhanced-request.d.ts +0 -213
- package/dist/request/macros.d.ts +0 -300
- package/dist/response/macros.d.ts +0 -245
- package/dist/response/response-factory.d.ts +0 -133
- package/dist/router/api-routes.d.ts +0 -5
- package/dist/router/file-based-routing.d.ts +0 -118
- package/dist/router/file-streaming.d.ts +0 -5
- package/dist/router/fluent-router.d.ts +0 -315
- package/dist/router/fluent-routing.d.ts +0 -271
- package/dist/router/group-organization.d.ts +0 -5
- package/dist/router/handler-resolver.d.ts +0 -24
- package/dist/router/http-methods.d.ts +0 -10
- package/dist/router/index.d.ts +0 -114
- package/dist/router/middleware-groups.d.ts +0 -94
- package/dist/router/middleware-integration.d.ts +0 -112
- package/dist/router/middleware.d.ts +0 -5
- package/dist/router/model-binding.d.ts +0 -5
- package/dist/router/optimized-route-matching.d.ts +0 -6
- package/dist/router/route-building.d.ts +0 -5
- package/dist/router/route-compiler.d.ts +0 -153
- package/dist/router/route-matching.d.ts +0 -5
- package/dist/router/route-trie.d.ts +0 -114
- package/dist/router/router.d.ts +0 -294
- package/dist/router/server.d.ts +0 -5
- package/dist/router/validation-integration.d.ts +0 -170
- package/dist/router/view-rendering.d.ts +0 -5
- package/dist/router/websocket.d.ts +0 -5
- package/dist/routing/route-caching.d.ts +0 -129
- package/dist/routing/route-throttling.d.ts +0 -150
- package/dist/routing/subdomain-routing.d.ts +0 -206
- package/dist/session/database-store.d.ts +0 -51
- package/dist/session/file-store.d.ts +0 -22
- package/dist/session/index.d.ts +0 -106
- package/dist/session/memory-store.d.ts +0 -21
- package/dist/session/redis-store.d.ts +0 -31
- package/dist/streaming/index.d.ts +0 -3
- package/dist/streaming/sse-handler.d.ts +0 -138
- package/dist/streaming/stream-handler.d.ts +0 -114
- package/dist/testing/auth-testing.d.ts +0 -156
- package/dist/testing/file-upload-testing.d.ts +0 -190
- package/dist/testing/index.d.ts +0 -10
- package/dist/testing/middleware-testing.d.ts +0 -138
- package/dist/testing/model-binding-testing.d.ts +0 -186
- package/dist/testing/performance-testing.d.ts +0 -235
- package/dist/testing/test-client.d.ts +0 -117
- package/dist/testing/test-request.d.ts +0 -85
- package/dist/testing/test-response.d.ts +0 -90
- package/dist/testing/types.d.ts +0 -207
- package/dist/testing/websocket-testing.d.ts +0 -227
- package/dist/types/controller-types.d.ts +0 -208
- package/dist/types/core.d.ts +0 -543
- package/dist/types/middleware-types.d.ts +0 -227
- package/dist/types/request-response-augmentation.d.ts +0 -261
- package/dist/types/route-inference.d.ts +0 -168
- package/dist/types.d.ts +0 -1782
- package/dist/url.d.ts +0 -56
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/query-preservation.d.ts +0 -48
- package/dist/utils.d.ts +0 -69
- package/dist/validation/validator.d.ts +0 -140
- package/dist/websocket/clustering.d.ts +0 -185
- package/src/auth.ts +0 -469
- package/src/cache/lru-cache.ts +0 -457
- package/src/cache/middleware-memoization.ts +0 -531
- package/src/cache/route-cache-warmer.ts +0 -486
- package/src/cache/sqlite-cache.ts +0 -783
- package/src/cache/streaming-cache.ts +0 -572
- package/src/cli/colors.ts +0 -29
- package/src/cli/index.ts +0 -287
- package/src/cli/middleware.ts +0 -291
- package/src/cli/openapi.ts +0 -407
- package/src/cli/router.ts +0 -188
- package/src/cli/routes.ts +0 -265
- package/src/cli/utils.ts +0 -531
- package/src/cli.ts +0 -5
- package/src/config.ts +0 -322
- package/src/container/container.ts +0 -740
- package/src/container/contextual-binding.ts +0 -603
- package/src/container/decorators.ts +0 -359
- package/src/container/service-provider.ts +0 -596
- package/src/development/hot-reload.ts +0 -673
- package/src/development/index.ts +0 -499
- package/src/development/performance-profiler.ts +0 -717
- package/src/development/route-debugger.ts +0 -527
- package/src/development/route-inspector.ts +0 -749
- package/src/development/typescript-utilities.ts +0 -682
- package/src/docs.ts +0 -397
- package/src/errors/circuit-breaker.ts +0 -732
- package/src/errors/error-handler.ts +0 -569
- package/src/errors/error-reporting.ts +0 -672
- package/src/errors/exceptions.ts +0 -536
- package/src/errors/graceful-degradation.ts +0 -621
- package/src/errors/index.ts +0 -21
- package/src/errors/router-errors.ts +0 -632
- package/src/file-serving/static-files.ts +0 -581
- package/src/index.ts +0 -14
- package/src/middleware/auth.ts +0 -219
- package/src/middleware/content_security_policy.ts +0 -215
- package/src/middleware/cors.ts +0 -74
- package/src/middleware/csrf.ts +0 -108
- package/src/middleware/ddos_protection.ts +0 -255
- package/src/middleware/file_security.ts +0 -191
- package/src/middleware/file_upload.ts +0 -264
- package/src/middleware/helmet.ts +0 -268
- package/src/middleware/index.ts +0 -117
- package/src/middleware/input_validation.ts +0 -449
- package/src/middleware/json_body.ts +0 -37
- package/src/middleware/performance_alerting.ts +0 -538
- package/src/middleware/performance_dashboard.ts +0 -661
- package/src/middleware/performance_monitor.ts +0 -943
- package/src/middleware/pipeline.ts +0 -489
- package/src/middleware/rate_limit.ts +0 -245
- package/src/middleware/request_id.ts +0 -36
- package/src/middleware/request_signing.ts +0 -636
- package/src/middleware/request_tracer.ts +0 -636
- package/src/middleware/response_cache.ts +0 -743
- package/src/middleware/security.ts +0 -482
- package/src/middleware/security_suite.ts +0 -257
- package/src/middleware/session.ts +0 -91
- package/src/model-binding/index.ts +0 -18
- package/src/model-binding/model-middleware.ts +0 -425
- package/src/model-binding/model-registry.ts +0 -550
- package/src/model-binding.ts +0 -370
- package/src/model-resolver-factory.ts +0 -106
- package/src/observability/correlation.ts +0 -691
- package/src/observability/health-checks.ts +0 -729
- package/src/observability/index.ts +0 -184
- package/src/observability/integration.ts +0 -548
- package/src/observability/metrics.ts +0 -753
- package/src/observability/tracing.ts +0 -638
- package/src/optimization/bun-utilities.ts +0 -778
- package/src/query-builder-integration.ts +0 -137
- package/src/request/context.ts +0 -62
- package/src/request/enhanced-request.ts +0 -857
- package/src/request/macros.ts +0 -688
- package/src/response/macros.ts +0 -612
- package/src/response/response-factory.ts +0 -596
- package/src/router/api-routes.ts +0 -243
- package/src/router/file-based-routing.ts +0 -670
- package/src/router/file-streaming.ts +0 -372
- package/src/router/fluent-router.ts +0 -927
- package/src/router/fluent-routing.ts +0 -797
- package/src/router/group-organization.ts +0 -213
- package/src/router/handler-resolver.ts +0 -291
- package/src/router/http-methods.ts +0 -377
- package/src/router/index.ts +0 -187
- package/src/router/middleware-groups.ts +0 -222
- package/src/router/middleware-integration.ts +0 -399
- package/src/router/middleware.ts +0 -231
- package/src/router/model-binding.ts +0 -215
- package/src/router/optimized-route-matching.ts +0 -253
- package/src/router/route-building.ts +0 -212
- package/src/router/route-compiler.ts +0 -702
- package/src/router/route-matching.ts +0 -349
- package/src/router/route-trie.ts +0 -464
- package/src/router/router.ts +0 -1581
- package/src/router/server.ts +0 -462
- package/src/router/validation-integration.ts +0 -443
- package/src/router/view-rendering.ts +0 -233
- package/src/router/websocket.ts +0 -100
- package/src/routing/route-caching.ts +0 -402
- package/src/routing/route-throttling.ts +0 -469
- package/src/routing/subdomain-routing.ts +0 -492
- package/src/session/database-store.ts +0 -109
- package/src/session/file-store.ts +0 -148
- package/src/session/index.ts +0 -244
- package/src/session/memory-store.ts +0 -88
- package/src/session/redis-store.ts +0 -93
- package/src/streaming/index.ts +0 -17
- package/src/streaming/sse-handler.ts +0 -482
- package/src/streaming/stream-handler.ts +0 -552
- package/src/testing/auth-testing.ts +0 -446
- package/src/testing/file-upload-testing.ts +0 -543
- package/src/testing/index.ts +0 -10
- package/src/testing/middleware-testing.ts +0 -322
- package/src/testing/model-binding-testing.ts +0 -645
- package/src/testing/performance-testing.ts +0 -738
- package/src/testing/test-client.ts +0 -310
- package/src/testing/test-request.ts +0 -315
- package/src/testing/test-response.ts +0 -332
- package/src/testing/types.ts +0 -224
- package/src/testing/websocket-testing.ts +0 -590
- package/src/types/controller-types.ts +0 -385
- package/src/types/core.ts +0 -683
- package/src/types/middleware-types.ts +0 -419
- package/src/types/request-response-augmentation.ts +0 -489
- package/src/types/route-inference.ts +0 -357
- package/src/types.ts +0 -2055
- package/src/url.ts +0 -126
- package/src/utils/index.ts +0 -1
- package/src/utils/query-preservation.ts +0 -201
- package/src/utils.ts +0 -327
- package/src/validation/validator.ts +0 -685
- package/src/websocket/clustering.ts +0 -762
package/dist/cli.js
DELETED
|
@@ -1,3195 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
middleware
|
|
4
|
-
} from "./chunk-1mvtv6jw.js";
|
|
5
|
-
|
|
6
|
-
// src/cli/index.ts
|
|
7
|
-
import process13 from "process";
|
|
8
|
-
|
|
9
|
-
// ../../node_modules/@stacksjs/clapp/dist/index.js
|
|
10
|
-
import { EventEmitter } from "events";
|
|
11
|
-
import process2 from "process";
|
|
12
|
-
import process3 from "process";
|
|
13
|
-
import process4 from "process";
|
|
14
|
-
import process5, { stdin, stdout } from "process";
|
|
15
|
-
import process6, { stdin as stdin2, stdout as stdout2 } from "process";
|
|
16
|
-
import readline2 from "readline";
|
|
17
|
-
var __create = Object.create;
|
|
18
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
19
|
-
var __defProp = Object.defineProperty;
|
|
20
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
21
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
22
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
23
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
24
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
25
|
-
for (let key of __getOwnPropNames(mod))
|
|
26
|
-
if (!__hasOwnProp.call(to, key))
|
|
27
|
-
__defProp(to, key, {
|
|
28
|
-
get: () => mod[key],
|
|
29
|
-
enumerable: true
|
|
30
|
-
});
|
|
31
|
-
return to;
|
|
32
|
-
};
|
|
33
|
-
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
-
var require_lib = __commonJS((exports, module) => {
|
|
35
|
-
function toArr(any) {
|
|
36
|
-
return any == null ? [] : Array.isArray(any) ? any : [any];
|
|
37
|
-
}
|
|
38
|
-
function toVal(out, key, val, opts) {
|
|
39
|
-
var x, old = out[key], nxt = ~opts.string.indexOf(key) ? val == null || val === true ? "" : String(val) : typeof val === "boolean" ? val : ~opts.boolean.indexOf(key) ? val === "false" ? false : val === "true" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;
|
|
40
|
-
out[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];
|
|
41
|
-
}
|
|
42
|
-
module.exports = function(args, opts) {
|
|
43
|
-
args = args || [];
|
|
44
|
-
opts = opts || {};
|
|
45
|
-
var k, arr, arg, name, val, out = { _: [] };
|
|
46
|
-
var i = 0, j = 0, idx = 0, len = args.length;
|
|
47
|
-
const alibi = opts.alias !== undefined;
|
|
48
|
-
const strict = opts.unknown !== undefined;
|
|
49
|
-
const defaults = opts.default !== undefined;
|
|
50
|
-
opts.alias = opts.alias || {};
|
|
51
|
-
opts.string = toArr(opts.string);
|
|
52
|
-
opts.boolean = toArr(opts.boolean);
|
|
53
|
-
if (alibi) {
|
|
54
|
-
for (k in opts.alias) {
|
|
55
|
-
arr = opts.alias[k] = toArr(opts.alias[k]);
|
|
56
|
-
for (i = 0;i < arr.length; i++) {
|
|
57
|
-
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
for (i = opts.boolean.length;i-- > 0; ) {
|
|
62
|
-
arr = opts.alias[opts.boolean[i]] || [];
|
|
63
|
-
for (j = arr.length;j-- > 0; )
|
|
64
|
-
opts.boolean.push(arr[j]);
|
|
65
|
-
}
|
|
66
|
-
for (i = opts.string.length;i-- > 0; ) {
|
|
67
|
-
arr = opts.alias[opts.string[i]] || [];
|
|
68
|
-
for (j = arr.length;j-- > 0; )
|
|
69
|
-
opts.string.push(arr[j]);
|
|
70
|
-
}
|
|
71
|
-
if (defaults) {
|
|
72
|
-
for (k in opts.default) {
|
|
73
|
-
name = typeof opts.default[k];
|
|
74
|
-
arr = opts.alias[k] = opts.alias[k] || [];
|
|
75
|
-
if (opts[name] !== undefined) {
|
|
76
|
-
opts[name].push(k);
|
|
77
|
-
for (i = 0;i < arr.length; i++) {
|
|
78
|
-
opts[name].push(arr[i]);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
const keys = strict ? Object.keys(opts.alias) : [];
|
|
84
|
-
for (i = 0;i < len; i++) {
|
|
85
|
-
arg = args[i];
|
|
86
|
-
if (arg === "--") {
|
|
87
|
-
out._ = out._.concat(args.slice(++i));
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
for (j = 0;j < arg.length; j++) {
|
|
91
|
-
if (arg.charCodeAt(j) !== 45)
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
if (j === 0) {
|
|
95
|
-
out._.push(arg);
|
|
96
|
-
} else if (arg.substring(j, j + 3) === "no-") {
|
|
97
|
-
name = arg.substring(j + 3);
|
|
98
|
-
if (strict && !~keys.indexOf(name)) {
|
|
99
|
-
return opts.unknown(arg);
|
|
100
|
-
}
|
|
101
|
-
out[name] = false;
|
|
102
|
-
} else {
|
|
103
|
-
for (idx = j + 1;idx < arg.length; idx++) {
|
|
104
|
-
if (arg.charCodeAt(idx) === 61)
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
name = arg.substring(j, idx);
|
|
108
|
-
val = arg.substring(++idx) || (i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i]);
|
|
109
|
-
arr = j === 2 ? [name] : name;
|
|
110
|
-
for (idx = 0;idx < arr.length; idx++) {
|
|
111
|
-
name = arr[idx];
|
|
112
|
-
if (strict && !~keys.indexOf(name))
|
|
113
|
-
return opts.unknown("-".repeat(j) + name);
|
|
114
|
-
toVal(out, name, idx + 1 < arr.length || val, opts);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (defaults) {
|
|
119
|
-
for (k in opts.default) {
|
|
120
|
-
if (out[k] === undefined) {
|
|
121
|
-
out[k] = opts.default[k];
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (alibi) {
|
|
126
|
-
for (k in out) {
|
|
127
|
-
arr = opts.alias[k] || [];
|
|
128
|
-
while (arr.length > 0) {
|
|
129
|
-
out[arr.shift()] = out[k];
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return out;
|
|
134
|
-
};
|
|
135
|
-
});
|
|
136
|
-
var require_picocolors = __commonJS((exports, module) => {
|
|
137
|
-
var p = process || {};
|
|
138
|
-
var argv = p.argv || [];
|
|
139
|
-
var env = p.env || {};
|
|
140
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
141
|
-
var formatter = (open, close, replace = open) => (input) => {
|
|
142
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
143
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
144
|
-
};
|
|
145
|
-
var replaceClose = (string, close, replace, index) => {
|
|
146
|
-
let result = "", cursor2 = 0;
|
|
147
|
-
do {
|
|
148
|
-
result += string.substring(cursor2, index) + replace;
|
|
149
|
-
cursor2 = index + close.length;
|
|
150
|
-
index = string.indexOf(close, cursor2);
|
|
151
|
-
} while (~index);
|
|
152
|
-
return result + string.substring(cursor2);
|
|
153
|
-
};
|
|
154
|
-
var createColors = (enabled = isColorSupported) => {
|
|
155
|
-
let f = enabled ? formatter : () => String;
|
|
156
|
-
return {
|
|
157
|
-
isColorSupported: enabled,
|
|
158
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
159
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
160
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
161
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
162
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
163
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
164
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
165
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
166
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
167
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
168
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
169
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
170
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
171
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
172
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
173
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
174
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
175
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
176
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
177
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
178
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
179
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
180
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
181
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
182
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
183
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
184
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
185
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
186
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
187
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
188
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
189
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
190
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
191
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
192
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
193
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
194
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
195
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
196
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
197
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
198
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
199
|
-
};
|
|
200
|
-
};
|
|
201
|
-
module.exports = createColors();
|
|
202
|
-
module.exports.createColors = createColors;
|
|
203
|
-
});
|
|
204
|
-
var require_emoji_regex = __commonJS((exports, module) => {
|
|
205
|
-
module.exports = () => {
|
|
206
|
-
return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC2\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
|
|
207
|
-
};
|
|
208
|
-
});
|
|
209
|
-
var import_mri = __toESM(require_lib(), 1);
|
|
210
|
-
function removeBrackets(v) {
|
|
211
|
-
return v.replace(/[<[].+/, "").trim();
|
|
212
|
-
}
|
|
213
|
-
function findAllBrackets(v) {
|
|
214
|
-
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
|
|
215
|
-
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
|
|
216
|
-
const res = [];
|
|
217
|
-
const parse = (match) => {
|
|
218
|
-
let variadic = false;
|
|
219
|
-
let value = match[1];
|
|
220
|
-
if (value.startsWith("...")) {
|
|
221
|
-
value = value.slice(3);
|
|
222
|
-
variadic = true;
|
|
223
|
-
}
|
|
224
|
-
return {
|
|
225
|
-
required: match[0].startsWith("<"),
|
|
226
|
-
value,
|
|
227
|
-
variadic
|
|
228
|
-
};
|
|
229
|
-
};
|
|
230
|
-
let angledMatch;
|
|
231
|
-
while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
|
|
232
|
-
res.push(parse(angledMatch));
|
|
233
|
-
}
|
|
234
|
-
let squareMatch;
|
|
235
|
-
while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
|
|
236
|
-
res.push(parse(squareMatch));
|
|
237
|
-
}
|
|
238
|
-
return res;
|
|
239
|
-
}
|
|
240
|
-
function getMriOptions(options) {
|
|
241
|
-
const result = { alias: {}, boolean: [] };
|
|
242
|
-
for (const [index, option] of options.entries()) {
|
|
243
|
-
if (option.names.length > 1) {
|
|
244
|
-
result.alias[option.names[0]] = option.names.slice(1);
|
|
245
|
-
}
|
|
246
|
-
if (option.isBoolean) {
|
|
247
|
-
if (option.negated) {
|
|
248
|
-
const hasStringTypeOption = options.some((o, i) => {
|
|
249
|
-
return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
|
|
250
|
-
});
|
|
251
|
-
if (!hasStringTypeOption) {
|
|
252
|
-
result.boolean.push(option.names[0]);
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
result.boolean.push(option.names[0]);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return result;
|
|
260
|
-
}
|
|
261
|
-
function findLongest(arr) {
|
|
262
|
-
return arr.sort((a, b) => {
|
|
263
|
-
return a.length > b.length ? -1 : 1;
|
|
264
|
-
})[0];
|
|
265
|
-
}
|
|
266
|
-
function padRight(str, length) {
|
|
267
|
-
return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
|
|
268
|
-
}
|
|
269
|
-
function camelcase(input) {
|
|
270
|
-
return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {
|
|
271
|
-
return p1 + p2.toUpperCase();
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
function setDotProp(obj, keys, val) {
|
|
275
|
-
let i = 0;
|
|
276
|
-
const length = keys.length;
|
|
277
|
-
let t = obj;
|
|
278
|
-
let x;
|
|
279
|
-
for (;i < length; ++i) {
|
|
280
|
-
x = t[keys[i]];
|
|
281
|
-
t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : [];
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
function setByType(obj, transforms) {
|
|
285
|
-
for (const key of Object.keys(transforms)) {
|
|
286
|
-
const transform = transforms[key];
|
|
287
|
-
if (transform.shouldTransform) {
|
|
288
|
-
obj[key] = Array.prototype.concat.call([], obj[key]);
|
|
289
|
-
if (typeof transform.transformFunction === "function") {
|
|
290
|
-
obj[key] = obj[key].map(transform.transformFunction);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
function getFileName(input) {
|
|
296
|
-
const m = /([^\\/]+)$/.exec(input);
|
|
297
|
-
return m ? m[1] : "";
|
|
298
|
-
}
|
|
299
|
-
function camelcaseOptionName(name) {
|
|
300
|
-
return name.split(".").map((v, i) => {
|
|
301
|
-
return i === 0 ? camelcase(v) : v;
|
|
302
|
-
}).join(".");
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
class ClappError extends Error {
|
|
306
|
-
constructor(message) {
|
|
307
|
-
super(message);
|
|
308
|
-
this.name = this.constructor.name;
|
|
309
|
-
if (typeof Error.captureStackTrace === "function") {
|
|
310
|
-
Error.captureStackTrace(this, this.constructor);
|
|
311
|
-
} else {
|
|
312
|
-
this.stack = new Error(message).stack;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
function isUnicodeSupported() {
|
|
317
|
-
const { env } = process2;
|
|
318
|
-
const { TERM, TERM_PROGRAM } = env;
|
|
319
|
-
if (process2.platform !== "win32") {
|
|
320
|
-
return TERM !== "linux";
|
|
321
|
-
}
|
|
322
|
-
return Boolean(env.WT_SESSION) || Boolean(env.TERMINUS_SUBLIME) || env.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
323
|
-
}
|
|
324
|
-
var ESC = "\x1B";
|
|
325
|
-
var CSI = `${ESC}[`;
|
|
326
|
-
var cursor = {
|
|
327
|
-
to(x, y) {
|
|
328
|
-
if (!y)
|
|
329
|
-
return `${CSI}${x + 1}G`;
|
|
330
|
-
return `${CSI}${y + 1};${x + 1}H`;
|
|
331
|
-
},
|
|
332
|
-
move(x, y) {
|
|
333
|
-
let ret = "";
|
|
334
|
-
if (x < 0)
|
|
335
|
-
ret += `${CSI}${-x}D`;
|
|
336
|
-
else if (x > 0)
|
|
337
|
-
ret += `${CSI}${x}C`;
|
|
338
|
-
if (y < 0)
|
|
339
|
-
ret += `${CSI}${-y}A`;
|
|
340
|
-
else if (y > 0)
|
|
341
|
-
ret += `${CSI}${y}B`;
|
|
342
|
-
return ret;
|
|
343
|
-
},
|
|
344
|
-
up: (count = 1) => `${CSI}${count}A`,
|
|
345
|
-
down: (count = 1) => `${CSI}${count}B`,
|
|
346
|
-
forward: (count = 1) => `${CSI}${count}C`,
|
|
347
|
-
backward: (count = 1) => `${CSI}${count}D`,
|
|
348
|
-
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
|
349
|
-
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
|
350
|
-
left: `${CSI}G`,
|
|
351
|
-
hide: `${CSI}?25l`,
|
|
352
|
-
show: `${CSI}?25h`,
|
|
353
|
-
save: `${ESC}7`,
|
|
354
|
-
restore: `${ESC}8`
|
|
355
|
-
};
|
|
356
|
-
var erase = {
|
|
357
|
-
screen: `${CSI}2J`,
|
|
358
|
-
up: (count = 1) => `${CSI}1J`.repeat(count),
|
|
359
|
-
down: (count = 1) => `${CSI}J`.repeat(count),
|
|
360
|
-
line: `${CSI}2K`,
|
|
361
|
-
lineEnd: `${CSI}K`,
|
|
362
|
-
lineStart: `${CSI}1K`,
|
|
363
|
-
lines(count) {
|
|
364
|
-
let clear = "";
|
|
365
|
-
for (let i = 0;i < count; i++)
|
|
366
|
-
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
367
|
-
if (count)
|
|
368
|
-
clear += cursor.left;
|
|
369
|
-
return clear;
|
|
370
|
-
}
|
|
371
|
-
};
|
|
372
|
-
var clear = {
|
|
373
|
-
screen: `${ESC}c`
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
class Option {
|
|
377
|
-
rawName;
|
|
378
|
-
description;
|
|
379
|
-
name;
|
|
380
|
-
names;
|
|
381
|
-
isBoolean;
|
|
382
|
-
required;
|
|
383
|
-
config;
|
|
384
|
-
negated;
|
|
385
|
-
constructor(rawName, description, config) {
|
|
386
|
-
this.rawName = rawName;
|
|
387
|
-
this.description = description;
|
|
388
|
-
this.config = Object.assign({}, config);
|
|
389
|
-
rawName = rawName.replace(/\.\*/g, "");
|
|
390
|
-
this.negated = false;
|
|
391
|
-
this.names = removeBrackets(rawName).split(",").map((v) => {
|
|
392
|
-
let name = v.trim().replace(/^-{1,2}/, "");
|
|
393
|
-
if (name.startsWith("no-")) {
|
|
394
|
-
this.negated = true;
|
|
395
|
-
name = name.replace(/^no-/, "");
|
|
396
|
-
}
|
|
397
|
-
return camelcaseOptionName(name);
|
|
398
|
-
}).sort((a, b) => a.length > b.length ? 1 : -1);
|
|
399
|
-
this.name = this.names[this.names.length - 1];
|
|
400
|
-
if (this.negated && this.config.default == null) {
|
|
401
|
-
this.config.default = true;
|
|
402
|
-
}
|
|
403
|
-
if (rawName.includes("<")) {
|
|
404
|
-
this.required = true;
|
|
405
|
-
} else if (rawName.includes("[")) {
|
|
406
|
-
this.required = false;
|
|
407
|
-
} else {
|
|
408
|
-
this.isBoolean = true;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
var processArgs = process3.argv;
|
|
413
|
-
var platformInfo = `${process3.platform}-${process3.arch} bun-v${typeof Bun !== "undefined" ? Bun.version : "unknown"}`;
|
|
414
|
-
var processArgs2 = process4.argv;
|
|
415
|
-
var platformInfo2 = `${process4.platform}-${process4.arch} node-${process4.version}`;
|
|
416
|
-
|
|
417
|
-
class Command {
|
|
418
|
-
rawName;
|
|
419
|
-
description;
|
|
420
|
-
config;
|
|
421
|
-
cli;
|
|
422
|
-
options;
|
|
423
|
-
aliasNames;
|
|
424
|
-
name;
|
|
425
|
-
args;
|
|
426
|
-
commandAction;
|
|
427
|
-
usageText;
|
|
428
|
-
versionNumber;
|
|
429
|
-
examples;
|
|
430
|
-
helpCallback;
|
|
431
|
-
globalCommand;
|
|
432
|
-
constructor(rawName, description, config, cli) {
|
|
433
|
-
this.rawName = rawName;
|
|
434
|
-
this.description = description;
|
|
435
|
-
this.config = config;
|
|
436
|
-
this.cli = cli;
|
|
437
|
-
this.options = [];
|
|
438
|
-
this.aliasNames = [];
|
|
439
|
-
this.name = removeBrackets(rawName);
|
|
440
|
-
this.args = findAllBrackets(rawName);
|
|
441
|
-
this.examples = [];
|
|
442
|
-
if (!config) {
|
|
443
|
-
this.config = {};
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
usage(text) {
|
|
447
|
-
this.usageText = text;
|
|
448
|
-
return this;
|
|
449
|
-
}
|
|
450
|
-
allowUnknownOptions() {
|
|
451
|
-
this.config.allowUnknownOptions = true;
|
|
452
|
-
return this;
|
|
453
|
-
}
|
|
454
|
-
ignoreOptionDefaultValue() {
|
|
455
|
-
this.config.ignoreOptionDefaultValue = true;
|
|
456
|
-
return this;
|
|
457
|
-
}
|
|
458
|
-
version(version, customFlags = "-v, --version") {
|
|
459
|
-
this.versionNumber = version;
|
|
460
|
-
this.option(customFlags, "Display version number");
|
|
461
|
-
return this;
|
|
462
|
-
}
|
|
463
|
-
example(example) {
|
|
464
|
-
this.examples.push(example);
|
|
465
|
-
return this;
|
|
466
|
-
}
|
|
467
|
-
option(rawName, description, config) {
|
|
468
|
-
const option = new Option(rawName, description, config);
|
|
469
|
-
this.options.push(option);
|
|
470
|
-
return this;
|
|
471
|
-
}
|
|
472
|
-
alias(name) {
|
|
473
|
-
this.aliasNames.push(name);
|
|
474
|
-
return this;
|
|
475
|
-
}
|
|
476
|
-
action(callback) {
|
|
477
|
-
this.commandAction = callback;
|
|
478
|
-
return this;
|
|
479
|
-
}
|
|
480
|
-
isMatched(name) {
|
|
481
|
-
return this.name === name || this.aliasNames.includes(name);
|
|
482
|
-
}
|
|
483
|
-
get isDefaultCommand() {
|
|
484
|
-
return this.name === "" || this.aliasNames.includes("!");
|
|
485
|
-
}
|
|
486
|
-
get isGlobalCommand() {
|
|
487
|
-
return this instanceof GlobalCommand;
|
|
488
|
-
}
|
|
489
|
-
hasOption(name) {
|
|
490
|
-
name = name.split(".")[0];
|
|
491
|
-
return !!this.options.find((option) => {
|
|
492
|
-
return option.names.includes(name);
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
outputHelp() {
|
|
496
|
-
const { name, commands } = this.cli;
|
|
497
|
-
const {
|
|
498
|
-
versionNumber,
|
|
499
|
-
options: globalOptions,
|
|
500
|
-
helpCallback
|
|
501
|
-
} = this.cli.globalCommand;
|
|
502
|
-
let sections = [
|
|
503
|
-
{
|
|
504
|
-
body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
|
|
505
|
-
}
|
|
506
|
-
];
|
|
507
|
-
sections.push({
|
|
508
|
-
title: "Usage",
|
|
509
|
-
body: ` $ ${name} ${this.usageText || this.rawName}`
|
|
510
|
-
});
|
|
511
|
-
const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
|
|
512
|
-
if (showCommands) {
|
|
513
|
-
const longestCommandName = findLongest(commands.map((command) => command.rawName));
|
|
514
|
-
sections.push({
|
|
515
|
-
title: "Commands",
|
|
516
|
-
body: commands.map((command) => {
|
|
517
|
-
return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
|
|
518
|
-
}).join(`
|
|
519
|
-
`)
|
|
520
|
-
});
|
|
521
|
-
sections.push({
|
|
522
|
-
title: `For more info, run any command with the \`--help\` flag`,
|
|
523
|
-
body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join(`
|
|
524
|
-
`)
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
|
|
528
|
-
if (!this.isGlobalCommand && !this.isDefaultCommand) {
|
|
529
|
-
options = options.filter((option) => option.name !== "version");
|
|
530
|
-
}
|
|
531
|
-
if (options.length > 0) {
|
|
532
|
-
const longestOptionName = findLongest(options.map((option) => option.rawName));
|
|
533
|
-
sections.push({
|
|
534
|
-
title: "Options",
|
|
535
|
-
body: options.map((option) => {
|
|
536
|
-
return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined ? "" : `(default: ${option.config.default})`}`;
|
|
537
|
-
}).join(`
|
|
538
|
-
`)
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
if (this.examples.length > 0) {
|
|
542
|
-
sections.push({
|
|
543
|
-
title: "Examples",
|
|
544
|
-
body: this.examples.map((example) => {
|
|
545
|
-
if (typeof example === "function") {
|
|
546
|
-
return example(name);
|
|
547
|
-
}
|
|
548
|
-
return example;
|
|
549
|
-
}).join(`
|
|
550
|
-
`)
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
if (helpCallback) {
|
|
554
|
-
sections = helpCallback(sections) || sections;
|
|
555
|
-
}
|
|
556
|
-
console.log(sections.map((section) => {
|
|
557
|
-
return section.title ? `${section.title}:
|
|
558
|
-
${section.body}` : section.body;
|
|
559
|
-
}).join(`
|
|
560
|
-
|
|
561
|
-
`));
|
|
562
|
-
}
|
|
563
|
-
outputVersion() {
|
|
564
|
-
const { name } = this.cli;
|
|
565
|
-
const { versionNumber } = this.cli.globalCommand;
|
|
566
|
-
if (versionNumber) {
|
|
567
|
-
let platformInfo3;
|
|
568
|
-
if (Bun) {
|
|
569
|
-
platformInfo3 = platformInfo;
|
|
570
|
-
} else {
|
|
571
|
-
platformInfo3 = platformInfo2;
|
|
572
|
-
}
|
|
573
|
-
console.log(`${name}/${versionNumber} ${platformInfo3}`);
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
checkRequiredArgs() {
|
|
577
|
-
const minimalArgsCount = this.args.filter((arg) => arg.required).length;
|
|
578
|
-
if (this.cli.args.length < minimalArgsCount) {
|
|
579
|
-
throw new ClappError(`missing required args for command \`${this.rawName}\``);
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
checkUnknownOptions() {
|
|
583
|
-
const { options, globalCommand } = this.cli;
|
|
584
|
-
if (!this.config.allowUnknownOptions) {
|
|
585
|
-
for (const name of Object.keys(options)) {
|
|
586
|
-
if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
|
|
587
|
-
throw new ClappError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
checkOptionValue() {
|
|
593
|
-
const { options: parsedOptions, globalCommand } = this.cli;
|
|
594
|
-
const options = [...globalCommand.options, ...this.options];
|
|
595
|
-
for (const option of options) {
|
|
596
|
-
const value = parsedOptions[option.name.split(".")[0]];
|
|
597
|
-
if (option.required) {
|
|
598
|
-
const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));
|
|
599
|
-
if (value === true || value === false && !hasNegated) {
|
|
600
|
-
throw new ClappError(`option \`${option.rawName}\` value is missing`);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
class GlobalCommand extends Command {
|
|
608
|
-
constructor(cli) {
|
|
609
|
-
super("@@global@@", "", {}, cli);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
var Command_default = Command;
|
|
613
|
-
|
|
614
|
-
class CLI extends EventEmitter {
|
|
615
|
-
name;
|
|
616
|
-
commands;
|
|
617
|
-
globalCommand;
|
|
618
|
-
matchedCommand;
|
|
619
|
-
matchedCommandName;
|
|
620
|
-
rawArgs;
|
|
621
|
-
args;
|
|
622
|
-
options;
|
|
623
|
-
showHelpOnExit;
|
|
624
|
-
showVersionOnExit;
|
|
625
|
-
constructor(name = "") {
|
|
626
|
-
super();
|
|
627
|
-
this.name = name;
|
|
628
|
-
this.commands = [];
|
|
629
|
-
this.rawArgs = [];
|
|
630
|
-
this.args = [];
|
|
631
|
-
this.options = {};
|
|
632
|
-
this.globalCommand = new GlobalCommand(this);
|
|
633
|
-
this.globalCommand.usage("<command> [options]");
|
|
634
|
-
}
|
|
635
|
-
usage(text) {
|
|
636
|
-
this.globalCommand.usage(text);
|
|
637
|
-
return this;
|
|
638
|
-
}
|
|
639
|
-
command(rawName, description, config) {
|
|
640
|
-
if (!config) {
|
|
641
|
-
config = {};
|
|
642
|
-
}
|
|
643
|
-
const command = new Command_default(rawName, description || "", config, this);
|
|
644
|
-
command.globalCommand = this.globalCommand;
|
|
645
|
-
this.commands.push(command);
|
|
646
|
-
return command;
|
|
647
|
-
}
|
|
648
|
-
option(rawName, description, config) {
|
|
649
|
-
this.globalCommand.option(rawName, description, config);
|
|
650
|
-
return this;
|
|
651
|
-
}
|
|
652
|
-
help(callback) {
|
|
653
|
-
this.globalCommand.option("-h, --help", "Display this message");
|
|
654
|
-
this.globalCommand.helpCallback = callback;
|
|
655
|
-
this.showHelpOnExit = true;
|
|
656
|
-
return this;
|
|
657
|
-
}
|
|
658
|
-
version(version, customFlags = "-v, --version") {
|
|
659
|
-
this.globalCommand.version(version, customFlags);
|
|
660
|
-
this.showVersionOnExit = true;
|
|
661
|
-
return this;
|
|
662
|
-
}
|
|
663
|
-
example(example) {
|
|
664
|
-
this.globalCommand.example(example);
|
|
665
|
-
return this;
|
|
666
|
-
}
|
|
667
|
-
outputHelp() {
|
|
668
|
-
if (this.matchedCommand) {
|
|
669
|
-
this.matchedCommand.outputHelp();
|
|
670
|
-
} else {
|
|
671
|
-
this.globalCommand.outputHelp();
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
outputVersion() {
|
|
675
|
-
this.globalCommand.outputVersion();
|
|
676
|
-
}
|
|
677
|
-
setParsedInfo({ args, options }, matchedCommand, matchedCommandName) {
|
|
678
|
-
this.args = args;
|
|
679
|
-
this.options = options;
|
|
680
|
-
if (matchedCommand) {
|
|
681
|
-
this.matchedCommand = matchedCommand;
|
|
682
|
-
}
|
|
683
|
-
if (matchedCommandName) {
|
|
684
|
-
this.matchedCommandName = matchedCommandName;
|
|
685
|
-
}
|
|
686
|
-
return this;
|
|
687
|
-
}
|
|
688
|
-
unsetMatchedCommand() {
|
|
689
|
-
this.matchedCommand = undefined;
|
|
690
|
-
this.matchedCommandName = undefined;
|
|
691
|
-
}
|
|
692
|
-
parse(argv = processArgs2, {
|
|
693
|
-
run = true
|
|
694
|
-
} = {}) {
|
|
695
|
-
this.rawArgs = argv;
|
|
696
|
-
if (!this.name) {
|
|
697
|
-
this.name = argv[1] ? getFileName(argv[1]) : "cli";
|
|
698
|
-
}
|
|
699
|
-
let shouldParse = true;
|
|
700
|
-
for (const command of this.commands) {
|
|
701
|
-
const parsed = this.mri(argv.slice(2), command);
|
|
702
|
-
const commandName = parsed.args[0];
|
|
703
|
-
if (command.isMatched(commandName)) {
|
|
704
|
-
shouldParse = false;
|
|
705
|
-
const parsedInfo = {
|
|
706
|
-
...parsed,
|
|
707
|
-
args: parsed.args.slice(1)
|
|
708
|
-
};
|
|
709
|
-
this.setParsedInfo(parsedInfo, command, commandName);
|
|
710
|
-
this.emit(`command:${commandName}`, command);
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
if (shouldParse) {
|
|
714
|
-
for (const command of this.commands) {
|
|
715
|
-
if (command.name === "") {
|
|
716
|
-
shouldParse = false;
|
|
717
|
-
const parsed = this.mri(argv.slice(2), command);
|
|
718
|
-
this.setParsedInfo(parsed, command);
|
|
719
|
-
this.emit(`command:!`, command);
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
if (shouldParse) {
|
|
724
|
-
const parsed = this.mri(argv.slice(2));
|
|
725
|
-
this.setParsedInfo(parsed);
|
|
726
|
-
}
|
|
727
|
-
if (this.options.help && this.showHelpOnExit) {
|
|
728
|
-
this.outputHelp();
|
|
729
|
-
run = false;
|
|
730
|
-
this.unsetMatchedCommand();
|
|
731
|
-
}
|
|
732
|
-
if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {
|
|
733
|
-
this.outputVersion();
|
|
734
|
-
run = false;
|
|
735
|
-
this.unsetMatchedCommand();
|
|
736
|
-
}
|
|
737
|
-
const parsedArgv = { args: this.args, options: this.options };
|
|
738
|
-
if (run) {
|
|
739
|
-
this.runMatchedCommand();
|
|
740
|
-
}
|
|
741
|
-
if (!this.matchedCommand && this.args[0]) {
|
|
742
|
-
this.emit("command:*");
|
|
743
|
-
}
|
|
744
|
-
return parsedArgv;
|
|
745
|
-
}
|
|
746
|
-
mri(argv, command) {
|
|
747
|
-
const cliOptions = [
|
|
748
|
-
...this.globalCommand.options,
|
|
749
|
-
...command ? command.options : []
|
|
750
|
-
];
|
|
751
|
-
const mriOptions = getMriOptions(cliOptions);
|
|
752
|
-
let argsAfterDoubleDashes = [];
|
|
753
|
-
const doubleDashesIndex = argv.indexOf("--");
|
|
754
|
-
if (doubleDashesIndex > -1) {
|
|
755
|
-
argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
|
|
756
|
-
argv = argv.slice(0, doubleDashesIndex);
|
|
757
|
-
}
|
|
758
|
-
let parsed = import_mri.default(argv, mriOptions);
|
|
759
|
-
parsed = Object.keys(parsed).reduce((res, name) => {
|
|
760
|
-
return {
|
|
761
|
-
...res,
|
|
762
|
-
[camelcaseOptionName(name)]: parsed[name]
|
|
763
|
-
};
|
|
764
|
-
}, { _: [] });
|
|
765
|
-
const args = parsed._;
|
|
766
|
-
const options = {
|
|
767
|
-
"--": argsAfterDoubleDashes
|
|
768
|
-
};
|
|
769
|
-
const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
|
|
770
|
-
const transforms = Object.create(null);
|
|
771
|
-
for (const cliOption of cliOptions) {
|
|
772
|
-
if (!ignoreDefault && cliOption.config.default !== undefined) {
|
|
773
|
-
for (const name of cliOption.names) {
|
|
774
|
-
options[name] = cliOption.config.default;
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
if (Array.isArray(cliOption.config.type)) {
|
|
778
|
-
if (transforms[cliOption.name] === undefined) {
|
|
779
|
-
transforms[cliOption.name] = Object.create(null);
|
|
780
|
-
transforms[cliOption.name].shouldTransform = true;
|
|
781
|
-
transforms[cliOption.name].transformFunction = cliOption.config.type[0];
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
for (const key of Object.keys(parsed)) {
|
|
786
|
-
if (key !== "_") {
|
|
787
|
-
const keys = key.split(".");
|
|
788
|
-
setDotProp(options, keys, parsed[key]);
|
|
789
|
-
setByType(options, transforms);
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
return {
|
|
793
|
-
args,
|
|
794
|
-
options
|
|
795
|
-
};
|
|
796
|
-
}
|
|
797
|
-
runMatchedCommand() {
|
|
798
|
-
const { args, options, matchedCommand: command } = this;
|
|
799
|
-
if (!command || !command.commandAction)
|
|
800
|
-
return;
|
|
801
|
-
command.checkUnknownOptions();
|
|
802
|
-
command.checkOptionValue();
|
|
803
|
-
command.checkRequiredArgs();
|
|
804
|
-
const actionArgs = [];
|
|
805
|
-
command.args.forEach((arg, index) => {
|
|
806
|
-
if (arg.variadic) {
|
|
807
|
-
actionArgs.push(args.slice(index));
|
|
808
|
-
} else {
|
|
809
|
-
actionArgs.push(args[index]);
|
|
810
|
-
}
|
|
811
|
-
});
|
|
812
|
-
actionArgs.push(options);
|
|
813
|
-
return command.commandAction.apply(this, actionArgs);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
817
|
-
var actions = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
818
|
-
var settings = {
|
|
819
|
-
actions: new Set(actions),
|
|
820
|
-
aliases: new Map([
|
|
821
|
-
["k", "up"],
|
|
822
|
-
["j", "down"],
|
|
823
|
-
["h", "left"],
|
|
824
|
-
["l", "right"],
|
|
825
|
-
["\x03", "cancel"],
|
|
826
|
-
["escape", "cancel"]
|
|
827
|
-
]),
|
|
828
|
-
messages: {
|
|
829
|
-
cancel: "Canceled",
|
|
830
|
-
error: "Something went wrong"
|
|
831
|
-
}
|
|
832
|
-
};
|
|
833
|
-
function isActionKey(key, action) {
|
|
834
|
-
if (typeof key === "string") {
|
|
835
|
-
return settings.aliases.get(key) === action;
|
|
836
|
-
}
|
|
837
|
-
for (const value of key) {
|
|
838
|
-
if (value === undefined)
|
|
839
|
-
continue;
|
|
840
|
-
if (isActionKey(value, action)) {
|
|
841
|
-
return true;
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
return false;
|
|
845
|
-
}
|
|
846
|
-
function diffLines(a, b) {
|
|
847
|
-
if (a === b)
|
|
848
|
-
return [];
|
|
849
|
-
const aLines = a.split(`
|
|
850
|
-
`);
|
|
851
|
-
const bLines = b.split(`
|
|
852
|
-
`);
|
|
853
|
-
const diff = [];
|
|
854
|
-
for (let i = 0;i < Math.max(aLines.length, bLines.length); i++) {
|
|
855
|
-
if (aLines[i] !== bLines[i])
|
|
856
|
-
diff.push(i);
|
|
857
|
-
}
|
|
858
|
-
return diff;
|
|
859
|
-
}
|
|
860
|
-
var isWindows = process5.platform.startsWith("win");
|
|
861
|
-
var CANCEL_SYMBOL = Symbol("clapp:cancel");
|
|
862
|
-
function setRawMode(input, value) {
|
|
863
|
-
const i = input;
|
|
864
|
-
if (i.isTTY)
|
|
865
|
-
i.setRawMode(value);
|
|
866
|
-
}
|
|
867
|
-
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
868
|
-
function ansiRegex({ onlyFirst = false } = {}) {
|
|
869
|
-
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
|
|
870
|
-
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
|
|
871
|
-
const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
|
|
872
|
-
const pattern = `${osc}|${csi}`;
|
|
873
|
-
return new RegExp(pattern, onlyFirst ? undefined : "g");
|
|
874
|
-
}
|
|
875
|
-
var regex = ansiRegex();
|
|
876
|
-
function stripAnsi(string2) {
|
|
877
|
-
if (typeof string2 !== "string") {
|
|
878
|
-
throw new TypeError(`Expected a \`string\`, got \`${typeof string2}\``);
|
|
879
|
-
}
|
|
880
|
-
return string2.replace(regex, "");
|
|
881
|
-
}
|
|
882
|
-
function isAmbiguous(x) {
|
|
883
|
-
return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
|
|
884
|
-
}
|
|
885
|
-
function isFullWidth(x) {
|
|
886
|
-
return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
|
|
887
|
-
}
|
|
888
|
-
function isWide(x) {
|
|
889
|
-
return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x === 94192 || x === 94193 || x >= 94208 && x <= 100343 || x >= 100352 && x <= 101589 || x >= 101631 && x <= 101640 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128727 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129673 || x >= 129679 && x <= 129734 || x >= 129742 && x <= 129756 || x >= 129759 && x <= 129769 || x >= 129776 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
890
|
-
}
|
|
891
|
-
function validate(codePoint) {
|
|
892
|
-
if (!Number.isSafeInteger(codePoint)) {
|
|
893
|
-
throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
|
|
897
|
-
validate(codePoint);
|
|
898
|
-
if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
|
|
899
|
-
return 2;
|
|
900
|
-
}
|
|
901
|
-
return 1;
|
|
902
|
-
}
|
|
903
|
-
var import_emoji_regex = __toESM(require_emoji_regex(), 1);
|
|
904
|
-
var segmenter = new Intl.Segmenter;
|
|
905
|
-
var defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
|
|
906
|
-
function stringWidth(string2, options = {}) {
|
|
907
|
-
if (typeof string2 !== "string" || string2.length === 0) {
|
|
908
|
-
return 0;
|
|
909
|
-
}
|
|
910
|
-
const {
|
|
911
|
-
ambiguousIsNarrow = true,
|
|
912
|
-
countAnsiEscapeCodes = false
|
|
913
|
-
} = options;
|
|
914
|
-
if (!countAnsiEscapeCodes) {
|
|
915
|
-
string2 = stripAnsi(string2);
|
|
916
|
-
}
|
|
917
|
-
if (string2.length === 0) {
|
|
918
|
-
return 0;
|
|
919
|
-
}
|
|
920
|
-
let width = 0;
|
|
921
|
-
const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
|
|
922
|
-
for (const { segment: character } of segmenter.segment(string2)) {
|
|
923
|
-
const codePoint = character.codePointAt(0);
|
|
924
|
-
if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
|
|
925
|
-
continue;
|
|
926
|
-
}
|
|
927
|
-
if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) {
|
|
928
|
-
continue;
|
|
929
|
-
}
|
|
930
|
-
if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) {
|
|
931
|
-
continue;
|
|
932
|
-
}
|
|
933
|
-
if (codePoint >= 55296 && codePoint <= 57343) {
|
|
934
|
-
continue;
|
|
935
|
-
}
|
|
936
|
-
if (codePoint >= 65024 && codePoint <= 65039) {
|
|
937
|
-
continue;
|
|
938
|
-
}
|
|
939
|
-
if (defaultIgnorableCodePointRegex.test(character)) {
|
|
940
|
-
continue;
|
|
941
|
-
}
|
|
942
|
-
if (import_emoji_regex.default().test(character)) {
|
|
943
|
-
width += 2;
|
|
944
|
-
continue;
|
|
945
|
-
}
|
|
946
|
-
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
|
|
947
|
-
}
|
|
948
|
-
return width;
|
|
949
|
-
}
|
|
950
|
-
var ANSI_BACKGROUND_OFFSET = 10;
|
|
951
|
-
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
952
|
-
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
953
|
-
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
954
|
-
var styles = {
|
|
955
|
-
modifier: {
|
|
956
|
-
reset: [0, 0],
|
|
957
|
-
bold: [1, 22],
|
|
958
|
-
dim: [2, 22],
|
|
959
|
-
italic: [3, 23],
|
|
960
|
-
underline: [4, 24],
|
|
961
|
-
overline: [53, 55],
|
|
962
|
-
inverse: [7, 27],
|
|
963
|
-
hidden: [8, 28],
|
|
964
|
-
strikethrough: [9, 29]
|
|
965
|
-
},
|
|
966
|
-
color: {
|
|
967
|
-
black: [30, 39],
|
|
968
|
-
red: [31, 39],
|
|
969
|
-
green: [32, 39],
|
|
970
|
-
yellow: [33, 39],
|
|
971
|
-
blue: [34, 39],
|
|
972
|
-
magenta: [35, 39],
|
|
973
|
-
cyan: [36, 39],
|
|
974
|
-
white: [37, 39],
|
|
975
|
-
blackBright: [90, 39],
|
|
976
|
-
gray: [90, 39],
|
|
977
|
-
grey: [90, 39],
|
|
978
|
-
redBright: [91, 39],
|
|
979
|
-
greenBright: [92, 39],
|
|
980
|
-
yellowBright: [93, 39],
|
|
981
|
-
blueBright: [94, 39],
|
|
982
|
-
magentaBright: [95, 39],
|
|
983
|
-
cyanBright: [96, 39],
|
|
984
|
-
whiteBright: [97, 39]
|
|
985
|
-
},
|
|
986
|
-
bgColor: {
|
|
987
|
-
bgBlack: [40, 49],
|
|
988
|
-
bgRed: [41, 49],
|
|
989
|
-
bgGreen: [42, 49],
|
|
990
|
-
bgYellow: [43, 49],
|
|
991
|
-
bgBlue: [44, 49],
|
|
992
|
-
bgMagenta: [45, 49],
|
|
993
|
-
bgCyan: [46, 49],
|
|
994
|
-
bgWhite: [47, 49],
|
|
995
|
-
bgBlackBright: [100, 49],
|
|
996
|
-
bgGray: [100, 49],
|
|
997
|
-
bgGrey: [100, 49],
|
|
998
|
-
bgRedBright: [101, 49],
|
|
999
|
-
bgGreenBright: [102, 49],
|
|
1000
|
-
bgYellowBright: [103, 49],
|
|
1001
|
-
bgBlueBright: [104, 49],
|
|
1002
|
-
bgMagentaBright: [105, 49],
|
|
1003
|
-
bgCyanBright: [106, 49],
|
|
1004
|
-
bgWhiteBright: [107, 49]
|
|
1005
|
-
}
|
|
1006
|
-
};
|
|
1007
|
-
var modifierNames = Object.keys(styles.modifier);
|
|
1008
|
-
var foregroundColorNames = Object.keys(styles.color);
|
|
1009
|
-
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
1010
|
-
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
1011
|
-
function assembleStyles() {
|
|
1012
|
-
const codes = new Map;
|
|
1013
|
-
for (const [groupName, group] of Object.entries(styles)) {
|
|
1014
|
-
for (const [styleName, style] of Object.entries(group)) {
|
|
1015
|
-
styles[styleName] = {
|
|
1016
|
-
open: `\x1B[${style[0]}m`,
|
|
1017
|
-
close: `\x1B[${style[1]}m`
|
|
1018
|
-
};
|
|
1019
|
-
group[styleName] = styles[styleName];
|
|
1020
|
-
codes.set(style[0], style[1]);
|
|
1021
|
-
}
|
|
1022
|
-
Object.defineProperty(styles, groupName, {
|
|
1023
|
-
value: group,
|
|
1024
|
-
enumerable: false
|
|
1025
|
-
});
|
|
1026
|
-
}
|
|
1027
|
-
Object.defineProperty(styles, "codes", {
|
|
1028
|
-
value: codes,
|
|
1029
|
-
enumerable: false
|
|
1030
|
-
});
|
|
1031
|
-
styles.color.close = "\x1B[39m";
|
|
1032
|
-
styles.bgColor.close = "\x1B[49m";
|
|
1033
|
-
styles.color.ansi = wrapAnsi16();
|
|
1034
|
-
styles.color.ansi256 = wrapAnsi256();
|
|
1035
|
-
styles.color.ansi16m = wrapAnsi16m();
|
|
1036
|
-
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
1037
|
-
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
1038
|
-
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
1039
|
-
Object.defineProperties(styles, {
|
|
1040
|
-
rgbToAnsi256: {
|
|
1041
|
-
value: (red, green, blue) => {
|
|
1042
|
-
if (red === green && green === blue) {
|
|
1043
|
-
if (red < 8) {
|
|
1044
|
-
return 16;
|
|
1045
|
-
}
|
|
1046
|
-
if (red > 248) {
|
|
1047
|
-
return 231;
|
|
1048
|
-
}
|
|
1049
|
-
return Math.round((red - 8) / 247 * 24) + 232;
|
|
1050
|
-
}
|
|
1051
|
-
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
1052
|
-
},
|
|
1053
|
-
enumerable: false
|
|
1054
|
-
},
|
|
1055
|
-
hexToRgb: {
|
|
1056
|
-
value: (hex) => {
|
|
1057
|
-
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
1058
|
-
if (!matches) {
|
|
1059
|
-
return [0, 0, 0];
|
|
1060
|
-
}
|
|
1061
|
-
let [colorString] = matches;
|
|
1062
|
-
if (colorString.length === 3) {
|
|
1063
|
-
colorString = [...colorString].map((character) => character + character).join("");
|
|
1064
|
-
}
|
|
1065
|
-
const integer = Number.parseInt(colorString, 16);
|
|
1066
|
-
return [
|
|
1067
|
-
integer >> 16 & 255,
|
|
1068
|
-
integer >> 8 & 255,
|
|
1069
|
-
integer & 255
|
|
1070
|
-
];
|
|
1071
|
-
},
|
|
1072
|
-
enumerable: false
|
|
1073
|
-
},
|
|
1074
|
-
hexToAnsi256: {
|
|
1075
|
-
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
1076
|
-
enumerable: false
|
|
1077
|
-
},
|
|
1078
|
-
ansi256ToAnsi: {
|
|
1079
|
-
value: (code) => {
|
|
1080
|
-
if (code < 8) {
|
|
1081
|
-
return 30 + code;
|
|
1082
|
-
}
|
|
1083
|
-
if (code < 16) {
|
|
1084
|
-
return 90 + (code - 8);
|
|
1085
|
-
}
|
|
1086
|
-
let red;
|
|
1087
|
-
let green;
|
|
1088
|
-
let blue;
|
|
1089
|
-
if (code >= 232) {
|
|
1090
|
-
red = ((code - 232) * 10 + 8) / 255;
|
|
1091
|
-
green = red;
|
|
1092
|
-
blue = red;
|
|
1093
|
-
} else {
|
|
1094
|
-
code -= 16;
|
|
1095
|
-
const remainder = code % 36;
|
|
1096
|
-
red = Math.floor(code / 36) / 5;
|
|
1097
|
-
green = Math.floor(remainder / 6) / 5;
|
|
1098
|
-
blue = remainder % 6 / 5;
|
|
1099
|
-
}
|
|
1100
|
-
const value = Math.max(red, green, blue) * 2;
|
|
1101
|
-
if (value === 0) {
|
|
1102
|
-
return 30;
|
|
1103
|
-
}
|
|
1104
|
-
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
1105
|
-
if (value === 2) {
|
|
1106
|
-
result += 60;
|
|
1107
|
-
}
|
|
1108
|
-
return result;
|
|
1109
|
-
},
|
|
1110
|
-
enumerable: false
|
|
1111
|
-
},
|
|
1112
|
-
rgbToAnsi: {
|
|
1113
|
-
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
1114
|
-
enumerable: false
|
|
1115
|
-
},
|
|
1116
|
-
hexToAnsi: {
|
|
1117
|
-
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
1118
|
-
enumerable: false
|
|
1119
|
-
}
|
|
1120
|
-
});
|
|
1121
|
-
return styles;
|
|
1122
|
-
}
|
|
1123
|
-
var ansiStyles = assembleStyles();
|
|
1124
|
-
var ansi_styles_default = ansiStyles;
|
|
1125
|
-
var ESCAPES = new Set([
|
|
1126
|
-
"\x1B",
|
|
1127
|
-
"\x9B"
|
|
1128
|
-
]);
|
|
1129
|
-
var END_CODE = 39;
|
|
1130
|
-
var ANSI_ESCAPE_BELL = "\x07";
|
|
1131
|
-
var ANSI_CSI = "[";
|
|
1132
|
-
var ANSI_OSC = "]";
|
|
1133
|
-
var ANSI_SGR_TERMINATOR = "m";
|
|
1134
|
-
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
1135
|
-
var wrapAnsiCode = (code) => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
1136
|
-
var wrapAnsiHyperlink = (url) => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
1137
|
-
var wordLengths = (string2) => string2.split(" ").map((character) => stringWidth(character));
|
|
1138
|
-
var wrapWord = (rows, word, columns) => {
|
|
1139
|
-
const characters = [...word];
|
|
1140
|
-
let isInsideEscape = false;
|
|
1141
|
-
let isInsideLinkEscape = false;
|
|
1142
|
-
let visible = stringWidth(stripAnsi(rows.at(-1)));
|
|
1143
|
-
for (const [index, character] of characters.entries()) {
|
|
1144
|
-
const characterLength = stringWidth(character);
|
|
1145
|
-
if (visible + characterLength <= columns) {
|
|
1146
|
-
rows[rows.length - 1] += character;
|
|
1147
|
-
} else {
|
|
1148
|
-
rows.push(character);
|
|
1149
|
-
visible = 0;
|
|
1150
|
-
}
|
|
1151
|
-
if (ESCAPES.has(character)) {
|
|
1152
|
-
isInsideEscape = true;
|
|
1153
|
-
const ansiEscapeLinkCandidate = characters.slice(index + 1, index + 1 + ANSI_ESCAPE_LINK.length).join("");
|
|
1154
|
-
isInsideLinkEscape = ansiEscapeLinkCandidate === ANSI_ESCAPE_LINK;
|
|
1155
|
-
}
|
|
1156
|
-
if (isInsideEscape) {
|
|
1157
|
-
if (isInsideLinkEscape) {
|
|
1158
|
-
if (character === ANSI_ESCAPE_BELL) {
|
|
1159
|
-
isInsideEscape = false;
|
|
1160
|
-
isInsideLinkEscape = false;
|
|
1161
|
-
}
|
|
1162
|
-
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
1163
|
-
isInsideEscape = false;
|
|
1164
|
-
}
|
|
1165
|
-
continue;
|
|
1166
|
-
}
|
|
1167
|
-
visible += characterLength;
|
|
1168
|
-
if (visible === columns && index < characters.length - 1) {
|
|
1169
|
-
rows.push("");
|
|
1170
|
-
visible = 0;
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
if (!visible && rows.at(-1).length > 0 && rows.length > 1) {
|
|
1174
|
-
rows[rows.length - 2] += rows.pop();
|
|
1175
|
-
}
|
|
1176
|
-
};
|
|
1177
|
-
var stringVisibleTrimSpacesRight = (string2) => {
|
|
1178
|
-
const words = string2.split(" ");
|
|
1179
|
-
let last = words.length;
|
|
1180
|
-
while (last > 0) {
|
|
1181
|
-
if (stringWidth(words[last - 1]) > 0) {
|
|
1182
|
-
break;
|
|
1183
|
-
}
|
|
1184
|
-
last--;
|
|
1185
|
-
}
|
|
1186
|
-
if (last === words.length) {
|
|
1187
|
-
return string2;
|
|
1188
|
-
}
|
|
1189
|
-
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
1190
|
-
};
|
|
1191
|
-
var exec = (string2, columns, options = {}) => {
|
|
1192
|
-
if (options.trim !== false && string2.trim() === "") {
|
|
1193
|
-
return "";
|
|
1194
|
-
}
|
|
1195
|
-
let returnValue = "";
|
|
1196
|
-
let escapeCode;
|
|
1197
|
-
let escapeUrl;
|
|
1198
|
-
const lengths = wordLengths(string2);
|
|
1199
|
-
let rows = [""];
|
|
1200
|
-
for (const [index, word] of string2.split(" ").entries()) {
|
|
1201
|
-
if (options.trim !== false) {
|
|
1202
|
-
rows[rows.length - 1] = rows.at(-1).trimStart();
|
|
1203
|
-
}
|
|
1204
|
-
let rowLength = stringWidth(rows.at(-1));
|
|
1205
|
-
if (index !== 0) {
|
|
1206
|
-
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
1207
|
-
rows.push("");
|
|
1208
|
-
rowLength = 0;
|
|
1209
|
-
}
|
|
1210
|
-
if (rowLength > 0 || options.trim === false) {
|
|
1211
|
-
rows[rows.length - 1] += " ";
|
|
1212
|
-
rowLength++;
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
if (options.hard && lengths[index] > columns) {
|
|
1216
|
-
const remainingColumns = columns - rowLength;
|
|
1217
|
-
const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns);
|
|
1218
|
-
const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns);
|
|
1219
|
-
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
1220
|
-
rows.push("");
|
|
1221
|
-
}
|
|
1222
|
-
wrapWord(rows, word, columns);
|
|
1223
|
-
continue;
|
|
1224
|
-
}
|
|
1225
|
-
if (rowLength + lengths[index] > columns && rowLength > 0 && lengths[index] > 0) {
|
|
1226
|
-
if (options.wordWrap === false && rowLength < columns) {
|
|
1227
|
-
wrapWord(rows, word, columns);
|
|
1228
|
-
continue;
|
|
1229
|
-
}
|
|
1230
|
-
rows.push("");
|
|
1231
|
-
}
|
|
1232
|
-
if (rowLength + lengths[index] > columns && options.wordWrap === false) {
|
|
1233
|
-
wrapWord(rows, word, columns);
|
|
1234
|
-
continue;
|
|
1235
|
-
}
|
|
1236
|
-
rows[rows.length - 1] += word;
|
|
1237
|
-
}
|
|
1238
|
-
if (options.trim !== false) {
|
|
1239
|
-
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
1240
|
-
}
|
|
1241
|
-
const preString = rows.join(`
|
|
1242
|
-
`);
|
|
1243
|
-
const pre = [...preString];
|
|
1244
|
-
let preStringIndex = 0;
|
|
1245
|
-
for (const [index, character] of pre.entries()) {
|
|
1246
|
-
returnValue += character;
|
|
1247
|
-
if (ESCAPES.has(character)) {
|
|
1248
|
-
const { groups } = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(preString.slice(preStringIndex)) || { groups: {} };
|
|
1249
|
-
if (groups.code !== undefined) {
|
|
1250
|
-
const code2 = Number.parseFloat(groups.code);
|
|
1251
|
-
escapeCode = code2 === END_CODE ? undefined : code2;
|
|
1252
|
-
} else if (groups.uri !== undefined) {
|
|
1253
|
-
escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
const code = ansi_styles_default.codes.get(Number(escapeCode));
|
|
1257
|
-
if (pre[index + 1] === `
|
|
1258
|
-
`) {
|
|
1259
|
-
if (escapeUrl) {
|
|
1260
|
-
returnValue += wrapAnsiHyperlink("");
|
|
1261
|
-
}
|
|
1262
|
-
if (escapeCode && code) {
|
|
1263
|
-
returnValue += wrapAnsiCode(code);
|
|
1264
|
-
}
|
|
1265
|
-
} else if (character === `
|
|
1266
|
-
`) {
|
|
1267
|
-
if (escapeCode && code) {
|
|
1268
|
-
returnValue += wrapAnsiCode(escapeCode);
|
|
1269
|
-
}
|
|
1270
|
-
if (escapeUrl) {
|
|
1271
|
-
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
1272
|
-
}
|
|
1273
|
-
}
|
|
1274
|
-
preStringIndex += character.length;
|
|
1275
|
-
}
|
|
1276
|
-
return returnValue;
|
|
1277
|
-
};
|
|
1278
|
-
function wrapAnsi(string2, columns, options) {
|
|
1279
|
-
return String(string2).normalize().replaceAll(`\r
|
|
1280
|
-
`, `
|
|
1281
|
-
`).split(`
|
|
1282
|
-
`).map((line) => exec(line, columns, options)).join(`
|
|
1283
|
-
`);
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
class Prompt {
|
|
1287
|
-
input;
|
|
1288
|
-
output;
|
|
1289
|
-
_abortSignal;
|
|
1290
|
-
rl;
|
|
1291
|
-
opts;
|
|
1292
|
-
_render;
|
|
1293
|
-
_track = false;
|
|
1294
|
-
_prevFrame = "";
|
|
1295
|
-
_subscribers = new Map;
|
|
1296
|
-
_cursor = 0;
|
|
1297
|
-
_manualLine = "";
|
|
1298
|
-
state = "initial";
|
|
1299
|
-
error = "";
|
|
1300
|
-
value;
|
|
1301
|
-
userInput = "";
|
|
1302
|
-
constructor(options, trackValue = true) {
|
|
1303
|
-
const { input = stdin2, output = stdout2, render, signal, ...opts } = options;
|
|
1304
|
-
this.opts = opts;
|
|
1305
|
-
this.onKeypress = this.onKeypress.bind(this);
|
|
1306
|
-
this.close = this.close.bind(this);
|
|
1307
|
-
this.render = this.render.bind(this);
|
|
1308
|
-
this._render = render.bind(this);
|
|
1309
|
-
this._track = trackValue;
|
|
1310
|
-
this._abortSignal = signal;
|
|
1311
|
-
this.input = input;
|
|
1312
|
-
this.output = output;
|
|
1313
|
-
}
|
|
1314
|
-
unsubscribe() {
|
|
1315
|
-
this._subscribers.clear();
|
|
1316
|
-
}
|
|
1317
|
-
setSubscriber(event, opts) {
|
|
1318
|
-
const params = this._subscribers.get(event) ?? [];
|
|
1319
|
-
params.push(opts);
|
|
1320
|
-
this._subscribers.set(event, params);
|
|
1321
|
-
}
|
|
1322
|
-
on(event, cb) {
|
|
1323
|
-
this.setSubscriber(event, { cb });
|
|
1324
|
-
return this;
|
|
1325
|
-
}
|
|
1326
|
-
once(event, cb) {
|
|
1327
|
-
this.setSubscriber(event, { cb, once: true });
|
|
1328
|
-
return this;
|
|
1329
|
-
}
|
|
1330
|
-
emit(event, ...data) {
|
|
1331
|
-
const cbs = this._subscribers.get(event) ?? [];
|
|
1332
|
-
const cleanup = [];
|
|
1333
|
-
for (const subscriber of cbs) {
|
|
1334
|
-
subscriber.cb(...data);
|
|
1335
|
-
if (subscriber.once) {
|
|
1336
|
-
cleanup.push(() => cbs.splice(cbs.indexOf(subscriber), 1));
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
for (const cb of cleanup) {
|
|
1340
|
-
cb();
|
|
1341
|
-
}
|
|
1342
|
-
return this;
|
|
1343
|
-
}
|
|
1344
|
-
prompt() {
|
|
1345
|
-
return new Promise((resolve) => {
|
|
1346
|
-
if (this._abortSignal) {
|
|
1347
|
-
if (this._abortSignal.aborted) {
|
|
1348
|
-
this.state = "cancel";
|
|
1349
|
-
this.close();
|
|
1350
|
-
return resolve(CANCEL_SYMBOL);
|
|
1351
|
-
}
|
|
1352
|
-
this._abortSignal.addEventListener("abort", () => {
|
|
1353
|
-
this.state = "cancel";
|
|
1354
|
-
this.close();
|
|
1355
|
-
}, { once: true });
|
|
1356
|
-
}
|
|
1357
|
-
this.rl = readline2.createInterface({
|
|
1358
|
-
input: this.input,
|
|
1359
|
-
tabSize: 2,
|
|
1360
|
-
prompt: "",
|
|
1361
|
-
escapeCodeTimeout: 50,
|
|
1362
|
-
terminal: true
|
|
1363
|
-
});
|
|
1364
|
-
this.rl.prompt();
|
|
1365
|
-
if (this.opts.initialUserInput !== undefined) {
|
|
1366
|
-
this._setUserInput(this.opts.initialUserInput, true);
|
|
1367
|
-
}
|
|
1368
|
-
this.input.on("keypress", this.onKeypress);
|
|
1369
|
-
setRawMode(this.input, true);
|
|
1370
|
-
this.output.on("resize", this.render);
|
|
1371
|
-
this.render();
|
|
1372
|
-
this.once("submit", () => {
|
|
1373
|
-
this.output.write(cursor.show);
|
|
1374
|
-
this.output.off("resize", this.render);
|
|
1375
|
-
setRawMode(this.input, false);
|
|
1376
|
-
resolve(this.value);
|
|
1377
|
-
});
|
|
1378
|
-
this.once("cancel", () => {
|
|
1379
|
-
this.output.write(cursor.show);
|
|
1380
|
-
this.output.off("resize", this.render);
|
|
1381
|
-
setRawMode(this.input, false);
|
|
1382
|
-
resolve(CANCEL_SYMBOL);
|
|
1383
|
-
});
|
|
1384
|
-
});
|
|
1385
|
-
}
|
|
1386
|
-
_isActionKey(char, _key) {
|
|
1387
|
-
return char === "\t";
|
|
1388
|
-
}
|
|
1389
|
-
_setValue(value) {
|
|
1390
|
-
this.value = value;
|
|
1391
|
-
this.emit("value", this.value);
|
|
1392
|
-
}
|
|
1393
|
-
_setUserInput(value, write) {
|
|
1394
|
-
this.userInput = value ?? "";
|
|
1395
|
-
this.emit("userInput", this.userInput);
|
|
1396
|
-
if (write && this._track && this.rl) {
|
|
1397
|
-
this.rl.write(this.userInput);
|
|
1398
|
-
this._cursor = this.rl.cursor;
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
onKeypress(char, key) {
|
|
1402
|
-
if (this._track && key.name !== "return") {
|
|
1403
|
-
if (key.name && this._isActionKey(char, key)) {
|
|
1404
|
-
this.rl?.write(null, { ctrl: true, name: "h" });
|
|
1405
|
-
}
|
|
1406
|
-
this._cursor = this.rl?.cursor ?? 0;
|
|
1407
|
-
const isSpecialKey = key.name === "tab" || key.name === "escape" || key.name === "backspace" || key.name === "delete" || key.name === "enter" || key.name === "return" || key.name && ["up", "down", "left", "right"].includes(key.name);
|
|
1408
|
-
if (char && !isSpecialKey && char.length === 1 && char >= " ") {
|
|
1409
|
-
this._manualLine += char;
|
|
1410
|
-
} else if (key.name === "backspace" && this._manualLine.length > 0) {
|
|
1411
|
-
this._manualLine = this._manualLine.slice(0, -1);
|
|
1412
|
-
}
|
|
1413
|
-
const effectiveLine = this._manualLine.length >= (this.rl?.line?.length || 0) ? this._manualLine : this.rl?.line;
|
|
1414
|
-
this._setUserInput(effectiveLine);
|
|
1415
|
-
}
|
|
1416
|
-
if (this.state === "error") {
|
|
1417
|
-
this.state = "active";
|
|
1418
|
-
this.error = "";
|
|
1419
|
-
}
|
|
1420
|
-
if (key?.name) {
|
|
1421
|
-
if (!this._track && settings.aliases.has(key.name)) {
|
|
1422
|
-
this.emit("cursor", settings.aliases.get(key.name));
|
|
1423
|
-
}
|
|
1424
|
-
if (settings.actions.has(key.name)) {
|
|
1425
|
-
this.emit("cursor", key.name);
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
if (char && (char.toLowerCase() === "y" || char.toLowerCase() === "n")) {
|
|
1429
|
-
this.emit("confirm", char.toLowerCase() === "y");
|
|
1430
|
-
}
|
|
1431
|
-
this.emit("key", char?.toLowerCase(), key);
|
|
1432
|
-
if (key?.name === "return") {
|
|
1433
|
-
if (this.opts.validate) {
|
|
1434
|
-
const problem = this.opts.validate(this.value);
|
|
1435
|
-
if (problem) {
|
|
1436
|
-
this.error = problem instanceof Error ? problem.message : problem;
|
|
1437
|
-
this.state = "error";
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
if (this.state !== "error") {
|
|
1441
|
-
this.state = "submit";
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
if (isActionKey([char, key?.name, key?.sequence], "cancel")) {
|
|
1445
|
-
this.state = "cancel";
|
|
1446
|
-
}
|
|
1447
|
-
if (this.state === "submit" || this.state === "cancel") {
|
|
1448
|
-
this.emit("finalize");
|
|
1449
|
-
}
|
|
1450
|
-
this.render();
|
|
1451
|
-
if (this.state === "submit" || this.state === "cancel") {
|
|
1452
|
-
this.close();
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
close() {
|
|
1456
|
-
this.input.unpipe();
|
|
1457
|
-
this.input.removeListener("keypress", this.onKeypress);
|
|
1458
|
-
this.output.write(`
|
|
1459
|
-
`);
|
|
1460
|
-
setRawMode(this.input, false);
|
|
1461
|
-
this.rl?.close();
|
|
1462
|
-
this.rl = undefined;
|
|
1463
|
-
this.emit(`${this.state}`, this.value);
|
|
1464
|
-
if (this.state === "cancel") {
|
|
1465
|
-
setTimeout(() => {
|
|
1466
|
-
this.unsubscribe();
|
|
1467
|
-
}, 10);
|
|
1468
|
-
} else {
|
|
1469
|
-
this.unsubscribe();
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
restoreCursor() {
|
|
1473
|
-
const lines = wrapAnsi(this._prevFrame, process6.stdout.columns, { hard: true, trim: false }).split(`
|
|
1474
|
-
`).length - 1;
|
|
1475
|
-
this.output.write(cursor.move(-999, lines * -1));
|
|
1476
|
-
}
|
|
1477
|
-
render() {
|
|
1478
|
-
const frame = wrapAnsi(this._render(this) ?? "", process6.stdout.columns, {
|
|
1479
|
-
hard: true,
|
|
1480
|
-
trim: false
|
|
1481
|
-
});
|
|
1482
|
-
if (frame === this._prevFrame) {
|
|
1483
|
-
return;
|
|
1484
|
-
}
|
|
1485
|
-
if (this.state === "initial") {
|
|
1486
|
-
this.output.write(cursor.hide);
|
|
1487
|
-
} else {
|
|
1488
|
-
const diff = diffLines(this._prevFrame, frame);
|
|
1489
|
-
this.restoreCursor();
|
|
1490
|
-
if (diff && diff?.length === 1) {
|
|
1491
|
-
const diffLine = diff[0];
|
|
1492
|
-
this.output.write(cursor.move(0, diffLine));
|
|
1493
|
-
this.output.write(erase.lines(1));
|
|
1494
|
-
const lines = frame.split(`
|
|
1495
|
-
`);
|
|
1496
|
-
this.output.write(lines[diffLine]);
|
|
1497
|
-
this._prevFrame = frame;
|
|
1498
|
-
this.output.write(cursor.move(0, lines.length - diffLine - 1));
|
|
1499
|
-
return;
|
|
1500
|
-
}
|
|
1501
|
-
if (diff && diff?.length > 1) {
|
|
1502
|
-
const diffLine = diff[0];
|
|
1503
|
-
this.output.write(cursor.move(0, diffLine));
|
|
1504
|
-
this.output.write(erase.down());
|
|
1505
|
-
const lines = frame.split(`
|
|
1506
|
-
`);
|
|
1507
|
-
const newLines = lines.slice(diffLine);
|
|
1508
|
-
this.output.write(newLines.join(`
|
|
1509
|
-
`));
|
|
1510
|
-
this._prevFrame = frame;
|
|
1511
|
-
return;
|
|
1512
|
-
}
|
|
1513
|
-
this.output.write(erase.down());
|
|
1514
|
-
}
|
|
1515
|
-
this.output.write(frame);
|
|
1516
|
-
if (this.state === "initial") {
|
|
1517
|
-
this.state = "active";
|
|
1518
|
-
}
|
|
1519
|
-
this._prevFrame = frame;
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
function getCursorForValue(selected, items) {
|
|
1523
|
-
if (selected === undefined) {
|
|
1524
|
-
return 0;
|
|
1525
|
-
}
|
|
1526
|
-
const currLength = items.length;
|
|
1527
|
-
if (currLength === 0) {
|
|
1528
|
-
return 0;
|
|
1529
|
-
}
|
|
1530
|
-
const index = items.findIndex((item) => item.value === selected);
|
|
1531
|
-
return index !== -1 ? index : 0;
|
|
1532
|
-
}
|
|
1533
|
-
function defaultFilter(input, option) {
|
|
1534
|
-
const label = option.label ?? String(option.value);
|
|
1535
|
-
return label.toLowerCase().includes(input.toLowerCase());
|
|
1536
|
-
}
|
|
1537
|
-
function normalisedValue(multiple, values) {
|
|
1538
|
-
if (!values) {
|
|
1539
|
-
return;
|
|
1540
|
-
}
|
|
1541
|
-
if (multiple) {
|
|
1542
|
-
return values;
|
|
1543
|
-
}
|
|
1544
|
-
return values[0];
|
|
1545
|
-
}
|
|
1546
|
-
|
|
1547
|
-
class AutocompletePrompt extends Prompt {
|
|
1548
|
-
filteredOptions;
|
|
1549
|
-
multiple;
|
|
1550
|
-
isNavigating = false;
|
|
1551
|
-
selectedValues = [];
|
|
1552
|
-
focusedValue;
|
|
1553
|
-
#cursor = 0;
|
|
1554
|
-
#lastUserInput = "";
|
|
1555
|
-
#filterFn;
|
|
1556
|
-
#options;
|
|
1557
|
-
get cursor() {
|
|
1558
|
-
return this.#cursor;
|
|
1559
|
-
}
|
|
1560
|
-
get userInputWithCursor() {
|
|
1561
|
-
if (!this.userInput) {
|
|
1562
|
-
return import_picocolors.default.inverse(import_picocolors.default.hidden("_"));
|
|
1563
|
-
}
|
|
1564
|
-
if (this._cursor >= this.userInput.length) {
|
|
1565
|
-
return `${this.userInput}\u2588`;
|
|
1566
|
-
}
|
|
1567
|
-
const s1 = this.userInput.slice(0, this._cursor);
|
|
1568
|
-
const [s2, ...s3] = this.userInput.slice(this._cursor);
|
|
1569
|
-
return `${s1}${import_picocolors.default.inverse(s2)}${s3.join("")}`;
|
|
1570
|
-
}
|
|
1571
|
-
get options() {
|
|
1572
|
-
if (typeof this.#options === "function") {
|
|
1573
|
-
return this.#options();
|
|
1574
|
-
}
|
|
1575
|
-
return this.#options;
|
|
1576
|
-
}
|
|
1577
|
-
constructor(opts) {
|
|
1578
|
-
super(opts);
|
|
1579
|
-
this.#options = opts.options;
|
|
1580
|
-
const options = this.options;
|
|
1581
|
-
this.filteredOptions = [...options];
|
|
1582
|
-
this.multiple = opts.multiple === true;
|
|
1583
|
-
this.#filterFn = opts.filter ?? defaultFilter;
|
|
1584
|
-
let initialValues;
|
|
1585
|
-
if (opts.initialValue && Array.isArray(opts.initialValue)) {
|
|
1586
|
-
if (this.multiple) {
|
|
1587
|
-
initialValues = opts.initialValue;
|
|
1588
|
-
} else {
|
|
1589
|
-
initialValues = opts.initialValue.slice(0, 1);
|
|
1590
|
-
}
|
|
1591
|
-
} else {
|
|
1592
|
-
if (!this.multiple && this.options.length > 0) {
|
|
1593
|
-
initialValues = [this.options[0].value];
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
if (initialValues) {
|
|
1597
|
-
for (const selectedValue of initialValues) {
|
|
1598
|
-
const selectedIndex = options.findIndex((opt) => opt.value === selectedValue);
|
|
1599
|
-
if (selectedIndex !== -1) {
|
|
1600
|
-
this.toggleSelected(selectedValue);
|
|
1601
|
-
this.#cursor = selectedIndex;
|
|
1602
|
-
}
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
this.focusedValue = this.options[this.#cursor]?.value;
|
|
1606
|
-
this.on("key", (char, key) => this.#onKey(char, key));
|
|
1607
|
-
this.on("userInput", (value) => this.#onUserInputChanged(value));
|
|
1608
|
-
}
|
|
1609
|
-
_isActionKey(char, key) {
|
|
1610
|
-
return char === "\t" || this.multiple && this.isNavigating && key.name === "space" && char !== undefined && char !== "";
|
|
1611
|
-
}
|
|
1612
|
-
#onKey(_char, key) {
|
|
1613
|
-
const isUpKey = key.name === "up";
|
|
1614
|
-
const isDownKey = key.name === "down";
|
|
1615
|
-
const isReturnKey = key.name === "return";
|
|
1616
|
-
if (isUpKey || isDownKey) {
|
|
1617
|
-
this.#cursor = Math.max(0, Math.min(this.#cursor + (isUpKey ? -1 : 1), this.filteredOptions.length - 1));
|
|
1618
|
-
this.focusedValue = this.filteredOptions[this.#cursor]?.value;
|
|
1619
|
-
if (!this.multiple) {
|
|
1620
|
-
this.selectedValues = [this.focusedValue];
|
|
1621
|
-
}
|
|
1622
|
-
this.isNavigating = true;
|
|
1623
|
-
} else if (isReturnKey) {
|
|
1624
|
-
this.value = normalisedValue(this.multiple, this.selectedValues);
|
|
1625
|
-
} else {
|
|
1626
|
-
if (this.multiple) {
|
|
1627
|
-
if (this.focusedValue !== undefined && (key.name === "tab" || this.isNavigating && key.name === "space")) {
|
|
1628
|
-
this.toggleSelected(this.focusedValue);
|
|
1629
|
-
} else {
|
|
1630
|
-
this.isNavigating = false;
|
|
1631
|
-
}
|
|
1632
|
-
} else {
|
|
1633
|
-
if (this.focusedValue) {
|
|
1634
|
-
this.selectedValues = [this.focusedValue];
|
|
1635
|
-
}
|
|
1636
|
-
this.isNavigating = false;
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
deselectAll() {
|
|
1641
|
-
this.selectedValues = [];
|
|
1642
|
-
}
|
|
1643
|
-
toggleSelected(value) {
|
|
1644
|
-
if (this.filteredOptions.length === 0) {
|
|
1645
|
-
return;
|
|
1646
|
-
}
|
|
1647
|
-
if (this.multiple) {
|
|
1648
|
-
if (this.selectedValues.includes(value)) {
|
|
1649
|
-
this.selectedValues = this.selectedValues.filter((v) => v !== value);
|
|
1650
|
-
} else {
|
|
1651
|
-
this.selectedValues = [...this.selectedValues, value];
|
|
1652
|
-
}
|
|
1653
|
-
} else {
|
|
1654
|
-
this.selectedValues = [value];
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
|
-
#onUserInputChanged(value) {
|
|
1658
|
-
if (value !== this.#lastUserInput) {
|
|
1659
|
-
this.#lastUserInput = value;
|
|
1660
|
-
const options = this.options;
|
|
1661
|
-
if (value) {
|
|
1662
|
-
this.filteredOptions = options.filter((opt) => this.#filterFn(value, opt));
|
|
1663
|
-
} else {
|
|
1664
|
-
this.filteredOptions = [...options];
|
|
1665
|
-
}
|
|
1666
|
-
this.#cursor = getCursorForValue(this.focusedValue, this.filteredOptions);
|
|
1667
|
-
this.focusedValue = this.filteredOptions[this.#cursor]?.value;
|
|
1668
|
-
if (!this.multiple) {
|
|
1669
|
-
if (this.focusedValue !== undefined) {
|
|
1670
|
-
this.toggleSelected(this.focusedValue);
|
|
1671
|
-
} else {
|
|
1672
|
-
this.deselectAll();
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
|
-
class GroupMultiSelectPrompt extends Prompt {
|
|
1679
|
-
options;
|
|
1680
|
-
cursor = 0;
|
|
1681
|
-
#selectableGroups;
|
|
1682
|
-
getGroupItems(group) {
|
|
1683
|
-
return this.options.filter((o) => o.group === group);
|
|
1684
|
-
}
|
|
1685
|
-
isGroupSelected(group) {
|
|
1686
|
-
const items = this.getGroupItems(group);
|
|
1687
|
-
const value = this.value;
|
|
1688
|
-
if (value === undefined) {
|
|
1689
|
-
return false;
|
|
1690
|
-
}
|
|
1691
|
-
return items.every((i) => value.includes(i.value));
|
|
1692
|
-
}
|
|
1693
|
-
toggleValue() {
|
|
1694
|
-
const item = this.options[this.cursor];
|
|
1695
|
-
if (this.value === undefined) {
|
|
1696
|
-
this.value = [];
|
|
1697
|
-
}
|
|
1698
|
-
if (item.group === true) {
|
|
1699
|
-
const group = item.value;
|
|
1700
|
-
const groupedItems = this.getGroupItems(group);
|
|
1701
|
-
if (this.isGroupSelected(group)) {
|
|
1702
|
-
this.value = this.value.filter((v) => groupedItems.findIndex((i) => i.value === v) === -1);
|
|
1703
|
-
} else {
|
|
1704
|
-
this.value = [...this.value, ...groupedItems.map((i) => i.value)];
|
|
1705
|
-
}
|
|
1706
|
-
this.value = Array.from(new Set(this.value));
|
|
1707
|
-
} else {
|
|
1708
|
-
const selected = this.value.includes(item.value);
|
|
1709
|
-
this.value = selected ? this.value.filter((v) => v !== item.value) : [...this.value, item.value];
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
constructor(opts) {
|
|
1713
|
-
super(opts, false);
|
|
1714
|
-
const { options } = opts;
|
|
1715
|
-
this.#selectableGroups = opts.selectableGroups !== false;
|
|
1716
|
-
this.options = Object.entries(options).flatMap(([key, option]) => [
|
|
1717
|
-
{ value: key, group: true, label: key },
|
|
1718
|
-
...option.map((opt) => ({ ...opt, group: key }))
|
|
1719
|
-
]);
|
|
1720
|
-
this.value = [...opts.initialValues ?? []];
|
|
1721
|
-
this.cursor = Math.max(this.options.findIndex(({ value }) => value === opts.cursorAt), this.#selectableGroups ? 0 : 1);
|
|
1722
|
-
this.on("cursor", (key) => {
|
|
1723
|
-
switch (key) {
|
|
1724
|
-
case "left":
|
|
1725
|
-
case "up": {
|
|
1726
|
-
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
1727
|
-
const currentIsGroup = this.options[this.cursor]?.group === true;
|
|
1728
|
-
if (!this.#selectableGroups && currentIsGroup) {
|
|
1729
|
-
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
1730
|
-
}
|
|
1731
|
-
break;
|
|
1732
|
-
}
|
|
1733
|
-
case "down":
|
|
1734
|
-
case "right": {
|
|
1735
|
-
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
1736
|
-
const currentIsGroup = this.options[this.cursor]?.group === true;
|
|
1737
|
-
if (!this.#selectableGroups && currentIsGroup) {
|
|
1738
|
-
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
1739
|
-
}
|
|
1740
|
-
break;
|
|
1741
|
-
}
|
|
1742
|
-
case "space":
|
|
1743
|
-
this.toggleValue();
|
|
1744
|
-
break;
|
|
1745
|
-
}
|
|
1746
|
-
});
|
|
1747
|
-
}
|
|
1748
|
-
}
|
|
1749
|
-
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
1750
|
-
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
1751
|
-
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
1752
|
-
var codes = {
|
|
1753
|
-
red: ["\x1B[31m", "\x1B[39m"],
|
|
1754
|
-
green: ["\x1B[32m", "\x1B[39m"],
|
|
1755
|
-
blue: ["\x1B[34m", "\x1B[39m"],
|
|
1756
|
-
yellow: ["\x1B[33m", "\x1B[39m"],
|
|
1757
|
-
cyan: ["\x1B[36m", "\x1B[39m"],
|
|
1758
|
-
magenta: ["\x1B[35m", "\x1B[39m"],
|
|
1759
|
-
white: ["\x1B[37m", "\x1B[39m"],
|
|
1760
|
-
gray: ["\x1B[90m", "\x1B[39m"],
|
|
1761
|
-
bgRed: ["\x1B[41m", "\x1B[49m"],
|
|
1762
|
-
bgGreen: ["\x1B[42m", "\x1B[49m"],
|
|
1763
|
-
bgBlue: ["\x1B[44m", "\x1B[49m"],
|
|
1764
|
-
bgYellow: ["\x1B[43m", "\x1B[49m"],
|
|
1765
|
-
bgCyan: ["\x1B[46m", "\x1B[49m"],
|
|
1766
|
-
bgMagenta: ["\x1B[45m", "\x1B[49m"],
|
|
1767
|
-
bold: ["\x1B[1m", "\x1B[22m"],
|
|
1768
|
-
italic: ["\x1B[3m", "\x1B[23m"],
|
|
1769
|
-
underline: ["\x1B[4m", "\x1B[24m"],
|
|
1770
|
-
dim: ["\x1B[2m", "\x1B[22m"],
|
|
1771
|
-
inverse: ["\x1B[7m", "\x1B[27m"],
|
|
1772
|
-
hidden: ["\x1B[8m", "\x1B[28m"],
|
|
1773
|
-
strikethrough: ["\x1B[9m", "\x1B[29m"]
|
|
1774
|
-
};
|
|
1775
|
-
var theme = {
|
|
1776
|
-
primary: "blue",
|
|
1777
|
-
secondary: "cyan",
|
|
1778
|
-
success: "green",
|
|
1779
|
-
warning: "yellow",
|
|
1780
|
-
error: "red",
|
|
1781
|
-
info: "magenta",
|
|
1782
|
-
muted: "gray"
|
|
1783
|
-
};
|
|
1784
|
-
function detectColorSupport() {
|
|
1785
|
-
return true;
|
|
1786
|
-
}
|
|
1787
|
-
function createStyler() {
|
|
1788
|
-
const styler = {};
|
|
1789
|
-
styler.supportsColor = detectColorSupport();
|
|
1790
|
-
function createStyleFunction(styleName, styles2 = []) {
|
|
1791
|
-
const styleList = styleName === "" ? [] : [...styles2, styleName];
|
|
1792
|
-
const fn = function(text) {
|
|
1793
|
-
if (!styler.supportsColor)
|
|
1794
|
-
return text;
|
|
1795
|
-
let openCodes = "";
|
|
1796
|
-
let closeCodes = "";
|
|
1797
|
-
for (const style of styleList) {
|
|
1798
|
-
if (style in theme && theme[style] in codes) {
|
|
1799
|
-
const themeStyle = theme[style];
|
|
1800
|
-
openCodes += codes[themeStyle][0];
|
|
1801
|
-
closeCodes = codes[themeStyle][1] + closeCodes;
|
|
1802
|
-
} else if (style in codes) {
|
|
1803
|
-
openCodes += codes[style][0];
|
|
1804
|
-
closeCodes = codes[style][1] + closeCodes;
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
return openCodes + text + closeCodes;
|
|
1808
|
-
};
|
|
1809
|
-
const allStyles2 = [...Object.keys(codes), ...Object.keys(theme)];
|
|
1810
|
-
for (const style of allStyles2) {
|
|
1811
|
-
if (!(style in fn)) {
|
|
1812
|
-
Object.defineProperty(fn, style, {
|
|
1813
|
-
get() {
|
|
1814
|
-
return createStyleFunction(style, styleList);
|
|
1815
|
-
}
|
|
1816
|
-
});
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
return fn;
|
|
1820
|
-
}
|
|
1821
|
-
const allStyles = [...Object.keys(codes), ...Object.keys(theme)];
|
|
1822
|
-
for (const style of allStyles) {
|
|
1823
|
-
if (!(style in styler)) {
|
|
1824
|
-
Object.defineProperty(styler, style, {
|
|
1825
|
-
get() {
|
|
1826
|
-
return createStyleFunction(style);
|
|
1827
|
-
}
|
|
1828
|
-
});
|
|
1829
|
-
}
|
|
1830
|
-
}
|
|
1831
|
-
return styler;
|
|
1832
|
-
}
|
|
1833
|
-
var style = createStyler();
|
|
1834
|
-
var unicode = isUnicodeSupported();
|
|
1835
|
-
var unicodeOr = (c, fallback) => unicode ? c : fallback;
|
|
1836
|
-
var S_STEP_ACTIVE = unicodeOr("\u25C6", "*");
|
|
1837
|
-
var S_STEP_CANCEL = unicodeOr("\u25A0", "x");
|
|
1838
|
-
var S_STEP_ERROR = unicodeOr("\u25B2", "x");
|
|
1839
|
-
var S_STEP_SUBMIT = unicodeOr("\u25C7", "o");
|
|
1840
|
-
var S_BAR_START = unicodeOr("\u250C", "T");
|
|
1841
|
-
var S_BAR = unicodeOr("\u2502", "|");
|
|
1842
|
-
var S_BAR_END = unicodeOr("\u2514", "\u2014");
|
|
1843
|
-
var S_RADIO_ACTIVE = unicodeOr("\u25CF", ">");
|
|
1844
|
-
var S_RADIO_INACTIVE = unicodeOr("\u25CB", " ");
|
|
1845
|
-
var S_CHECKBOX_ACTIVE = unicodeOr("\u25FB", "[\u2022]");
|
|
1846
|
-
var S_CHECKBOX_SELECTED = unicodeOr("\u25FC", "[+]");
|
|
1847
|
-
var S_CHECKBOX_INACTIVE = unicodeOr("\u25FB", "[ ]");
|
|
1848
|
-
var S_PASSWORD_MASK = unicodeOr("\u25AA", "\u2022");
|
|
1849
|
-
var S_BAR_H = unicodeOr("\u2500", "-");
|
|
1850
|
-
var S_CORNER_TOP_RIGHT = unicodeOr("\u256E", "+");
|
|
1851
|
-
var S_CONNECT_LEFT = unicodeOr("\u251C", "+");
|
|
1852
|
-
var S_CORNER_BOTTOM_RIGHT = unicodeOr("\u256F", "+");
|
|
1853
|
-
var S_INFO = unicodeOr("\u25CF", "\u2022");
|
|
1854
|
-
var S_SUCCESS = unicodeOr("\u25C6", "*");
|
|
1855
|
-
var S_WARN = unicodeOr("\u25B2", "!");
|
|
1856
|
-
var S_ERROR = unicodeOr("\u25A0", "x");
|
|
1857
|
-
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
1858
|
-
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
1859
|
-
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
1860
|
-
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
1861
|
-
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
1862
|
-
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
1863
|
-
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
1864
|
-
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
1865
|
-
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
1866
|
-
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
1867
|
-
var S_PROGRESS_CHAR = {
|
|
1868
|
-
light: unicodeOr("\u2500", "-"),
|
|
1869
|
-
heavy: unicodeOr("\u2501", "="),
|
|
1870
|
-
block: unicodeOr("\u2588", "#")
|
|
1871
|
-
};
|
|
1872
|
-
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
1873
|
-
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
1874
|
-
var import_picocolors18 = __toESM(require_picocolors(), 1);
|
|
1875
|
-
function getPrefix() {
|
|
1876
|
-
return `${import_picocolors18.default.gray(S_BAR)} `;
|
|
1877
|
-
}
|
|
1878
|
-
var prefix = getPrefix();
|
|
1879
|
-
var color18 = __toESM(require_picocolors(), 1);
|
|
1880
|
-
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
1881
|
-
// package.json
|
|
1882
|
-
var version = "0.0.13";
|
|
1883
|
-
|
|
1884
|
-
// src/cli/middleware.ts
|
|
1885
|
-
import fs from "fs/promises";
|
|
1886
|
-
import path from "path";
|
|
1887
|
-
import process7 from "process";
|
|
1888
|
-
|
|
1889
|
-
// src/cli/colors.ts
|
|
1890
|
-
var colors = {
|
|
1891
|
-
reset: "\x1B[0m",
|
|
1892
|
-
bold: "\x1B[1m",
|
|
1893
|
-
dim: "\x1B[2m",
|
|
1894
|
-
red: "\x1B[31m",
|
|
1895
|
-
green: "\x1B[32m",
|
|
1896
|
-
yellow: "\x1B[33m",
|
|
1897
|
-
blue: "\x1B[34m",
|
|
1898
|
-
cyan: "\x1B[36m",
|
|
1899
|
-
white: "\x1B[37m",
|
|
1900
|
-
gray: "\x1B[90m"
|
|
1901
|
-
};
|
|
1902
|
-
var chalk = {
|
|
1903
|
-
red: (text) => `${colors.red}${text}${colors.reset}`,
|
|
1904
|
-
green: (text) => `${colors.green}${text}${colors.reset}`,
|
|
1905
|
-
yellow: (text) => `${colors.yellow}${text}${colors.reset}`,
|
|
1906
|
-
blue: (text) => `${colors.blue}${text}${colors.reset}`,
|
|
1907
|
-
cyan: (text) => `${colors.cyan}${text}${colors.reset}`,
|
|
1908
|
-
white: (text) => `${colors.white}${text}${colors.reset}`,
|
|
1909
|
-
gray: (text) => `${colors.gray}${text}${colors.reset}`,
|
|
1910
|
-
bold: (text) => `${colors.bold}${text}${colors.reset}`,
|
|
1911
|
-
dim: (text) => `${colors.dim}${text}${colors.reset}`,
|
|
1912
|
-
hex: (_color) => (text) => text
|
|
1913
|
-
};
|
|
1914
|
-
|
|
1915
|
-
// src/cli/middleware.ts
|
|
1916
|
-
async function generateMiddlewareTypes(outputPath) {
|
|
1917
|
-
const middlewareInfo = Object.entries(middleware).map(([key, instance]) => ({
|
|
1918
|
-
name: key,
|
|
1919
|
-
className: instance.constructor.name
|
|
1920
|
-
}));
|
|
1921
|
-
const typeContent = `/**
|
|
1922
|
-
* This file is auto-generated.
|
|
1923
|
-
* DO NOT EDIT THIS FILE DIRECTLY.
|
|
1924
|
-
* To update, run 'bun router middleware:types'
|
|
1925
|
-
*/
|
|
1926
|
-
import type { ${middlewareInfo.map((m) => m.className).join(", ")} } from './middleware'
|
|
1927
|
-
|
|
1928
|
-
/**
|
|
1929
|
-
* Available middleware map with middleware names as keys
|
|
1930
|
-
*/
|
|
1931
|
-
export interface MiddlewareMap {
|
|
1932
|
-
${middlewareInfo.map((m) => ` '${m.name}': ${m.className}`).join(`
|
|
1933
|
-
`)}
|
|
1934
|
-
}
|
|
1935
|
-
|
|
1936
|
-
/**
|
|
1937
|
-
* String literal type of available middleware names
|
|
1938
|
-
*/
|
|
1939
|
-
export type MiddlewareName = ${middlewareInfo.map((m) => `'${m.name}'`).join(" | ")}
|
|
1940
|
-
|
|
1941
|
-
/**
|
|
1942
|
-
* Middleware configuration type for router setup
|
|
1943
|
-
*/
|
|
1944
|
-
export type MiddlewareConfig = MiddlewareName | ${middlewareInfo.map((m) => m.className).join(" | ")}
|
|
1945
|
-
|
|
1946
|
-
/**
|
|
1947
|
-
* Function to check if a middleware name is valid
|
|
1948
|
-
*/
|
|
1949
|
-
export function isValidMiddleware(name: string): name is MiddlewareName {
|
|
1950
|
-
return [${middlewareInfo.map((m) => `'${m.name}'`).join(", ")}].includes(name)
|
|
1951
|
-
}
|
|
1952
|
-
`;
|
|
1953
|
-
await fs.writeFile(outputPath, typeContent);
|
|
1954
|
-
}
|
|
1955
|
-
async function findTsFiles(dir) {
|
|
1956
|
-
const files = [];
|
|
1957
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
1958
|
-
for (const entry of entries) {
|
|
1959
|
-
const fullPath = path.join(dir, entry.name);
|
|
1960
|
-
if (entry.isDirectory()) {
|
|
1961
|
-
files.push(...await findTsFiles(fullPath));
|
|
1962
|
-
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
1963
|
-
files.push(fullPath);
|
|
1964
|
-
}
|
|
1965
|
-
}
|
|
1966
|
-
return files;
|
|
1967
|
-
}
|
|
1968
|
-
async function scanFileForMiddleware(filePath) {
|
|
1969
|
-
const middlewareClasses = [];
|
|
1970
|
-
try {
|
|
1971
|
-
const content = await fs.readFile(filePath, "utf-8");
|
|
1972
|
-
const classRegex = /export\s+(?:default\s+)?class\s+(\w+)\s+(?:implements\s+Middleware|\{[\s\S]*?handle\s*\([\s\S]*?\))/g;
|
|
1973
|
-
let match = null;
|
|
1974
|
-
while (match = classRegex.exec(content)) {
|
|
1975
|
-
const className = match[1];
|
|
1976
|
-
if (className.includes("Middleware") || match[0].includes("implements Middleware")) {
|
|
1977
|
-
const relativePath = path.relative(process7.cwd(), filePath);
|
|
1978
|
-
const importPath = relativePath.replace(/\.ts$/, "");
|
|
1979
|
-
middlewareClasses.push({
|
|
1980
|
-
name: className,
|
|
1981
|
-
path: importPath
|
|
1982
|
-
});
|
|
1983
|
-
}
|
|
1984
|
-
}
|
|
1985
|
-
} catch (error) {
|
|
1986
|
-
console.warn(chalk.yellow(`Error scanning file ${filePath}: ${error}`));
|
|
1987
|
-
}
|
|
1988
|
-
return middlewareClasses;
|
|
1989
|
-
}
|
|
1990
|
-
async function generateMiddlewareMap(directoryPath, outputPath) {
|
|
1991
|
-
console.log(chalk.blue(`Scanning directory: ${directoryPath} for middleware classes...`));
|
|
1992
|
-
try {
|
|
1993
|
-
const tsFiles = await findTsFiles(directoryPath);
|
|
1994
|
-
const allMiddleware = [];
|
|
1995
|
-
for (const file of tsFiles) {
|
|
1996
|
-
const middlewareInFile = await scanFileForMiddleware(file);
|
|
1997
|
-
allMiddleware.push(...middlewareInFile);
|
|
1998
|
-
}
|
|
1999
|
-
if (allMiddleware.length === 0) {
|
|
2000
|
-
console.warn(chalk.yellow("No middleware classes found in the specified directory."));
|
|
2001
|
-
return;
|
|
2002
|
-
}
|
|
2003
|
-
const imports = allMiddleware.map((m) => `import { ${m.name} } from '${m.path}'`).join(`
|
|
2004
|
-
`);
|
|
2005
|
-
const interfaceMembers = allMiddleware.map((m) => ` ${m.name}: typeof ${m.name}`).join(`
|
|
2006
|
-
`);
|
|
2007
|
-
const typeNames = allMiddleware.map((m) => m.name).join(" | ");
|
|
2008
|
-
const typeContent = `/**
|
|
2009
|
-
* This file is auto-generated.
|
|
2010
|
-
* DO NOT EDIT THIS FILE DIRECTLY.
|
|
2011
|
-
* To update, run 'bun router middleware:map'
|
|
2012
|
-
*/
|
|
2013
|
-
|
|
2014
|
-
${imports}
|
|
2015
|
-
|
|
2016
|
-
/**
|
|
2017
|
-
* Map of all available middleware in the project
|
|
2018
|
-
*/
|
|
2019
|
-
export interface MiddlewareMap {
|
|
2020
|
-
${interfaceMembers}
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2023
|
-
/**
|
|
2024
|
-
* Type representing all available middleware classes in the project
|
|
2025
|
-
*/
|
|
2026
|
-
export type MiddlewareType = ${typeNames}
|
|
2027
|
-
|
|
2028
|
-
/**
|
|
2029
|
-
* Type for a middleware handler function
|
|
2030
|
-
*/
|
|
2031
|
-
export type MiddlewareHandler = (req: any, next: () => Promise<Response>) => Promise<Response>
|
|
2032
|
-
|
|
2033
|
-
/**
|
|
2034
|
-
* Ensure the middleware module exports all the middleware classes used in the project
|
|
2035
|
-
*/
|
|
2036
|
-
export const middlewareMap: MiddlewareMap = {
|
|
2037
|
-
${allMiddleware.map((m) => ` ${m.name}: ${m.name}`).join(`,
|
|
2038
|
-
`)}
|
|
2039
|
-
}
|
|
2040
|
-
`;
|
|
2041
|
-
await fs.writeFile(outputPath, typeContent);
|
|
2042
|
-
console.log(chalk.green(`\u2728 Middleware map generated at ${outputPath} with ${allMiddleware.length} middleware classes`));
|
|
2043
|
-
console.log(chalk.blue("Found middleware classes:"));
|
|
2044
|
-
for (const m of allMiddleware) {
|
|
2045
|
-
console.log(chalk.cyan(` - ${m.name} (${m.path})`));
|
|
2046
|
-
}
|
|
2047
|
-
} catch (error) {
|
|
2048
|
-
console.error(chalk.red(`Error generating middleware map: ${error}`));
|
|
2049
|
-
throw error;
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
async function watchDirectoryForMiddleware(directoryPath, outputPath) {
|
|
2053
|
-
try {
|
|
2054
|
-
await fs.access(directoryPath);
|
|
2055
|
-
} catch {
|
|
2056
|
-
console.error(chalk.red(`Directory not found at ${directoryPath}`));
|
|
2057
|
-
process7.exit(1);
|
|
2058
|
-
}
|
|
2059
|
-
await generateMiddlewareMap(directoryPath, outputPath);
|
|
2060
|
-
console.log(chalk.blue(`Watching for changes in ${directoryPath}...`));
|
|
2061
|
-
let timeoutId = null;
|
|
2062
|
-
const watcher = fs.watch(directoryPath, { recursive: true });
|
|
2063
|
-
for await (const _event of watcher) {
|
|
2064
|
-
if (timeoutId) {
|
|
2065
|
-
clearTimeout(timeoutId);
|
|
2066
|
-
}
|
|
2067
|
-
timeoutId = setTimeout(async () => {
|
|
2068
|
-
console.log(chalk.yellow(`Changes detected. Regenerating middleware map...`));
|
|
2069
|
-
try {
|
|
2070
|
-
await generateMiddlewareMap(directoryPath, outputPath);
|
|
2071
|
-
} catch (error) {
|
|
2072
|
-
console.error(chalk.red(`Error regenerating middleware map: ${error.message}`));
|
|
2073
|
-
}
|
|
2074
|
-
timeoutId = null;
|
|
2075
|
-
}, 500);
|
|
2076
|
-
}
|
|
2077
|
-
}
|
|
2078
|
-
async function watchMiddlewareDirectory(outputPath) {
|
|
2079
|
-
const middlewarePath = path.join(process7.cwd(), "src", "middleware");
|
|
2080
|
-
try {
|
|
2081
|
-
await fs.access(middlewarePath);
|
|
2082
|
-
} catch {
|
|
2083
|
-
console.error(chalk.red(`Middleware directory not found at ${middlewarePath}`));
|
|
2084
|
-
process7.exit(1);
|
|
2085
|
-
}
|
|
2086
|
-
await generateMiddlewareTypes(outputPath);
|
|
2087
|
-
console.log(chalk.green(`\u2728 Middleware types generated at ${outputPath}`));
|
|
2088
|
-
console.log(chalk.blue(`Watching for changes in ${middlewarePath}...`));
|
|
2089
|
-
let timeoutId = null;
|
|
2090
|
-
const watcher = fs.watch(middlewarePath, { recursive: true });
|
|
2091
|
-
for await (const _event of watcher) {
|
|
2092
|
-
if (timeoutId) {
|
|
2093
|
-
clearTimeout(timeoutId);
|
|
2094
|
-
}
|
|
2095
|
-
timeoutId = setTimeout(async () => {
|
|
2096
|
-
console.log(chalk.yellow(`Changes detected in middleware directory. Regenerating types...`));
|
|
2097
|
-
try {
|
|
2098
|
-
await generateMiddlewareTypes(outputPath);
|
|
2099
|
-
console.log(chalk.green(`\u2728 Middleware types regenerated at ${outputPath}`));
|
|
2100
|
-
} catch (error) {
|
|
2101
|
-
console.error(chalk.red(`Error regenerating types: ${error.message}`));
|
|
2102
|
-
}
|
|
2103
|
-
timeoutId = null;
|
|
2104
|
-
}, 500);
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
2107
|
-
|
|
2108
|
-
// src/cli/openapi.ts
|
|
2109
|
-
import fs2 from "fs/promises";
|
|
2110
|
-
import process9 from "process";
|
|
2111
|
-
async function generateOpenAPISpec(options) {
|
|
2112
|
-
try {
|
|
2113
|
-
const routesFile = `${process9.cwd()}/routes/index.ts`;
|
|
2114
|
-
const { router } = await import(routesFile);
|
|
2115
|
-
if (!router) {
|
|
2116
|
-
console.error(chalk.red(`Could not find router instance in ${routesFile}.`));
|
|
2117
|
-
process9.exit(1);
|
|
2118
|
-
}
|
|
2119
|
-
const routes = router.routes || [];
|
|
2120
|
-
if (routes.length === 0) {
|
|
2121
|
-
console.log(chalk.yellow("No routes defined. Creating empty OpenAPI specification."));
|
|
2122
|
-
}
|
|
2123
|
-
const apiRoutes = routes.filter((route) => {
|
|
2124
|
-
return route.type === "api" || route.path.startsWith("/api");
|
|
2125
|
-
});
|
|
2126
|
-
const openapi = {
|
|
2127
|
-
openapi: "3.0.3",
|
|
2128
|
-
info: {
|
|
2129
|
-
title: options.title || "API Documentation",
|
|
2130
|
-
version: options.version || "1.0.0",
|
|
2131
|
-
description: options.description || "Generated API documentation"
|
|
2132
|
-
},
|
|
2133
|
-
servers: generateServers(options),
|
|
2134
|
-
paths: {},
|
|
2135
|
-
components: {
|
|
2136
|
-
schemas: {},
|
|
2137
|
-
securitySchemes: {}
|
|
2138
|
-
},
|
|
2139
|
-
tags: []
|
|
2140
|
-
};
|
|
2141
|
-
const uniqueTags = new Set;
|
|
2142
|
-
for (const route of apiRoutes) {
|
|
2143
|
-
const pathItem = openapi.paths[route.path] || {};
|
|
2144
|
-
let tag = "";
|
|
2145
|
-
if (options.tags !== false) {
|
|
2146
|
-
tag = route.tag || extractTagFromPath(route.path);
|
|
2147
|
-
uniqueTags.add(tag);
|
|
2148
|
-
}
|
|
2149
|
-
const operation = {
|
|
2150
|
-
summary: route.summary || `${route.method.toUpperCase()} ${route.path}`,
|
|
2151
|
-
description: route.description || "",
|
|
2152
|
-
operationId: route.name || generateOperationId(route.method, route.path),
|
|
2153
|
-
parameters: generateParameters(route),
|
|
2154
|
-
responses: generateResponses(route)
|
|
2155
|
-
};
|
|
2156
|
-
if (tag) {
|
|
2157
|
-
operation.tags = [tag];
|
|
2158
|
-
}
|
|
2159
|
-
if (["post", "put", "patch"].includes(route.method.toLowerCase())) {
|
|
2160
|
-
operation.requestBody = generateRequestBody(route);
|
|
2161
|
-
}
|
|
2162
|
-
if (options.security !== false && route.middleware) {
|
|
2163
|
-
const securityItems = extractSecurityFromMiddleware(route.middleware);
|
|
2164
|
-
if (securityItems.length > 0) {
|
|
2165
|
-
operation.security = securityItems;
|
|
2166
|
-
}
|
|
2167
|
-
}
|
|
2168
|
-
pathItem[route.method.toLowerCase()] = operation;
|
|
2169
|
-
openapi.paths[route.path] = pathItem;
|
|
2170
|
-
}
|
|
2171
|
-
if (options.tags !== false) {
|
|
2172
|
-
openapi.tags = Array.from(uniqueTags).map((tag) => ({
|
|
2173
|
-
name: tag,
|
|
2174
|
-
description: `Operations related to ${tag}`
|
|
2175
|
-
}));
|
|
2176
|
-
}
|
|
2177
|
-
const outputPath = options.output || "openapi.json";
|
|
2178
|
-
await fs2.writeFile(outputPath, JSON.stringify(openapi, null, 2));
|
|
2179
|
-
console.log(chalk.green(`\u2728 OpenAPI specification generated at ${outputPath}`));
|
|
2180
|
-
console.log(chalk.blue(`Import this file into Postman, Swagger UI, or other API tools to explore your API.`));
|
|
2181
|
-
} catch (error) {
|
|
2182
|
-
if (error.code === "ERR_MODULE_NOT_FOUND") {
|
|
2183
|
-
console.error(chalk.red(`Routes file not found at ${process9.cwd()}/routes/index.ts`));
|
|
2184
|
-
console.error(chalk.yellow('Make sure your routes are defined and exported as "router" in routes/index.ts'));
|
|
2185
|
-
} else {
|
|
2186
|
-
console.error(chalk.red(`Error generating OpenAPI specification: ${error.message}`));
|
|
2187
|
-
}
|
|
2188
|
-
throw error;
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
|
-
function generateServers(options) {
|
|
2192
|
-
const servers = [];
|
|
2193
|
-
if (options.servers) {
|
|
2194
|
-
const serverUrls = options.servers.split(",").map((url) => url.trim());
|
|
2195
|
-
for (const url of serverUrls) {
|
|
2196
|
-
servers.push({
|
|
2197
|
-
url,
|
|
2198
|
-
description: `Server ${servers.length + 1}`
|
|
2199
|
-
});
|
|
2200
|
-
}
|
|
2201
|
-
}
|
|
2202
|
-
if (servers.length === 0) {
|
|
2203
|
-
servers.push({
|
|
2204
|
-
url: options.basePath || "/",
|
|
2205
|
-
description: "Default server"
|
|
2206
|
-
});
|
|
2207
|
-
}
|
|
2208
|
-
return servers;
|
|
2209
|
-
}
|
|
2210
|
-
function extractTagFromPath(path2) {
|
|
2211
|
-
const segments = path2.split("/").filter(Boolean);
|
|
2212
|
-
if (segments.length > 0) {
|
|
2213
|
-
if (segments[0].toLowerCase() === "api" && segments.length > 1) {
|
|
2214
|
-
return segments[1];
|
|
2215
|
-
}
|
|
2216
|
-
return segments[0];
|
|
2217
|
-
}
|
|
2218
|
-
return "default";
|
|
2219
|
-
}
|
|
2220
|
-
function generateOperationId(method, path2) {
|
|
2221
|
-
const pathWithoutParams = path2.replace(/\{([^}]+)\}/g, "_$1");
|
|
2222
|
-
const segments = pathWithoutParams.split("/").filter(Boolean);
|
|
2223
|
-
if (segments.length === 0) {
|
|
2224
|
-
return method.toLowerCase();
|
|
2225
|
-
}
|
|
2226
|
-
let operationId = method.toLowerCase();
|
|
2227
|
-
for (const segment of segments) {
|
|
2228
|
-
operationId += segment.charAt(0).toUpperCase() + segment.slice(1);
|
|
2229
|
-
}
|
|
2230
|
-
return operationId;
|
|
2231
|
-
}
|
|
2232
|
-
function generateParameters(route) {
|
|
2233
|
-
const parameters = [];
|
|
2234
|
-
const pathParams = route.path.match(/\{([^}]+)\}/g);
|
|
2235
|
-
if (pathParams) {
|
|
2236
|
-
for (const param of pathParams) {
|
|
2237
|
-
const paramName = param.slice(1, -1);
|
|
2238
|
-
parameters.push({
|
|
2239
|
-
name: paramName,
|
|
2240
|
-
in: "path",
|
|
2241
|
-
required: true,
|
|
2242
|
-
schema: {
|
|
2243
|
-
type: "string"
|
|
2244
|
-
},
|
|
2245
|
-
description: `Path parameter: ${paramName}`
|
|
2246
|
-
});
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
if (route.params && route.params.query) {
|
|
2250
|
-
for (const [name, schema] of Object.entries(route.params.query)) {
|
|
2251
|
-
parameters.push({
|
|
2252
|
-
name,
|
|
2253
|
-
in: "query",
|
|
2254
|
-
schema: mapSchemaType(schema),
|
|
2255
|
-
required: schema.required === true,
|
|
2256
|
-
description: schema.description || `Query parameter: ${name}`
|
|
2257
|
-
});
|
|
2258
|
-
}
|
|
2259
|
-
}
|
|
2260
|
-
return parameters;
|
|
2261
|
-
}
|
|
2262
|
-
function mapSchemaType(schema) {
|
|
2263
|
-
if (!schema || typeof schema !== "object") {
|
|
2264
|
-
return { type: "string" };
|
|
2265
|
-
}
|
|
2266
|
-
const openApiSchema = {};
|
|
2267
|
-
if (schema.type) {
|
|
2268
|
-
openApiSchema.type = schema.type;
|
|
2269
|
-
}
|
|
2270
|
-
if (schema.format) {
|
|
2271
|
-
openApiSchema.format = schema.format;
|
|
2272
|
-
}
|
|
2273
|
-
if (schema.enum) {
|
|
2274
|
-
openApiSchema.enum = schema.enum;
|
|
2275
|
-
}
|
|
2276
|
-
if (schema.default !== undefined) {
|
|
2277
|
-
openApiSchema.default = schema.default;
|
|
2278
|
-
}
|
|
2279
|
-
return openApiSchema;
|
|
2280
|
-
}
|
|
2281
|
-
function generateResponses(route) {
|
|
2282
|
-
const responses = {
|
|
2283
|
-
200: {
|
|
2284
|
-
description: "Successful response",
|
|
2285
|
-
content: {
|
|
2286
|
-
"application/json": {
|
|
2287
|
-
schema: {}
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
}
|
|
2291
|
-
};
|
|
2292
|
-
responses["400"] = {
|
|
2293
|
-
description: "Bad request",
|
|
2294
|
-
content: {
|
|
2295
|
-
"application/json": {
|
|
2296
|
-
schema: {
|
|
2297
|
-
type: "object",
|
|
2298
|
-
properties: {
|
|
2299
|
-
error: { type: "string" }
|
|
2300
|
-
}
|
|
2301
|
-
}
|
|
2302
|
-
}
|
|
2303
|
-
}
|
|
2304
|
-
};
|
|
2305
|
-
responses["401"] = {
|
|
2306
|
-
description: "Unauthorized",
|
|
2307
|
-
content: {
|
|
2308
|
-
"application/json": {
|
|
2309
|
-
schema: {
|
|
2310
|
-
type: "object",
|
|
2311
|
-
properties: {
|
|
2312
|
-
error: { type: "string" }
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
}
|
|
2316
|
-
}
|
|
2317
|
-
};
|
|
2318
|
-
responses["404"] = {
|
|
2319
|
-
description: "Not found",
|
|
2320
|
-
content: {
|
|
2321
|
-
"application/json": {
|
|
2322
|
-
schema: {
|
|
2323
|
-
type: "object",
|
|
2324
|
-
properties: {
|
|
2325
|
-
error: { type: "string" }
|
|
2326
|
-
}
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
|
-
};
|
|
2331
|
-
responses["500"] = {
|
|
2332
|
-
description: "Server error",
|
|
2333
|
-
content: {
|
|
2334
|
-
"application/json": {
|
|
2335
|
-
schema: {
|
|
2336
|
-
type: "object",
|
|
2337
|
-
properties: {
|
|
2338
|
-
error: { type: "string" }
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
}
|
|
2343
|
-
};
|
|
2344
|
-
if (route.responses) {
|
|
2345
|
-
for (const [status, response] of Object.entries(route.responses)) {
|
|
2346
|
-
responses[status] = {
|
|
2347
|
-
description: response.description || `Response with status ${status}`,
|
|
2348
|
-
content: {
|
|
2349
|
-
"application/json": {
|
|
2350
|
-
schema: response.schema || {}
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
};
|
|
2354
|
-
}
|
|
2355
|
-
}
|
|
2356
|
-
return responses;
|
|
2357
|
-
}
|
|
2358
|
-
function generateRequestBody(route) {
|
|
2359
|
-
const requestBody = {
|
|
2360
|
-
required: true,
|
|
2361
|
-
content: {
|
|
2362
|
-
"application/json": {
|
|
2363
|
-
schema: {
|
|
2364
|
-
type: "object"
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
2368
|
-
};
|
|
2369
|
-
if (route.params && route.params.body) {
|
|
2370
|
-
requestBody.content["application/json"].schema = route.params.body;
|
|
2371
|
-
}
|
|
2372
|
-
return requestBody;
|
|
2373
|
-
}
|
|
2374
|
-
function extractSecurityFromMiddleware(middleware2) {
|
|
2375
|
-
const securityItems = [];
|
|
2376
|
-
for (const mw of middleware2) {
|
|
2377
|
-
const name = typeof mw === "string" ? mw : mw.name;
|
|
2378
|
-
if (name && name.toLowerCase().includes("auth")) {
|
|
2379
|
-
if (name.toLowerCase().includes("jwt")) {
|
|
2380
|
-
securityItems.push({ BearerAuth: [] });
|
|
2381
|
-
} else if (name.toLowerCase().includes("apikey")) {
|
|
2382
|
-
securityItems.push({ ApiKeyAuth: [] });
|
|
2383
|
-
} else if (name.toLowerCase().includes("basic")) {
|
|
2384
|
-
securityItems.push({ BasicAuth: [] });
|
|
2385
|
-
} else {
|
|
2386
|
-
securityItems.push({ [name]: [] });
|
|
2387
|
-
}
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
return securityItems;
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2393
|
-
// src/cli/router.ts
|
|
2394
|
-
import fs3 from "fs/promises";
|
|
2395
|
-
import path2 from "path";
|
|
2396
|
-
import process10 from "process";
|
|
2397
|
-
async function generateRouterTypes(outputPath) {
|
|
2398
|
-
try {
|
|
2399
|
-
const routesFile = `${process10.cwd()}/routes/index.ts`;
|
|
2400
|
-
const { router } = await import(routesFile);
|
|
2401
|
-
if (!router) {
|
|
2402
|
-
console.error(chalk.red(`Could not find router instance in ${routesFile}.`));
|
|
2403
|
-
process10.exit(1);
|
|
2404
|
-
}
|
|
2405
|
-
const routerMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(router)).filter((method) => !method.startsWith("_") && method !== "constructor" && typeof router[method] === "function");
|
|
2406
|
-
const extendedProperties = Object.keys(router).filter((prop) => !["routes", "middleware", "hooks", "config"].includes(prop) && typeof prop === "string" && !prop.startsWith("_"));
|
|
2407
|
-
const typeContent = `/**
|
|
2408
|
-
* This file is auto-generated.
|
|
2409
|
-
* DO NOT EDIT THIS FILE DIRECTLY.
|
|
2410
|
-
* To update, run 'bun router router:types'
|
|
2411
|
-
*/
|
|
2412
|
-
import type { Router, RouteHandler, MiddlewareHandler, RouteDefinition } from '../src/types'
|
|
2413
|
-
|
|
2414
|
-
/**
|
|
2415
|
-
* Extended Router interface with all available methods and properties
|
|
2416
|
-
*/
|
|
2417
|
-
export interface ExtendedRouter extends Router {
|
|
2418
|
-
${routerMethods.map((method) => {
|
|
2419
|
-
if (["get", "post", "put", "delete", "patch", "options", "head"].includes(method)) {
|
|
2420
|
-
return `${method}(path: string, handler: RouteHandler, options?: any): Router`;
|
|
2421
|
-
} else if (method === "use") {
|
|
2422
|
-
return `${method}(middleware: MiddlewareHandler | MiddlewareHandler[]): Router`;
|
|
2423
|
-
} else if (method === "group") {
|
|
2424
|
-
return `${method}(prefix: string, callback: (router: Router) => void): Router`;
|
|
2425
|
-
} else {
|
|
2426
|
-
return `${method}: Function`;
|
|
2427
|
-
}
|
|
2428
|
-
}).join(`
|
|
2429
|
-
`)}
|
|
2430
|
-
|
|
2431
|
-
${extendedProperties.map((prop) => {
|
|
2432
|
-
const propType = typeof router[prop];
|
|
2433
|
-
return `${prop}: ${propType}`;
|
|
2434
|
-
}).join(`
|
|
2435
|
-
`)}
|
|
2436
|
-
}
|
|
2437
|
-
|
|
2438
|
-
/**
|
|
2439
|
-
* Type for extending the router with custom methods
|
|
2440
|
-
*/
|
|
2441
|
-
export type RouterExtension = {
|
|
2442
|
-
[key: string]: Function | any
|
|
2443
|
-
}
|
|
2444
|
-
|
|
2445
|
-
/**
|
|
2446
|
-
* Helper type for correctly typing router extensions
|
|
2447
|
-
*
|
|
2448
|
-
* Example usage:
|
|
2449
|
-
* \`\`\`typescript
|
|
2450
|
-
* import { Router, ExtendRouter } from './router-types'
|
|
2451
|
-
*
|
|
2452
|
-
* // Define extension type
|
|
2453
|
-
* interface MyCustomRouter extends ExtendRouter<{
|
|
2454
|
-
* customMethod(param: string): void
|
|
2455
|
-
* }> {}
|
|
2456
|
-
*
|
|
2457
|
-
* // Create and extend the router
|
|
2458
|
-
* const router = new Router() as MyCustomRouter
|
|
2459
|
-
* router.customMethod = (param: string) => {
|
|
2460
|
-
* console.log(param)
|
|
2461
|
-
* }
|
|
2462
|
-
* \`\`\`
|
|
2463
|
-
*/
|
|
2464
|
-
export type ExtendRouter<T extends RouterExtension> = Router & T
|
|
2465
|
-
`;
|
|
2466
|
-
await fs3.writeFile(outputPath, typeContent);
|
|
2467
|
-
console.log(chalk.green(`\u2728 Router types generated at ${outputPath}`));
|
|
2468
|
-
} catch (error) {
|
|
2469
|
-
if (error.code === "ERR_MODULE_NOT_FOUND") {
|
|
2470
|
-
console.error(chalk.red(`Routes file not found at ${process10.cwd()}/routes/index.ts`));
|
|
2471
|
-
console.error(chalk.yellow('Make sure your routes are defined and exported as "router" in routes/index.ts'));
|
|
2472
|
-
} else {
|
|
2473
|
-
console.error(chalk.red(`Error generating router types: ${error.message}`));
|
|
2474
|
-
}
|
|
2475
|
-
throw error;
|
|
2476
|
-
}
|
|
2477
|
-
}
|
|
2478
|
-
async function watchRouterFiles(outputPath) {
|
|
2479
|
-
const routerFiles = [
|
|
2480
|
-
path2.join(process10.cwd(), "routes"),
|
|
2481
|
-
path2.join(process10.cwd(), "src")
|
|
2482
|
-
];
|
|
2483
|
-
let validPath = false;
|
|
2484
|
-
for (const dirPath of routerFiles) {
|
|
2485
|
-
try {
|
|
2486
|
-
await fs3.access(dirPath);
|
|
2487
|
-
validPath = true;
|
|
2488
|
-
break;
|
|
2489
|
-
} catch {}
|
|
2490
|
-
}
|
|
2491
|
-
if (!validPath) {
|
|
2492
|
-
console.error(chalk.red(`No valid source directories found to watch.`));
|
|
2493
|
-
process10.exit(1);
|
|
2494
|
-
}
|
|
2495
|
-
await generateRouterTypes(outputPath);
|
|
2496
|
-
console.log(chalk.green(`\u2728 Router types generated at ${outputPath}`));
|
|
2497
|
-
console.log(chalk.blue(`Watching for changes in router files...`));
|
|
2498
|
-
let timeoutId = null;
|
|
2499
|
-
for (const dirPath of routerFiles) {
|
|
2500
|
-
try {
|
|
2501
|
-
const watcher = fs3.watch(dirPath, { recursive: true });
|
|
2502
|
-
(async () => {
|
|
2503
|
-
for await (const _event of watcher) {
|
|
2504
|
-
if (timeoutId) {
|
|
2505
|
-
clearTimeout(timeoutId);
|
|
2506
|
-
}
|
|
2507
|
-
timeoutId = setTimeout(async () => {
|
|
2508
|
-
console.log(chalk.yellow(`Changes detected in router files. Regenerating types...`));
|
|
2509
|
-
try {
|
|
2510
|
-
await generateRouterTypes(outputPath);
|
|
2511
|
-
console.log(chalk.green(`\u2728 Router types regenerated at ${outputPath}`));
|
|
2512
|
-
} catch (error) {
|
|
2513
|
-
console.error(chalk.red(`Error regenerating types: ${error.message}`));
|
|
2514
|
-
}
|
|
2515
|
-
timeoutId = null;
|
|
2516
|
-
}, 500);
|
|
2517
|
-
}
|
|
2518
|
-
})();
|
|
2519
|
-
} catch {}
|
|
2520
|
-
}
|
|
2521
|
-
}
|
|
2522
|
-
|
|
2523
|
-
// src/cli/routes.ts
|
|
2524
|
-
import fs4 from "fs/promises";
|
|
2525
|
-
import path3 from "path";
|
|
2526
|
-
import process11 from "process";
|
|
2527
|
-
async function displayRoutes(options) {
|
|
2528
|
-
try {
|
|
2529
|
-
const routesFile = `${process11.cwd()}/routes/index.ts`;
|
|
2530
|
-
const { router } = await import(routesFile);
|
|
2531
|
-
if (!router) {
|
|
2532
|
-
console.error(chalk.red(`Could not find router instance in ${routesFile}.`));
|
|
2533
|
-
process11.exit(1);
|
|
2534
|
-
}
|
|
2535
|
-
const routes = router.routes || [];
|
|
2536
|
-
if (routes.length === 0) {
|
|
2537
|
-
console.log(chalk.yellow("No routes defined."));
|
|
2538
|
-
return;
|
|
2539
|
-
}
|
|
2540
|
-
let filteredRoutes = routes;
|
|
2541
|
-
if (options.path) {
|
|
2542
|
-
filteredRoutes = filteredRoutes.filter((route) => route.path.startsWith(options.path));
|
|
2543
|
-
}
|
|
2544
|
-
console.log(chalk.bold(`
|
|
2545
|
-
Routes:`));
|
|
2546
|
-
console.log(chalk.dim("+-----------------+-------------------------+------------------+----------------+"));
|
|
2547
|
-
console.log(chalk.dim("| ") + chalk.bold("Method") + chalk.dim(" | ") + chalk.bold("URI") + chalk.dim(" | ") + chalk.bold("Name") + chalk.dim(" | ") + chalk.bold("Handler") + chalk.dim(" |"));
|
|
2548
|
-
console.log(chalk.dim("+-----------------+-------------------------+------------------+----------------+"));
|
|
2549
|
-
filteredRoutes.forEach((route) => {
|
|
2550
|
-
const method = padString(route.method, 15);
|
|
2551
|
-
const path4 = padString(route.path, 23);
|
|
2552
|
-
const name = padString(route.name || "", 16);
|
|
2553
|
-
let handler;
|
|
2554
|
-
if (typeof route.handler === "string") {
|
|
2555
|
-
handler = route.handler;
|
|
2556
|
-
} else if (typeof route.handler === "function") {
|
|
2557
|
-
handler = route.handler.name ? `${route.handler.name}()` : "Anonymous Function";
|
|
2558
|
-
} else {
|
|
2559
|
-
handler = "Class Handler";
|
|
2560
|
-
}
|
|
2561
|
-
handler = padString(handler, 14);
|
|
2562
|
-
console.log(chalk.dim("| ") + getMethodColor(route.method)(method) + chalk.dim(" | ") + chalk.green(path4) + chalk.dim(" | ") + chalk.yellow(name) + chalk.dim(" | ") + chalk.blue(handler) + chalk.dim(" |"));
|
|
2563
|
-
if (options.verbose && route.middleware && route.middleware.length > 0) {
|
|
2564
|
-
console.log(chalk.dim("| | ") + chalk.dim("Middleware: ") + route.middleware.map((m) => typeof m === "string" ? m : m.name || "Anonymous").join(", ") + chalk.dim(" |"));
|
|
2565
|
-
}
|
|
2566
|
-
});
|
|
2567
|
-
console.log(chalk.dim("+-----------------+-------------------------+------------------+----------------+"));
|
|
2568
|
-
console.log(`
|
|
2569
|
-
Showing ${filteredRoutes.length} routes`);
|
|
2570
|
-
} catch (error) {
|
|
2571
|
-
console.error(chalk.red(`Error: ${error.message}`));
|
|
2572
|
-
console.error(chalk.yellow(`Make sure your routes are defined in ${process11.cwd()}/routes/index.ts and export a 'router' instance.`));
|
|
2573
|
-
throw error;
|
|
2574
|
-
}
|
|
2575
|
-
}
|
|
2576
|
-
async function generateRouteTypes(outputPath) {
|
|
2577
|
-
try {
|
|
2578
|
-
const routesFile = `${process11.cwd()}/routes/index.ts`;
|
|
2579
|
-
const { router } = await import(routesFile);
|
|
2580
|
-
if (!router) {
|
|
2581
|
-
console.error(chalk.red(`Could not find router instance in ${routesFile}.`));
|
|
2582
|
-
process11.exit(1);
|
|
2583
|
-
}
|
|
2584
|
-
const routes = router.routes || [];
|
|
2585
|
-
if (routes.length === 0) {
|
|
2586
|
-
console.log(chalk.yellow("No routes defined. Creating empty types file."));
|
|
2587
|
-
}
|
|
2588
|
-
const routeNames = routes.map((route) => {
|
|
2589
|
-
if (route.name)
|
|
2590
|
-
return route.name;
|
|
2591
|
-
const methodLower = route.method.toLowerCase();
|
|
2592
|
-
const pathFormatted = route.path.replace(/^\//, "").replace(/\//g, ".").replace(/\{([^}]+)\}/g, ":$1");
|
|
2593
|
-
return pathFormatted ? `${methodLower}.${pathFormatted}` : methodLower;
|
|
2594
|
-
});
|
|
2595
|
-
const uniqueRouteNames = [...new Set(routeNames)];
|
|
2596
|
-
const typeContent = `/**
|
|
2597
|
-
* This file is auto-generated.
|
|
2598
|
-
* DO NOT EDIT THIS FILE DIRECTLY.
|
|
2599
|
-
* To update, run 'bun router route:types'
|
|
2600
|
-
*/
|
|
2601
|
-
|
|
2602
|
-
/**
|
|
2603
|
-
* String literal type for all available route names
|
|
2604
|
-
*/
|
|
2605
|
-
export type RouteName = ${uniqueRouteNames.length > 0 ? uniqueRouteNames.map((name) => `'${name}'`).join(" | ") : "string"}
|
|
2606
|
-
|
|
2607
|
-
/**
|
|
2608
|
-
* Object type with route names as keys and string (for path generation) as values
|
|
2609
|
-
*/
|
|
2610
|
-
export interface RouteNameMap {
|
|
2611
|
-
${uniqueRouteNames.map((name) => ` '${name}': string`).join(`
|
|
2612
|
-
`)}
|
|
2613
|
-
}
|
|
2614
|
-
|
|
2615
|
-
/**
|
|
2616
|
-
* Type-safe function to generate a URL for a named route
|
|
2617
|
-
*/
|
|
2618
|
-
export type RouteFunction = <T extends RouteName>(name: T, params?: Record<string, string>) => string
|
|
2619
|
-
|
|
2620
|
-
/**
|
|
2621
|
-
* Validate that a string is a valid route name
|
|
2622
|
-
*/
|
|
2623
|
-
export function isValidRouteName(name: string): name is RouteName {
|
|
2624
|
-
return [${uniqueRouteNames.map((name) => `'${name}'`).join(", ")}].includes(name)
|
|
2625
|
-
}
|
|
2626
|
-
`;
|
|
2627
|
-
await fs4.writeFile(outputPath, typeContent);
|
|
2628
|
-
console.log(chalk.green(`\u2728 Route types generated at ${outputPath}`));
|
|
2629
|
-
} catch (error) {
|
|
2630
|
-
if (error.code === "ERR_MODULE_NOT_FOUND") {
|
|
2631
|
-
console.error(chalk.red(`Routes file not found at ${process11.cwd()}/routes/index.ts`));
|
|
2632
|
-
console.error(chalk.yellow('Make sure your routes are defined and exported as "router" in routes/index.ts'));
|
|
2633
|
-
} else {
|
|
2634
|
-
console.error(chalk.red(`Error generating route types: ${error.message}`));
|
|
2635
|
-
}
|
|
2636
|
-
throw error;
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
async function watchRoutesDirectory(outputPath) {
|
|
2640
|
-
const routesPath = path3.join(process11.cwd(), "routes");
|
|
2641
|
-
try {
|
|
2642
|
-
await fs4.access(routesPath);
|
|
2643
|
-
} catch {
|
|
2644
|
-
console.error(chalk.red(`Routes directory not found at ${routesPath}`));
|
|
2645
|
-
process11.exit(1);
|
|
2646
|
-
}
|
|
2647
|
-
await generateRouteTypes(outputPath);
|
|
2648
|
-
console.log(chalk.green(`\u2728 Route types generated at ${outputPath}`));
|
|
2649
|
-
console.log(chalk.blue(`Watching for changes in ${routesPath}...`));
|
|
2650
|
-
let timeoutId = null;
|
|
2651
|
-
const watcher = fs4.watch(routesPath, { recursive: true });
|
|
2652
|
-
for await (const _event of watcher) {
|
|
2653
|
-
if (timeoutId) {
|
|
2654
|
-
clearTimeout(timeoutId);
|
|
2655
|
-
}
|
|
2656
|
-
timeoutId = setTimeout(async () => {
|
|
2657
|
-
console.log(chalk.yellow(`Changes detected in routes directory. Regenerating types...`));
|
|
2658
|
-
try {
|
|
2659
|
-
await generateRouteTypes(outputPath);
|
|
2660
|
-
console.log(chalk.green(`\u2728 Route types regenerated at ${outputPath}`));
|
|
2661
|
-
} catch (error) {
|
|
2662
|
-
console.error(chalk.red(`Error regenerating types: ${error.message}`));
|
|
2663
|
-
}
|
|
2664
|
-
timeoutId = null;
|
|
2665
|
-
}, 500);
|
|
2666
|
-
}
|
|
2667
|
-
}
|
|
2668
|
-
function padString(str, length) {
|
|
2669
|
-
return (str + " ".repeat(length)).substring(0, length);
|
|
2670
|
-
}
|
|
2671
|
-
function getMethodColor(method) {
|
|
2672
|
-
switch (method.toUpperCase()) {
|
|
2673
|
-
case "GET":
|
|
2674
|
-
return chalk.cyan;
|
|
2675
|
-
case "POST":
|
|
2676
|
-
return chalk.green;
|
|
2677
|
-
case "PUT":
|
|
2678
|
-
return chalk.yellow;
|
|
2679
|
-
case "PATCH":
|
|
2680
|
-
return chalk.yellow;
|
|
2681
|
-
case "DELETE":
|
|
2682
|
-
return chalk.red;
|
|
2683
|
-
case "OPTIONS":
|
|
2684
|
-
return chalk.gray;
|
|
2685
|
-
default:
|
|
2686
|
-
return chalk.white;
|
|
2687
|
-
}
|
|
2688
|
-
}
|
|
2689
|
-
|
|
2690
|
-
// src/cli/utils.ts
|
|
2691
|
-
import process12 from "process";
|
|
2692
|
-
var format = {
|
|
2693
|
-
success: (message) => chalk.green(`\u2728 ${message}`),
|
|
2694
|
-
info: (message) => chalk.blue(message),
|
|
2695
|
-
warning: (message) => chalk.yellow(message),
|
|
2696
|
-
error: (message) => chalk.red(message),
|
|
2697
|
-
dim: (message) => chalk.dim(message),
|
|
2698
|
-
bold: (message) => chalk.bold(message)
|
|
2699
|
-
};
|
|
2700
|
-
var logger = {
|
|
2701
|
-
success: (message) => console.log(format.success(message)),
|
|
2702
|
-
info: (message) => console.log(format.info(message)),
|
|
2703
|
-
warning: (message) => console.log(format.warning(message)),
|
|
2704
|
-
error: (message) => console.error(format.error(message)),
|
|
2705
|
-
debug: (message) => console.debug(format.dim(message))
|
|
2706
|
-
};
|
|
2707
|
-
async function loadRouter() {
|
|
2708
|
-
try {
|
|
2709
|
-
const routesFile = `${process12.cwd()}/routes/index.ts`;
|
|
2710
|
-
const { router } = await import(routesFile);
|
|
2711
|
-
if (!router) {
|
|
2712
|
-
logger.error(`Could not find router instance in ${routesFile}.`);
|
|
2713
|
-
process12.exit(1);
|
|
2714
|
-
}
|
|
2715
|
-
return router;
|
|
2716
|
-
} catch (error) {
|
|
2717
|
-
if (error.code === "ERR_MODULE_NOT_FOUND") {
|
|
2718
|
-
logger.error(`Routes file not found at ${process12.cwd()}/routes/index.ts`);
|
|
2719
|
-
logger.warning('Make sure your routes are defined and exported as "router" in routes/index.ts');
|
|
2720
|
-
} else {
|
|
2721
|
-
logger.error(`Error loading router: ${error.message}`);
|
|
2722
|
-
}
|
|
2723
|
-
throw error;
|
|
2724
|
-
}
|
|
2725
|
-
}
|
|
2726
|
-
function getMethodColor2(method) {
|
|
2727
|
-
switch (method.toUpperCase()) {
|
|
2728
|
-
case "GET":
|
|
2729
|
-
return chalk.cyan.toString();
|
|
2730
|
-
case "POST":
|
|
2731
|
-
return chalk.green.toString();
|
|
2732
|
-
case "PUT":
|
|
2733
|
-
return chalk.yellow.toString();
|
|
2734
|
-
case "PATCH":
|
|
2735
|
-
return chalk.yellow.toString();
|
|
2736
|
-
case "DELETE":
|
|
2737
|
-
return chalk.red.toString();
|
|
2738
|
-
case "OPTIONS":
|
|
2739
|
-
return chalk.gray.toString();
|
|
2740
|
-
default:
|
|
2741
|
-
return chalk.white.toString();
|
|
2742
|
-
}
|
|
2743
|
-
}
|
|
2744
|
-
async function checkRouterHealth(options) {
|
|
2745
|
-
logger.info("\uD83D\uDD0D Checking router health...");
|
|
2746
|
-
try {
|
|
2747
|
-
const router = await loadRouter();
|
|
2748
|
-
const routes = router.routes || [];
|
|
2749
|
-
const globalMiddleware = router.globalMiddleware || [];
|
|
2750
|
-
const namedRoutes = router.namedRoutes || new Map;
|
|
2751
|
-
const health = {
|
|
2752
|
-
totalRoutes: routes.length,
|
|
2753
|
-
namedRoutes: namedRoutes.size,
|
|
2754
|
-
globalMiddleware: globalMiddleware.length,
|
|
2755
|
-
routesByMethod: {},
|
|
2756
|
-
duplicateRoutes: [],
|
|
2757
|
-
routesWithMiddleware: 0,
|
|
2758
|
-
staticRoutes: 0,
|
|
2759
|
-
dynamicRoutes: 0
|
|
2760
|
-
};
|
|
2761
|
-
const routeMap = new Map;
|
|
2762
|
-
for (const route of routes) {
|
|
2763
|
-
const key = `${route.method}:${route.path}`;
|
|
2764
|
-
health.routesByMethod[route.method] = (health.routesByMethod[route.method] || 0) + 1;
|
|
2765
|
-
if (!routeMap.has(key)) {
|
|
2766
|
-
routeMap.set(key, []);
|
|
2767
|
-
}
|
|
2768
|
-
routeMap.get(key).push(route.path);
|
|
2769
|
-
if (routeMap.get(key).length > 1) {
|
|
2770
|
-
health.duplicateRoutes.push({ path: route.path, method: route.method });
|
|
2771
|
-
}
|
|
2772
|
-
if (route.middleware && route.middleware.length > 0) {
|
|
2773
|
-
health.routesWithMiddleware++;
|
|
2774
|
-
}
|
|
2775
|
-
if (route.path.includes("{") || route.path.includes("*")) {
|
|
2776
|
-
health.dynamicRoutes++;
|
|
2777
|
-
} else {
|
|
2778
|
-
health.staticRoutes++;
|
|
2779
|
-
}
|
|
2780
|
-
}
|
|
2781
|
-
logger.success(`Router health check completed`);
|
|
2782
|
-
console.log(`\uD83D\uDCCA Routes: ${health.totalRoutes} total (${health.staticRoutes} static, ${health.dynamicRoutes} dynamic)`);
|
|
2783
|
-
console.log(`\uD83D\uDCDB Named routes: ${health.namedRoutes}`);
|
|
2784
|
-
console.log(`\uD83D\uDEE1\uFE0F Global middleware: ${health.globalMiddleware}`);
|
|
2785
|
-
console.log(`\uD83D\uDD27 Routes with middleware: ${health.routesWithMiddleware}`);
|
|
2786
|
-
if (options.verbose) {
|
|
2787
|
-
console.log(`
|
|
2788
|
-
\uD83D\uDCC8 Routes by method:`);
|
|
2789
|
-
for (const [method, count] of Object.entries(health.routesByMethod)) {
|
|
2790
|
-
const color = getMethodColor2(method);
|
|
2791
|
-
console.log(` ${chalk.hex(color)(method.padEnd(8))}: ${count}`);
|
|
2792
|
-
}
|
|
2793
|
-
if (health.duplicateRoutes.length > 0) {
|
|
2794
|
-
logger.warning(`
|
|
2795
|
-
\u26A0\uFE0F Found ${health.duplicateRoutes.length} duplicate route(s):`);
|
|
2796
|
-
for (const duplicate of health.duplicateRoutes) {
|
|
2797
|
-
console.log(` ${duplicate.method} ${duplicate.path}`);
|
|
2798
|
-
}
|
|
2799
|
-
}
|
|
2800
|
-
const issues = [];
|
|
2801
|
-
if (health.totalRoutes === 0) {
|
|
2802
|
-
issues.push("No routes defined");
|
|
2803
|
-
}
|
|
2804
|
-
if (health.duplicateRoutes.length > 0) {
|
|
2805
|
-
issues.push(`${health.duplicateRoutes.length} duplicate routes`);
|
|
2806
|
-
}
|
|
2807
|
-
if (health.routesWithMiddleware === 0 && health.globalMiddleware === 0) {
|
|
2808
|
-
issues.push("No middleware configured");
|
|
2809
|
-
}
|
|
2810
|
-
if (issues.length > 0) {
|
|
2811
|
-
logger.warning(`
|
|
2812
|
-
\u26A0\uFE0F Potential issues:`);
|
|
2813
|
-
for (const issue of issues) {
|
|
2814
|
-
console.log(` \u2022 ${issue}`);
|
|
2815
|
-
}
|
|
2816
|
-
} else {
|
|
2817
|
-
logger.success(`
|
|
2818
|
-
\u2705 No issues detected`);
|
|
2819
|
-
}
|
|
2820
|
-
}
|
|
2821
|
-
} catch (error) {
|
|
2822
|
-
logger.error(`Health check failed: ${error.message}`);
|
|
2823
|
-
throw error;
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
2826
|
-
async function testRoutes(options) {
|
|
2827
|
-
const baseUrl = options.baseUrl || "http://localhost:3000";
|
|
2828
|
-
const timeout = options.timeout || 5000;
|
|
2829
|
-
const allowedMethods = options.method ? options.method.split(",").map((m) => m.trim().toUpperCase()) : null;
|
|
2830
|
-
logger.info(`\uD83E\uDDEA Testing routes at ${baseUrl}...`);
|
|
2831
|
-
try {
|
|
2832
|
-
const router = await loadRouter();
|
|
2833
|
-
const routes = router.routes || [];
|
|
2834
|
-
let filteredRoutes = routes;
|
|
2835
|
-
if (options.filter) {
|
|
2836
|
-
const pattern = new RegExp(options.filter.replace(/\*/g, ".*"));
|
|
2837
|
-
filteredRoutes = routes.filter((route) => pattern.test(route.path));
|
|
2838
|
-
}
|
|
2839
|
-
if (allowedMethods) {
|
|
2840
|
-
filteredRoutes = filteredRoutes.filter((route) => allowedMethods.includes(route.method));
|
|
2841
|
-
}
|
|
2842
|
-
if (filteredRoutes.length === 0) {
|
|
2843
|
-
logger.warning("No routes match the specified filters");
|
|
2844
|
-
return;
|
|
2845
|
-
}
|
|
2846
|
-
logger.info(`Testing ${filteredRoutes.length} routes...`);
|
|
2847
|
-
const results = {
|
|
2848
|
-
total: 0,
|
|
2849
|
-
passed: 0,
|
|
2850
|
-
failed: 0,
|
|
2851
|
-
errors: []
|
|
2852
|
-
};
|
|
2853
|
-
for (const route of filteredRoutes) {
|
|
2854
|
-
results.total++;
|
|
2855
|
-
if (route.path.includes("{")) {
|
|
2856
|
-
logger.debug(`Skipping parameterized route: ${route.method} ${route.path}`);
|
|
2857
|
-
continue;
|
|
2858
|
-
}
|
|
2859
|
-
try {
|
|
2860
|
-
const url = `${baseUrl}${route.path}`;
|
|
2861
|
-
const response = await fetch(url, {
|
|
2862
|
-
method: route.method,
|
|
2863
|
-
signal: AbortSignal.timeout(timeout)
|
|
2864
|
-
});
|
|
2865
|
-
if (response.status < 500) {
|
|
2866
|
-
results.passed++;
|
|
2867
|
-
logger.debug(`\u2705 ${route.method} ${route.path} \u2192 ${response.status}`);
|
|
2868
|
-
} else {
|
|
2869
|
-
results.failed++;
|
|
2870
|
-
results.errors.push({
|
|
2871
|
-
route: `${route.method} ${route.path}`,
|
|
2872
|
-
error: `HTTP ${response.status}`
|
|
2873
|
-
});
|
|
2874
|
-
}
|
|
2875
|
-
} catch (error) {
|
|
2876
|
-
results.failed++;
|
|
2877
|
-
results.errors.push({
|
|
2878
|
-
route: `${route.method} ${route.path}`,
|
|
2879
|
-
error: error.message
|
|
2880
|
-
});
|
|
2881
|
-
}
|
|
2882
|
-
}
|
|
2883
|
-
console.log(`
|
|
2884
|
-
\uD83D\uDCCA Test Results:`);
|
|
2885
|
-
console.log(` Total: ${results.total}`);
|
|
2886
|
-
console.log(` Passed: ${chalk.green(String(results.passed))}`);
|
|
2887
|
-
console.log(` Failed: ${chalk.red(String(results.failed))}`);
|
|
2888
|
-
if (results.errors.length > 0) {
|
|
2889
|
-
console.log(`
|
|
2890
|
-
\u274C Failures:`);
|
|
2891
|
-
for (const error of results.errors) {
|
|
2892
|
-
console.log(` ${error.route}: ${error.error}`);
|
|
2893
|
-
}
|
|
2894
|
-
}
|
|
2895
|
-
if (results.failed > 0) {
|
|
2896
|
-
process12.exit(1);
|
|
2897
|
-
} else {
|
|
2898
|
-
logger.success("All tests passed!");
|
|
2899
|
-
}
|
|
2900
|
-
} catch (error) {
|
|
2901
|
-
logger.error(`Route testing failed: ${error.message}`);
|
|
2902
|
-
throw error;
|
|
2903
|
-
}
|
|
2904
|
-
}
|
|
2905
|
-
async function debugRoute(path4, options) {
|
|
2906
|
-
const method = options.method?.toUpperCase() || "GET";
|
|
2907
|
-
logger.info(`\uD83D\uDD0D Debugging route matching for: ${method} ${path4}`);
|
|
2908
|
-
try {
|
|
2909
|
-
const router = await loadRouter();
|
|
2910
|
-
const match = router.matchRoute ? router.matchRoute(path4, method) : null;
|
|
2911
|
-
if (match) {
|
|
2912
|
-
logger.success(`\u2705 Route matched!`);
|
|
2913
|
-
console.log(` Route: ${match.route.method} ${match.route.path}`);
|
|
2914
|
-
console.log(` Handler: ${typeof match.route.handler}`);
|
|
2915
|
-
if (Object.keys(match.params || {}).length > 0) {
|
|
2916
|
-
console.log(` Parameters:`);
|
|
2917
|
-
for (const [key, value] of Object.entries(match.params)) {
|
|
2918
|
-
console.log(` ${key}: ${value}`);
|
|
2919
|
-
}
|
|
2920
|
-
}
|
|
2921
|
-
if (match.route.middleware && match.route.middleware.length > 0) {
|
|
2922
|
-
console.log(` Middleware: ${match.route.middleware.length} handler(s)`);
|
|
2923
|
-
}
|
|
2924
|
-
if (match.route.name) {
|
|
2925
|
-
console.log(` Named route: ${match.route.name}`);
|
|
2926
|
-
}
|
|
2927
|
-
} else {
|
|
2928
|
-
logger.error(`\u274C No route matched for ${method} ${path4}`);
|
|
2929
|
-
if (options.verbose) {
|
|
2930
|
-
console.log(`
|
|
2931
|
-
\uD83D\uDCCB Available routes:`);
|
|
2932
|
-
const routes = router.routes || [];
|
|
2933
|
-
const methodRoutes = routes.filter((r) => r.method === method);
|
|
2934
|
-
if (methodRoutes.length === 0) {
|
|
2935
|
-
console.log(` No routes defined for ${method} method`);
|
|
2936
|
-
} else {
|
|
2937
|
-
for (const route of methodRoutes) {
|
|
2938
|
-
console.log(` ${route.method} ${route.path}`);
|
|
2939
|
-
}
|
|
2940
|
-
}
|
|
2941
|
-
}
|
|
2942
|
-
}
|
|
2943
|
-
} catch (error) {
|
|
2944
|
-
logger.error(`Route debugging failed: ${error.message}`);
|
|
2945
|
-
throw error;
|
|
2946
|
-
}
|
|
2947
|
-
}
|
|
2948
|
-
async function clearCaches(options) {
|
|
2949
|
-
logger.info("\uD83D\uDDD1\uFE0F Clearing route caches...");
|
|
2950
|
-
try {
|
|
2951
|
-
const router = await loadRouter();
|
|
2952
|
-
if (options.stats) {
|
|
2953
|
-
if (router.getCacheStats) {
|
|
2954
|
-
const stats = router.getCacheStats();
|
|
2955
|
-
console.log("\uD83D\uDCCA Cache statistics before clearing:");
|
|
2956
|
-
console.log(` Hit rate: ${stats.hitRate}%`);
|
|
2957
|
-
console.log(` Total hits: ${stats.hits}`);
|
|
2958
|
-
console.log(` Total misses: ${stats.misses}`);
|
|
2959
|
-
console.log(` Cache size: ${stats.size}`);
|
|
2960
|
-
}
|
|
2961
|
-
if (router.routeCache) {
|
|
2962
|
-
console.log(` Route cache entries: ${router.routeCache.size}`);
|
|
2963
|
-
}
|
|
2964
|
-
if (router.templateCache) {
|
|
2965
|
-
console.log(` Template cache entries: ${router.templateCache.size}`);
|
|
2966
|
-
}
|
|
2967
|
-
}
|
|
2968
|
-
if (router.clearRouteCache) {
|
|
2969
|
-
router.clearRouteCache();
|
|
2970
|
-
}
|
|
2971
|
-
if (router.routeCache && router.routeCache.clear) {
|
|
2972
|
-
router.routeCache.clear();
|
|
2973
|
-
}
|
|
2974
|
-
if (router.templateCache && router.templateCache.clear) {
|
|
2975
|
-
router.templateCache.clear();
|
|
2976
|
-
}
|
|
2977
|
-
if (router.clearModelCache) {
|
|
2978
|
-
router.clearModelCache();
|
|
2979
|
-
}
|
|
2980
|
-
logger.success("\u2705 Caches cleared successfully");
|
|
2981
|
-
} catch (error) {
|
|
2982
|
-
logger.error(`Cache clearing failed: ${error.message}`);
|
|
2983
|
-
throw error;
|
|
2984
|
-
}
|
|
2985
|
-
}
|
|
2986
|
-
async function validateRoutes(options) {
|
|
2987
|
-
logger.info("\uD83D\uDD0D Validating route definitions...");
|
|
2988
|
-
try {
|
|
2989
|
-
const router = await loadRouter();
|
|
2990
|
-
const routes = router.routes || [];
|
|
2991
|
-
const issues = [];
|
|
2992
|
-
const warnings = [];
|
|
2993
|
-
for (const route of routes) {
|
|
2994
|
-
if (!route.method) {
|
|
2995
|
-
issues.push(`Route missing method: ${route.path}`);
|
|
2996
|
-
}
|
|
2997
|
-
if (!route.path) {
|
|
2998
|
-
issues.push(`Route missing path: ${route.method || "UNKNOWN"}`);
|
|
2999
|
-
}
|
|
3000
|
-
if (!route.handler) {
|
|
3001
|
-
issues.push(`Route missing handler: ${route.method} ${route.path}`);
|
|
3002
|
-
}
|
|
3003
|
-
if (route.path && !route.path.startsWith("/")) {
|
|
3004
|
-
issues.push(`Route path should start with '/': ${route.method} ${route.path}`);
|
|
3005
|
-
}
|
|
3006
|
-
if (route.path && route.path.includes("{")) {
|
|
3007
|
-
const params = route.path.match(/\{[^}]+\}/g) || [];
|
|
3008
|
-
for (const param of params) {
|
|
3009
|
-
if (!param.match(/^\{[a-z_]\w*(\?|:[^}]+)?\}$/i)) {
|
|
3010
|
-
issues.push(`Invalid parameter syntax in ${route.method} ${route.path}: ${param}`);
|
|
3011
|
-
}
|
|
3012
|
-
}
|
|
3013
|
-
}
|
|
3014
|
-
if (options.strict) {
|
|
3015
|
-
if (!route.name && !route.path.includes("{") && route.path !== "/") {
|
|
3016
|
-
warnings.push(`Consider adding a name to route: ${route.method} ${route.path}`);
|
|
3017
|
-
}
|
|
3018
|
-
if (route.path.includes("/admin") && (!route.middleware || route.middleware.length === 0)) {
|
|
3019
|
-
warnings.push(`Admin route missing middleware: ${route.method} ${route.path}`);
|
|
3020
|
-
}
|
|
3021
|
-
}
|
|
3022
|
-
}
|
|
3023
|
-
const routeMap = new Map;
|
|
3024
|
-
for (const route of routes) {
|
|
3025
|
-
const key = `${route.method}:${route.path}`;
|
|
3026
|
-
routeMap.set(key, (routeMap.get(key) || 0) + 1);
|
|
3027
|
-
}
|
|
3028
|
-
for (const [key, count] of routeMap.entries()) {
|
|
3029
|
-
if (count > 1) {
|
|
3030
|
-
issues.push(`Duplicate route detected: ${key} (${count} times)`);
|
|
3031
|
-
}
|
|
3032
|
-
}
|
|
3033
|
-
if (issues.length === 0 && warnings.length === 0) {
|
|
3034
|
-
logger.success("\u2705 All route definitions are valid");
|
|
3035
|
-
return;
|
|
3036
|
-
}
|
|
3037
|
-
if (issues.length > 0) {
|
|
3038
|
-
logger.error(`\u274C Found ${issues.length} validation error(s):`);
|
|
3039
|
-
for (const issue of issues) {
|
|
3040
|
-
console.log(` \u2022 ${issue}`);
|
|
3041
|
-
}
|
|
3042
|
-
}
|
|
3043
|
-
if (warnings.length > 0) {
|
|
3044
|
-
logger.warning(`\u26A0\uFE0F Found ${warnings.length} warning(s):`);
|
|
3045
|
-
for (const warning of warnings) {
|
|
3046
|
-
console.log(` \u2022 ${warning}`);
|
|
3047
|
-
}
|
|
3048
|
-
}
|
|
3049
|
-
if (options.fix) {
|
|
3050
|
-
logger.info("\uD83D\uDD27 Auto-fixing is not yet implemented");
|
|
3051
|
-
}
|
|
3052
|
-
if (issues.length > 0) {
|
|
3053
|
-
process12.exit(1);
|
|
3054
|
-
}
|
|
3055
|
-
} catch (error) {
|
|
3056
|
-
logger.error(`Route validation failed: ${error.message}`);
|
|
3057
|
-
throw error;
|
|
3058
|
-
}
|
|
3059
|
-
}
|
|
3060
|
-
|
|
3061
|
-
// src/cli/index.ts
|
|
3062
|
-
function createCLI() {
|
|
3063
|
-
const cli = new CLI("router");
|
|
3064
|
-
cli.version(version);
|
|
3065
|
-
registerRouteCommands(cli);
|
|
3066
|
-
registerMiddlewareCommands(cli);
|
|
3067
|
-
registerRouterCommands(cli);
|
|
3068
|
-
registerOpenAPICommands(cli);
|
|
3069
|
-
registerUtilityCommands(cli);
|
|
3070
|
-
cli.help();
|
|
3071
|
-
return cli;
|
|
3072
|
-
}
|
|
3073
|
-
function registerRouteCommands(cli) {
|
|
3074
|
-
cli.command("route:list", "List all registered routes").option("-v, --verbose", "Show detailed information including middleware").option("-vv, --extra-verbose", "Show very detailed information").option("--path <path>", "Filter routes by path prefix").option("--except-vendor", "Exclude vendor routes").option("--only-vendor", "Show only vendor routes").example("router route:list").example("router route:list -v").example("router route:list --path=/api").action(async (options) => {
|
|
3075
|
-
try {
|
|
3076
|
-
await displayRoutes(options);
|
|
3077
|
-
} catch (error) {
|
|
3078
|
-
console.error(`Failed to list routes: ${error.message}`);
|
|
3079
|
-
process13.exit(1);
|
|
3080
|
-
}
|
|
3081
|
-
});
|
|
3082
|
-
cli.command("route:types", "Generate TypeScript types for route names").option("--output <file>", "Output file path", { default: "route-types.ts" }).option("--watch", "Watch for changes in routes directory").example("router route:types").example("router route:types --output src/types/routes.ts").example("router route:types --watch").action(async (options) => {
|
|
3083
|
-
try {
|
|
3084
|
-
const outputPath = options.output || "route-types.ts";
|
|
3085
|
-
if (options.watch) {
|
|
3086
|
-
await watchRoutesDirectory(outputPath);
|
|
3087
|
-
} else {
|
|
3088
|
-
await generateRouteTypes(outputPath);
|
|
3089
|
-
}
|
|
3090
|
-
} catch (error) {
|
|
3091
|
-
console.error(`Failed to generate route types: ${error.message}`);
|
|
3092
|
-
process13.exit(1);
|
|
3093
|
-
}
|
|
3094
|
-
});
|
|
3095
|
-
}
|
|
3096
|
-
function registerMiddlewareCommands(cli) {
|
|
3097
|
-
cli.command("middleware:types", "Generate TypeScript types for middleware configurations").option("--output <file>", "Output file path", { default: "middleware-types.ts" }).option("--watch", "Watch for changes in middleware directory").example("router middleware:types").example("router middleware:types --output src/types/middleware.ts").example("router middleware:types --watch").action(async (options) => {
|
|
3098
|
-
try {
|
|
3099
|
-
const outputPath = options.output || "middleware-types.ts";
|
|
3100
|
-
if (options.watch) {
|
|
3101
|
-
await watchMiddlewareDirectory(outputPath);
|
|
3102
|
-
} else {
|
|
3103
|
-
await generateMiddlewareTypes(outputPath);
|
|
3104
|
-
}
|
|
3105
|
-
} catch (error) {
|
|
3106
|
-
console.error(`Failed to generate middleware types: ${error.message}`);
|
|
3107
|
-
process13.exit(1);
|
|
3108
|
-
}
|
|
3109
|
-
});
|
|
3110
|
-
cli.command("middleware:map", "Generate TypeScript types for all middleware in the project").option("--dir <directory>", "Directory to scan for middleware classes", { default: "src" }).option("--output <file>", "Output file path", { default: "middleware-map.ts" }).option("--watch", "Watch for changes in the specified directory").example("router middleware:map").example("router middleware:map --dir app").example("router middleware:map --output src/types/project-middleware.ts").example("router middleware:map --watch").action(async (options) => {
|
|
3111
|
-
try {
|
|
3112
|
-
const outputPath = options.output || "middleware-map.ts";
|
|
3113
|
-
const directoryPath = options.dir || "src";
|
|
3114
|
-
if (options.watch) {
|
|
3115
|
-
await watchDirectoryForMiddleware(directoryPath, outputPath);
|
|
3116
|
-
} else {
|
|
3117
|
-
await generateMiddlewareMap(directoryPath, outputPath);
|
|
3118
|
-
}
|
|
3119
|
-
} catch (error) {
|
|
3120
|
-
console.error(`Failed to generate middleware map: ${error.message}`);
|
|
3121
|
-
process13.exit(1);
|
|
3122
|
-
}
|
|
3123
|
-
});
|
|
3124
|
-
}
|
|
3125
|
-
function registerRouterCommands(cli) {
|
|
3126
|
-
cli.command("router:types", "Generate TypeScript types for router extensions").option("--output <file>", "Output file path", { default: "router-types.ts" }).option("--watch", "Watch for changes in router files").example("router router:types").example("router router:types --output src/types/router.ts").example("router router:types --watch").action(async (options) => {
|
|
3127
|
-
try {
|
|
3128
|
-
const outputPath = options.output || "router-types.ts";
|
|
3129
|
-
if (options.watch) {
|
|
3130
|
-
await watchRouterFiles(outputPath);
|
|
3131
|
-
} else {
|
|
3132
|
-
await generateRouterTypes(outputPath);
|
|
3133
|
-
}
|
|
3134
|
-
} catch (error) {
|
|
3135
|
-
console.error(`Failed to generate router types: ${error.message}`);
|
|
3136
|
-
process13.exit(1);
|
|
3137
|
-
}
|
|
3138
|
-
});
|
|
3139
|
-
}
|
|
3140
|
-
function registerOpenAPICommands(cli) {
|
|
3141
|
-
cli.command("openapi", "Generate OpenAPI specification for API routes").option("--output <file>", "Output file path", { default: "openapi.json" }).option("--title <title>", "API title", { default: "API Documentation" }).option("--version <version>", "API version", { default: "1.0.0" }).option("--description <description>", "API description").option("--base-path <path>", "Base API path", { default: "/" }).option("--servers <urls>", "Comma-separated list of server URLs").option("--tags", "Group endpoints by tags", { default: true }).option("--security", "Include security schemes if available", { default: true }).example("router openapi").example("router openapi --output api-spec.json").example('router openapi --title "My API" --version 2.0').example("router openapi --servers http://localhost:3000,https://api.example.com").action(async (options) => {
|
|
3142
|
-
try {
|
|
3143
|
-
await generateOpenAPISpec(options);
|
|
3144
|
-
} catch (error) {
|
|
3145
|
-
console.error(`Failed to generate OpenAPI specification: ${error.message}`);
|
|
3146
|
-
process13.exit(1);
|
|
3147
|
-
}
|
|
3148
|
-
});
|
|
3149
|
-
}
|
|
3150
|
-
function registerUtilityCommands(cli) {
|
|
3151
|
-
cli.command("health", "Check router health and configuration").option("--verbose", "Show detailed health information").example("router health").example("router health --verbose").action(async (options) => {
|
|
3152
|
-
try {
|
|
3153
|
-
await checkRouterHealth(options);
|
|
3154
|
-
} catch (error) {
|
|
3155
|
-
console.error(`Health check failed: ${error.message}`);
|
|
3156
|
-
process13.exit(1);
|
|
3157
|
-
}
|
|
3158
|
-
});
|
|
3159
|
-
cli.command("test:routes", "Test routes by making HTTP requests").option("--base-url <url>", "Base URL for testing", { default: "http://localhost:3000" }).option("--filter <pattern>", "Filter routes by path pattern").option("--method <methods>", "Test only specific HTTP methods (comma-separated)").option("--timeout <ms>", "Request timeout in milliseconds", { default: 5000 }).example("router test:routes").example("router test:routes --base-url http://localhost:8080").example('router test:routes --filter "/api/*"').example("router test:routes --method GET,POST").action(async (options) => {
|
|
3160
|
-
try {
|
|
3161
|
-
await testRoutes(options);
|
|
3162
|
-
} catch (error) {
|
|
3163
|
-
console.error(`Route testing failed: ${error.message}`);
|
|
3164
|
-
process13.exit(1);
|
|
3165
|
-
}
|
|
3166
|
-
});
|
|
3167
|
-
cli.command("debug:route <path>", "Debug route matching for a specific path").option("--method <method>", "HTTP method to test", { default: "GET" }).option("--verbose", "Show detailed matching information").example("router debug:route /api/users/123").example("router debug:route /api/users/123 --method POST --verbose").action(async (path4, options) => {
|
|
3168
|
-
try {
|
|
3169
|
-
await debugRoute(path4, options);
|
|
3170
|
-
} catch (error) {
|
|
3171
|
-
console.error(`Route debugging failed: ${error.message}`);
|
|
3172
|
-
process13.exit(1);
|
|
3173
|
-
}
|
|
3174
|
-
});
|
|
3175
|
-
cli.command("cache:clear", "Clear route caches").option("--stats", "Show cache statistics before clearing").example("router cache:clear").example("router cache:clear --stats").action(async (options) => {
|
|
3176
|
-
try {
|
|
3177
|
-
await clearCaches(options);
|
|
3178
|
-
} catch (error) {
|
|
3179
|
-
console.error(`Cache clearing failed: ${error.message}`);
|
|
3180
|
-
process13.exit(1);
|
|
3181
|
-
}
|
|
3182
|
-
});
|
|
3183
|
-
cli.command("validate", "Validate route definitions and configuration").option("--strict", "Use strict validation rules").option("--fix", "Automatically fix simple issues").example("router validate").example("router validate --strict --fix").action(async (options) => {
|
|
3184
|
-
try {
|
|
3185
|
-
await validateRoutes(options);
|
|
3186
|
-
} catch (error) {
|
|
3187
|
-
console.error(`Route validation failed: ${error.message}`);
|
|
3188
|
-
process13.exit(1);
|
|
3189
|
-
}
|
|
3190
|
-
});
|
|
3191
|
-
}
|
|
3192
|
-
|
|
3193
|
-
// src/cli.ts
|
|
3194
|
-
var cli = createCLI();
|
|
3195
|
-
cli.parse();
|