epicshop 6.81.0 → 6.82.1
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 +42 -13
- package/dist/commands/workshops.d.ts +1 -1
- package/dist/commands/workshops.js +15 -2
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -28,6 +28,15 @@ function formatHelp(helpText) {
|
|
|
28
28
|
.replace(/--[\w-]+/g, (match) => chalk.yellow(match))
|
|
29
29
|
.replace(/-\w(?=\s|,)/g, (match) => chalk.yellow(match));
|
|
30
30
|
}
|
|
31
|
+
function resolveWorkshopContextCwd(explicitWorkshopDir) {
|
|
32
|
+
const fromFlag = explicitWorkshopDir?.trim()
|
|
33
|
+
? explicitWorkshopDir.trim()
|
|
34
|
+
: undefined;
|
|
35
|
+
if (fromFlag)
|
|
36
|
+
return fromFlag;
|
|
37
|
+
const fromEnv = process.env.EPICSHOP_CONTEXT_CWD;
|
|
38
|
+
return fromEnv?.trim() ? fromEnv.trim() : undefined;
|
|
39
|
+
}
|
|
31
40
|
// Set up yargs CLI
|
|
32
41
|
const cli = yargs(args)
|
|
33
42
|
.scriptName('epicshop')
|
|
@@ -767,6 +776,11 @@ const cli = yargs(args)
|
|
|
767
776
|
type: 'boolean',
|
|
768
777
|
description: 'Output saved playgrounds as JSON (saved list)',
|
|
769
778
|
default: false,
|
|
779
|
+
})
|
|
780
|
+
.option('workshop-dir', {
|
|
781
|
+
alias: 'w',
|
|
782
|
+
type: 'string',
|
|
783
|
+
description: 'Path to a workshop directory to use as context (instead of the current working directory)',
|
|
770
784
|
})
|
|
771
785
|
.option('silent', {
|
|
772
786
|
alias: 's',
|
|
@@ -784,9 +798,9 @@ const cli = yargs(args)
|
|
|
784
798
|
.example('$0 playground saved 2026.01.18_11.12.00_01.01.problem', 'Set playground from a saved copy');
|
|
785
799
|
}, async (argv) => {
|
|
786
800
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
787
|
-
const workshopRoot = await findWorkshopRoot();
|
|
801
|
+
const workshopRoot = await findWorkshopRoot(resolveWorkshopContextCwd(argv.workshopDir));
|
|
788
802
|
if (!workshopRoot) {
|
|
789
|
-
console.error(chalk.red('❌
|
|
803
|
+
console.error(chalk.red('❌ Workshop not found. Please cd into a workshop directory or pass --workshop-dir.'));
|
|
790
804
|
process.exit(1);
|
|
791
805
|
}
|
|
792
806
|
const originalCwd = process.cwd();
|
|
@@ -903,6 +917,11 @@ const cli = yargs(args)
|
|
|
903
917
|
type: 'boolean',
|
|
904
918
|
description: 'Output as JSON',
|
|
905
919
|
default: false,
|
|
920
|
+
})
|
|
921
|
+
.option('workshop-dir', {
|
|
922
|
+
alias: 'w',
|
|
923
|
+
type: 'string',
|
|
924
|
+
description: 'Path to a workshop directory to use as context (instead of the current working directory)',
|
|
906
925
|
})
|
|
907
926
|
.option('silent', {
|
|
908
927
|
alias: 's',
|
|
@@ -917,9 +936,9 @@ const cli = yargs(args)
|
|
|
917
936
|
.example('$0 progress update 01-01-problem --incomplete', 'Mark lesson as incomplete');
|
|
918
937
|
}, async (argv) => {
|
|
919
938
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
920
|
-
const workshopRoot = await findWorkshopRoot();
|
|
939
|
+
const workshopRoot = await findWorkshopRoot(resolveWorkshopContextCwd(argv.workshopDir));
|
|
921
940
|
if (!workshopRoot) {
|
|
922
|
-
console.error(chalk.red('❌
|
|
941
|
+
console.error(chalk.red('❌ Workshop not found. Please cd into a workshop directory or pass --workshop-dir.'));
|
|
923
942
|
process.exit(1);
|
|
924
943
|
}
|
|
925
944
|
const originalCwd = process.cwd();
|
|
@@ -970,14 +989,19 @@ const cli = yargs(args)
|
|
|
970
989
|
type: 'boolean',
|
|
971
990
|
description: 'Run without output logs',
|
|
972
991
|
default: false,
|
|
992
|
+
})
|
|
993
|
+
.option('workshop-dir', {
|
|
994
|
+
alias: 'w',
|
|
995
|
+
type: 'string',
|
|
996
|
+
description: 'Path to a workshop directory to use as context (instead of the current working directory)',
|
|
973
997
|
})
|
|
974
998
|
.example('$0 diff', 'Select apps to diff (defaults to playground vs solution)')
|
|
975
999
|
.example('$0 diff 01.02.problem 01.02.solution', 'Show diff between two apps');
|
|
976
1000
|
}, async (argv) => {
|
|
977
1001
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
978
|
-
const workshopRoot = await findWorkshopRoot();
|
|
1002
|
+
const workshopRoot = await findWorkshopRoot(resolveWorkshopContextCwd(argv.workshopDir));
|
|
979
1003
|
if (!workshopRoot) {
|
|
980
|
-
console.error(chalk.red('❌
|
|
1004
|
+
console.error(chalk.red('❌ Workshop not found. Please cd into a workshop directory or pass --workshop-dir.'));
|
|
981
1005
|
process.exit(1);
|
|
982
1006
|
}
|
|
983
1007
|
const originalCwd = process.cwd();
|
|
@@ -1027,6 +1051,11 @@ const cli = yargs(args)
|
|
|
1027
1051
|
type: 'boolean',
|
|
1028
1052
|
description: 'Run without output logs',
|
|
1029
1053
|
default: false,
|
|
1054
|
+
})
|
|
1055
|
+
.option('workshop-dir', {
|
|
1056
|
+
alias: 'w',
|
|
1057
|
+
type: 'string',
|
|
1058
|
+
description: 'Path to a workshop directory to use as context (instead of the current working directory)',
|
|
1030
1059
|
})
|
|
1031
1060
|
.example('$0 exercises', 'List all exercises with progress')
|
|
1032
1061
|
.example('$0 exercises 1', 'Show details for exercise 1')
|
|
@@ -1034,9 +1063,9 @@ const cli = yargs(args)
|
|
|
1034
1063
|
.example('$0 exercises --json', 'Output exercises as JSON');
|
|
1035
1064
|
}, async (argv) => {
|
|
1036
1065
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
1037
|
-
const workshopRoot = await findWorkshopRoot();
|
|
1066
|
+
const workshopRoot = await findWorkshopRoot(resolveWorkshopContextCwd(argv.workshopDir));
|
|
1038
1067
|
if (!workshopRoot) {
|
|
1039
|
-
console.error(chalk.red('❌
|
|
1068
|
+
console.error(chalk.red('❌ Workshop not found. Please cd into a workshop directory or pass --workshop-dir.'));
|
|
1040
1069
|
process.exit(1);
|
|
1041
1070
|
}
|
|
1042
1071
|
const originalCwd = process.cwd();
|
|
@@ -1087,7 +1116,7 @@ try {
|
|
|
1087
1116
|
if (args.length === 0) {
|
|
1088
1117
|
// Check if we're inside a workshop first
|
|
1089
1118
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
1090
|
-
const workshopRoot = await findWorkshopRoot();
|
|
1119
|
+
const workshopRoot = await findWorkshopRoot(resolveWorkshopContextCwd());
|
|
1091
1120
|
// Get workshop title if we're inside one
|
|
1092
1121
|
let workshopTitle = null;
|
|
1093
1122
|
if (workshopRoot) {
|
|
@@ -1495,7 +1524,7 @@ try {
|
|
|
1495
1524
|
}
|
|
1496
1525
|
case 'exercises': {
|
|
1497
1526
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
1498
|
-
const wsRoot = await findWorkshopRoot();
|
|
1527
|
+
const wsRoot = await findWorkshopRoot(resolveWorkshopContextCwd());
|
|
1499
1528
|
if (!wsRoot) {
|
|
1500
1529
|
console.error(chalk.red('❌ Not inside a workshop directory'));
|
|
1501
1530
|
process.exit(1);
|
|
@@ -1515,7 +1544,7 @@ try {
|
|
|
1515
1544
|
}
|
|
1516
1545
|
case 'playground': {
|
|
1517
1546
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
1518
|
-
const wsRoot = await findWorkshopRoot();
|
|
1547
|
+
const wsRoot = await findWorkshopRoot(resolveWorkshopContextCwd());
|
|
1519
1548
|
if (!wsRoot) {
|
|
1520
1549
|
console.error(chalk.red('❌ Not inside a workshop directory'));
|
|
1521
1550
|
process.exit(1);
|
|
@@ -1535,7 +1564,7 @@ try {
|
|
|
1535
1564
|
}
|
|
1536
1565
|
case 'progress': {
|
|
1537
1566
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
1538
|
-
const wsRoot = await findWorkshopRoot();
|
|
1567
|
+
const wsRoot = await findWorkshopRoot(resolveWorkshopContextCwd());
|
|
1539
1568
|
if (!wsRoot) {
|
|
1540
1569
|
console.error(chalk.red('❌ Not inside a workshop directory'));
|
|
1541
1570
|
process.exit(1);
|
|
@@ -1555,7 +1584,7 @@ try {
|
|
|
1555
1584
|
}
|
|
1556
1585
|
case 'diff': {
|
|
1557
1586
|
const { findWorkshopRoot } = await import("./commands/workshops.js");
|
|
1558
|
-
const wsRoot = await findWorkshopRoot();
|
|
1587
|
+
const wsRoot = await findWorkshopRoot(resolveWorkshopContextCwd());
|
|
1559
1588
|
if (!wsRoot) {
|
|
1560
1589
|
console.error(chalk.red('❌ Not inside a workshop directory'));
|
|
1561
1590
|
process.exit(1);
|
|
@@ -4,7 +4,7 @@ import '@epic-web/workshop-utils/init-env';
|
|
|
4
4
|
* looking for a package.json with an epicshop field.
|
|
5
5
|
* Returns the workshop root path if found, null otherwise.
|
|
6
6
|
*/
|
|
7
|
-
export declare function findWorkshopRoot(): Promise<string | null>;
|
|
7
|
+
export declare function findWorkshopRoot(startDir?: string): Promise<string | null>;
|
|
8
8
|
/**
|
|
9
9
|
* Check if the current working directory is inside a workshop
|
|
10
10
|
* (has epicshop config in package.json in current dir or any parent)
|
|
@@ -38,8 +38,21 @@ const EPIC_SITES = [
|
|
|
38
38
|
* looking for a package.json with an epicshop field.
|
|
39
39
|
* Returns the workshop root path if found, null otherwise.
|
|
40
40
|
*/
|
|
41
|
-
export async function findWorkshopRoot() {
|
|
42
|
-
let currentDir =
|
|
41
|
+
export async function findWorkshopRoot(startDir) {
|
|
42
|
+
let currentDir = startDir
|
|
43
|
+
? path.resolve(resolvePathWithTilde(startDir))
|
|
44
|
+
: process.cwd();
|
|
45
|
+
// If the user gave us a file path (or something that isn't a directory),
|
|
46
|
+
// treat the containing folder as the start point.
|
|
47
|
+
try {
|
|
48
|
+
const stat = await fs.promises.stat(currentDir);
|
|
49
|
+
if (!stat.isDirectory()) {
|
|
50
|
+
currentDir = path.dirname(currentDir);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// If the path doesn't exist, we still attempt to walk upward from it.
|
|
55
|
+
}
|
|
43
56
|
const root = path.parse(currentDir).root;
|
|
44
57
|
while (currentDir !== root) {
|
|
45
58
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "epicshop",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.82.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"build:watch": "nx watch --projects=epicshop -- nx run \\$NX_PROJECT_NAME:build"
|
|
100
100
|
},
|
|
101
101
|
"dependencies": {
|
|
102
|
-
"@epic-web/workshop-utils": "6.
|
|
102
|
+
"@epic-web/workshop-utils": "6.82.1",
|
|
103
103
|
"@inquirer/prompts": "^8.2.0",
|
|
104
104
|
"@sentry/node": "^10.38.0",
|
|
105
105
|
"chalk": "^5.6.2",
|