epicshop 6.65.0 → 6.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +18 -0
- package/dist/utils/sentry-cli.d.ts +18 -0
- package/dist/utils/sentry-cli.js +135 -0
- package/package.json +6 -5
package/dist/cli.js
CHANGED
|
@@ -5,9 +5,11 @@ import { matchSorter } from 'match-sorter';
|
|
|
5
5
|
import yargs from 'yargs';
|
|
6
6
|
import { hideBin } from 'yargs/helpers';
|
|
7
7
|
import { assertCanPrompt } from "./utils/cli-runtime.js";
|
|
8
|
+
import { initCliSentry } from "./utils/sentry-cli.js";
|
|
8
9
|
// Check for --help on start command before yargs parses
|
|
9
10
|
// (yargs exits before command handler when help is requested)
|
|
10
11
|
const args = hideBin(process.argv);
|
|
12
|
+
const cliSentry = initCliSentry(args);
|
|
11
13
|
if ((args.includes('--help') || args.includes('-h')) &&
|
|
12
14
|
(args.length === 0 || args[0] === 'start')) {
|
|
13
15
|
const { displayHelp } = await import("./commands/start.js");
|
|
@@ -34,6 +36,9 @@ const cli = yargs(args)
|
|
|
34
36
|
.alias('h', 'help')
|
|
35
37
|
.version(false)
|
|
36
38
|
.showHelpOnFail(true)
|
|
39
|
+
.middleware((argv) => {
|
|
40
|
+
cliSentry.setCommandContextFromArgv(argv);
|
|
41
|
+
})
|
|
37
42
|
.command('start [workshop]', 'Start a workshop (auto-detects if inside a workshop directory)', (yargs) => {
|
|
38
43
|
return yargs
|
|
39
44
|
.positional('workshop', {
|
|
@@ -663,6 +668,12 @@ const cli = yargs(args)
|
|
|
663
668
|
throw error;
|
|
664
669
|
}
|
|
665
670
|
}
|
|
671
|
+
if (!argv.subcommand) {
|
|
672
|
+
cliSentry.setCommandContext({
|
|
673
|
+
command: 'auth',
|
|
674
|
+
subcommand,
|
|
675
|
+
});
|
|
676
|
+
}
|
|
666
677
|
let result;
|
|
667
678
|
switch (subcommand) {
|
|
668
679
|
case 'status':
|
|
@@ -1172,6 +1183,7 @@ try {
|
|
|
1172
1183
|
});
|
|
1173
1184
|
},
|
|
1174
1185
|
});
|
|
1186
|
+
cliSentry.setCommandContext({ command: subcommand, interactive: true });
|
|
1175
1187
|
switch (subcommand) {
|
|
1176
1188
|
case 'start': {
|
|
1177
1189
|
const { findWorkshopRoot, startWorkshop } = await import("./commands/workshops.js");
|
|
@@ -1421,6 +1433,10 @@ try {
|
|
|
1421
1433
|
});
|
|
1422
1434
|
},
|
|
1423
1435
|
});
|
|
1436
|
+
cliSentry.setCommandContext({
|
|
1437
|
+
command: 'auth',
|
|
1438
|
+
subcommand: authSubcommand,
|
|
1439
|
+
});
|
|
1424
1440
|
let authResult;
|
|
1425
1441
|
switch (authSubcommand) {
|
|
1426
1442
|
case 'status':
|
|
@@ -1532,6 +1548,8 @@ catch (error) {
|
|
|
1532
1548
|
if (error.message === 'USER_QUIT') {
|
|
1533
1549
|
process.exit(0);
|
|
1534
1550
|
}
|
|
1551
|
+
cliSentry.captureException(error);
|
|
1552
|
+
await cliSentry.flush();
|
|
1535
1553
|
console.error(chalk.red('❌ Error:'), error);
|
|
1536
1554
|
process.exit(1);
|
|
1537
1555
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type CliCommandContext = {
|
|
2
|
+
command?: string;
|
|
3
|
+
subcommand?: string;
|
|
4
|
+
flags?: string[];
|
|
5
|
+
interactive?: boolean;
|
|
6
|
+
help?: boolean;
|
|
7
|
+
};
|
|
8
|
+
type CliSentry = {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
setCommandContext: (update: Partial<CliCommandContext>) => void;
|
|
11
|
+
setCommandContextFromArgv: (argv: {
|
|
12
|
+
_: Array<string | number>;
|
|
13
|
+
}) => void;
|
|
14
|
+
captureException: (error: unknown) => void;
|
|
15
|
+
flush: (timeoutMs?: number) => Promise<boolean>;
|
|
16
|
+
};
|
|
17
|
+
export declare function initCliSentry(args: string[]): CliSentry;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/node';
|
|
2
|
+
import { getEnv } from '@epic-web/workshop-utils/init-env';
|
|
3
|
+
const HELP_FLAGS = new Set(['--help', '-h']);
|
|
4
|
+
function extractFlags(args) {
|
|
5
|
+
const flags = new Set();
|
|
6
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
7
|
+
const arg = args[i];
|
|
8
|
+
if (!arg || arg === '-' || !arg.startsWith('-')) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
if (arg === '--') {
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
if (arg.startsWith('--')) {
|
|
15
|
+
const [flag] = arg.split('=');
|
|
16
|
+
if (flag)
|
|
17
|
+
flags.add(flag);
|
|
18
|
+
if (!arg.includes('=') && args[i + 1] && !args[i + 1]?.startsWith('-')) {
|
|
19
|
+
i += 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
flags.add(arg);
|
|
24
|
+
if (arg.length === 2 && args[i + 1] && !args[i + 1]?.startsWith('-')) {
|
|
25
|
+
i += 1;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return Array.from(flags).sort();
|
|
30
|
+
}
|
|
31
|
+
function deriveCommandContext(args) {
|
|
32
|
+
const interactive = args.length === 0;
|
|
33
|
+
const doubleDashIndex = args.indexOf('--');
|
|
34
|
+
const argsBeforeDoubleDash = doubleDashIndex >= 0 ? args.slice(0, doubleDashIndex) : args;
|
|
35
|
+
const help = argsBeforeDoubleDash.some((arg) => HELP_FLAGS.has(arg));
|
|
36
|
+
const flags = extractFlags(args);
|
|
37
|
+
let command;
|
|
38
|
+
const firstNonFlagIndex = args.findIndex((arg) => !arg.startsWith('-'));
|
|
39
|
+
if (firstNonFlagIndex >= 0) {
|
|
40
|
+
command = args[firstNonFlagIndex];
|
|
41
|
+
}
|
|
42
|
+
if (!command) {
|
|
43
|
+
if (help) {
|
|
44
|
+
command = 'help';
|
|
45
|
+
}
|
|
46
|
+
else if (interactive) {
|
|
47
|
+
command = 'chooser';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
command,
|
|
52
|
+
flags,
|
|
53
|
+
interactive,
|
|
54
|
+
help: help || command === 'help',
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function deriveCommandContextFromArgv(args, argv) {
|
|
58
|
+
const baseContext = deriveCommandContext(args);
|
|
59
|
+
const segments = argv._?.map(String).filter(Boolean) ?? [];
|
|
60
|
+
const command = segments[0] ?? baseContext.command;
|
|
61
|
+
const hasSubcommand = Object.prototype.hasOwnProperty.call(argv, 'subcommand');
|
|
62
|
+
const subcommand = hasSubcommand && typeof argv.subcommand === 'string'
|
|
63
|
+
? argv.subcommand
|
|
64
|
+
: baseContext.subcommand;
|
|
65
|
+
const help = Boolean(argv.help ?? argv.h ?? baseContext.help);
|
|
66
|
+
return {
|
|
67
|
+
...baseContext,
|
|
68
|
+
command,
|
|
69
|
+
subcommand,
|
|
70
|
+
help,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function applyCommandContext(context) {
|
|
74
|
+
Sentry.setTag('cli.command', context.command ?? 'unknown');
|
|
75
|
+
Sentry.setTag('cli.subcommand', context.subcommand ?? 'none');
|
|
76
|
+
if (context.interactive !== undefined) {
|
|
77
|
+
Sentry.setTag('cli.interactive', context.interactive ? 'true' : 'false');
|
|
78
|
+
}
|
|
79
|
+
if (context.help !== undefined) {
|
|
80
|
+
Sentry.setTag('cli.help', context.help ? 'true' : 'false');
|
|
81
|
+
}
|
|
82
|
+
Sentry.setContext('cli', {
|
|
83
|
+
command: context.command ?? 'unknown',
|
|
84
|
+
subcommand: context.subcommand ?? null,
|
|
85
|
+
flags: context.flags ?? [],
|
|
86
|
+
interactive: context.interactive ?? false,
|
|
87
|
+
help: context.help ?? false,
|
|
88
|
+
stdin_tty: Boolean(process.stdin.isTTY),
|
|
89
|
+
stdout_tty: Boolean(process.stdout.isTTY),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export function initCliSentry(args) {
|
|
93
|
+
const env = getEnv();
|
|
94
|
+
const enabled = env.EPICSHOP_IS_PUBLISHED && Boolean(env.SENTRY_DSN);
|
|
95
|
+
if (!enabled) {
|
|
96
|
+
return {
|
|
97
|
+
enabled,
|
|
98
|
+
setCommandContext: () => { },
|
|
99
|
+
setCommandContextFromArgv: () => { },
|
|
100
|
+
captureException: () => { },
|
|
101
|
+
flush: async () => true,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
Sentry.init({
|
|
105
|
+
dsn: env.SENTRY_DSN,
|
|
106
|
+
sendDefaultPii: false,
|
|
107
|
+
environment: env.EPICSHOP_IS_PUBLISHED ? 'production' : 'development',
|
|
108
|
+
tracesSampleRate: 1,
|
|
109
|
+
});
|
|
110
|
+
Sentry.setTags({
|
|
111
|
+
epicshop_github_repo: env.EPICSHOP_GITHUB_REPO || 'unknown',
|
|
112
|
+
epicshop_workshop_instance_id: env.EPICSHOP_WORKSHOP_INSTANCE_ID || 'unknown',
|
|
113
|
+
epicshop_app_version: env.EPICSHOP_APP_VERSION || 'unknown',
|
|
114
|
+
epicshop_published: env.EPICSHOP_IS_PUBLISHED ? 'true' : 'false',
|
|
115
|
+
});
|
|
116
|
+
let currentContext = deriveCommandContext(args);
|
|
117
|
+
applyCommandContext(currentContext);
|
|
118
|
+
return {
|
|
119
|
+
enabled,
|
|
120
|
+
setCommandContext(update) {
|
|
121
|
+
currentContext = { ...currentContext, ...update };
|
|
122
|
+
applyCommandContext(currentContext);
|
|
123
|
+
},
|
|
124
|
+
setCommandContextFromArgv(argv) {
|
|
125
|
+
currentContext = deriveCommandContextFromArgv(args, argv);
|
|
126
|
+
applyCommandContext(currentContext);
|
|
127
|
+
},
|
|
128
|
+
captureException(error) {
|
|
129
|
+
Sentry.captureException(error);
|
|
130
|
+
},
|
|
131
|
+
flush(timeoutMs = 2000) {
|
|
132
|
+
return Sentry.flush(timeoutMs);
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "epicshop",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.67.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -93,15 +93,16 @@
|
|
|
93
93
|
"build:watch": "nx watch --projects=epicshop -- nx run \\$NX_PROJECT_NAME:build"
|
|
94
94
|
},
|
|
95
95
|
"dependencies": {
|
|
96
|
-
"@epic-web/workshop-utils": "6.
|
|
96
|
+
"@epic-web/workshop-utils": "6.67.0",
|
|
97
97
|
"@inquirer/prompts": "^8.2.0",
|
|
98
|
+
"@sentry/node": "^10.35.0",
|
|
98
99
|
"chalk": "^5.6.2",
|
|
99
100
|
"close-with-grace": "^2.4.0",
|
|
100
101
|
"execa": "^9.6.1",
|
|
101
102
|
"get-port": "^7.1.0",
|
|
102
103
|
"match-sorter": "^8.2.0",
|
|
103
|
-
"openid-client": "^6.8.1",
|
|
104
104
|
"open": "^11.0.0",
|
|
105
|
+
"openid-client": "^6.8.1",
|
|
105
106
|
"ora": "^9.0.0",
|
|
106
107
|
"yargs": "^18.0.0"
|
|
107
108
|
},
|
|
@@ -109,8 +110,8 @@
|
|
|
109
110
|
"@epic-web/config": "^1.21.3",
|
|
110
111
|
"@types/node": "^25.0.9",
|
|
111
112
|
"@types/yargs": "^17.0.35",
|
|
112
|
-
"
|
|
113
|
-
"
|
|
113
|
+
"vitest": "^4.0.17",
|
|
114
|
+
"zshy": "^0.7.0"
|
|
114
115
|
},
|
|
115
116
|
"repository": {
|
|
116
117
|
"type": "git",
|