@fml-inc/fml 0.0.26 → 0.0.28
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/.claude-plugin/plugin.json +1 -0
- package/dist/chunk-2CRFCFE4.js +11 -0
- package/dist/chunk-2CRFCFE4.js.map +1 -0
- package/dist/{chunk-WXDGVKXK.js → chunk-ECXIFGGY.js} +146 -6
- package/dist/chunk-ECXIFGGY.js.map +1 -0
- package/dist/chunk-NLFKYSN7.js +640 -0
- package/dist/chunk-NLFKYSN7.js.map +1 -0
- package/dist/chunk-UALBZA5X.js +123 -0
- package/dist/chunk-UALBZA5X.js.map +1 -0
- package/dist/{chunk-FS55W24B.js → chunk-USJO3G5V.js} +29 -3
- package/dist/chunk-USJO3G5V.js.map +1 -0
- package/dist/chunk-YIWT7BWN.js +33 -0
- package/dist/chunk-YIWT7BWN.js.map +1 -0
- package/dist/{chunk-EL2WSQBR.js → chunk-ZA4RG25C.js} +6 -33
- package/dist/chunk-ZA4RG25C.js.map +1 -0
- package/dist/cli.js +2052 -87
- package/dist/cli.js.map +1 -1
- package/dist/{daemon-J4WSZXVY.js → daemon-2YGD43RJ.js} +3 -2
- package/dist/daemon-utils-LIG6K2MK.js +17 -0
- package/dist/doctor-YV6KQEGW.js +2019 -0
- package/dist/doctor-YV6KQEGW.js.map +1 -0
- package/dist/esm-GTDP7OMQ-EP6UYLQG.js +14442 -0
- package/dist/esm-GTDP7OMQ-EP6UYLQG.js.map +1 -0
- package/dist/mcp/server.js +7 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/postinstall.js +0 -69
- package/dist/postinstall.js.map +1 -1
- package/dist/{token-store-KQSMR6XA.js → token-store-Y35HF3FJ.js} +2 -2
- package/dist/token-store-Y35HF3FJ.js.map +1 -0
- package/package.json +4 -4
- package/dist/chunk-EL2WSQBR.js.map +0 -1
- package/dist/chunk-FS55W24B.js.map +0 -1
- package/dist/chunk-WXDGVKXK.js.map +0 -1
- /package/dist/{daemon-J4WSZXVY.js.map → daemon-2YGD43RJ.js.map} +0 -0
- /package/dist/{token-store-KQSMR6XA.js.map → daemon-utils-LIG6K2MK.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
config,
|
|
4
|
+
loadUnifiedConfig,
|
|
5
|
+
saveUnifiedConfig
|
|
6
|
+
} from "./chunk-NLFKYSN7.js";
|
|
2
7
|
import {
|
|
3
8
|
createApiClient,
|
|
4
9
|
ensureNativeModules,
|
|
5
10
|
getAuthenticatedClient
|
|
6
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ECXIFGGY.js";
|
|
12
|
+
import "./chunk-UALBZA5X.js";
|
|
7
13
|
import {
|
|
8
14
|
AUTH_STORE_PATH,
|
|
9
15
|
CONVEX_URL,
|
|
@@ -14,33 +20,1766 @@ import {
|
|
|
14
20
|
WORKOS_AUTH_URL,
|
|
15
21
|
getActiveEnv,
|
|
16
22
|
getSelectedOrg,
|
|
23
|
+
getSiteUrl,
|
|
17
24
|
getValidToken,
|
|
18
25
|
initSentry,
|
|
19
26
|
readTokens,
|
|
20
27
|
setSelectedOrg,
|
|
21
28
|
writeEnvConfig,
|
|
22
29
|
writeTokens
|
|
23
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-USJO3G5V.js";
|
|
24
31
|
import {
|
|
25
32
|
handleStart,
|
|
26
33
|
handleStop,
|
|
27
|
-
panopticonExec,
|
|
28
34
|
parsePanopticonRunning
|
|
29
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-YIWT7BWN.js";
|
|
36
|
+
import {
|
|
37
|
+
panopticonExec
|
|
38
|
+
} from "./chunk-ZA4RG25C.js";
|
|
30
39
|
import {
|
|
31
40
|
FML_DATA_DIR,
|
|
32
41
|
FML_LOG_DIR
|
|
33
42
|
} from "./chunk-4YEAQJPF.js";
|
|
43
|
+
import "./chunk-2CRFCFE4.js";
|
|
34
44
|
import "./chunk-PZ5AY32C.js";
|
|
35
45
|
|
|
36
|
-
// src/cli.ts
|
|
37
|
-
import { Command } from "commander";
|
|
46
|
+
// src/cli.ts
|
|
47
|
+
import { Command } from "commander";
|
|
48
|
+
|
|
49
|
+
// src/commands/doctor.ts
|
|
50
|
+
import ora from "ora";
|
|
51
|
+
import pc from "picocolors";
|
|
52
|
+
|
|
53
|
+
// node_modules/.pnpm/@fml-inc+panopticon@0.2.2/node_modules/@fml-inc/panopticon/dist/chunk-6NMLAGHC.js
|
|
54
|
+
import os from "os";
|
|
55
|
+
import path from "path";
|
|
56
|
+
function urlToObject(url) {
|
|
57
|
+
return {
|
|
58
|
+
href: url.href,
|
|
59
|
+
protocol: url.protocol,
|
|
60
|
+
username: url.username,
|
|
61
|
+
password: url.password,
|
|
62
|
+
host: url.host,
|
|
63
|
+
hostname: url.hostname,
|
|
64
|
+
port: url.port,
|
|
65
|
+
pathname: url.pathname,
|
|
66
|
+
search: url.search,
|
|
67
|
+
searchParams: [...url.searchParams].map(([key, value]) => ({ key, value })),
|
|
68
|
+
hash: url.hash,
|
|
69
|
+
origin: url.origin
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
var prettyLogStyles = {
|
|
73
|
+
reset: [0, 0],
|
|
74
|
+
bold: [1, 22],
|
|
75
|
+
dim: [2, 22],
|
|
76
|
+
italic: [3, 23],
|
|
77
|
+
underline: [4, 24],
|
|
78
|
+
overline: [53, 55],
|
|
79
|
+
inverse: [7, 27],
|
|
80
|
+
hidden: [8, 28],
|
|
81
|
+
strikethrough: [9, 29],
|
|
82
|
+
black: [30, 39],
|
|
83
|
+
red: [31, 39],
|
|
84
|
+
green: [32, 39],
|
|
85
|
+
yellow: [33, 39],
|
|
86
|
+
blue: [34, 39],
|
|
87
|
+
magenta: [35, 39],
|
|
88
|
+
cyan: [36, 39],
|
|
89
|
+
white: [37, 39],
|
|
90
|
+
blackBright: [90, 39],
|
|
91
|
+
redBright: [91, 39],
|
|
92
|
+
greenBright: [92, 39],
|
|
93
|
+
yellowBright: [93, 39],
|
|
94
|
+
blueBright: [94, 39],
|
|
95
|
+
magentaBright: [95, 39],
|
|
96
|
+
cyanBright: [96, 39],
|
|
97
|
+
whiteBright: [97, 39],
|
|
98
|
+
bgBlack: [40, 49],
|
|
99
|
+
bgRed: [41, 49],
|
|
100
|
+
bgGreen: [42, 49],
|
|
101
|
+
bgYellow: [43, 49],
|
|
102
|
+
bgBlue: [44, 49],
|
|
103
|
+
bgMagenta: [45, 49],
|
|
104
|
+
bgCyan: [46, 49],
|
|
105
|
+
bgWhite: [47, 49],
|
|
106
|
+
bgBlackBright: [100, 49],
|
|
107
|
+
bgRedBright: [101, 49],
|
|
108
|
+
bgGreenBright: [102, 49],
|
|
109
|
+
bgYellowBright: [103, 49],
|
|
110
|
+
bgBlueBright: [104, 49],
|
|
111
|
+
bgMagentaBright: [105, 49],
|
|
112
|
+
bgCyanBright: [106, 49],
|
|
113
|
+
bgWhiteBright: [107, 49]
|
|
114
|
+
};
|
|
115
|
+
function formatTemplate(settings, template, values, hideUnsetPlaceholder = false) {
|
|
116
|
+
const templateString = String(template);
|
|
117
|
+
const ansiColorWrap = (placeholderValue, code) => `\x1B[${code[0]}m${placeholderValue}\x1B[${code[1]}m`;
|
|
118
|
+
const styleWrap = (value, style) => {
|
|
119
|
+
if (style != null && typeof style === "string") {
|
|
120
|
+
return ansiColorWrap(value, prettyLogStyles[style]);
|
|
121
|
+
} else if (style != null && Array.isArray(style)) {
|
|
122
|
+
return style.reduce((prevValue, thisStyle) => styleWrap(prevValue, thisStyle), value);
|
|
123
|
+
} else {
|
|
124
|
+
if (style != null && style[value.trim()] != null) {
|
|
125
|
+
return styleWrap(value, style[value.trim()]);
|
|
126
|
+
} else if (style != null && style["*"] != null) {
|
|
127
|
+
return styleWrap(value, style["*"]);
|
|
128
|
+
} else {
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const defaultStyle = null;
|
|
134
|
+
return templateString.replace(/{{(.+?)}}/g, (_, placeholder) => {
|
|
135
|
+
const value = values[placeholder] != null ? String(values[placeholder]) : hideUnsetPlaceholder ? "" : _;
|
|
136
|
+
return settings.stylePrettyLogs ? styleWrap(value, settings?.prettyLogStyles?.[placeholder] ?? defaultStyle) + ansiColorWrap("", prettyLogStyles.reset) : value;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function formatNumberAddZeros(value, digits = 2, addNumber = 0) {
|
|
140
|
+
if (value != null && isNaN(value)) {
|
|
141
|
+
return "";
|
|
142
|
+
}
|
|
143
|
+
value = value != null ? value + addNumber : value;
|
|
144
|
+
return digits === 2 ? value == null ? "--" : value < 10 ? "0" + value : value.toString() : value == null ? "---" : value < 10 ? "00" + value : value < 100 ? "0" + value : value.toString();
|
|
145
|
+
}
|
|
146
|
+
function buildPrettyMeta(settings, meta) {
|
|
147
|
+
if (meta == null) {
|
|
148
|
+
return {
|
|
149
|
+
text: "",
|
|
150
|
+
template: settings.prettyLogTemplate,
|
|
151
|
+
placeholders: {}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
let template = settings.prettyLogTemplate;
|
|
155
|
+
const placeholderValues = {};
|
|
156
|
+
if (template.includes("{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}}")) {
|
|
157
|
+
template = template.replace("{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}}", "{{dateIsoStr}}");
|
|
158
|
+
} else {
|
|
159
|
+
if (settings.prettyLogTimeZone === "UTC") {
|
|
160
|
+
placeholderValues["yyyy"] = meta.date?.getUTCFullYear() ?? "----";
|
|
161
|
+
placeholderValues["mm"] = formatNumberAddZeros(meta.date?.getUTCMonth(), 2, 1);
|
|
162
|
+
placeholderValues["dd"] = formatNumberAddZeros(meta.date?.getUTCDate(), 2);
|
|
163
|
+
placeholderValues["hh"] = formatNumberAddZeros(meta.date?.getUTCHours(), 2);
|
|
164
|
+
placeholderValues["MM"] = formatNumberAddZeros(meta.date?.getUTCMinutes(), 2);
|
|
165
|
+
placeholderValues["ss"] = formatNumberAddZeros(meta.date?.getUTCSeconds(), 2);
|
|
166
|
+
placeholderValues["ms"] = formatNumberAddZeros(meta.date?.getUTCMilliseconds(), 3);
|
|
167
|
+
} else {
|
|
168
|
+
placeholderValues["yyyy"] = meta.date?.getFullYear() ?? "----";
|
|
169
|
+
placeholderValues["mm"] = formatNumberAddZeros(meta.date?.getMonth(), 2, 1);
|
|
170
|
+
placeholderValues["dd"] = formatNumberAddZeros(meta.date?.getDate(), 2);
|
|
171
|
+
placeholderValues["hh"] = formatNumberAddZeros(meta.date?.getHours(), 2);
|
|
172
|
+
placeholderValues["MM"] = formatNumberAddZeros(meta.date?.getMinutes(), 2);
|
|
173
|
+
placeholderValues["ss"] = formatNumberAddZeros(meta.date?.getSeconds(), 2);
|
|
174
|
+
placeholderValues["ms"] = formatNumberAddZeros(meta.date?.getMilliseconds(), 3);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const dateInSettingsTimeZone = settings.prettyLogTimeZone === "UTC" ? meta.date : meta.date != null ? new Date(meta.date.getTime() - meta.date.getTimezoneOffset() * 6e4) : void 0;
|
|
178
|
+
placeholderValues["rawIsoStr"] = dateInSettingsTimeZone?.toISOString() ?? "";
|
|
179
|
+
placeholderValues["dateIsoStr"] = dateInSettingsTimeZone?.toISOString().replace("T", " ").replace("Z", "") ?? "";
|
|
180
|
+
placeholderValues["logLevelName"] = meta.logLevelName;
|
|
181
|
+
placeholderValues["fileNameWithLine"] = meta.path?.fileNameWithLine ?? "";
|
|
182
|
+
placeholderValues["filePathWithLine"] = meta.path?.filePathWithLine ?? "";
|
|
183
|
+
placeholderValues["fullFilePath"] = meta.path?.fullFilePath ?? "";
|
|
184
|
+
let parentNamesString = settings.parentNames?.join(settings.prettyErrorParentNamesSeparator);
|
|
185
|
+
parentNamesString = parentNamesString != null && meta.name != null ? parentNamesString + settings.prettyErrorParentNamesSeparator : void 0;
|
|
186
|
+
const combinedName = meta.name != null || parentNamesString != null ? `${parentNamesString ?? ""}${meta.name ?? ""}` : "";
|
|
187
|
+
placeholderValues["name"] = combinedName;
|
|
188
|
+
placeholderValues["nameWithDelimiterPrefix"] = combinedName.length > 0 ? settings.prettyErrorLoggerNameDelimiter + combinedName : "";
|
|
189
|
+
placeholderValues["nameWithDelimiterSuffix"] = combinedName.length > 0 ? combinedName + settings.prettyErrorLoggerNameDelimiter : "";
|
|
190
|
+
if (settings.overwrite?.addPlaceholders != null) {
|
|
191
|
+
settings.overwrite.addPlaceholders(meta, placeholderValues);
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
text: formatTemplate(settings, template, placeholderValues),
|
|
195
|
+
template,
|
|
196
|
+
placeholders: placeholderValues
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
var DEFAULT_IGNORE_PATTERNS = [
|
|
200
|
+
/(?:^|[\\/])node_modules[\\/].*tslog/i,
|
|
201
|
+
/(?:^|[\\/])deps[\\/].*tslog/i,
|
|
202
|
+
/tslog[\\/]+src[\\/]+internal[\\/]/i,
|
|
203
|
+
/tslog[\\/]+src[\\/]BaseLogger/i,
|
|
204
|
+
/tslog[\\/]+src[\\/]index/i
|
|
205
|
+
];
|
|
206
|
+
function splitStackLines(error) {
|
|
207
|
+
const stack = typeof error?.stack === "string" ? error.stack : void 0;
|
|
208
|
+
if (stack == null || stack.length === 0) {
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
return stack.split("\n").map((line) => line.trimEnd());
|
|
212
|
+
}
|
|
213
|
+
function sanitizeStackLines(lines) {
|
|
214
|
+
return lines.filter((line) => line.length > 0 && !/^\s*Error\b/.test(line));
|
|
215
|
+
}
|
|
216
|
+
function toStackFrames(lines, parseLine) {
|
|
217
|
+
const frames = [];
|
|
218
|
+
for (const line of lines) {
|
|
219
|
+
const frame = parseLine(line);
|
|
220
|
+
if (frame != null) {
|
|
221
|
+
frames.push(frame);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return frames;
|
|
225
|
+
}
|
|
226
|
+
function findFirstExternalFrameIndex(frames, ignorePatterns = DEFAULT_IGNORE_PATTERNS) {
|
|
227
|
+
for (let index = 0; index < frames.length; index += 1) {
|
|
228
|
+
const frame = frames[index];
|
|
229
|
+
const filePathCandidate = frame.filePath ?? "";
|
|
230
|
+
const fullPathCandidate = frame.fullFilePath ?? "";
|
|
231
|
+
if (!ignorePatterns.some((pattern) => pattern.test(filePathCandidate) || pattern.test(fullPathCandidate))) {
|
|
232
|
+
return index;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return 0;
|
|
236
|
+
}
|
|
237
|
+
function getCleanStackLines(error) {
|
|
238
|
+
return sanitizeStackLines(splitStackLines(error));
|
|
239
|
+
}
|
|
240
|
+
function buildStackTrace(error, parseLine) {
|
|
241
|
+
return toStackFrames(getCleanStackLines(error), parseLine);
|
|
242
|
+
}
|
|
243
|
+
function clampIndex(index, maxExclusive) {
|
|
244
|
+
if (index < 0) {
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
247
|
+
if (index >= maxExclusive) {
|
|
248
|
+
return Math.max(0, maxExclusive - 1);
|
|
249
|
+
}
|
|
250
|
+
return index;
|
|
251
|
+
}
|
|
252
|
+
function getDefaultIgnorePatterns() {
|
|
253
|
+
return [...DEFAULT_IGNORE_PATTERNS];
|
|
254
|
+
}
|
|
255
|
+
var DEFAULT_CAUSE_DEPTH = 5;
|
|
256
|
+
function collectErrorCauses(error, options = {}) {
|
|
257
|
+
const maxDepth = options.maxDepth ?? DEFAULT_CAUSE_DEPTH;
|
|
258
|
+
const causes = [];
|
|
259
|
+
const visited = /* @__PURE__ */ new Set();
|
|
260
|
+
let current = error;
|
|
261
|
+
let depth = 0;
|
|
262
|
+
while (current != null && depth < maxDepth) {
|
|
263
|
+
const cause = current?.cause;
|
|
264
|
+
if (cause == null || visited.has(cause)) {
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
visited.add(cause);
|
|
268
|
+
causes.push(toError(cause));
|
|
269
|
+
current = cause;
|
|
270
|
+
depth += 1;
|
|
271
|
+
}
|
|
272
|
+
return causes;
|
|
273
|
+
}
|
|
274
|
+
function toError(value) {
|
|
275
|
+
if (value instanceof Error) {
|
|
276
|
+
return value;
|
|
277
|
+
}
|
|
278
|
+
const error = new Error(typeof value === "string" ? value : JSON.stringify(value));
|
|
279
|
+
if (typeof value === "object" && value != null) {
|
|
280
|
+
Object.assign(error, value);
|
|
281
|
+
}
|
|
282
|
+
return error;
|
|
283
|
+
}
|
|
284
|
+
function jsonStringifyRecursive(obj) {
|
|
285
|
+
const cache = /* @__PURE__ */ new Set();
|
|
286
|
+
return JSON.stringify(obj, (key, value) => {
|
|
287
|
+
if (typeof value === "object" && value !== null) {
|
|
288
|
+
if (cache.has(value)) {
|
|
289
|
+
return "[Circular]";
|
|
290
|
+
}
|
|
291
|
+
cache.add(value);
|
|
292
|
+
}
|
|
293
|
+
if (typeof value === "bigint") {
|
|
294
|
+
return `${value}`;
|
|
295
|
+
}
|
|
296
|
+
if (typeof value === "undefined") {
|
|
297
|
+
return "[undefined]";
|
|
298
|
+
}
|
|
299
|
+
return value;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
function inspect(obj, opts) {
|
|
303
|
+
const ctx = {
|
|
304
|
+
seen: [],
|
|
305
|
+
stylize: stylizeNoColor
|
|
306
|
+
};
|
|
307
|
+
if (opts != null) {
|
|
308
|
+
_extend(ctx, opts);
|
|
309
|
+
}
|
|
310
|
+
if (isUndefined(ctx.showHidden))
|
|
311
|
+
ctx.showHidden = false;
|
|
312
|
+
if (isUndefined(ctx.depth))
|
|
313
|
+
ctx.depth = 2;
|
|
314
|
+
if (isUndefined(ctx.colors))
|
|
315
|
+
ctx.colors = true;
|
|
316
|
+
if (isUndefined(ctx.customInspect))
|
|
317
|
+
ctx.customInspect = true;
|
|
318
|
+
if (ctx.colors)
|
|
319
|
+
ctx.stylize = stylizeWithColor;
|
|
320
|
+
return formatValue(ctx, obj, ctx.depth);
|
|
321
|
+
}
|
|
322
|
+
inspect.colors = prettyLogStyles;
|
|
323
|
+
inspect.styles = {
|
|
324
|
+
special: "cyan",
|
|
325
|
+
number: "yellow",
|
|
326
|
+
boolean: "yellow",
|
|
327
|
+
undefined: "grey",
|
|
328
|
+
null: "bold",
|
|
329
|
+
string: "green",
|
|
330
|
+
date: "magenta",
|
|
331
|
+
regexp: "red"
|
|
332
|
+
};
|
|
333
|
+
function isBoolean(arg) {
|
|
334
|
+
return typeof arg === "boolean";
|
|
335
|
+
}
|
|
336
|
+
function isUndefined(arg) {
|
|
337
|
+
return arg === void 0;
|
|
338
|
+
}
|
|
339
|
+
function stylizeNoColor(str) {
|
|
340
|
+
return str;
|
|
341
|
+
}
|
|
342
|
+
function stylizeWithColor(str, styleType) {
|
|
343
|
+
const style = inspect.styles[styleType];
|
|
344
|
+
if (style != null && inspect?.colors?.[style]?.[0] != null && inspect?.colors?.[style]?.[1] != null) {
|
|
345
|
+
return "\x1B[" + inspect.colors[style][0] + "m" + str + "\x1B[" + inspect.colors[style][1] + "m";
|
|
346
|
+
} else {
|
|
347
|
+
return str;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function isFunction(arg) {
|
|
351
|
+
return typeof arg === "function";
|
|
352
|
+
}
|
|
353
|
+
function isString(arg) {
|
|
354
|
+
return typeof arg === "string";
|
|
355
|
+
}
|
|
356
|
+
function isNumber(arg) {
|
|
357
|
+
return typeof arg === "number";
|
|
358
|
+
}
|
|
359
|
+
function isNull(arg) {
|
|
360
|
+
return arg === null;
|
|
361
|
+
}
|
|
362
|
+
function hasOwn(obj, prop) {
|
|
363
|
+
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
364
|
+
}
|
|
365
|
+
function isRegExp(re) {
|
|
366
|
+
return isObject(re) && objectToString(re) === "[object RegExp]";
|
|
367
|
+
}
|
|
368
|
+
function isObject(arg) {
|
|
369
|
+
return typeof arg === "object" && arg !== null;
|
|
370
|
+
}
|
|
371
|
+
function isError(e) {
|
|
372
|
+
return isObject(e) && (objectToString(e) === "[object Error]" || e instanceof Error);
|
|
373
|
+
}
|
|
374
|
+
function isDate(d) {
|
|
375
|
+
return isObject(d) && objectToString(d) === "[object Date]";
|
|
376
|
+
}
|
|
377
|
+
function objectToString(o) {
|
|
378
|
+
return Object.prototype.toString.call(o);
|
|
379
|
+
}
|
|
380
|
+
function arrayToHash(array) {
|
|
381
|
+
const hash = {};
|
|
382
|
+
array.forEach((val) => {
|
|
383
|
+
hash[val] = true;
|
|
384
|
+
});
|
|
385
|
+
return hash;
|
|
386
|
+
}
|
|
387
|
+
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
|
388
|
+
const output = [];
|
|
389
|
+
for (let i = 0, l = value.length; i < l; ++i) {
|
|
390
|
+
if (hasOwn(value, String(i))) {
|
|
391
|
+
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true));
|
|
392
|
+
} else {
|
|
393
|
+
output.push("");
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
keys.forEach((key) => {
|
|
397
|
+
if (!key.match(/^\d+$/)) {
|
|
398
|
+
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true));
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
return output;
|
|
402
|
+
}
|
|
403
|
+
function formatError(value) {
|
|
404
|
+
return "[" + Error.prototype.toString.call(value) + "]";
|
|
405
|
+
}
|
|
406
|
+
function formatValue(ctx, value, recurseTimes = 0) {
|
|
407
|
+
if (ctx.customInspect && value != null && isFunction(value) && value?.inspect !== inspect && !(value?.constructor && value?.constructor.prototype === value)) {
|
|
408
|
+
if (typeof value.inspect !== "function" && value.toString != null) {
|
|
409
|
+
return value.toString();
|
|
410
|
+
}
|
|
411
|
+
let ret = value?.inspect(recurseTimes, ctx);
|
|
412
|
+
if (!isString(ret)) {
|
|
413
|
+
ret = formatValue(ctx, ret, recurseTimes);
|
|
414
|
+
}
|
|
415
|
+
return ret;
|
|
416
|
+
}
|
|
417
|
+
const primitive = formatPrimitive(ctx, value);
|
|
418
|
+
if (primitive) {
|
|
419
|
+
return primitive;
|
|
420
|
+
}
|
|
421
|
+
let keys = Object.keys(value);
|
|
422
|
+
const visibleKeys = arrayToHash(keys);
|
|
423
|
+
try {
|
|
424
|
+
if (ctx.showHidden && Object.getOwnPropertyNames) {
|
|
425
|
+
keys = Object.getOwnPropertyNames(value);
|
|
426
|
+
}
|
|
427
|
+
} catch {
|
|
428
|
+
}
|
|
429
|
+
if (isError(value) && (keys.indexOf("message") >= 0 || keys.indexOf("description") >= 0)) {
|
|
430
|
+
return formatError(value);
|
|
431
|
+
}
|
|
432
|
+
if (keys.length === 0) {
|
|
433
|
+
if (isFunction(ctx.stylize)) {
|
|
434
|
+
if (isFunction(value)) {
|
|
435
|
+
const name = value.name ? ": " + value.name : "";
|
|
436
|
+
return ctx.stylize("[Function" + name + "]", "special");
|
|
437
|
+
}
|
|
438
|
+
if (isRegExp(value)) {
|
|
439
|
+
return ctx.stylize(RegExp.prototype.toString.call(value), "regexp");
|
|
440
|
+
}
|
|
441
|
+
if (isDate(value)) {
|
|
442
|
+
return ctx.stylize(Date.prototype.toISOString.call(value), "date");
|
|
443
|
+
}
|
|
444
|
+
if (isError(value)) {
|
|
445
|
+
return formatError(value);
|
|
446
|
+
}
|
|
447
|
+
} else {
|
|
448
|
+
return value;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
let base = "";
|
|
452
|
+
let array = false;
|
|
453
|
+
let braces = ["{\n", "\n}"];
|
|
454
|
+
if (Array.isArray(value)) {
|
|
455
|
+
array = true;
|
|
456
|
+
braces = ["[\n", "\n]"];
|
|
457
|
+
}
|
|
458
|
+
if (isFunction(value)) {
|
|
459
|
+
const n = value.name ? ": " + value.name : "";
|
|
460
|
+
base = " [Function" + n + "]";
|
|
461
|
+
}
|
|
462
|
+
if (isRegExp(value)) {
|
|
463
|
+
base = " " + RegExp.prototype.toString.call(value);
|
|
464
|
+
}
|
|
465
|
+
if (isDate(value)) {
|
|
466
|
+
base = " " + Date.prototype.toUTCString.call(value);
|
|
467
|
+
}
|
|
468
|
+
if (isError(value)) {
|
|
469
|
+
base = " " + formatError(value);
|
|
470
|
+
}
|
|
471
|
+
if (keys.length === 0 && (!array || value.length == 0)) {
|
|
472
|
+
return braces[0] + base + braces[1];
|
|
473
|
+
}
|
|
474
|
+
if (recurseTimes < 0) {
|
|
475
|
+
if (isRegExp(value)) {
|
|
476
|
+
return ctx.stylize(RegExp.prototype.toString.call(value), "regexp");
|
|
477
|
+
} else {
|
|
478
|
+
return ctx.stylize("[Object]", "special");
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
ctx.seen.push(value);
|
|
482
|
+
let output;
|
|
483
|
+
if (array) {
|
|
484
|
+
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
|
485
|
+
} else {
|
|
486
|
+
output = keys.map((key) => {
|
|
487
|
+
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
ctx.seen.pop();
|
|
491
|
+
return reduceToSingleString(output, base, braces);
|
|
492
|
+
}
|
|
493
|
+
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
|
|
494
|
+
let name, str;
|
|
495
|
+
let desc = { value: void 0 };
|
|
496
|
+
try {
|
|
497
|
+
desc.value = value[key];
|
|
498
|
+
} catch {
|
|
499
|
+
}
|
|
500
|
+
try {
|
|
501
|
+
if (Object.getOwnPropertyDescriptor) {
|
|
502
|
+
desc = Object.getOwnPropertyDescriptor(value, key) || desc;
|
|
503
|
+
}
|
|
504
|
+
} catch {
|
|
505
|
+
}
|
|
506
|
+
if (desc.get) {
|
|
507
|
+
if (desc.set) {
|
|
508
|
+
str = ctx.stylize("[Getter/Setter]", "special");
|
|
509
|
+
} else {
|
|
510
|
+
str = ctx.stylize("[Getter]", "special");
|
|
511
|
+
}
|
|
512
|
+
} else {
|
|
513
|
+
if (desc.set) {
|
|
514
|
+
str = ctx.stylize("[Setter]", "special");
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (!hasOwn(visibleKeys, key)) {
|
|
518
|
+
name = "[" + key + "]";
|
|
519
|
+
}
|
|
520
|
+
if (!str) {
|
|
521
|
+
if (ctx.seen.indexOf(desc.value) < 0) {
|
|
522
|
+
if (isNull(recurseTimes)) {
|
|
523
|
+
str = formatValue(ctx, desc.value, void 0);
|
|
524
|
+
} else {
|
|
525
|
+
str = formatValue(ctx, desc.value, recurseTimes - 1);
|
|
526
|
+
}
|
|
527
|
+
if (str.indexOf("\n") > -1) {
|
|
528
|
+
if (array) {
|
|
529
|
+
str = str.split("\n").map((line) => {
|
|
530
|
+
return " " + line;
|
|
531
|
+
}).join("\n").substr(2);
|
|
532
|
+
} else {
|
|
533
|
+
str = "\n" + str.split("\n").map((line) => {
|
|
534
|
+
return " " + line;
|
|
535
|
+
}).join("\n");
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
} else {
|
|
539
|
+
str = ctx.stylize("[Circular]", "special");
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
if (isUndefined(name)) {
|
|
543
|
+
if (array && key.match(/^\d+$/)) {
|
|
544
|
+
return str;
|
|
545
|
+
}
|
|
546
|
+
name = JSON.stringify("" + key);
|
|
547
|
+
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
|
548
|
+
name = name.substr(1, name.length - 2);
|
|
549
|
+
name = ctx.stylize(name, "name");
|
|
550
|
+
} else {
|
|
551
|
+
name = name.replace(/'/g, "\\'").replace(/\\"/g, "\\'").replace(/(^"|"$)/g, "'");
|
|
552
|
+
name = ctx.stylize(name, "string");
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return name + ": " + str;
|
|
556
|
+
}
|
|
557
|
+
function formatPrimitive(ctx, value) {
|
|
558
|
+
if (isUndefined(value))
|
|
559
|
+
return ctx.stylize("undefined", "undefined");
|
|
560
|
+
if (isString(value)) {
|
|
561
|
+
const simple = "'" + JSON.stringify(value).replace(/^"|"$/g, "").replace(/'/g, "\\'").replace(/\\"/g, "\\'") + "'";
|
|
562
|
+
return ctx.stylize(simple, "string");
|
|
563
|
+
}
|
|
564
|
+
if (isNumber(value))
|
|
565
|
+
return ctx.stylize("" + value, "number");
|
|
566
|
+
if (isBoolean(value))
|
|
567
|
+
return ctx.stylize("" + value, "boolean");
|
|
568
|
+
if (isNull(value))
|
|
569
|
+
return ctx.stylize("null", "null");
|
|
570
|
+
}
|
|
571
|
+
function reduceToSingleString(output, base, braces) {
|
|
572
|
+
return braces[0] + (base === "" ? "" : base + "\n") + " " + output.join(",\n ") + " " + braces[1];
|
|
573
|
+
}
|
|
574
|
+
function _extend(origin, add) {
|
|
575
|
+
const typedOrigin = { ...origin };
|
|
576
|
+
if (!add || !isObject(add))
|
|
577
|
+
return origin;
|
|
578
|
+
const clonedAdd = { ...add };
|
|
579
|
+
const keys = Object.keys(add);
|
|
580
|
+
let i = keys.length;
|
|
581
|
+
while (i--) {
|
|
582
|
+
typedOrigin[keys[i]] = clonedAdd[keys[i]];
|
|
583
|
+
}
|
|
584
|
+
return typedOrigin;
|
|
585
|
+
}
|
|
586
|
+
function formatWithOptions(inspectOptions, ...args) {
|
|
587
|
+
const ctx = {
|
|
588
|
+
seen: [],
|
|
589
|
+
stylize: stylizeNoColor
|
|
590
|
+
};
|
|
591
|
+
if (inspectOptions != null) {
|
|
592
|
+
_extend(ctx, inspectOptions);
|
|
593
|
+
}
|
|
594
|
+
const first = args[0];
|
|
595
|
+
let a = 0;
|
|
596
|
+
let str = "";
|
|
597
|
+
let join = "";
|
|
598
|
+
if (typeof first === "string") {
|
|
599
|
+
if (args.length === 1) {
|
|
600
|
+
return first;
|
|
601
|
+
}
|
|
602
|
+
let tempStr;
|
|
603
|
+
let lastPos = 0;
|
|
604
|
+
for (let i = 0; i < first.length - 1; i++) {
|
|
605
|
+
if (first.charCodeAt(i) === 37) {
|
|
606
|
+
const nextChar = first.charCodeAt(++i);
|
|
607
|
+
if (a + 1 !== args.length) {
|
|
608
|
+
switch (nextChar) {
|
|
609
|
+
case 115: {
|
|
610
|
+
const tempArg = args[++a];
|
|
611
|
+
if (typeof tempArg === "number") {
|
|
612
|
+
tempStr = formatPrimitive(ctx, tempArg);
|
|
613
|
+
} else if (typeof tempArg === "bigint") {
|
|
614
|
+
tempStr = formatPrimitive(ctx, tempArg);
|
|
615
|
+
} else if (typeof tempArg !== "object" || tempArg === null) {
|
|
616
|
+
tempStr = String(tempArg);
|
|
617
|
+
} else {
|
|
618
|
+
tempStr = inspect(tempArg, {
|
|
619
|
+
...inspectOptions,
|
|
620
|
+
compact: 3,
|
|
621
|
+
colors: false,
|
|
622
|
+
depth: 0
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
break;
|
|
626
|
+
}
|
|
627
|
+
case 106:
|
|
628
|
+
tempStr = jsonStringifyRecursive(args[++a]);
|
|
629
|
+
break;
|
|
630
|
+
case 100: {
|
|
631
|
+
const tempNum = args[++a];
|
|
632
|
+
if (typeof tempNum === "bigint") {
|
|
633
|
+
tempStr = formatPrimitive(ctx, tempNum);
|
|
634
|
+
} else if (typeof tempNum === "symbol") {
|
|
635
|
+
tempStr = "NaN";
|
|
636
|
+
} else {
|
|
637
|
+
tempStr = formatPrimitive(ctx, tempNum);
|
|
638
|
+
}
|
|
639
|
+
break;
|
|
640
|
+
}
|
|
641
|
+
case 79:
|
|
642
|
+
tempStr = inspect(args[++a], inspectOptions);
|
|
643
|
+
break;
|
|
644
|
+
case 111:
|
|
645
|
+
tempStr = inspect(args[++a], {
|
|
646
|
+
...inspectOptions,
|
|
647
|
+
showHidden: true,
|
|
648
|
+
showProxy: true,
|
|
649
|
+
depth: 4
|
|
650
|
+
});
|
|
651
|
+
break;
|
|
652
|
+
case 105: {
|
|
653
|
+
const tempInteger = args[++a];
|
|
654
|
+
if (typeof tempInteger === "bigint") {
|
|
655
|
+
tempStr = formatPrimitive(ctx, tempInteger);
|
|
656
|
+
} else if (typeof tempInteger === "symbol") {
|
|
657
|
+
tempStr = "NaN";
|
|
658
|
+
} else {
|
|
659
|
+
tempStr = formatPrimitive(ctx, parseInt(tempStr));
|
|
660
|
+
}
|
|
661
|
+
break;
|
|
662
|
+
}
|
|
663
|
+
case 102: {
|
|
664
|
+
const tempFloat = args[++a];
|
|
665
|
+
if (typeof tempFloat === "symbol") {
|
|
666
|
+
tempStr = "NaN";
|
|
667
|
+
} else {
|
|
668
|
+
tempStr = formatPrimitive(ctx, parseInt(tempFloat));
|
|
669
|
+
}
|
|
670
|
+
break;
|
|
671
|
+
}
|
|
672
|
+
case 99:
|
|
673
|
+
a += 1;
|
|
674
|
+
tempStr = "";
|
|
675
|
+
break;
|
|
676
|
+
case 37:
|
|
677
|
+
str += first.slice(lastPos, i);
|
|
678
|
+
lastPos = i + 1;
|
|
679
|
+
continue;
|
|
680
|
+
default:
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
if (lastPos !== i - 1) {
|
|
684
|
+
str += first.slice(lastPos, i - 1);
|
|
685
|
+
}
|
|
686
|
+
str += tempStr;
|
|
687
|
+
lastPos = i + 1;
|
|
688
|
+
} else if (nextChar === 37) {
|
|
689
|
+
str += first.slice(lastPos, i);
|
|
690
|
+
lastPos = i + 1;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
if (lastPos !== 0) {
|
|
695
|
+
a++;
|
|
696
|
+
join = " ";
|
|
697
|
+
if (lastPos < first.length) {
|
|
698
|
+
str += first.slice(lastPos);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
while (a < args.length) {
|
|
703
|
+
const value = args[a];
|
|
704
|
+
str += join;
|
|
705
|
+
str += typeof value !== "string" ? inspect(value, inspectOptions) : value;
|
|
706
|
+
join = " ";
|
|
707
|
+
a++;
|
|
708
|
+
}
|
|
709
|
+
return str;
|
|
710
|
+
}
|
|
711
|
+
function safeGetCwd() {
|
|
712
|
+
try {
|
|
713
|
+
const nodeProcess = globalThis?.process;
|
|
714
|
+
if (typeof nodeProcess?.cwd === "function") {
|
|
715
|
+
return nodeProcess.cwd();
|
|
716
|
+
}
|
|
717
|
+
} catch {
|
|
718
|
+
}
|
|
719
|
+
try {
|
|
720
|
+
const deno = globalThis?.["Deno"];
|
|
721
|
+
if (typeof deno?.cwd === "function") {
|
|
722
|
+
return deno.cwd();
|
|
723
|
+
}
|
|
724
|
+
} catch {
|
|
725
|
+
}
|
|
726
|
+
return void 0;
|
|
727
|
+
}
|
|
728
|
+
function isBrowserEnvironment() {
|
|
729
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
730
|
+
}
|
|
731
|
+
function consoleSupportsCssStyling() {
|
|
732
|
+
if (!isBrowserEnvironment()) {
|
|
733
|
+
return false;
|
|
734
|
+
}
|
|
735
|
+
const navigatorObj = globalThis?.navigator;
|
|
736
|
+
const userAgent = navigatorObj?.userAgent ?? "";
|
|
737
|
+
if (/firefox/i.test(userAgent)) {
|
|
738
|
+
return true;
|
|
739
|
+
}
|
|
740
|
+
const windowObj = globalThis;
|
|
741
|
+
if (windowObj?.CSS?.supports?.("color", "#000")) {
|
|
742
|
+
return true;
|
|
743
|
+
}
|
|
744
|
+
return /safari/i.test(userAgent) && !/chrome/i.test(userAgent);
|
|
745
|
+
}
|
|
746
|
+
function createLoggerEnvironment() {
|
|
747
|
+
const runtimeInfo = detectRuntimeInfo();
|
|
748
|
+
const meta = createRuntimeMeta(runtimeInfo);
|
|
749
|
+
const usesBrowserStack = runtimeInfo.name === "browser" || runtimeInfo.name === "worker";
|
|
750
|
+
const callerIgnorePatterns = usesBrowserStack ? [...getDefaultIgnorePatterns(), /node_modules[\\/].*tslog/i] : [...getDefaultIgnorePatterns(), /node:(?:internal|vm)/i, /\binternal[\\/]/i];
|
|
751
|
+
let cachedCwd;
|
|
752
|
+
const environment = {
|
|
753
|
+
getMeta(logLevelId, logLevelName, stackDepthLevel, hideLogPositionForPerformance, name, parentNames) {
|
|
754
|
+
return Object.assign({}, meta, {
|
|
755
|
+
name,
|
|
756
|
+
parentNames,
|
|
757
|
+
date: /* @__PURE__ */ new Date(),
|
|
758
|
+
logLevelId,
|
|
759
|
+
logLevelName,
|
|
760
|
+
path: !hideLogPositionForPerformance ? environment.getCallerStackFrame(stackDepthLevel) : void 0
|
|
761
|
+
});
|
|
762
|
+
},
|
|
763
|
+
getCallerStackFrame(stackDepthLevel, error = new Error()) {
|
|
764
|
+
const frames = buildStackTrace(error, (line) => parseStackLine(line));
|
|
765
|
+
if (frames.length === 0) {
|
|
766
|
+
return {};
|
|
767
|
+
}
|
|
768
|
+
const autoIndex = findFirstExternalFrameIndex(frames, callerIgnorePatterns);
|
|
769
|
+
const useManualIndex = Number.isFinite(stackDepthLevel) && stackDepthLevel >= 0;
|
|
770
|
+
const resolvedIndex = useManualIndex ? clampIndex(stackDepthLevel, frames.length) : clampIndex(autoIndex, frames.length);
|
|
771
|
+
return frames[resolvedIndex] ?? {};
|
|
772
|
+
},
|
|
773
|
+
getErrorTrace(error) {
|
|
774
|
+
return buildStackTrace(error, (line) => parseStackLine(line));
|
|
775
|
+
},
|
|
776
|
+
isError(value) {
|
|
777
|
+
return isNativeError(value);
|
|
778
|
+
},
|
|
779
|
+
isBuffer(value) {
|
|
780
|
+
return typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" ? Buffer.isBuffer(value) : false;
|
|
781
|
+
},
|
|
782
|
+
prettyFormatLogObj(maskedArgs, settings) {
|
|
783
|
+
return maskedArgs.reduce((result, arg) => {
|
|
784
|
+
if (environment.isError(arg)) {
|
|
785
|
+
result.errors.push(environment.prettyFormatErrorObj(arg, settings));
|
|
786
|
+
} else {
|
|
787
|
+
result.args.push(arg);
|
|
788
|
+
}
|
|
789
|
+
return result;
|
|
790
|
+
}, { args: [], errors: [] });
|
|
791
|
+
},
|
|
792
|
+
prettyFormatErrorObj(error, settings) {
|
|
793
|
+
const stackLines = formatStackFrames(environment.getErrorTrace(error), settings);
|
|
794
|
+
const causeSections = collectErrorCauses(error).map((cause, index) => {
|
|
795
|
+
const header = `Caused by (${index + 1}): ${cause.name ?? "Error"}${cause.message ? `: ${cause.message}` : ""}`;
|
|
796
|
+
const frames = formatStackFrames(buildStackTrace(cause, (line) => parseStackLine(line)), settings);
|
|
797
|
+
return [header, ...frames].join("\n");
|
|
798
|
+
});
|
|
799
|
+
const placeholderValuesError = {
|
|
800
|
+
errorName: ` ${error.name} `,
|
|
801
|
+
errorMessage: formatErrorMessage(error),
|
|
802
|
+
errorStack: [...stackLines, ...causeSections].join("\n")
|
|
803
|
+
};
|
|
804
|
+
return formatTemplate(settings, settings.prettyErrorTemplate, placeholderValuesError);
|
|
805
|
+
},
|
|
806
|
+
transportFormatted(logMetaMarkup, logArgs, logErrors, logMeta, settings) {
|
|
807
|
+
const prettyLogs = settings.stylePrettyLogs !== false;
|
|
808
|
+
const logErrorsStr = (logErrors.length > 0 && logArgs.length > 0 ? "\n" : "") + logErrors.join("\n");
|
|
809
|
+
const sanitizedMetaMarkup = stripAnsi(logMetaMarkup);
|
|
810
|
+
const metaMarkupForText = prettyLogs ? logMetaMarkup : sanitizedMetaMarkup;
|
|
811
|
+
if (shouldUseCss(prettyLogs)) {
|
|
812
|
+
settings.prettyInspectOptions.colors = false;
|
|
813
|
+
const formattedArgs2 = formatWithOptionsSafe(settings.prettyInspectOptions, logArgs);
|
|
814
|
+
const cssMeta = logMeta != null ? buildCssMetaOutput(settings, logMeta) : { text: sanitizedMetaMarkup, styles: [] };
|
|
815
|
+
const hasCssMeta = cssMeta.text.length > 0 && cssMeta.styles.length > 0;
|
|
816
|
+
const metaOutput = hasCssMeta ? cssMeta.text : sanitizedMetaMarkup;
|
|
817
|
+
const output = metaOutput + formattedArgs2 + logErrorsStr;
|
|
818
|
+
if (hasCssMeta) {
|
|
819
|
+
console.log(output, ...cssMeta.styles);
|
|
820
|
+
} else {
|
|
821
|
+
console.log(output);
|
|
822
|
+
}
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
settings.prettyInspectOptions.colors = prettyLogs;
|
|
826
|
+
const formattedArgs = formatWithOptionsSafe(settings.prettyInspectOptions, logArgs);
|
|
827
|
+
console.log(metaMarkupForText + formattedArgs + logErrorsStr);
|
|
828
|
+
},
|
|
829
|
+
transportJSON(json) {
|
|
830
|
+
console.log(jsonStringifyRecursive(json));
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
if (getNodeEnv() === "test") {
|
|
834
|
+
environment.__resetWorkingDirectoryCacheForTests = () => {
|
|
835
|
+
cachedCwd = void 0;
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
return environment;
|
|
839
|
+
function parseStackLine(line) {
|
|
840
|
+
return usesBrowserStack ? parseBrowserStackLine(line) : parseServerStackLine(line);
|
|
841
|
+
}
|
|
842
|
+
function parseServerStackLine(rawLine) {
|
|
843
|
+
if (typeof rawLine !== "string" || rawLine.length === 0) {
|
|
844
|
+
return void 0;
|
|
845
|
+
}
|
|
846
|
+
const trimmedLine = rawLine.trim();
|
|
847
|
+
if (!trimmedLine.includes(" at ") && !trimmedLine.startsWith("at ")) {
|
|
848
|
+
return void 0;
|
|
849
|
+
}
|
|
850
|
+
const line = trimmedLine.replace(/^at\s+/, "");
|
|
851
|
+
let method;
|
|
852
|
+
let location = line;
|
|
853
|
+
const methodMatch = line.match(/^(.*?)\s+\((.*)\)$/);
|
|
854
|
+
if (methodMatch) {
|
|
855
|
+
method = methodMatch[1];
|
|
856
|
+
location = methodMatch[2];
|
|
857
|
+
}
|
|
858
|
+
const sanitizedLocation = location.replace(/^\(/, "").replace(/\)$/, "");
|
|
859
|
+
const withoutQuery = sanitizedLocation.replace(/\?.*$/, "");
|
|
860
|
+
let fileLine;
|
|
861
|
+
let fileColumn;
|
|
862
|
+
let filePathCandidate = withoutQuery;
|
|
863
|
+
const segments = withoutQuery.split(":");
|
|
864
|
+
if (segments.length >= 3 && /^\d+$/.test(segments[segments.length - 1] ?? "")) {
|
|
865
|
+
fileColumn = segments.pop();
|
|
866
|
+
fileLine = segments.pop();
|
|
867
|
+
filePathCandidate = segments.join(":");
|
|
868
|
+
} else if (segments.length >= 2 && /^\d+$/.test(segments[segments.length - 1] ?? "")) {
|
|
869
|
+
fileLine = segments.pop();
|
|
870
|
+
filePathCandidate = segments.join(":");
|
|
871
|
+
}
|
|
872
|
+
let normalizedPath = filePathCandidate.replace(/^file:\/\//, "");
|
|
873
|
+
const cwd = getWorkingDirectory();
|
|
874
|
+
if (cwd != null && normalizedPath.startsWith(cwd)) {
|
|
875
|
+
normalizedPath = normalizedPath.slice(cwd.length);
|
|
876
|
+
normalizedPath = normalizedPath.replace(/^[\\/]/, "");
|
|
877
|
+
}
|
|
878
|
+
if (normalizedPath.length === 0) {
|
|
879
|
+
normalizedPath = filePathCandidate;
|
|
880
|
+
}
|
|
881
|
+
const normalizedPathWithoutLine = normalizeFilePath(normalizedPath);
|
|
882
|
+
const effectivePath = normalizedPathWithoutLine.length > 0 ? normalizedPathWithoutLine : normalizedPath;
|
|
883
|
+
const pathSegments = effectivePath.split(/\\|\//);
|
|
884
|
+
const fileName = pathSegments[pathSegments.length - 1];
|
|
885
|
+
const fileNameWithLine = fileName && fileLine ? `${fileName}:${fileLine}` : void 0;
|
|
886
|
+
const filePathWithLine = effectivePath && fileLine ? `${effectivePath}:${fileLine}` : void 0;
|
|
887
|
+
return {
|
|
888
|
+
fullFilePath: sanitizedLocation,
|
|
889
|
+
fileName,
|
|
890
|
+
fileNameWithLine,
|
|
891
|
+
fileColumn,
|
|
892
|
+
fileLine,
|
|
893
|
+
filePath: effectivePath,
|
|
894
|
+
filePathWithLine,
|
|
895
|
+
method
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
function parseBrowserStackLine(line) {
|
|
899
|
+
const href = globalThis.location?.origin;
|
|
900
|
+
if (line == null) {
|
|
901
|
+
return void 0;
|
|
902
|
+
}
|
|
903
|
+
const match = line.match(BROWSER_PATH_REGEX);
|
|
904
|
+
if (!match) {
|
|
905
|
+
return void 0;
|
|
906
|
+
}
|
|
907
|
+
const filePath = match[1]?.replace(/\?.*$/, "");
|
|
908
|
+
if (filePath == null) {
|
|
909
|
+
return void 0;
|
|
910
|
+
}
|
|
911
|
+
const pathParts = filePath.split("/");
|
|
912
|
+
const fileLine = match[2];
|
|
913
|
+
const fileColumn = match[3];
|
|
914
|
+
const fileName = pathParts[pathParts.length - 1];
|
|
915
|
+
return {
|
|
916
|
+
fullFilePath: href ? `${href}${filePath}` : filePath,
|
|
917
|
+
fileName,
|
|
918
|
+
fileNameWithLine: fileName && fileLine ? `${fileName}:${fileLine}` : void 0,
|
|
919
|
+
fileColumn,
|
|
920
|
+
fileLine,
|
|
921
|
+
filePath,
|
|
922
|
+
filePathWithLine: fileLine ? `${filePath}:${fileLine}` : void 0,
|
|
923
|
+
method: void 0
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
function formatStackFrames(frames, settings) {
|
|
927
|
+
return frames.map((stackFrame) => formatTemplate(settings, settings.prettyErrorStackTemplate, { ...stackFrame }, true));
|
|
928
|
+
}
|
|
929
|
+
function formatErrorMessage(error) {
|
|
930
|
+
return Object.getOwnPropertyNames(error).filter((key) => key !== "stack" && key !== "cause").reduce((result, key) => {
|
|
931
|
+
const value = error[key];
|
|
932
|
+
if (typeof value === "function") {
|
|
933
|
+
return result;
|
|
934
|
+
}
|
|
935
|
+
result.push(String(value));
|
|
936
|
+
return result;
|
|
937
|
+
}, []).join(", ");
|
|
938
|
+
}
|
|
939
|
+
function shouldUseCss(prettyLogs) {
|
|
940
|
+
return prettyLogs && (runtimeInfo.name === "browser" || runtimeInfo.name === "worker") && consoleSupportsCssStyling();
|
|
941
|
+
}
|
|
942
|
+
function stripAnsi(value) {
|
|
943
|
+
return value.replace(ANSI_REGEX, "");
|
|
944
|
+
}
|
|
945
|
+
function buildCssMetaOutput(settings, metaValue) {
|
|
946
|
+
if (metaValue == null) {
|
|
947
|
+
return { text: "", styles: [] };
|
|
948
|
+
}
|
|
949
|
+
const { template, placeholders } = buildPrettyMeta(settings, metaValue);
|
|
950
|
+
const parts = [];
|
|
951
|
+
const styles = [];
|
|
952
|
+
let lastIndex = 0;
|
|
953
|
+
const placeholderRegex = /{{(.+?)}}/g;
|
|
954
|
+
let match;
|
|
955
|
+
while ((match = placeholderRegex.exec(template)) != null) {
|
|
956
|
+
if (match.index > lastIndex) {
|
|
957
|
+
parts.push(template.slice(lastIndex, match.index));
|
|
958
|
+
}
|
|
959
|
+
const key = match[1];
|
|
960
|
+
const rawValue = placeholders[key] != null ? String(placeholders[key]) : "";
|
|
961
|
+
const tokens = collectStyleTokens(settings.prettyLogStyles?.[key], rawValue);
|
|
962
|
+
const css = tokensToCss(tokens);
|
|
963
|
+
if (css.length > 0) {
|
|
964
|
+
parts.push(`%c${rawValue}%c`);
|
|
965
|
+
styles.push(css, "");
|
|
966
|
+
} else {
|
|
967
|
+
parts.push(rawValue);
|
|
968
|
+
}
|
|
969
|
+
lastIndex = placeholderRegex.lastIndex;
|
|
970
|
+
}
|
|
971
|
+
if (lastIndex < template.length) {
|
|
972
|
+
parts.push(template.slice(lastIndex));
|
|
973
|
+
}
|
|
974
|
+
return {
|
|
975
|
+
text: parts.join(""),
|
|
976
|
+
styles
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
function collectStyleTokens(style, value) {
|
|
980
|
+
if (style == null) {
|
|
981
|
+
return [];
|
|
982
|
+
}
|
|
983
|
+
if (typeof style === "string") {
|
|
984
|
+
return [style];
|
|
985
|
+
}
|
|
986
|
+
if (Array.isArray(style)) {
|
|
987
|
+
return style.flatMap((token) => collectStyleTokens(token, value));
|
|
988
|
+
}
|
|
989
|
+
if (typeof style === "object") {
|
|
990
|
+
const normalizedValue = value.trim();
|
|
991
|
+
const nextStyle = style[normalizedValue] ?? style["*"];
|
|
992
|
+
if (nextStyle == null) {
|
|
993
|
+
return [];
|
|
994
|
+
}
|
|
995
|
+
return collectStyleTokens(nextStyle, value);
|
|
996
|
+
}
|
|
997
|
+
return [];
|
|
998
|
+
}
|
|
999
|
+
function tokensToCss(tokens) {
|
|
1000
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1001
|
+
const cssParts = [];
|
|
1002
|
+
for (const token of tokens) {
|
|
1003
|
+
const css = styleTokenToCss(token);
|
|
1004
|
+
if (css != null && css.length > 0 && !seen.has(css)) {
|
|
1005
|
+
seen.add(css);
|
|
1006
|
+
cssParts.push(css);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
return cssParts.join("; ");
|
|
1010
|
+
}
|
|
1011
|
+
function styleTokenToCss(token) {
|
|
1012
|
+
const color = COLOR_TOKENS[token];
|
|
1013
|
+
if (color != null) {
|
|
1014
|
+
return `color: ${color}`;
|
|
1015
|
+
}
|
|
1016
|
+
const background = BACKGROUND_TOKENS[token];
|
|
1017
|
+
if (background != null) {
|
|
1018
|
+
return `background-color: ${background}`;
|
|
1019
|
+
}
|
|
1020
|
+
switch (token) {
|
|
1021
|
+
case "bold":
|
|
1022
|
+
return "font-weight: bold";
|
|
1023
|
+
case "dim":
|
|
1024
|
+
return "opacity: 0.75";
|
|
1025
|
+
case "italic":
|
|
1026
|
+
return "font-style: italic";
|
|
1027
|
+
case "underline":
|
|
1028
|
+
return "text-decoration: underline";
|
|
1029
|
+
case "overline":
|
|
1030
|
+
return "text-decoration: overline";
|
|
1031
|
+
case "inverse":
|
|
1032
|
+
return "filter: invert(1)";
|
|
1033
|
+
case "hidden":
|
|
1034
|
+
return "visibility: hidden";
|
|
1035
|
+
case "strikethrough":
|
|
1036
|
+
return "text-decoration: line-through";
|
|
1037
|
+
default:
|
|
1038
|
+
return void 0;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
function getWorkingDirectory() {
|
|
1042
|
+
if (cachedCwd === void 0) {
|
|
1043
|
+
cachedCwd = safeGetCwd() ?? null;
|
|
1044
|
+
}
|
|
1045
|
+
return cachedCwd ?? void 0;
|
|
1046
|
+
}
|
|
1047
|
+
function shouldCaptureHostname() {
|
|
1048
|
+
return runtimeInfo.name === "node" || runtimeInfo.name === "deno" || runtimeInfo.name === "bun";
|
|
1049
|
+
}
|
|
1050
|
+
function shouldCaptureRuntimeVersion() {
|
|
1051
|
+
return runtimeInfo.name === "node" || runtimeInfo.name === "deno" || runtimeInfo.name === "bun";
|
|
1052
|
+
}
|
|
1053
|
+
function createRuntimeMeta(info) {
|
|
1054
|
+
if (info.name === "browser" || info.name === "worker") {
|
|
1055
|
+
return {
|
|
1056
|
+
runtime: info.name,
|
|
1057
|
+
browser: info.userAgent
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
const metaStatic = {
|
|
1061
|
+
runtime: info.name
|
|
1062
|
+
};
|
|
1063
|
+
if (shouldCaptureRuntimeVersion()) {
|
|
1064
|
+
metaStatic.runtimeVersion = info.version ?? "unknown";
|
|
1065
|
+
}
|
|
1066
|
+
if (shouldCaptureHostname()) {
|
|
1067
|
+
metaStatic.hostname = info.hostname ?? "unknown";
|
|
1068
|
+
}
|
|
1069
|
+
return metaStatic;
|
|
1070
|
+
}
|
|
1071
|
+
function formatWithOptionsSafe(options, args) {
|
|
1072
|
+
try {
|
|
1073
|
+
return formatWithOptions(options, ...args);
|
|
1074
|
+
} catch {
|
|
1075
|
+
return args.map(stringifyFallback).join(" ");
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
function stringifyFallback(value) {
|
|
1079
|
+
if (typeof value === "string") {
|
|
1080
|
+
return value;
|
|
1081
|
+
}
|
|
1082
|
+
try {
|
|
1083
|
+
return JSON.stringify(value);
|
|
1084
|
+
} catch {
|
|
1085
|
+
return String(value);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
function normalizeFilePath(value) {
|
|
1089
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
1090
|
+
return value;
|
|
1091
|
+
}
|
|
1092
|
+
const replaced = value.replace(/\\+/g, "\\").replace(/\\/g, "/");
|
|
1093
|
+
const hasRootDoubleSlash = replaced.startsWith("//");
|
|
1094
|
+
const hasLeadingSlash = replaced.startsWith("/") && !hasRootDoubleSlash;
|
|
1095
|
+
const driveMatch = replaced.match(/^[A-Za-z]:/);
|
|
1096
|
+
const drivePrefix = driveMatch ? driveMatch[0] : "";
|
|
1097
|
+
const withoutDrive = drivePrefix ? replaced.slice(drivePrefix.length) : replaced;
|
|
1098
|
+
const segments = withoutDrive.split("/");
|
|
1099
|
+
const normalizedSegments = [];
|
|
1100
|
+
for (const segment of segments) {
|
|
1101
|
+
if (segment === "" || segment === ".") {
|
|
1102
|
+
continue;
|
|
1103
|
+
}
|
|
1104
|
+
if (segment === "..") {
|
|
1105
|
+
if (normalizedSegments.length > 0) {
|
|
1106
|
+
normalizedSegments.pop();
|
|
1107
|
+
}
|
|
1108
|
+
continue;
|
|
1109
|
+
}
|
|
1110
|
+
normalizedSegments.push(segment);
|
|
1111
|
+
}
|
|
1112
|
+
let normalized = normalizedSegments.join("/");
|
|
1113
|
+
if (hasRootDoubleSlash) {
|
|
1114
|
+
normalized = `//${normalized}`;
|
|
1115
|
+
} else if (hasLeadingSlash) {
|
|
1116
|
+
normalized = `/${normalized}`;
|
|
1117
|
+
} else if (drivePrefix !== "") {
|
|
1118
|
+
normalized = `${drivePrefix}${normalized.length > 0 ? `/${normalized}` : ""}`;
|
|
1119
|
+
}
|
|
1120
|
+
if (normalized.length === 0) {
|
|
1121
|
+
return value;
|
|
1122
|
+
}
|
|
1123
|
+
return normalized;
|
|
1124
|
+
}
|
|
1125
|
+
function detectRuntimeInfo() {
|
|
1126
|
+
if (isBrowserEnvironment()) {
|
|
1127
|
+
const navigatorObj = globalThis.navigator;
|
|
1128
|
+
return {
|
|
1129
|
+
name: "browser",
|
|
1130
|
+
userAgent: navigatorObj?.userAgent
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
const globalScope = globalThis;
|
|
1134
|
+
if (typeof globalScope.importScripts === "function") {
|
|
1135
|
+
return {
|
|
1136
|
+
name: "worker",
|
|
1137
|
+
userAgent: globalScope.navigator?.userAgent
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
const globalAny = globalThis;
|
|
1141
|
+
if (globalAny.Bun != null) {
|
|
1142
|
+
const bunVersion = globalAny.Bun.version;
|
|
1143
|
+
return {
|
|
1144
|
+
name: "bun",
|
|
1145
|
+
version: bunVersion != null ? `bun/${bunVersion}` : void 0,
|
|
1146
|
+
hostname: getEnvironmentHostname(globalAny.process, globalAny.Deno, globalAny.Bun, globalAny.location)
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
if (globalAny.Deno != null) {
|
|
1150
|
+
const denoHostname = resolveDenoHostname(globalAny.Deno);
|
|
1151
|
+
const denoVersion = globalAny.Deno?.version?.deno;
|
|
1152
|
+
return {
|
|
1153
|
+
name: "deno",
|
|
1154
|
+
version: denoVersion != null ? `deno/${denoVersion}` : void 0,
|
|
1155
|
+
hostname: denoHostname ?? getEnvironmentHostname(globalAny.process, globalAny.Deno, globalAny.Bun, globalAny.location)
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
if (globalAny.process?.versions?.node != null || globalAny.process?.version != null) {
|
|
1159
|
+
return {
|
|
1160
|
+
name: "node",
|
|
1161
|
+
version: globalAny.process?.versions?.node ?? globalAny.process?.version,
|
|
1162
|
+
hostname: getEnvironmentHostname(globalAny.process, globalAny.Deno, globalAny.Bun, globalAny.location)
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
if (globalAny.process != null) {
|
|
1166
|
+
return {
|
|
1167
|
+
name: "node",
|
|
1168
|
+
version: "unknown",
|
|
1169
|
+
hostname: getEnvironmentHostname(globalAny.process, globalAny.Deno, globalAny.Bun, globalAny.location)
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
1172
|
+
return {
|
|
1173
|
+
name: "unknown"
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
function getEnvironmentHostname(nodeProcess, deno, bun, location) {
|
|
1177
|
+
const processHostname = nodeProcess?.env?.HOSTNAME ?? nodeProcess?.env?.HOST ?? nodeProcess?.env?.COMPUTERNAME;
|
|
1178
|
+
if (processHostname != null && processHostname.length > 0) {
|
|
1179
|
+
return processHostname;
|
|
1180
|
+
}
|
|
1181
|
+
const bunHostname = bun?.env?.HOSTNAME ?? bun?.env?.HOST ?? bun?.env?.COMPUTERNAME;
|
|
1182
|
+
if (bunHostname != null && bunHostname.length > 0) {
|
|
1183
|
+
return bunHostname;
|
|
1184
|
+
}
|
|
1185
|
+
try {
|
|
1186
|
+
const denoEnvGet = deno?.env?.get;
|
|
1187
|
+
if (typeof denoEnvGet === "function") {
|
|
1188
|
+
const value = denoEnvGet("HOSTNAME");
|
|
1189
|
+
if (value != null && value.length > 0) {
|
|
1190
|
+
return value;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
} catch {
|
|
1194
|
+
}
|
|
1195
|
+
if (location?.hostname != null && location.hostname.length > 0) {
|
|
1196
|
+
return location.hostname;
|
|
1197
|
+
}
|
|
1198
|
+
return void 0;
|
|
1199
|
+
}
|
|
1200
|
+
function resolveDenoHostname(deno) {
|
|
1201
|
+
try {
|
|
1202
|
+
if (typeof deno?.hostname === "function") {
|
|
1203
|
+
const value = deno.hostname();
|
|
1204
|
+
if (value != null && value.length > 0) {
|
|
1205
|
+
return value;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
} catch {
|
|
1209
|
+
}
|
|
1210
|
+
const locationHostname = globalThis.location?.hostname;
|
|
1211
|
+
if (locationHostname != null && locationHostname.length > 0) {
|
|
1212
|
+
return locationHostname;
|
|
1213
|
+
}
|
|
1214
|
+
return void 0;
|
|
1215
|
+
}
|
|
1216
|
+
function getNodeEnv() {
|
|
1217
|
+
const globalProcess = globalThis?.process;
|
|
1218
|
+
return globalProcess?.env?.NODE_ENV;
|
|
1219
|
+
}
|
|
1220
|
+
function isNativeError(value) {
|
|
1221
|
+
if (value instanceof Error) {
|
|
1222
|
+
return true;
|
|
1223
|
+
}
|
|
1224
|
+
if (value != null && typeof value === "object") {
|
|
1225
|
+
const objectTag = Object.prototype.toString.call(value);
|
|
1226
|
+
if (/\[object .*Error\]/.test(objectTag)) {
|
|
1227
|
+
return true;
|
|
1228
|
+
}
|
|
1229
|
+
const name = value.name;
|
|
1230
|
+
if (typeof name === "string" && name.endsWith("Error")) {
|
|
1231
|
+
return true;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
return false;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
var ANSI_REGEX = /\u001b\[[0-9;]*m/g;
|
|
1238
|
+
var COLOR_TOKENS = {
|
|
1239
|
+
black: "#000000",
|
|
1240
|
+
red: "#ef5350",
|
|
1241
|
+
green: "#66bb6a",
|
|
1242
|
+
yellow: "#fdd835",
|
|
1243
|
+
blue: "#42a5f5",
|
|
1244
|
+
magenta: "#ab47bc",
|
|
1245
|
+
cyan: "#26c6da",
|
|
1246
|
+
white: "#fafafa",
|
|
1247
|
+
blackBright: "#424242",
|
|
1248
|
+
redBright: "#ff7043",
|
|
1249
|
+
greenBright: "#81c784",
|
|
1250
|
+
yellowBright: "#ffe082",
|
|
1251
|
+
blueBright: "#64b5f6",
|
|
1252
|
+
magentaBright: "#ce93d8",
|
|
1253
|
+
cyanBright: "#4dd0e1",
|
|
1254
|
+
whiteBright: "#ffffff"
|
|
1255
|
+
};
|
|
1256
|
+
var BACKGROUND_TOKENS = {
|
|
1257
|
+
bgBlack: "#000000",
|
|
1258
|
+
bgRed: "#ef5350",
|
|
1259
|
+
bgGreen: "#66bb6a",
|
|
1260
|
+
bgYellow: "#fdd835",
|
|
1261
|
+
bgBlue: "#42a5f5",
|
|
1262
|
+
bgMagenta: "#ab47bc",
|
|
1263
|
+
bgCyan: "#26c6da",
|
|
1264
|
+
bgWhite: "#fafafa",
|
|
1265
|
+
bgBlackBright: "#424242",
|
|
1266
|
+
bgRedBright: "#ff7043",
|
|
1267
|
+
bgGreenBright: "#81c784",
|
|
1268
|
+
bgYellowBright: "#ffe082",
|
|
1269
|
+
bgBlueBright: "#64b5f6",
|
|
1270
|
+
bgMagentaBright: "#ce93d8",
|
|
1271
|
+
bgCyanBright: "#4dd0e1",
|
|
1272
|
+
bgWhiteBright: "#ffffff"
|
|
1273
|
+
};
|
|
1274
|
+
var BROWSER_PATH_REGEX = /(?:(?:file|https?|global code|[^@]+)@)?(?:file:)?((?:\/[^:/]+){2,})(?::(\d+))?(?::(\d+))?/;
|
|
1275
|
+
var runtime = createLoggerEnvironment();
|
|
1276
|
+
var BaseLogger = class {
|
|
1277
|
+
constructor(settings, logObj, stackDepthLevel = Number.NaN) {
|
|
1278
|
+
this.logObj = logObj;
|
|
1279
|
+
this.stackDepthLevel = stackDepthLevel;
|
|
1280
|
+
this.runtime = runtime;
|
|
1281
|
+
this.maxErrorCauseDepth = 5;
|
|
1282
|
+
this.settings = {
|
|
1283
|
+
type: settings?.type ?? "pretty",
|
|
1284
|
+
name: settings?.name,
|
|
1285
|
+
parentNames: settings?.parentNames,
|
|
1286
|
+
minLevel: settings?.minLevel ?? 0,
|
|
1287
|
+
argumentsArrayName: settings?.argumentsArrayName,
|
|
1288
|
+
hideLogPositionForProduction: settings?.hideLogPositionForProduction ?? false,
|
|
1289
|
+
prettyLogTemplate: settings?.prettyLogTemplate ?? "{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}} {{logLevelName}} {{filePathWithLine}}{{nameWithDelimiterPrefix}} ",
|
|
1290
|
+
prettyErrorTemplate: settings?.prettyErrorTemplate ?? "\n{{errorName}} {{errorMessage}}\nerror stack:\n{{errorStack}}",
|
|
1291
|
+
prettyErrorStackTemplate: settings?.prettyErrorStackTemplate ?? " \u2022 {{fileName}} {{method}}\n {{filePathWithLine}}",
|
|
1292
|
+
prettyErrorParentNamesSeparator: settings?.prettyErrorParentNamesSeparator ?? ":",
|
|
1293
|
+
prettyErrorLoggerNameDelimiter: settings?.prettyErrorLoggerNameDelimiter ?? " ",
|
|
1294
|
+
stylePrettyLogs: settings?.stylePrettyLogs ?? true,
|
|
1295
|
+
prettyLogTimeZone: settings?.prettyLogTimeZone ?? "UTC",
|
|
1296
|
+
prettyLogStyles: settings?.prettyLogStyles ?? {
|
|
1297
|
+
logLevelName: {
|
|
1298
|
+
"*": ["bold", "black", "bgWhiteBright", "dim"],
|
|
1299
|
+
SILLY: ["bold", "white"],
|
|
1300
|
+
TRACE: ["bold", "whiteBright"],
|
|
1301
|
+
DEBUG: ["bold", "green"],
|
|
1302
|
+
INFO: ["bold", "blue"],
|
|
1303
|
+
WARN: ["bold", "yellow"],
|
|
1304
|
+
ERROR: ["bold", "red"],
|
|
1305
|
+
FATAL: ["bold", "redBright"]
|
|
1306
|
+
},
|
|
1307
|
+
dateIsoStr: "white",
|
|
1308
|
+
filePathWithLine: "white",
|
|
1309
|
+
name: ["white", "bold"],
|
|
1310
|
+
nameWithDelimiterPrefix: ["white", "bold"],
|
|
1311
|
+
nameWithDelimiterSuffix: ["white", "bold"],
|
|
1312
|
+
errorName: ["bold", "bgRedBright", "whiteBright"],
|
|
1313
|
+
fileName: ["yellow"],
|
|
1314
|
+
fileNameWithLine: "white"
|
|
1315
|
+
},
|
|
1316
|
+
prettyInspectOptions: settings?.prettyInspectOptions ?? {
|
|
1317
|
+
colors: true,
|
|
1318
|
+
compact: false,
|
|
1319
|
+
depth: Infinity
|
|
1320
|
+
},
|
|
1321
|
+
metaProperty: settings?.metaProperty ?? "_meta",
|
|
1322
|
+
maskPlaceholder: settings?.maskPlaceholder ?? "[***]",
|
|
1323
|
+
maskValuesOfKeys: settings?.maskValuesOfKeys ?? ["password"],
|
|
1324
|
+
maskValuesOfKeysCaseInsensitive: settings?.maskValuesOfKeysCaseInsensitive ?? false,
|
|
1325
|
+
maskValuesRegEx: settings?.maskValuesRegEx,
|
|
1326
|
+
prefix: [...settings?.prefix ?? []],
|
|
1327
|
+
attachedTransports: [...settings?.attachedTransports ?? []],
|
|
1328
|
+
overwrite: {
|
|
1329
|
+
mask: settings?.overwrite?.mask,
|
|
1330
|
+
toLogObj: settings?.overwrite?.toLogObj,
|
|
1331
|
+
addMeta: settings?.overwrite?.addMeta,
|
|
1332
|
+
addPlaceholders: settings?.overwrite?.addPlaceholders,
|
|
1333
|
+
formatMeta: settings?.overwrite?.formatMeta,
|
|
1334
|
+
formatLogObj: settings?.overwrite?.formatLogObj,
|
|
1335
|
+
transportFormatted: settings?.overwrite?.transportFormatted,
|
|
1336
|
+
transportJSON: settings?.overwrite?.transportJSON
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
this.captureStackForMeta = this._shouldCaptureStack();
|
|
1340
|
+
}
|
|
1341
|
+
log(logLevelId, logLevelName, ...args) {
|
|
1342
|
+
if (logLevelId < this.settings.minLevel) {
|
|
1343
|
+
return;
|
|
1344
|
+
}
|
|
1345
|
+
const resolvedArgs = this._resolveLogArguments(args);
|
|
1346
|
+
const logArgs = [...this.settings.prefix, ...resolvedArgs];
|
|
1347
|
+
const maskedArgs = this.settings.overwrite?.mask != null ? this.settings.overwrite?.mask(logArgs) : this.settings.maskValuesOfKeys != null && this.settings.maskValuesOfKeys.length > 0 ? this._mask(logArgs) : logArgs;
|
|
1348
|
+
const thisLogObj = this.logObj != null ? this._recursiveCloneAndExecuteFunctions(this.logObj) : void 0;
|
|
1349
|
+
const logObj = this.settings.overwrite?.toLogObj != null ? this.settings.overwrite?.toLogObj(maskedArgs, thisLogObj) : this._toLogObj(maskedArgs, thisLogObj);
|
|
1350
|
+
const logObjWithMeta = this.settings.overwrite?.addMeta != null ? this.settings.overwrite?.addMeta(logObj, logLevelId, logLevelName) : this._addMetaToLogObj(logObj, logLevelId, logLevelName);
|
|
1351
|
+
const logMeta = logObjWithMeta?.[this.settings.metaProperty];
|
|
1352
|
+
let logMetaMarkup;
|
|
1353
|
+
let logArgsAndErrorsMarkup = void 0;
|
|
1354
|
+
if (this.settings.overwrite?.formatMeta != null) {
|
|
1355
|
+
logMetaMarkup = this.settings.overwrite?.formatMeta(logObjWithMeta?.[this.settings.metaProperty]);
|
|
1356
|
+
}
|
|
1357
|
+
if (this.settings.overwrite?.formatLogObj != null) {
|
|
1358
|
+
logArgsAndErrorsMarkup = this.settings.overwrite?.formatLogObj(maskedArgs, this.settings);
|
|
1359
|
+
}
|
|
1360
|
+
if (this.settings.type === "pretty") {
|
|
1361
|
+
logMetaMarkup = logMetaMarkup ?? this._prettyFormatLogObjMeta(logObjWithMeta?.[this.settings.metaProperty]);
|
|
1362
|
+
logArgsAndErrorsMarkup = logArgsAndErrorsMarkup ?? runtime.prettyFormatLogObj(maskedArgs, this.settings);
|
|
1363
|
+
}
|
|
1364
|
+
if (logMetaMarkup != null && logArgsAndErrorsMarkup != null) {
|
|
1365
|
+
if (this.settings.overwrite?.transportFormatted != null) {
|
|
1366
|
+
const transport = this.settings.overwrite.transportFormatted;
|
|
1367
|
+
const declaredParams = transport.length;
|
|
1368
|
+
if (declaredParams < 4) {
|
|
1369
|
+
transport(logMetaMarkup, logArgsAndErrorsMarkup.args, logArgsAndErrorsMarkup.errors);
|
|
1370
|
+
} else if (declaredParams === 4) {
|
|
1371
|
+
transport(logMetaMarkup, logArgsAndErrorsMarkup.args, logArgsAndErrorsMarkup.errors, logMeta);
|
|
1372
|
+
} else {
|
|
1373
|
+
transport(logMetaMarkup, logArgsAndErrorsMarkup.args, logArgsAndErrorsMarkup.errors, logMeta, this.settings);
|
|
1374
|
+
}
|
|
1375
|
+
} else {
|
|
1376
|
+
runtime.transportFormatted(logMetaMarkup, logArgsAndErrorsMarkup.args, logArgsAndErrorsMarkup.errors, logMeta, this.settings);
|
|
1377
|
+
}
|
|
1378
|
+
} else {
|
|
1379
|
+
if (this.settings.overwrite?.transportJSON != null) {
|
|
1380
|
+
this.settings.overwrite.transportJSON(logObjWithMeta);
|
|
1381
|
+
} else if (this.settings.type !== "hidden") {
|
|
1382
|
+
runtime.transportJSON(logObjWithMeta);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
if (this.settings.attachedTransports != null && this.settings.attachedTransports.length > 0) {
|
|
1386
|
+
this.settings.attachedTransports.forEach((transportLogger) => {
|
|
1387
|
+
transportLogger(logObjWithMeta);
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
return logObjWithMeta;
|
|
1391
|
+
}
|
|
1392
|
+
attachTransport(transportLogger) {
|
|
1393
|
+
this.settings.attachedTransports.push(transportLogger);
|
|
1394
|
+
}
|
|
1395
|
+
getSubLogger(settings, logObj) {
|
|
1396
|
+
const subLoggerSettings = {
|
|
1397
|
+
...this.settings,
|
|
1398
|
+
...settings,
|
|
1399
|
+
parentNames: this.settings?.parentNames != null && this.settings?.name != null ? [...this.settings.parentNames, this.settings.name] : this.settings?.name != null ? [this.settings.name] : void 0,
|
|
1400
|
+
prefix: [...this.settings.prefix, ...settings?.prefix ?? []]
|
|
1401
|
+
};
|
|
1402
|
+
const subLogger = new this.constructor(subLoggerSettings, logObj ?? this.logObj, this.stackDepthLevel);
|
|
1403
|
+
return subLogger;
|
|
1404
|
+
}
|
|
1405
|
+
_mask(args) {
|
|
1406
|
+
const maskKeys = this._getMaskKeys();
|
|
1407
|
+
return args?.map((arg) => {
|
|
1408
|
+
return this._recursiveCloneAndMaskValuesOfKeys(arg, maskKeys);
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
_getMaskKeys() {
|
|
1412
|
+
const maskKeys = this.settings.maskValuesOfKeys ?? [];
|
|
1413
|
+
const signature = maskKeys.map(String).join("|");
|
|
1414
|
+
if (this.settings.maskValuesOfKeysCaseInsensitive === true) {
|
|
1415
|
+
if (this.maskKeysCache?.source === maskKeys && this.maskKeysCache.caseInsensitive === true && this.maskKeysCache.signature === signature) {
|
|
1416
|
+
return this.maskKeysCache.normalized;
|
|
1417
|
+
}
|
|
1418
|
+
const normalized = maskKeys.map((key) => typeof key === "string" ? key.toLowerCase() : String(key).toLowerCase());
|
|
1419
|
+
this.maskKeysCache = {
|
|
1420
|
+
source: maskKeys,
|
|
1421
|
+
caseInsensitive: true,
|
|
1422
|
+
normalized,
|
|
1423
|
+
signature
|
|
1424
|
+
};
|
|
1425
|
+
return normalized;
|
|
1426
|
+
}
|
|
1427
|
+
this.maskKeysCache = {
|
|
1428
|
+
source: maskKeys,
|
|
1429
|
+
caseInsensitive: false,
|
|
1430
|
+
normalized: maskKeys,
|
|
1431
|
+
signature
|
|
1432
|
+
};
|
|
1433
|
+
return maskKeys;
|
|
1434
|
+
}
|
|
1435
|
+
_resolveLogArguments(args) {
|
|
1436
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
1437
|
+
const candidate = args[0];
|
|
1438
|
+
if (candidate.length === 0) {
|
|
1439
|
+
const result = candidate();
|
|
1440
|
+
return Array.isArray(result) ? result : [result];
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
return args;
|
|
1444
|
+
}
|
|
1445
|
+
_recursiveCloneAndMaskValuesOfKeys(source, keys, seen = []) {
|
|
1446
|
+
if (seen.includes(source)) {
|
|
1447
|
+
return { ...source };
|
|
1448
|
+
}
|
|
1449
|
+
if (typeof source === "object" && source !== null) {
|
|
1450
|
+
seen.push(source);
|
|
1451
|
+
}
|
|
1452
|
+
if (runtime.isError(source) || runtime.isBuffer(source)) {
|
|
1453
|
+
return source;
|
|
1454
|
+
} else if (source instanceof Map) {
|
|
1455
|
+
return new Map(source);
|
|
1456
|
+
} else if (source instanceof Set) {
|
|
1457
|
+
return new Set(source);
|
|
1458
|
+
} else if (Array.isArray(source)) {
|
|
1459
|
+
return source.map((item) => this._recursiveCloneAndMaskValuesOfKeys(item, keys, seen));
|
|
1460
|
+
} else if (source instanceof Date) {
|
|
1461
|
+
return new Date(source.getTime());
|
|
1462
|
+
} else if (source instanceof URL) {
|
|
1463
|
+
return urlToObject(source);
|
|
1464
|
+
} else if (source !== null && typeof source === "object") {
|
|
1465
|
+
const baseObject = runtime.isError(source) ? this._cloneError(source) : Object.create(Object.getPrototypeOf(source));
|
|
1466
|
+
return Object.getOwnPropertyNames(source).reduce((o, prop) => {
|
|
1467
|
+
const lookupKey = this.settings?.maskValuesOfKeysCaseInsensitive !== true ? prop : typeof prop === "string" ? prop.toLowerCase() : String(prop).toLowerCase();
|
|
1468
|
+
o[prop] = keys.includes(lookupKey) ? this.settings.maskPlaceholder : (() => {
|
|
1469
|
+
try {
|
|
1470
|
+
return this._recursiveCloneAndMaskValuesOfKeys(source[prop], keys, seen);
|
|
1471
|
+
} catch {
|
|
1472
|
+
return null;
|
|
1473
|
+
}
|
|
1474
|
+
})();
|
|
1475
|
+
return o;
|
|
1476
|
+
}, baseObject);
|
|
1477
|
+
} else {
|
|
1478
|
+
if (typeof source === "string") {
|
|
1479
|
+
let modifiedSource = source;
|
|
1480
|
+
for (const regEx of this.settings?.maskValuesRegEx || []) {
|
|
1481
|
+
modifiedSource = modifiedSource.replace(regEx, this.settings?.maskPlaceholder || "");
|
|
1482
|
+
}
|
|
1483
|
+
return modifiedSource;
|
|
1484
|
+
}
|
|
1485
|
+
return source;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
_recursiveCloneAndExecuteFunctions(source, seen = []) {
|
|
1489
|
+
if (this.isObjectOrArray(source) && seen.includes(source)) {
|
|
1490
|
+
return this.shallowCopy(source);
|
|
1491
|
+
}
|
|
1492
|
+
if (this.isObjectOrArray(source)) {
|
|
1493
|
+
seen.push(source);
|
|
1494
|
+
}
|
|
1495
|
+
if (Array.isArray(source)) {
|
|
1496
|
+
return source.map((item) => this._recursiveCloneAndExecuteFunctions(item, seen));
|
|
1497
|
+
} else if (source instanceof Date) {
|
|
1498
|
+
return new Date(source.getTime());
|
|
1499
|
+
} else if (this.isObject(source)) {
|
|
1500
|
+
return Object.getOwnPropertyNames(source).reduce((o, prop) => {
|
|
1501
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, prop);
|
|
1502
|
+
if (descriptor) {
|
|
1503
|
+
Object.defineProperty(o, prop, descriptor);
|
|
1504
|
+
const value = source[prop];
|
|
1505
|
+
o[prop] = typeof value === "function" ? value() : this._recursiveCloneAndExecuteFunctions(value, seen);
|
|
1506
|
+
}
|
|
1507
|
+
return o;
|
|
1508
|
+
}, Object.create(Object.getPrototypeOf(source)));
|
|
1509
|
+
} else {
|
|
1510
|
+
return source;
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
isObjectOrArray(value) {
|
|
1514
|
+
return typeof value === "object" && value !== null;
|
|
1515
|
+
}
|
|
1516
|
+
isObject(value) {
|
|
1517
|
+
return typeof value === "object" && !Array.isArray(value) && value !== null;
|
|
1518
|
+
}
|
|
1519
|
+
shallowCopy(source) {
|
|
1520
|
+
if (Array.isArray(source)) {
|
|
1521
|
+
return [...source];
|
|
1522
|
+
} else {
|
|
1523
|
+
return { ...source };
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
_toLogObj(args, clonedLogObj = {}) {
|
|
1527
|
+
args = args?.map((arg) => runtime.isError(arg) ? this._toErrorObject(arg) : arg);
|
|
1528
|
+
if (this.settings.argumentsArrayName == null) {
|
|
1529
|
+
if (args.length === 1 && !Array.isArray(args[0]) && runtime.isBuffer(args[0]) !== true && !(args[0] instanceof Date)) {
|
|
1530
|
+
clonedLogObj = typeof args[0] === "object" && args[0] != null ? { ...args[0], ...clonedLogObj } : { 0: args[0], ...clonedLogObj };
|
|
1531
|
+
} else {
|
|
1532
|
+
clonedLogObj = { ...clonedLogObj, ...args };
|
|
1533
|
+
}
|
|
1534
|
+
} else {
|
|
1535
|
+
clonedLogObj = {
|
|
1536
|
+
...clonedLogObj,
|
|
1537
|
+
[this.settings.argumentsArrayName]: args
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1540
|
+
return clonedLogObj;
|
|
1541
|
+
}
|
|
1542
|
+
_cloneError(error) {
|
|
1543
|
+
const cloned = new error.constructor();
|
|
1544
|
+
Object.getOwnPropertyNames(error).forEach((key) => {
|
|
1545
|
+
cloned[key] = error[key];
|
|
1546
|
+
});
|
|
1547
|
+
return cloned;
|
|
1548
|
+
}
|
|
1549
|
+
_toErrorObject(error, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
1550
|
+
if (!seen.has(error)) {
|
|
1551
|
+
seen.add(error);
|
|
1552
|
+
}
|
|
1553
|
+
const errorObject = {
|
|
1554
|
+
nativeError: error,
|
|
1555
|
+
name: error.name ?? "Error",
|
|
1556
|
+
message: error.message,
|
|
1557
|
+
stack: runtime.getErrorTrace(error)
|
|
1558
|
+
};
|
|
1559
|
+
if (depth >= this.maxErrorCauseDepth) {
|
|
1560
|
+
return errorObject;
|
|
1561
|
+
}
|
|
1562
|
+
const causeValue = error.cause;
|
|
1563
|
+
if (causeValue != null) {
|
|
1564
|
+
const normalizedCause = toError(causeValue);
|
|
1565
|
+
if (!seen.has(normalizedCause)) {
|
|
1566
|
+
errorObject.cause = this._toErrorObject(normalizedCause, depth + 1, seen);
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
return errorObject;
|
|
1570
|
+
}
|
|
1571
|
+
_addMetaToLogObj(logObj, logLevelId, logLevelName) {
|
|
1572
|
+
return {
|
|
1573
|
+
...logObj,
|
|
1574
|
+
[this.settings.metaProperty]: runtime.getMeta(logLevelId, logLevelName, this.stackDepthLevel, !this.captureStackForMeta, this.settings.name, this.settings.parentNames)
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
_shouldCaptureStack() {
|
|
1578
|
+
if (this.settings.hideLogPositionForProduction) {
|
|
1579
|
+
return false;
|
|
1580
|
+
}
|
|
1581
|
+
if (this.settings.type === "json") {
|
|
1582
|
+
return true;
|
|
1583
|
+
}
|
|
1584
|
+
const template = this.settings.prettyLogTemplate ?? "";
|
|
1585
|
+
const stackPlaceholders = /{{\s*(file(Name|Path|Line|PathWithLine|NameWithLine)|fullFilePath)\s*}}/;
|
|
1586
|
+
if (stackPlaceholders.test(template)) {
|
|
1587
|
+
return true;
|
|
1588
|
+
}
|
|
1589
|
+
return false;
|
|
1590
|
+
}
|
|
1591
|
+
_prettyFormatLogObjMeta(logObjMeta) {
|
|
1592
|
+
return buildPrettyMeta(this.settings, logObjMeta).text;
|
|
1593
|
+
}
|
|
1594
|
+
};
|
|
1595
|
+
var Logger = class extends BaseLogger {
|
|
1596
|
+
constructor(settings, logObj) {
|
|
1597
|
+
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
1598
|
+
const normalizedSettings = { ...settings ?? {} };
|
|
1599
|
+
if (isBrowser) {
|
|
1600
|
+
normalizedSettings.stylePrettyLogs = settings?.stylePrettyLogs ?? true;
|
|
1601
|
+
}
|
|
1602
|
+
super(normalizedSettings, logObj, Number.NaN);
|
|
1603
|
+
}
|
|
1604
|
+
log(logLevelId, logLevelName, ...args) {
|
|
1605
|
+
return super.log(logLevelId, logLevelName, ...args);
|
|
1606
|
+
}
|
|
1607
|
+
silly(...args) {
|
|
1608
|
+
return super.log(0, "SILLY", ...args);
|
|
1609
|
+
}
|
|
1610
|
+
trace(...args) {
|
|
1611
|
+
return super.log(1, "TRACE", ...args);
|
|
1612
|
+
}
|
|
1613
|
+
debug(...args) {
|
|
1614
|
+
return super.log(2, "DEBUG", ...args);
|
|
1615
|
+
}
|
|
1616
|
+
info(...args) {
|
|
1617
|
+
return super.log(3, "INFO", ...args);
|
|
1618
|
+
}
|
|
1619
|
+
warn(...args) {
|
|
1620
|
+
return super.log(4, "WARN", ...args);
|
|
1621
|
+
}
|
|
1622
|
+
error(...args) {
|
|
1623
|
+
return super.log(5, "ERROR", ...args);
|
|
1624
|
+
}
|
|
1625
|
+
fatal(...args) {
|
|
1626
|
+
return super.log(6, "FATAL", ...args);
|
|
1627
|
+
}
|
|
1628
|
+
getSubLogger(settings, logObj) {
|
|
1629
|
+
return super.getSubLogger(settings, logObj);
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
function getLogDir() {
|
|
1633
|
+
switch (process.platform) {
|
|
1634
|
+
case "darwin":
|
|
1635
|
+
return path.join(os.homedir(), "Library", "Logs", "panopticon");
|
|
1636
|
+
case "win32":
|
|
1637
|
+
return path.join(
|
|
1638
|
+
process.env.LOCALAPPDATA ?? path.join(os.homedir(), "AppData", "Local"),
|
|
1639
|
+
"panopticon",
|
|
1640
|
+
"logs"
|
|
1641
|
+
);
|
|
1642
|
+
default:
|
|
1643
|
+
return path.join(
|
|
1644
|
+
process.env.XDG_STATE_HOME ?? path.join(os.homedir(), ".local", "state"),
|
|
1645
|
+
"panopticon",
|
|
1646
|
+
"logs"
|
|
1647
|
+
);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
var LOG_DIR = getLogDir();
|
|
1651
|
+
var logPaths = {
|
|
1652
|
+
server: path.join(LOG_DIR, "server.log"),
|
|
1653
|
+
otlp: path.join(LOG_DIR, "otlp-receiver.log"),
|
|
1654
|
+
mcp: path.join(LOG_DIR, "mcp-server.log"),
|
|
1655
|
+
proxy: path.join(LOG_DIR, "proxy.log"),
|
|
1656
|
+
hook: path.join(LOG_DIR, "hook-handler.log")
|
|
1657
|
+
};
|
|
1658
|
+
var DAEMON_NAMES = Object.keys(logPaths);
|
|
1659
|
+
var root = new Logger({
|
|
1660
|
+
name: "panopticon",
|
|
1661
|
+
type: "pretty",
|
|
1662
|
+
prettyLogTimeZone: "UTC",
|
|
1663
|
+
stylePrettyLogs: false,
|
|
1664
|
+
prettyLogTemplate: "{{dateIsoStr}} [{{name}}] {{logLevelName}} "
|
|
1665
|
+
});
|
|
1666
|
+
var log = {
|
|
1667
|
+
server: root.getSubLogger({ name: "server" }),
|
|
1668
|
+
scanner: root.getSubLogger({ name: "scanner" }),
|
|
1669
|
+
sync: root.getSubLogger({ name: "sync" }),
|
|
1670
|
+
proxy: root.getSubLogger({ name: "proxy" }),
|
|
1671
|
+
llm: root.getSubLogger({ name: "llm" }),
|
|
1672
|
+
mcp: root.getSubLogger({ name: "mcp" }),
|
|
1673
|
+
otlp: root.getSubLogger({ name: "otlp" }),
|
|
1674
|
+
hooks: root.getSubLogger({ name: "hooks" })
|
|
1675
|
+
};
|
|
1676
|
+
|
|
1677
|
+
// node_modules/.pnpm/@fml-inc+panopticon@0.2.2/node_modules/@fml-inc/panopticon/dist/chunk-WNBA7CY3.js
|
|
1678
|
+
function loadSyncConfig() {
|
|
1679
|
+
const cfg = loadUnifiedConfig();
|
|
1680
|
+
return { targets: cfg.sync.targets, filter: cfg.sync.filter };
|
|
1681
|
+
}
|
|
1682
|
+
function saveSyncConfig(syncCfg) {
|
|
1683
|
+
const cfg = loadUnifiedConfig();
|
|
1684
|
+
cfg.sync.targets = syncCfg.targets;
|
|
1685
|
+
cfg.sync.filter = syncCfg.filter;
|
|
1686
|
+
saveUnifiedConfig(cfg);
|
|
1687
|
+
}
|
|
1688
|
+
function addTarget(target) {
|
|
1689
|
+
const cfg = loadUnifiedConfig();
|
|
1690
|
+
const existing = cfg.sync.targets.findIndex((t) => t.name === target.name);
|
|
1691
|
+
if (existing >= 0) {
|
|
1692
|
+
cfg.sync.targets[existing] = target;
|
|
1693
|
+
} else {
|
|
1694
|
+
cfg.sync.targets.push(target);
|
|
1695
|
+
}
|
|
1696
|
+
saveUnifiedConfig(cfg);
|
|
1697
|
+
}
|
|
1698
|
+
function removeTarget(name) {
|
|
1699
|
+
const cfg = loadUnifiedConfig();
|
|
1700
|
+
const before = cfg.sync.targets.length;
|
|
1701
|
+
cfg.sync.targets = cfg.sync.targets.filter((t) => t.name !== name);
|
|
1702
|
+
if (cfg.sync.targets.length === before) return false;
|
|
1703
|
+
saveUnifiedConfig(cfg);
|
|
1704
|
+
return true;
|
|
1705
|
+
}
|
|
1706
|
+
function listTargets() {
|
|
1707
|
+
return loadUnifiedConfig().sync.targets;
|
|
1708
|
+
}
|
|
1709
|
+
var TOKEN_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
1710
|
+
|
|
1711
|
+
// node_modules/.pnpm/@fml-inc+panopticon@0.2.2/node_modules/@fml-inc/panopticon/dist/chunk-CL3PWTMD.js
|
|
1712
|
+
import http from "http";
|
|
1713
|
+
function post(path4, body, timeoutMs) {
|
|
1714
|
+
return new Promise((resolve, reject) => {
|
|
1715
|
+
const json = JSON.stringify(body);
|
|
1716
|
+
const req = http.request(
|
|
1717
|
+
{
|
|
1718
|
+
hostname: config.host,
|
|
1719
|
+
port: config.port,
|
|
1720
|
+
path: path4,
|
|
1721
|
+
method: "POST",
|
|
1722
|
+
headers: {
|
|
1723
|
+
"Content-Type": "application/json",
|
|
1724
|
+
"Content-Length": Buffer.byteLength(json)
|
|
1725
|
+
},
|
|
1726
|
+
timeout: timeoutMs
|
|
1727
|
+
},
|
|
1728
|
+
(res) => {
|
|
1729
|
+
const chunks = [];
|
|
1730
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
1731
|
+
res.on("end", () => {
|
|
1732
|
+
const text = Buffer.concat(chunks).toString("utf-8");
|
|
1733
|
+
let parsed;
|
|
1734
|
+
try {
|
|
1735
|
+
parsed = JSON.parse(text);
|
|
1736
|
+
} catch {
|
|
1737
|
+
reject(
|
|
1738
|
+
new Error(
|
|
1739
|
+
`Invalid JSON response from server: ${text.slice(0, 200)}`
|
|
1740
|
+
)
|
|
1741
|
+
);
|
|
1742
|
+
return;
|
|
1743
|
+
}
|
|
1744
|
+
if (res.statusCode && res.statusCode >= 400 && typeof parsed === "object" && parsed !== null && "error" in parsed) {
|
|
1745
|
+
reject(new Error(parsed.error));
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1748
|
+
resolve(parsed);
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
);
|
|
1752
|
+
req.on("error", (err) => {
|
|
1753
|
+
if (err.code === "ECONNREFUSED") {
|
|
1754
|
+
reject(
|
|
1755
|
+
new Error(
|
|
1756
|
+
"Panopticon server is not running. Start with: panopticon start"
|
|
1757
|
+
)
|
|
1758
|
+
);
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
reject(err);
|
|
1762
|
+
});
|
|
1763
|
+
req.on("timeout", () => {
|
|
1764
|
+
req.destroy();
|
|
1765
|
+
reject(new Error("Request to panopticon server timed out"));
|
|
1766
|
+
});
|
|
1767
|
+
req.write(json);
|
|
1768
|
+
req.end();
|
|
1769
|
+
});
|
|
1770
|
+
}
|
|
1771
|
+
var EXEC_TIMEOUT = 6e4;
|
|
1772
|
+
function callExec(command, params) {
|
|
1773
|
+
return post("/api/exec", { command, params }, EXEC_TIMEOUT);
|
|
1774
|
+
}
|
|
1775
|
+
function syncReset(target) {
|
|
1776
|
+
return callExec("sync-reset", target ? { target } : {});
|
|
1777
|
+
}
|
|
1778
|
+
function syncPending(target) {
|
|
1779
|
+
return callExec("sync-pending", { target });
|
|
1780
|
+
}
|
|
38
1781
|
|
|
39
1782
|
// src/commands/doctor.ts
|
|
40
|
-
import ora from "ora";
|
|
41
|
-
import pc from "picocolors";
|
|
42
|
-
import { loadSyncConfig } from "@fml-inc/panopticon/sync";
|
|
43
|
-
import { syncPending } from "@fml-inc/panopticon/api";
|
|
44
1783
|
function reportResult(result, spinner) {
|
|
45
1784
|
const text = `${result.label} \u2014 ${result.detail}`;
|
|
46
1785
|
if (spinner) {
|
|
@@ -98,7 +1837,7 @@ async function handleDoctor(opts) {
|
|
|
98
1837
|
{
|
|
99
1838
|
const spinner = startSpinner("panopticon");
|
|
100
1839
|
try {
|
|
101
|
-
const { doctor } = await import("
|
|
1840
|
+
const { doctor } = await import("./doctor-YV6KQEGW.js");
|
|
102
1841
|
const result = await doctor();
|
|
103
1842
|
if (spinner) spinner.stop();
|
|
104
1843
|
for (const check of result.checks) {
|
|
@@ -269,11 +2008,11 @@ async function handleDoctor(opts) {
|
|
|
269
2008
|
}
|
|
270
2009
|
|
|
271
2010
|
// src/commands/install.ts
|
|
2011
|
+
import { execFileSync } from "child_process";
|
|
272
2012
|
import fs from "fs";
|
|
273
|
-
import
|
|
274
|
-
import
|
|
2013
|
+
import os2 from "os";
|
|
2014
|
+
import path2 from "path";
|
|
275
2015
|
import { fileURLToPath } from "url";
|
|
276
|
-
import { addTarget, listTargets } from "@fml-inc/panopticon/sync";
|
|
277
2016
|
|
|
278
2017
|
// src/banner.ts
|
|
279
2018
|
import pc2 from "picocolors";
|
|
@@ -327,17 +2066,17 @@ function resolveGitHubToken() {
|
|
|
327
2066
|
}
|
|
328
2067
|
|
|
329
2068
|
// src/commands/install.ts
|
|
330
|
-
var CLAUDE_DIR =
|
|
331
|
-
var CLAUDE_SETTINGS_PATH =
|
|
332
|
-
var MARKETPLACE_DIR =
|
|
333
|
-
|
|
2069
|
+
var CLAUDE_DIR = path2.join(os2.homedir(), ".claude");
|
|
2070
|
+
var CLAUDE_SETTINGS_PATH = path2.join(CLAUDE_DIR, "settings.json");
|
|
2071
|
+
var MARKETPLACE_DIR = path2.join(
|
|
2072
|
+
os2.homedir(),
|
|
334
2073
|
".local",
|
|
335
2074
|
"share",
|
|
336
2075
|
"claude-plugins"
|
|
337
2076
|
);
|
|
338
2077
|
function getPluginRoot() {
|
|
339
|
-
let dir =
|
|
340
|
-
dir =
|
|
2078
|
+
let dir = path2.dirname(fileURLToPath(import.meta.url));
|
|
2079
|
+
dir = path2.resolve(dir, "..");
|
|
341
2080
|
return dir;
|
|
342
2081
|
}
|
|
343
2082
|
function readJsonFile(filePath) {
|
|
@@ -348,45 +2087,96 @@ function readJsonFile(filePath) {
|
|
|
348
2087
|
}
|
|
349
2088
|
}
|
|
350
2089
|
function writeJsonFile(filePath, data) {
|
|
351
|
-
fs.mkdirSync(
|
|
2090
|
+
fs.mkdirSync(path2.dirname(filePath), { recursive: true });
|
|
352
2091
|
fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}
|
|
353
2092
|
`);
|
|
354
2093
|
}
|
|
355
2094
|
async function handleInstall() {
|
|
356
2095
|
const pluginRoot = getPluginRoot();
|
|
357
2096
|
console.log("Installing fml...\n");
|
|
358
|
-
console.log("[1/
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
2097
|
+
console.log("[1/5] Setting up panopticon...");
|
|
2098
|
+
const { resolvePanopticonBin } = await import("./daemon-utils-LIG6K2MK.js");
|
|
2099
|
+
let freshInstall = false;
|
|
2100
|
+
const bin = resolvePanopticonBin();
|
|
2101
|
+
let needsInstall = !bin;
|
|
2102
|
+
if (bin) {
|
|
2103
|
+
const MIN_PANOPTICON = "0.2.2";
|
|
2104
|
+
const vResult = panopticonExec("--version", { timeout: 5e3 });
|
|
2105
|
+
const installed = vResult.ok ? vResult.stdout.trim().split("+")[0] : "0.0.0";
|
|
2106
|
+
if (installed < MIN_PANOPTICON) {
|
|
2107
|
+
console.log(` Found panopticon ${installed}, need >=${MIN_PANOPTICON}`);
|
|
2108
|
+
needsInstall = true;
|
|
363
2109
|
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
2110
|
+
}
|
|
2111
|
+
if (needsInstall) {
|
|
2112
|
+
console.log(
|
|
2113
|
+
bin ? " Upgrading @fml-inc/panopticon..." : " Installing @fml-inc/panopticon globally..."
|
|
2114
|
+
);
|
|
2115
|
+
try {
|
|
2116
|
+
execFileSync("npm", ["install", "-g", "@fml-inc/panopticon@latest"], {
|
|
2117
|
+
encoding: "utf-8",
|
|
2118
|
+
timeout: 12e4,
|
|
2119
|
+
stdio: "pipe"
|
|
2120
|
+
});
|
|
2121
|
+
freshInstall = true;
|
|
2122
|
+
console.log(" Installed @fml-inc/panopticon");
|
|
2123
|
+
} catch (err) {
|
|
2124
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2125
|
+
console.error(` Failed to install panopticon: ${msg}`);
|
|
2126
|
+
console.error(" Install manually: npm install -g @fml-inc/panopticon@latest");
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
if (!freshInstall) {
|
|
2130
|
+
const result = panopticonExec("install", { timeout: 6e4 });
|
|
2131
|
+
if (result.ok) {
|
|
2132
|
+
for (const line of result.stdout.trim().split("\n")) {
|
|
2133
|
+
console.log(` ${line}`);
|
|
2134
|
+
}
|
|
2135
|
+
} else {
|
|
2136
|
+
console.error(" panopticon install failed:");
|
|
2137
|
+
for (const line of result.stdout.trim().split("\n")) {
|
|
2138
|
+
console.error(` ${line}`);
|
|
2139
|
+
}
|
|
368
2140
|
}
|
|
369
2141
|
}
|
|
370
2142
|
console.log();
|
|
371
|
-
console.log("[2/
|
|
2143
|
+
console.log("[2/5] Creating fml directories...");
|
|
372
2144
|
for (const dir of [FML_DATA_DIR, FML_LOG_DIR]) {
|
|
373
2145
|
fs.mkdirSync(dir, { recursive: true });
|
|
374
2146
|
}
|
|
375
2147
|
console.log(` ${FML_DATA_DIR}`);
|
|
376
2148
|
console.log(` ${FML_LOG_DIR}
|
|
377
2149
|
`);
|
|
378
|
-
console.log("[3/
|
|
379
|
-
|
|
2150
|
+
console.log("[3/5] Writing plugin manifest...");
|
|
2151
|
+
const pkgJson = readJsonFile(path2.join(pluginRoot, "package.json"));
|
|
2152
|
+
const version = pkgJson?.version ?? "0.0.0-dev";
|
|
2153
|
+
const pluginManifestDir = path2.join(pluginRoot, ".claude-plugin");
|
|
2154
|
+
fs.mkdirSync(pluginManifestDir, { recursive: true });
|
|
2155
|
+
writeJsonFile(path2.join(pluginManifestDir, "plugin.json"), {
|
|
2156
|
+
name: "fml",
|
|
2157
|
+
version,
|
|
2158
|
+
description: "FML agent tools for Claude Code",
|
|
2159
|
+
mcpServers: {
|
|
2160
|
+
fml: {
|
|
2161
|
+
command: "node",
|
|
2162
|
+
args: ["${CLAUDE_PLUGIN_ROOT}/bin/mcp-server"]
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
console.log(` Version: ${version}
|
|
2167
|
+
`);
|
|
2168
|
+
console.log("[4/5] Setting up fml plugin...");
|
|
2169
|
+
fs.mkdirSync(path2.join(MARKETPLACE_DIR, ".claude-plugin"), {
|
|
380
2170
|
recursive: true
|
|
381
2171
|
});
|
|
382
|
-
const manifestPath =
|
|
2172
|
+
const manifestPath = path2.join(
|
|
383
2173
|
MARKETPLACE_DIR,
|
|
384
2174
|
".claude-plugin",
|
|
385
2175
|
"marketplace.json"
|
|
386
2176
|
);
|
|
387
2177
|
const manifest = readJsonFile(manifestPath) ?? {
|
|
388
2178
|
name: "local-plugins",
|
|
389
|
-
owner: { name:
|
|
2179
|
+
owner: { name: os2.userInfo().username },
|
|
390
2180
|
plugins: []
|
|
391
2181
|
};
|
|
392
2182
|
const plugins = manifest.plugins ?? [];
|
|
@@ -399,7 +2189,7 @@ async function handleInstall() {
|
|
|
399
2189
|
manifest.plugins = plugins;
|
|
400
2190
|
}
|
|
401
2191
|
writeJsonFile(manifestPath, manifest);
|
|
402
|
-
const marketplaceLink =
|
|
2192
|
+
const marketplaceLink = path2.join(MARKETPLACE_DIR, "fml");
|
|
403
2193
|
try {
|
|
404
2194
|
fs.unlinkSync(marketplaceLink);
|
|
405
2195
|
} catch {
|
|
@@ -416,9 +2206,25 @@ async function handleInstall() {
|
|
|
416
2206
|
settings.enabledPlugins = settings.enabledPlugins ?? {};
|
|
417
2207
|
settings.enabledPlugins["fml@local-plugins"] = true;
|
|
418
2208
|
writeJsonFile(CLAUDE_SETTINGS_PATH, settings);
|
|
419
|
-
console.log(` Claude settings: ${CLAUDE_SETTINGS_PATH}
|
|
420
|
-
|
|
421
|
-
|
|
2209
|
+
console.log(` Claude settings: ${CLAUDE_SETTINGS_PATH}`);
|
|
2210
|
+
try {
|
|
2211
|
+
try {
|
|
2212
|
+
execFileSync("claude", ["plugin", "install", "fml@local-plugins"], {
|
|
2213
|
+
stdio: "pipe",
|
|
2214
|
+
timeout: 15e3
|
|
2215
|
+
});
|
|
2216
|
+
} catch {
|
|
2217
|
+
execFileSync("claude", ["plugin", "update", "fml@local-plugins"], {
|
|
2218
|
+
stdio: "pipe",
|
|
2219
|
+
timeout: 15e3
|
|
2220
|
+
});
|
|
2221
|
+
}
|
|
2222
|
+
console.log(" Plugin registered via Claude Code CLI");
|
|
2223
|
+
} catch {
|
|
2224
|
+
console.log(" warn: claude CLI not found, run 'claude plugin install fml@local-plugins' manually");
|
|
2225
|
+
}
|
|
2226
|
+
console.log();
|
|
2227
|
+
console.log("[5/5] Configuring sync target...");
|
|
422
2228
|
const prodSyncUrl = DEFAULT_PROD_URL.replace(".cloud", ".site");
|
|
423
2229
|
const existingTargets = listTargets();
|
|
424
2230
|
const existingProd = existingTargets.find((t) => t.url === prodSyncUrl);
|
|
@@ -452,17 +2258,25 @@ async function handleInstall() {
|
|
|
452
2258
|
}
|
|
453
2259
|
|
|
454
2260
|
// src/commands/uninstall.ts
|
|
2261
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
455
2262
|
import fs2 from "fs";
|
|
456
|
-
import
|
|
457
|
-
import
|
|
458
|
-
var CLAUDE_DIR2 =
|
|
459
|
-
var CLAUDE_SETTINGS_PATH2 =
|
|
460
|
-
var MARKETPLACE_DIR2 =
|
|
461
|
-
|
|
2263
|
+
import os3 from "os";
|
|
2264
|
+
import path3 from "path";
|
|
2265
|
+
var CLAUDE_DIR2 = path3.join(os3.homedir(), ".claude");
|
|
2266
|
+
var CLAUDE_SETTINGS_PATH2 = path3.join(CLAUDE_DIR2, "settings.json");
|
|
2267
|
+
var MARKETPLACE_DIR2 = path3.join(
|
|
2268
|
+
os3.homedir(),
|
|
462
2269
|
".local",
|
|
463
2270
|
"share",
|
|
464
2271
|
"claude-plugins"
|
|
465
2272
|
);
|
|
2273
|
+
var PLUGIN_CACHE_DIR = path3.join(
|
|
2274
|
+
CLAUDE_DIR2,
|
|
2275
|
+
"plugins",
|
|
2276
|
+
"cache",
|
|
2277
|
+
"local-plugins",
|
|
2278
|
+
"fml"
|
|
2279
|
+
);
|
|
466
2280
|
function readJsonFile2(filePath) {
|
|
467
2281
|
try {
|
|
468
2282
|
return JSON.parse(fs2.readFileSync(filePath, "utf-8"));
|
|
@@ -478,9 +2292,48 @@ function handleUninstall(opts) {
|
|
|
478
2292
|
const targetSpecific = opts.target && opts.target !== "all";
|
|
479
2293
|
console.log("Uninstalling fml...\n");
|
|
480
2294
|
if (targetSpecific) {
|
|
481
|
-
console.log("[1/
|
|
2295
|
+
console.log("[1/5] Skipping plugin uninstall (target-specific uninstall)");
|
|
2296
|
+
} else {
|
|
2297
|
+
console.log("[1/5] Uninstalling MCP plugin...");
|
|
2298
|
+
try {
|
|
2299
|
+
execFileSync2(
|
|
2300
|
+
"claude",
|
|
2301
|
+
["plugin", "uninstall", "fml@local-plugins", "--scope", "user"],
|
|
2302
|
+
{ stdio: "pipe", timeout: 1e4 }
|
|
2303
|
+
);
|
|
2304
|
+
console.log(" Uninstalled (user scope)");
|
|
2305
|
+
} catch {
|
|
2306
|
+
}
|
|
2307
|
+
const installedPluginsPath = path3.join(
|
|
2308
|
+
CLAUDE_DIR2,
|
|
2309
|
+
"plugins",
|
|
2310
|
+
"installed_plugins.json"
|
|
2311
|
+
);
|
|
2312
|
+
const installedPlugins = readJsonFile2(installedPluginsPath);
|
|
2313
|
+
const plugins = installedPlugins?.plugins;
|
|
2314
|
+
const fmlEntries = plugins?.["fml@local-plugins"];
|
|
2315
|
+
if (plugins && fmlEntries) {
|
|
2316
|
+
for (const entry of fmlEntries) {
|
|
2317
|
+
const e = entry;
|
|
2318
|
+
if (e.scope === "project" && e.projectPath) {
|
|
2319
|
+
const projSettings = path3.join(e.projectPath, ".claude", "settings.json");
|
|
2320
|
+
const proj = readJsonFile2(projSettings);
|
|
2321
|
+
if (proj?.enabledPlugins?.["fml@local-plugins"] != null) {
|
|
2322
|
+
delete proj.enabledPlugins["fml@local-plugins"];
|
|
2323
|
+
writeJsonFile2(projSettings, proj);
|
|
2324
|
+
console.log(` Cleaned ${projSettings}`);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
delete plugins["fml@local-plugins"];
|
|
2329
|
+
writeJsonFile2(installedPluginsPath, installedPlugins);
|
|
2330
|
+
console.log(" Cleaned installed_plugins.json");
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
if (targetSpecific) {
|
|
2334
|
+
console.log("[2/5] Skipping plugin settings (target-specific uninstall)");
|
|
482
2335
|
} else {
|
|
483
|
-
console.log("[
|
|
2336
|
+
console.log("[2/5] Removing plugin from Claude Code settings...");
|
|
484
2337
|
const settings = readJsonFile2(CLAUDE_SETTINGS_PATH2);
|
|
485
2338
|
if (settings) {
|
|
486
2339
|
if (settings.enabledPlugins) {
|
|
@@ -496,17 +2349,17 @@ function handleUninstall(opts) {
|
|
|
496
2349
|
}
|
|
497
2350
|
}
|
|
498
2351
|
if (targetSpecific) {
|
|
499
|
-
console.log("[
|
|
2352
|
+
console.log("[3/5] Skipping marketplace (target-specific uninstall)");
|
|
500
2353
|
} else {
|
|
501
|
-
console.log("[
|
|
502
|
-
const marketplaceLink =
|
|
2354
|
+
console.log("[3/5] Removing marketplace registration...");
|
|
2355
|
+
const marketplaceLink = path3.join(MARKETPLACE_DIR2, "fml");
|
|
503
2356
|
try {
|
|
504
2357
|
fs2.rmSync(marketplaceLink, { recursive: true, force: true });
|
|
505
2358
|
console.log(` Removed ${marketplaceLink}`);
|
|
506
2359
|
} catch {
|
|
507
2360
|
console.log(" No marketplace link found, skipping");
|
|
508
2361
|
}
|
|
509
|
-
const manifestPath =
|
|
2362
|
+
const manifestPath = path3.join(
|
|
510
2363
|
MARKETPLACE_DIR2,
|
|
511
2364
|
".claude-plugin",
|
|
512
2365
|
"marketplace.json"
|
|
@@ -518,7 +2371,7 @@ function handleUninstall(opts) {
|
|
|
518
2371
|
console.log(` Updated ${manifestPath}`);
|
|
519
2372
|
}
|
|
520
2373
|
}
|
|
521
|
-
console.log("[
|
|
2374
|
+
console.log("[4/5] Running panopticon uninstall...");
|
|
522
2375
|
const panoArgs = ["uninstall"];
|
|
523
2376
|
if (opts.target) panoArgs.push("--target", opts.target);
|
|
524
2377
|
if (opts.purge) panoArgs.push("--purge");
|
|
@@ -534,9 +2387,18 @@ function handleUninstall(opts) {
|
|
|
534
2387
|
}
|
|
535
2388
|
}
|
|
536
2389
|
if (targetSpecific) {
|
|
537
|
-
console.log("[
|
|
538
|
-
} else
|
|
539
|
-
console.log("[
|
|
2390
|
+
console.log("[5/5] Skipping data removal (target-specific uninstall)");
|
|
2391
|
+
} else {
|
|
2392
|
+
console.log("[5/5] Removing plugin cache...");
|
|
2393
|
+
try {
|
|
2394
|
+
fs2.rmSync(PLUGIN_CACHE_DIR, { recursive: true, force: true });
|
|
2395
|
+
console.log(` Removed ${PLUGIN_CACHE_DIR}`);
|
|
2396
|
+
} catch {
|
|
2397
|
+
console.log(" No plugin cache found");
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
if (opts.purge) {
|
|
2401
|
+
console.log("Removing fml data and logs...");
|
|
540
2402
|
for (const dir of [FML_DATA_DIR, FML_LOG_DIR]) {
|
|
541
2403
|
try {
|
|
542
2404
|
fs2.rmSync(dir, { recursive: true, force: true });
|
|
@@ -546,7 +2408,7 @@ function handleUninstall(opts) {
|
|
|
546
2408
|
}
|
|
547
2409
|
}
|
|
548
2410
|
} else {
|
|
549
|
-
console.log("
|
|
2411
|
+
console.log("Keeping fml data (use --purge to remove)");
|
|
550
2412
|
}
|
|
551
2413
|
console.log("\nDone! FML has been uninstalled.");
|
|
552
2414
|
}
|
|
@@ -554,7 +2416,7 @@ function handleUninstall(opts) {
|
|
|
554
2416
|
// src/commands/update.ts
|
|
555
2417
|
import { execSync as execSync2 } from "child_process";
|
|
556
2418
|
async function handleUpdate() {
|
|
557
|
-
const currentVersion = true ? "0.0.
|
|
2419
|
+
const currentVersion = true ? "0.0.28+44c986f" : "unknown";
|
|
558
2420
|
console.log(`Current: ${currentVersion}`);
|
|
559
2421
|
console.log("Updating via npm...\n");
|
|
560
2422
|
try {
|
|
@@ -576,7 +2438,7 @@ async function handleUpdate() {
|
|
|
576
2438
|
|
|
577
2439
|
// src/auth/oauth.ts
|
|
578
2440
|
import crypto from "crypto";
|
|
579
|
-
import
|
|
2441
|
+
import http2 from "http";
|
|
580
2442
|
async function fetchWorkosClientId() {
|
|
581
2443
|
const { ConvexHttpClient } = await import("convex/browser");
|
|
582
2444
|
const client = new ConvexHttpClient(CONVEX_URL);
|
|
@@ -584,6 +2446,22 @@ async function fetchWorkosClientId() {
|
|
|
584
2446
|
const result = await client.query(ref, {});
|
|
585
2447
|
return result.workosClientId;
|
|
586
2448
|
}
|
|
2449
|
+
async function canOpenBrowser() {
|
|
2450
|
+
if (process.env.FML_DEVICE_FLOW === "1") return false;
|
|
2451
|
+
if (process.env.FML_NO_BROWSER === "1") return false;
|
|
2452
|
+
if (process.platform === "linux" && !process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) {
|
|
2453
|
+
return false;
|
|
2454
|
+
}
|
|
2455
|
+
if (process.env.SSH_CONNECTION) return false;
|
|
2456
|
+
if (process.env.CODESPACES) return false;
|
|
2457
|
+
if (process.env.REMOTE_CONTAINERS) return false;
|
|
2458
|
+
try {
|
|
2459
|
+
const fs4 = await import("fs");
|
|
2460
|
+
if (fs4.existsSync("/.dockerenv")) return false;
|
|
2461
|
+
} catch {
|
|
2462
|
+
}
|
|
2463
|
+
return true;
|
|
2464
|
+
}
|
|
587
2465
|
async function login() {
|
|
588
2466
|
const clientId = await fetchWorkosClientId();
|
|
589
2467
|
const codeVerifier = crypto.randomBytes(32).toString("base64url");
|
|
@@ -647,7 +2525,7 @@ function startCallbackServer(expectedState) {
|
|
|
647
2525
|
resolveCode = res;
|
|
648
2526
|
rejectCode = rej;
|
|
649
2527
|
});
|
|
650
|
-
const server =
|
|
2528
|
+
const server = http2.createServer((req, res) => {
|
|
651
2529
|
const url = new URL(req.url ?? "/", `http://localhost`);
|
|
652
2530
|
if (url.pathname === "/callback") {
|
|
653
2531
|
const code = url.searchParams.get("code");
|
|
@@ -707,6 +2585,93 @@ function startCallbackServer(expectedState) {
|
|
|
707
2585
|
});
|
|
708
2586
|
}
|
|
709
2587
|
|
|
2588
|
+
// src/auth/device-flow.ts
|
|
2589
|
+
import { createInterface } from "readline";
|
|
2590
|
+
function sleep(ms) {
|
|
2591
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2592
|
+
}
|
|
2593
|
+
function prompt(question) {
|
|
2594
|
+
const rl = createInterface({
|
|
2595
|
+
input: process.stdin,
|
|
2596
|
+
output: process.stderr
|
|
2597
|
+
// Use stderr so stdout stays clean for MCP
|
|
2598
|
+
});
|
|
2599
|
+
return new Promise((resolve) => {
|
|
2600
|
+
rl.question(question, (answer) => {
|
|
2601
|
+
rl.close();
|
|
2602
|
+
resolve(answer.trim());
|
|
2603
|
+
});
|
|
2604
|
+
});
|
|
2605
|
+
}
|
|
2606
|
+
async function deviceLogin() {
|
|
2607
|
+
const siteUrl = getSiteUrl();
|
|
2608
|
+
const codeRes = await fetch(`${siteUrl}/api/auth/device/code`, {
|
|
2609
|
+
method: "POST",
|
|
2610
|
+
headers: { "Content-Type": "application/json" }
|
|
2611
|
+
});
|
|
2612
|
+
if (!codeRes.ok) {
|
|
2613
|
+
const body = await codeRes.text();
|
|
2614
|
+
throw new Error(`Failed to start device flow: ${body}`);
|
|
2615
|
+
}
|
|
2616
|
+
const codeData = await codeRes.json();
|
|
2617
|
+
console.log("");
|
|
2618
|
+
console.log(" Paste this URL in your browser to sign in:");
|
|
2619
|
+
console.log("");
|
|
2620
|
+
console.log(` ${codeData.verificationUri}`);
|
|
2621
|
+
console.log("");
|
|
2622
|
+
const confirmationCode = await prompt(" Enter the code from your browser: ");
|
|
2623
|
+
if (!confirmationCode) {
|
|
2624
|
+
throw new Error("No confirmation code entered.");
|
|
2625
|
+
}
|
|
2626
|
+
const normalizedCode = confirmationCode.toUpperCase().replace(/[\s-]/g, "").replace(/^(.{4})/, "$1-");
|
|
2627
|
+
console.log(" Verifying...");
|
|
2628
|
+
let pollInterval = codeData.interval * 1e3;
|
|
2629
|
+
while (Date.now() < codeData.expiresAt) {
|
|
2630
|
+
const pollRes = await fetch(`${siteUrl}/api/auth/device/poll`, {
|
|
2631
|
+
method: "POST",
|
|
2632
|
+
headers: { "Content-Type": "application/json" },
|
|
2633
|
+
body: JSON.stringify({
|
|
2634
|
+
deviceCode: codeData.deviceCode,
|
|
2635
|
+
confirmationCode: normalizedCode
|
|
2636
|
+
})
|
|
2637
|
+
});
|
|
2638
|
+
if (pollRes.status === 429) {
|
|
2639
|
+
const data2 = await pollRes.json();
|
|
2640
|
+
pollInterval = (data2.interval ?? codeData.interval * 2) * 1e3;
|
|
2641
|
+
await sleep(pollInterval);
|
|
2642
|
+
continue;
|
|
2643
|
+
}
|
|
2644
|
+
const data = await pollRes.json();
|
|
2645
|
+
if (data.status === "pending") {
|
|
2646
|
+
await sleep(pollInterval);
|
|
2647
|
+
continue;
|
|
2648
|
+
}
|
|
2649
|
+
if (data.status === "authorized") {
|
|
2650
|
+
writeTokens({
|
|
2651
|
+
accessToken: data.accessToken,
|
|
2652
|
+
refreshToken: data.refreshToken,
|
|
2653
|
+
expiresAt: data.expiresAt,
|
|
2654
|
+
user: data.user,
|
|
2655
|
+
orgSlug: data.orgSlug ?? void 0,
|
|
2656
|
+
tokenType: "service"
|
|
2657
|
+
});
|
|
2658
|
+
return { email: data.user.email, name: data.user.name };
|
|
2659
|
+
}
|
|
2660
|
+
if (data.status === "invalid_code") {
|
|
2661
|
+
throw new Error(
|
|
2662
|
+
"Invalid confirmation code. Make sure you copied the code from the browser correctly."
|
|
2663
|
+
);
|
|
2664
|
+
}
|
|
2665
|
+
if (data.status === "expired") {
|
|
2666
|
+
throw new Error("Device authorization expired. Run `fml login` again.");
|
|
2667
|
+
}
|
|
2668
|
+
throw new Error(`Device authorization failed: ${data.status}`);
|
|
2669
|
+
}
|
|
2670
|
+
throw new Error(
|
|
2671
|
+
"Device authorization timed out (15 minutes). Run `fml login` again."
|
|
2672
|
+
);
|
|
2673
|
+
}
|
|
2674
|
+
|
|
710
2675
|
// src/commands/login.ts
|
|
711
2676
|
async function linkGitHubIdentity() {
|
|
712
2677
|
const token = resolveGitHubToken();
|
|
@@ -733,6 +2698,9 @@ async function linkGitHubIdentity() {
|
|
|
733
2698
|
console.warn("[fml] No FML token available \u2014 skipping identity link");
|
|
734
2699
|
return;
|
|
735
2700
|
}
|
|
2701
|
+
if (fmlToken.startsWith("fml_st_")) {
|
|
2702
|
+
return;
|
|
2703
|
+
}
|
|
736
2704
|
if (!CONVEX_URL) {
|
|
737
2705
|
console.warn(
|
|
738
2706
|
"[fml] No Convex URL configured \u2014 skipping identity link (run fml install first)"
|
|
@@ -768,11 +2736,11 @@ async function selectOrg() {
|
|
|
768
2736
|
} catch {
|
|
769
2737
|
}
|
|
770
2738
|
}
|
|
771
|
-
async function handleLogin() {
|
|
2739
|
+
async function handleLogin(opts) {
|
|
772
2740
|
const { name: envName } = getActiveEnv();
|
|
773
2741
|
const existingToken = await getValidToken();
|
|
774
2742
|
if (existingToken) {
|
|
775
|
-
const { readTokens: readTokens2 } = await import("./token-store-
|
|
2743
|
+
const { readTokens: readTokens2 } = await import("./token-store-Y35HF3FJ.js");
|
|
776
2744
|
const stored = readTokens2();
|
|
777
2745
|
console.log(
|
|
778
2746
|
`Already logged in as ${stored?.user.name} (${stored?.user.email}) on ${envName}.`
|
|
@@ -784,9 +2752,15 @@ async function handleLogin() {
|
|
|
784
2752
|
}
|
|
785
2753
|
console.log(`Signing in to FML (${envName})...`);
|
|
786
2754
|
try {
|
|
787
|
-
const
|
|
2755
|
+
const useDeviceFlow = opts?.device || !await canOpenBrowser();
|
|
2756
|
+
let result;
|
|
2757
|
+
if (useDeviceFlow) {
|
|
2758
|
+
result = await deviceLogin();
|
|
2759
|
+
} else {
|
|
2760
|
+
result = await login();
|
|
2761
|
+
}
|
|
788
2762
|
console.log(`
|
|
789
|
-
Logged in as ${name} (${email})`);
|
|
2763
|
+
Logged in as ${result.name} (${result.email})`);
|
|
790
2764
|
await linkGitHubIdentity();
|
|
791
2765
|
await selectOrg();
|
|
792
2766
|
console.log("You're all set! Restart Claude Code to use FML tools.");
|
|
@@ -899,14 +2873,6 @@ async function handleStatus() {
|
|
|
899
2873
|
}
|
|
900
2874
|
|
|
901
2875
|
// src/commands/sync.ts
|
|
902
|
-
import {
|
|
903
|
-
addTarget as addTarget2,
|
|
904
|
-
removeTarget,
|
|
905
|
-
listTargets as listTargets2,
|
|
906
|
-
loadSyncConfig as loadSyncConfig2,
|
|
907
|
-
saveSyncConfig
|
|
908
|
-
} from "@fml-inc/panopticon/sync";
|
|
909
|
-
import { syncPending as syncPending2, syncReset } from "@fml-inc/panopticon/api";
|
|
910
2876
|
var FML_SYNC_URL = CONVEX_URL.replace(".cloud", ".site");
|
|
911
2877
|
async function handleSyncSetup() {
|
|
912
2878
|
console.log("FML Sync Setup\n");
|
|
@@ -918,7 +2884,7 @@ async function handleSyncSetup() {
|
|
|
918
2884
|
process.exit(1);
|
|
919
2885
|
}
|
|
920
2886
|
console.log("GitHub token: found");
|
|
921
|
-
|
|
2887
|
+
addTarget({
|
|
922
2888
|
name: DEFAULT_TARGET_NAME,
|
|
923
2889
|
url: FML_SYNC_URL,
|
|
924
2890
|
tokenCommand: "gh auth token"
|
|
@@ -931,7 +2897,7 @@ Sync target "${DEFAULT_TARGET_NAME}" configured:`);
|
|
|
931
2897
|
Restart panopticon to activate: fml stop && fml start`);
|
|
932
2898
|
}
|
|
933
2899
|
async function handleSyncList() {
|
|
934
|
-
const targets =
|
|
2900
|
+
const targets = listTargets();
|
|
935
2901
|
if (targets.length === 0) {
|
|
936
2902
|
console.log(
|
|
937
2903
|
"No sync targets configured. Run `fml sync setup` or `fml sync add`."
|
|
@@ -947,14 +2913,14 @@ async function handleSyncList() {
|
|
|
947
2913
|
}
|
|
948
2914
|
}
|
|
949
2915
|
async function handleSyncAdd(name, url, opts) {
|
|
950
|
-
const existing =
|
|
2916
|
+
const existing = listTargets();
|
|
951
2917
|
if (existing.some((t) => t.name === name)) {
|
|
952
2918
|
console.error(
|
|
953
2919
|
`Target "${name}" already exists. Use \`fml sync edit\` to modify it.`
|
|
954
2920
|
);
|
|
955
2921
|
process.exit(1);
|
|
956
2922
|
}
|
|
957
|
-
|
|
2923
|
+
addTarget({
|
|
958
2924
|
name,
|
|
959
2925
|
url,
|
|
960
2926
|
tokenCommand: opts.tokenCmd,
|
|
@@ -978,8 +2944,8 @@ async function handleSyncRemove(name) {
|
|
|
978
2944
|
}
|
|
979
2945
|
}
|
|
980
2946
|
async function handleSyncEdit(name, opts) {
|
|
981
|
-
const
|
|
982
|
-
const target =
|
|
2947
|
+
const config3 = loadSyncConfig();
|
|
2948
|
+
const target = config3.targets.find((t) => t.name === name);
|
|
983
2949
|
if (!target) {
|
|
984
2950
|
console.error(`Target "${name}" not found.`);
|
|
985
2951
|
process.exit(1);
|
|
@@ -993,7 +2959,7 @@ async function handleSyncEdit(name, opts) {
|
|
|
993
2959
|
target.token = opts.token;
|
|
994
2960
|
delete target.tokenCommand;
|
|
995
2961
|
}
|
|
996
|
-
saveSyncConfig(
|
|
2962
|
+
saveSyncConfig(config3);
|
|
997
2963
|
console.log(`Sync target "${name}" updated:`);
|
|
998
2964
|
console.log(` URL: ${target.url}`);
|
|
999
2965
|
const auth = target.token ? "static token" : target.tokenCommand ? `command: ${target.tokenCommand}` : "none";
|
|
@@ -1001,7 +2967,7 @@ async function handleSyncEdit(name, opts) {
|
|
|
1001
2967
|
console.log("\nRestart panopticon to apply: fml stop && fml start");
|
|
1002
2968
|
}
|
|
1003
2969
|
async function handleSyncStatus() {
|
|
1004
|
-
const targets =
|
|
2970
|
+
const targets = listTargets();
|
|
1005
2971
|
if (targets.length === 0) {
|
|
1006
2972
|
console.log("No sync targets configured. Run `fml sync setup` first.");
|
|
1007
2973
|
return;
|
|
@@ -1012,7 +2978,7 @@ async function handleSyncStatus() {
|
|
|
1012
2978
|
console.log(` URL: ${target.url}`);
|
|
1013
2979
|
console.log(` Auth: ${auth}`);
|
|
1014
2980
|
try {
|
|
1015
|
-
const result = await
|
|
2981
|
+
const result = await syncPending(target.name);
|
|
1016
2982
|
if (result.totalPending === 0) {
|
|
1017
2983
|
console.log(" Status: up to date");
|
|
1018
2984
|
} else {
|
|
@@ -1038,14 +3004,13 @@ async function handleSyncReset(targetName) {
|
|
|
1038
3004
|
}
|
|
1039
3005
|
|
|
1040
3006
|
// src/commands/env.ts
|
|
1041
|
-
import { listTargets as listTargets3 } from "@fml-inc/panopticon/sync";
|
|
1042
3007
|
function handleEnvShow() {
|
|
1043
3008
|
const { name, convexUrl } = getActiveEnv();
|
|
1044
3009
|
console.log(`Environment: ${name}`);
|
|
1045
3010
|
console.log(` Convex URL: ${convexUrl}`);
|
|
1046
3011
|
}
|
|
1047
3012
|
async function handleEnvSwitch(target) {
|
|
1048
|
-
const targets =
|
|
3013
|
+
const targets = listTargets();
|
|
1049
3014
|
const match = targets.find((t) => t.name === target);
|
|
1050
3015
|
if (!match) {
|
|
1051
3016
|
console.error(`Sync target "${target}" not found. Available targets:`);
|
|
@@ -1615,7 +3580,7 @@ if (process.argv.length <= 2 || process.argv.includes("--help") || process.argv.
|
|
|
1615
3580
|
printBanner();
|
|
1616
3581
|
}
|
|
1617
3582
|
var program = new Command().name("fml").description("FML agent tools for Claude Code").version(
|
|
1618
|
-
true ? "0.0.
|
|
3583
|
+
true ? "0.0.28+44c986f" : "dev"
|
|
1619
3584
|
);
|
|
1620
3585
|
program.command("tools", { hidden: true }).description("List all available CLI commands (including hidden agent tools)").action(() => {
|
|
1621
3586
|
function formatCmd(cmd, prefix = "") {
|
|
@@ -1642,7 +3607,7 @@ program.command("uninstall").description("Remove fml plugin, hooks, and optional
|
|
|
1642
3607
|
"Target CLI: claude, gemini, codex, claude-desktop, all"
|
|
1643
3608
|
).option("--purge", "Also remove all data, logs, and auth tokens").action((opts) => handleUninstall(opts));
|
|
1644
3609
|
program.command("update").description("Update fml to the latest version").action(() => handleUpdate());
|
|
1645
|
-
program.command("login").description("Sign in to your FML account").action(() => handleLogin());
|
|
3610
|
+
program.command("login").description("Sign in to your FML account").option("--device", "Use device authorization flow (no browser needed)").action((opts) => handleLogin(opts));
|
|
1646
3611
|
program.command("logout").description("Sign out and clear stored credentials").action(() => handleLogout());
|
|
1647
3612
|
program.command("org").description("Show or select organization").argument("[slug]", "Org slug to select").action((slug) => handleOrg(slug));
|
|
1648
3613
|
program.command("status").description("Show current auth and daemon status").action(() => handleStatus());
|
|
@@ -1709,9 +3674,9 @@ messages.command("context").description("Get messages around a specific message"
|
|
|
1709
3674
|
var skills = program.command("skills", { hidden: true }).description("Browse and load skills");
|
|
1710
3675
|
skills.command("list").description("List available skills").action(() => handleSkillsList());
|
|
1711
3676
|
skills.command("load").description("Load a skill by ID").argument("<skill-id>", "Skill ID").action((skillId) => handleSkillsLoad(skillId));
|
|
1712
|
-
var
|
|
1713
|
-
|
|
1714
|
-
|
|
3677
|
+
var config2 = program.command("config", { hidden: true }).description("View team config snapshots");
|
|
3678
|
+
config2.command("list").description("List config snapshots for an org").requiredOption("--org <slug>", "Organization slug").option("--repo <full-name>", "Filter by repo (owner/name)").action((opts) => handleConfigList(opts));
|
|
3679
|
+
config2.command("detail").description("Get config snapshot detail").requiredOption("--org <slug>", "Organization slug").option("--user <username>", "GitHub username").option("--repo <full-name>", "Repository (owner/name)").action((opts) => handleConfigDetail(opts));
|
|
1715
3680
|
program.parseAsync(process.argv).catch((err) => {
|
|
1716
3681
|
Sentry.captureException(err);
|
|
1717
3682
|
console.error(err);
|