@epic-web/workshop-utils 6.12.0 โ 6.12.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.server.d.ts","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"AA6FA,wBAAsB,eAAe;;;;;;;;;;;;;;;GAqEpC;AAED,wBAAsB,qBAAqB;;;;;;;;;;;;;;;GAc1C;AAED,wBAAsB,eAAe;;;;;;;;;GAgDpC;AAED,wBAAsB,aAAa;;;;UAelC;AAED,wBAAsB,2BAA2B,2BAehD;AAED,wBAAsB,uBAAuB,
|
|
1
|
+
{"version":3,"file":"git.server.d.ts","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"AA6FA,wBAAsB,eAAe;;;;;;;;;;;;;;;GAqEpC;AAED,wBAAsB,qBAAqB;;;;;;;;;;;;;;;GAc1C;AAED,wBAAsB,eAAe;;;;;;;;;GAgDpC;AAED,wBAAsB,aAAa;;;;UAelC;AAED,wBAAsB,2BAA2B,2BAehD;AAED,wBAAsB,uBAAuB,qBAiB5C"}
|
package/dist/esm/git.server.js
CHANGED
|
@@ -206,6 +206,9 @@ export async function getLatestWorkshopAppVersion() {
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
export async function checkForExerciseChanges() {
|
|
209
|
+
const ENV = getEnv();
|
|
210
|
+
if (ENV.EPICSHOP_DEPLOYED)
|
|
211
|
+
return false;
|
|
209
212
|
const cwd = getWorkshopRoot();
|
|
210
213
|
try {
|
|
211
214
|
const { stdout } = await execaCommand('git status --porcelain exercises/', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.server.js","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEnD,KAAK,UAAU,+BAA+B,CAAC,GAAW;IACzD,IAAI,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;QAE3D,2DAA2D;QAC3D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,YAAY,CAC7C,+CAA+C,EAC/C,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CACpB,CAAA;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAA;YACjE,OAAM;QACP,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC9D,yGAAyG;QACzG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAA;QAE/C,IAAI,YAAY,GAAG,CAAC,CAAA;QAEpB,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,GAAG,KAAK,WAAW;gBAAE,SAAQ,CAAC,oCAAoC;YAEtE,gEAAgE;YAChE,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACxD,KAAK,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;oBACpE,MAAM,EAAE,EAAE;iBACV,CAAC,CAAC;gBACH,KAAK,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,GAAG,CAAC,EAAE;oBACjE,GAAG;oBACH,MAAM,EAAE,KAAK;iBACb,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;aAChC,CAAC,CAAA;YAEF,mEAAmE;YACnE,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;YAC7D,MAAM,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;YACjE,MAAM,QAAQ,GAAG,eAAe,IAAI,iBAAiB,CAAA;YAErD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAA;gBAClD,IAAI,CAAC;oBACJ,iEAAiE;oBACjE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;oBACnC,YAAY,EAAE,CAAA;gBACf,CAAC;gBAAC,MAAM,CAAC;oBACR,iEAAiE;oBACjE,8CAA8C;gBAC/C,CAAC;YACF,CAAC;QACF,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,cAAc,YAAY,qBAAqB,CAAC,CAAA;QAC7D,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;QAC9C,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CACX,kDAAkD,EAClD,eAAe,CAAC,KAAK,CAAC,CACtB,CAAA;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,YAAoB,EAAE,WAAmB;IAClE,MAAM,GAAG,GAAG,eAAe,EAAE,CAAA;IAC7B,IAAI,CAAC;QACJ,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAC/C,oCAAoC,EACpC,EAAE,GAAG,EAAE,CACP,CAAA;QACD,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAC3B,SAAS,CAAC,KAAK,CAAC,oCAAoC,CAAC,IAAI,EAAE,CAAA;QAC5D,MAAM,OAAO,GAAG,sBAAsB,QAAQ,IAAI,QAAQ,YAAY,YAAY,MAAM,WAAW,EAAE,CAAA;QACrG,OAAO,OAAO,CAAA;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAA;QACvE,OAAO,IAAI,CAAA;IACZ,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACpC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC3B,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAW,CAAA;IAC5C,CAAC;IAED,MAAM,GAAG,GAAG,eAAe,EAAE,CAAA;IAC7B,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAA;IACtC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAW,CAAA;IAExD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,qCAAqC,EAAE;QAC1E,GAAG;KACH,CAAC,CAAC,IAAI,CACN,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACX,CAAA;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAW,CAAA;IAC5C,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;IACpE,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAW,CAAA;IAC5C,CAAC;IAED,IAAI,WAAW,EAAE,YAAY,CAAA;IAC7B,IAAI,CAAC;QACJ,MAAM,aAAa,GAAG,CACrB,MAAM,YAAY,CAAC,iCAAiC,EAAE,EAAE,GAAG,EAAE,CAAC,CAC9D,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QAEf,WAAW,GAAG,CACb,MAAM,YAAY,CAAC,4BAA4B,EAAE,EAAE,GAAG,EAAE,CAAC,CACzD,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QAEf,MAAM,YAAY,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;QAE9C,YAAY,GAAG,CACd,MAAM,YAAY,CAAC,gCAAgC,aAAa,EAAE,EAAE;YACnE,GAAG;SACH,CAAC,CACF,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QAEf,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAC7B,KAAK,EACL,CAAC,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,oBAAoB,CAAC,EAC7D,EAAE,GAAG,EAAE,CACP,CAAA;QACD,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC7D,MAAM,gBAAgB,GAAG,MAAM,GAAG,CAAC,CAAA;QAEnC,OAAO;YACN,gBAAgB;YAChB,WAAW;YACX,YAAY;YACZ,QAAQ,EAAE,MAAM,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC;SAC5C,CAAA;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAA;QACpE,OAAO;YACN,gBAAgB,EAAE,KAAK;YACvB,WAAW;YACX,YAAY;YACZ,QAAQ,EACP,WAAW,IAAI,YAAY;gBAC1B,CAAC,CAAC,MAAM,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC;gBAC7C,CAAC,CAAC,IAAI;SACC,CAAA;IACX,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IAC1C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC3B,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAW,CAAA;IAC5C,CAAC;IAED,MAAM,GAAG,GAAG,iBAAiB,CAAA;IAC7B,OAAO,SAAS,CAAC;QAChB,GAAG,EAAE,IAAI,GAAG,EAAE;QACd,GAAG,EAAE,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;QACxB,GAAG;QACH,aAAa,EAAE,eAAe;QAC9B,KAAK,EAAE,oBAAoB;KAC3B,CAAC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACpC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;IACpB,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC3B,OAAO;YACN,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,qDAAqD;SACrD,CAAA;IACX,CAAC;IAED,MAAM,GAAG,GAAG,eAAe,EAAE,CAAA;IAC7B,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE,CAAA;QACvC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC/B,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,uBAAuB,EAAW,CAAA;QACxE,CAAC;QAED,MAAM,kBAAkB,GACvB,CAAC,MAAM,YAAY,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE;aACnE,MAAM,GAAG,CAAC,CAAA;QAEb,IAAI,kBAAkB,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAA;YACjD,MAAM,YAAY,CAAC,+BAA+B,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;QAC7D,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QAC3C,MAAM,YAAY,CAAC,sBAAsB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;QAEnD,IAAI,kBAAkB,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAA;YAChD,MAAM,YAAY,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;QAC7C,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAA;QAC/C,MAAM,YAAY,CAAC,aAAa,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;QAE5D,MAAM,+BAA+B,CAAC,GAAG,CAAC,CAAA;QAE1C,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,CAAC,OAAO,EAAE,UAAU,CAAA;QAChE,IAAI,gBAAgB,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAA;YAC/C,MAAM,YAAY,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;QAChE,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,uBAAuB,EAAW,CAAA;IACxE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,EAAW,CAAA;IACrE,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IAClC,MAAM,GAAG,GAAG,eAAe,EAAE,CAAA;IAC7B,IAAI,CAAC;QACJ,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,CAAC,oBAAoB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;QAC1E,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,YAAY,CAAC,wBAAwB,EAAE;YACxE,GAAG;SACH,CAAC,CAAA;QACF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,CAAC,yBAAyB,EAAE;YACtE,GAAG;SACH,CAAC,CAAA;QACF,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAA;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAA;QACnE,OAAO,IAAI,CAAA;IACZ,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B;IAChD,MAAM,GAAG,GAAG,eAAe,EAAE,CAAA;IAC7B,IAAI,CAAC;QACJ,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CACpC,yCAAyC,EACzC,EAAE,GAAG,EAAE,CACP,CAAA;QACD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CACZ,4CAA4C,EAC5C,eAAe,CAAC,KAAK,CAAC,CACtB,CAAA;QACD,OAAO,IAAI,CAAA;IACZ,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC5C,MAAM,GAAG,GAAG,eAAe,EAAE,CAAA;IAC7B,IAAI,CAAC;QACJ,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,mCAAmC,EAAE;YAC1E,GAAG;SACH,CAAC,CAAA;QACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CACZ,uCAAuC,EACvC,eAAe,CAAC,KAAK,CAAC,CACtB,CAAA;QACD,OAAO,KAAK,CAAA;IACb,CAAC;AACF,CAAC","sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { execa, execaCommand } from 'execa'\nimport { getWorkshopRoot } from './apps.server.js'\nimport { cachified, checkForUpdatesCache } from './cache.server.js'\nimport { getWorkshopConfig } from './config.server.js'\nimport { getEnv } from './env.server.js'\nimport { getErrorMessage } from './utils.js'\nimport { checkConnection } from './utils.server.js'\n\nasync function cleanupEmptyExerciseDirectories(cwd: string) {\n\ttry {\n\t\tconsole.log('๐งน Cleaning up empty exercise directories...')\n\n\t\t// Find all directories under exercises/* and exercises/*/*\n\t\tconst { stdout: allDirs } = await execaCommand(\n\t\t\t'find exercises -type d 2>/dev/null || echo \"\"',\n\t\t\t{ cwd, shell: true },\n\t\t)\n\n\t\tif (!allDirs.trim()) {\n\t\t\tconsole.log(' No exercises directory found, skipping cleanup.')\n\t\t\treturn\n\t\t}\n\n\t\tconst directories = allDirs.trim().split('\\n').filter(Boolean)\n\t\t// Sort directories in reverse order (deepest first) to ensure proper cleanup of nested empty directories\n\t\tdirectories.sort((a, b) => b.length - a.length)\n\n\t\tlet deletedCount = 0\n\n\t\tfor (const dir of directories) {\n\t\t\tif (dir === 'exercises') continue // Skip the root exercises directory\n\n\t\t\t// Check if directory has any files (excluding gitignored files)\n\t\t\tconst [trackedFiles, untrackedFiles] = await Promise.all([\n\t\t\t\texeca('git', ['ls-files', dir], { cwd, reject: false }).catch(() => ({\n\t\t\t\t\tstdout: '',\n\t\t\t\t})),\n\t\t\t\texeca('git', ['ls-files', '--others', '--exclude-standard', dir], {\n\t\t\t\t\tcwd,\n\t\t\t\t\treject: false,\n\t\t\t\t}).catch(() => ({ stdout: '' })),\n\t\t\t])\n\n\t\t\t// Fix: Use proper boolean logic to check if both outputs are empty\n\t\t\tconst hasTrackedFiles = trackedFiles.stdout.trim().length > 0\n\t\t\tconst hasUntrackedFiles = untrackedFiles.stdout.trim().length > 0\n\t\t\tconst hasFiles = hasTrackedFiles || hasUntrackedFiles\n\n\t\t\tif (!hasFiles) {\n\t\t\t\tconsole.log(` Deleting empty directory: ${dir}`)\n\t\t\t\ttry {\n\t\t\t\t\t// Use fs.rmdir instead of shell command to avoid shell injection\n\t\t\t\t\tawait fs.rmdir(path.join(cwd, dir))\n\t\t\t\t\tdeletedCount++\n\t\t\t\t} catch {\n\t\t\t\t\t// Directory might not be empty or might not exist, which is fine\n\t\t\t\t\t// We'll just continue with the next directory\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (deletedCount > 0) {\n\t\t\tconsole.log(` Deleted ${deletedCount} empty directories.`)\n\t\t} else {\n\t\t\tconsole.log(' No empty directories found.')\n\t\t}\n\t} catch (error) {\n\t\tconsole.warn(\n\t\t\t' Warning: Failed to cleanup empty directories:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t}\n}\n\nasync function getDiffUrl(commitBefore: string, commitAfter: string) {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout: remoteUrl } = await execaCommand(\n\t\t\t'git config --get remote.origin.url',\n\t\t\t{ cwd },\n\t\t)\n\t\tconst [, username, repoName] =\n\t\t\tremoteUrl.match(/(?:[^/]+\\/|:)([^/]+)\\/([^.]+)\\.git/) ?? []\n\t\tconst diffUrl = `https://github.com/${username}/${repoName}/compare/${commitBefore}...${commitAfter}`\n\t\treturn diffUrl\n\t} catch (error) {\n\t\tconsole.error('Failed to get repository info:', getErrorMessage(error))\n\t\treturn null\n\t}\n}\n\nexport async function checkForUpdates() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tconst cwd = getWorkshopRoot()\n\tconst online = await checkConnection()\n\tif (!online) return { updatesAvailable: false } as const\n\n\tconst isInRepo = await execaCommand('git rev-parse --is-inside-work-tree', {\n\t\tcwd,\n\t}).then(\n\t\t() => true,\n\t\t() => false,\n\t)\n\tif (!isInRepo) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tconst { stdout: remote } = await execaCommand('git remote', { cwd })\n\tif (!remote) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tlet localCommit, remoteCommit\n\ttry {\n\t\tconst currentBranch = (\n\t\t\tawait execaCommand('git rev-parse --abbrev-ref HEAD', { cwd })\n\t\t).stdout.trim()\n\n\t\tlocalCommit = (\n\t\t\tawait execaCommand('git rev-parse --short HEAD', { cwd })\n\t\t).stdout.trim()\n\n\t\tawait execaCommand('git fetch --all', { cwd })\n\n\t\tremoteCommit = (\n\t\t\tawait execaCommand(`git rev-parse --short origin/${currentBranch}`, {\n\t\t\t\tcwd,\n\t\t\t})\n\t\t).stdout.trim()\n\n\t\tconst { stdout } = await execa(\n\t\t\t'git',\n\t\t\t['rev-list', '--count', '--left-right', 'HEAD...@{upstream}'],\n\t\t\t{ cwd },\n\t\t)\n\t\tconst [, behind = 0] = stdout.trim().split(/\\s+/).map(Number)\n\t\tconst updatesAvailable = behind > 0\n\n\t\treturn {\n\t\t\tupdatesAvailable,\n\t\t\tlocalCommit,\n\t\t\tremoteCommit,\n\t\t\tdiffLink: await getDiffUrl(localCommit, remoteCommit),\n\t\t} as const\n\t} catch (error) {\n\t\tconsole.error('Unable to check for updates', getErrorMessage(error))\n\t\treturn {\n\t\t\tupdatesAvailable: false,\n\t\t\tlocalCommit,\n\t\t\tremoteCommit,\n\t\t\tdiffLink:\n\t\t\t\tlocalCommit && remoteCommit\n\t\t\t\t\t? await getDiffUrl(localCommit, remoteCommit)\n\t\t\t\t\t: null,\n\t\t} as const\n\t}\n}\n\nexport async function checkForUpdatesCached() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tconst key = 'checkForUpdates'\n\treturn cachified({\n\t\tttl: 1000 * 60,\n\t\tswr: 1000 * 60 * 60 * 24,\n\t\tkey,\n\t\tgetFreshValue: checkForUpdates,\n\t\tcache: checkForUpdatesCache,\n\t})\n}\n\nexport async function updateLocalRepo() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn {\n\t\t\tstatus: 'error',\n\t\t\tmessage: 'Updates are not available in deployed environments.',\n\t\t} as const\n\t}\n\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst updates = await checkForUpdates()\n\t\tif (!updates.updatesAvailable) {\n\t\t\treturn { status: 'success', message: 'No updates available.' } as const\n\t\t}\n\n\t\tconst uncommittedChanges =\n\t\t\t(await execaCommand('git status --porcelain', { cwd })).stdout.trim()\n\t\t\t\t.length > 0\n\n\t\tif (uncommittedChanges) {\n\t\t\tconsole.log('๐ Stashing uncommitted changes...')\n\t\t\tawait execaCommand('git stash --include-untracked', { cwd })\n\t\t}\n\n\t\tconsole.log('โฌ๏ธ Pulling latest changes...')\n\t\tawait execaCommand('git pull origin HEAD', { cwd })\n\n\t\tif (uncommittedChanges) {\n\t\t\tconsole.log('๐ re-applying stashed changes...')\n\t\t\tawait execaCommand('git stash pop', { cwd })\n\t\t}\n\n\t\tconsole.log('๐ฆ Re-installing dependencies...')\n\t\tawait execaCommand('npm install', { cwd, stdio: 'inherit' })\n\n\t\tawait cleanupEmptyExerciseDirectories(cwd)\n\n\t\tconst postUpdateScript = getWorkshopConfig().scripts?.postupdate\n\t\tif (postUpdateScript) {\n\t\t\tconsole.log('๐ Running post update script...')\n\t\t\tawait execaCommand(postUpdateScript, { cwd, stdio: 'inherit' })\n\t\t}\n\n\t\treturn { status: 'success', message: 'Updated successfully.' } as const\n\t} catch (error) {\n\t\treturn { status: 'error', message: getErrorMessage(error) } as const\n\t}\n}\n\nexport async function getCommitInfo() {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout: hash } = await execaCommand('git rev-parse HEAD', { cwd })\n\t\tconst { stdout: message } = await execaCommand('git log -1 --pretty=%B', {\n\t\t\tcwd,\n\t\t})\n\t\tconst { stdout: date } = await execaCommand('git log -1 --format=%cI', {\n\t\t\tcwd,\n\t\t})\n\t\treturn { hash: hash.trim(), message: message.trim(), date: date.trim() }\n\t} catch (error) {\n\t\tconsole.error('Failed to get commit info:', getErrorMessage(error))\n\t\treturn null\n\t}\n}\n\nexport async function getLatestWorkshopAppVersion() {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout } = await execaCommand(\n\t\t\t'npm view @epic-web/workshop-app version',\n\t\t\t{ cwd },\n\t\t)\n\t\treturn stdout.trim()\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t'Failed to get latest workshop app version:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t\treturn null\n\t}\n}\n\nexport async function checkForExerciseChanges() {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout } = await execaCommand('git status --porcelain exercises/', {\n\t\t\tcwd,\n\t\t})\n\t\treturn stdout.trim().length > 0\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t'Failed to check for exercise changes:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t\treturn false\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"git.server.js","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { execa, execaCommand } from 'execa'\nimport { getWorkshopRoot } from './apps.server.js'\nimport { cachified, checkForUpdatesCache } from './cache.server.js'\nimport { getWorkshopConfig } from './config.server.js'\nimport { getEnv } from './env.server.js'\nimport { getErrorMessage } from './utils.js'\nimport { checkConnection } from './utils.server.js'\n\nasync function cleanupEmptyExerciseDirectories(cwd: string) {\n\ttry {\n\t\tconsole.log('๐งน Cleaning up empty exercise directories...')\n\n\t\t// Find all directories under exercises/* and exercises/*/*\n\t\tconst { stdout: allDirs } = await execaCommand(\n\t\t\t'find exercises -type d 2>/dev/null || echo \"\"',\n\t\t\t{ cwd, shell: true },\n\t\t)\n\n\t\tif (!allDirs.trim()) {\n\t\t\tconsole.log(' No exercises directory found, skipping cleanup.')\n\t\t\treturn\n\t\t}\n\n\t\tconst directories = allDirs.trim().split('\\n').filter(Boolean)\n\t\t// Sort directories in reverse order (deepest first) to ensure proper cleanup of nested empty directories\n\t\tdirectories.sort((a, b) => b.length - a.length)\n\n\t\tlet deletedCount = 0\n\n\t\tfor (const dir of directories) {\n\t\t\tif (dir === 'exercises') continue // Skip the root exercises directory\n\n\t\t\t// Check if directory has any files (excluding gitignored files)\n\t\t\tconst [trackedFiles, untrackedFiles] = await Promise.all([\n\t\t\t\texeca('git', ['ls-files', dir], { cwd, reject: false }).catch(() => ({\n\t\t\t\t\tstdout: '',\n\t\t\t\t})),\n\t\t\t\texeca('git', ['ls-files', '--others', '--exclude-standard', dir], {\n\t\t\t\t\tcwd,\n\t\t\t\t\treject: false,\n\t\t\t\t}).catch(() => ({ stdout: '' })),\n\t\t\t])\n\n\t\t\t// Fix: Use proper boolean logic to check if both outputs are empty\n\t\t\tconst hasTrackedFiles = trackedFiles.stdout.trim().length > 0\n\t\t\tconst hasUntrackedFiles = untrackedFiles.stdout.trim().length > 0\n\t\t\tconst hasFiles = hasTrackedFiles || hasUntrackedFiles\n\n\t\t\tif (!hasFiles) {\n\t\t\t\tconsole.log(` Deleting empty directory: ${dir}`)\n\t\t\t\ttry {\n\t\t\t\t\t// Use fs.rmdir instead of shell command to avoid shell injection\n\t\t\t\t\tawait fs.rmdir(path.join(cwd, dir))\n\t\t\t\t\tdeletedCount++\n\t\t\t\t} catch {\n\t\t\t\t\t// Directory might not be empty or might not exist, which is fine\n\t\t\t\t\t// We'll just continue with the next directory\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (deletedCount > 0) {\n\t\t\tconsole.log(` Deleted ${deletedCount} empty directories.`)\n\t\t} else {\n\t\t\tconsole.log(' No empty directories found.')\n\t\t}\n\t} catch (error) {\n\t\tconsole.warn(\n\t\t\t' Warning: Failed to cleanup empty directories:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t}\n}\n\nasync function getDiffUrl(commitBefore: string, commitAfter: string) {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout: remoteUrl } = await execaCommand(\n\t\t\t'git config --get remote.origin.url',\n\t\t\t{ cwd },\n\t\t)\n\t\tconst [, username, repoName] =\n\t\t\tremoteUrl.match(/(?:[^/]+\\/|:)([^/]+)\\/([^.]+)\\.git/) ?? []\n\t\tconst diffUrl = `https://github.com/${username}/${repoName}/compare/${commitBefore}...${commitAfter}`\n\t\treturn diffUrl\n\t} catch (error) {\n\t\tconsole.error('Failed to get repository info:', getErrorMessage(error))\n\t\treturn null\n\t}\n}\n\nexport async function checkForUpdates() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tconst cwd = getWorkshopRoot()\n\tconst online = await checkConnection()\n\tif (!online) return { updatesAvailable: false } as const\n\n\tconst isInRepo = await execaCommand('git rev-parse --is-inside-work-tree', {\n\t\tcwd,\n\t}).then(\n\t\t() => true,\n\t\t() => false,\n\t)\n\tif (!isInRepo) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tconst { stdout: remote } = await execaCommand('git remote', { cwd })\n\tif (!remote) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tlet localCommit, remoteCommit\n\ttry {\n\t\tconst currentBranch = (\n\t\t\tawait execaCommand('git rev-parse --abbrev-ref HEAD', { cwd })\n\t\t).stdout.trim()\n\n\t\tlocalCommit = (\n\t\t\tawait execaCommand('git rev-parse --short HEAD', { cwd })\n\t\t).stdout.trim()\n\n\t\tawait execaCommand('git fetch --all', { cwd })\n\n\t\tremoteCommit = (\n\t\t\tawait execaCommand(`git rev-parse --short origin/${currentBranch}`, {\n\t\t\t\tcwd,\n\t\t\t})\n\t\t).stdout.trim()\n\n\t\tconst { stdout } = await execa(\n\t\t\t'git',\n\t\t\t['rev-list', '--count', '--left-right', 'HEAD...@{upstream}'],\n\t\t\t{ cwd },\n\t\t)\n\t\tconst [, behind = 0] = stdout.trim().split(/\\s+/).map(Number)\n\t\tconst updatesAvailable = behind > 0\n\n\t\treturn {\n\t\t\tupdatesAvailable,\n\t\t\tlocalCommit,\n\t\t\tremoteCommit,\n\t\t\tdiffLink: await getDiffUrl(localCommit, remoteCommit),\n\t\t} as const\n\t} catch (error) {\n\t\tconsole.error('Unable to check for updates', getErrorMessage(error))\n\t\treturn {\n\t\t\tupdatesAvailable: false,\n\t\t\tlocalCommit,\n\t\t\tremoteCommit,\n\t\t\tdiffLink:\n\t\t\t\tlocalCommit && remoteCommit\n\t\t\t\t\t? await getDiffUrl(localCommit, remoteCommit)\n\t\t\t\t\t: null,\n\t\t} as const\n\t}\n}\n\nexport async function checkForUpdatesCached() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tconst key = 'checkForUpdates'\n\treturn cachified({\n\t\tttl: 1000 * 60,\n\t\tswr: 1000 * 60 * 60 * 24,\n\t\tkey,\n\t\tgetFreshValue: checkForUpdates,\n\t\tcache: checkForUpdatesCache,\n\t})\n}\n\nexport async function updateLocalRepo() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn {\n\t\t\tstatus: 'error',\n\t\t\tmessage: 'Updates are not available in deployed environments.',\n\t\t} as const\n\t}\n\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst updates = await checkForUpdates()\n\t\tif (!updates.updatesAvailable) {\n\t\t\treturn { status: 'success', message: 'No updates available.' } as const\n\t\t}\n\n\t\tconst uncommittedChanges =\n\t\t\t(await execaCommand('git status --porcelain', { cwd })).stdout.trim()\n\t\t\t\t.length > 0\n\n\t\tif (uncommittedChanges) {\n\t\t\tconsole.log('๐ Stashing uncommitted changes...')\n\t\t\tawait execaCommand('git stash --include-untracked', { cwd })\n\t\t}\n\n\t\tconsole.log('โฌ๏ธ Pulling latest changes...')\n\t\tawait execaCommand('git pull origin HEAD', { cwd })\n\n\t\tif (uncommittedChanges) {\n\t\t\tconsole.log('๐ re-applying stashed changes...')\n\t\t\tawait execaCommand('git stash pop', { cwd })\n\t\t}\n\n\t\tconsole.log('๐ฆ Re-installing dependencies...')\n\t\tawait execaCommand('npm install', { cwd, stdio: 'inherit' })\n\n\t\tawait cleanupEmptyExerciseDirectories(cwd)\n\n\t\tconst postUpdateScript = getWorkshopConfig().scripts?.postupdate\n\t\tif (postUpdateScript) {\n\t\t\tconsole.log('๐ Running post update script...')\n\t\t\tawait execaCommand(postUpdateScript, { cwd, stdio: 'inherit' })\n\t\t}\n\n\t\treturn { status: 'success', message: 'Updated successfully.' } as const\n\t} catch (error) {\n\t\treturn { status: 'error', message: getErrorMessage(error) } as const\n\t}\n}\n\nexport async function getCommitInfo() {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout: hash } = await execaCommand('git rev-parse HEAD', { cwd })\n\t\tconst { stdout: message } = await execaCommand('git log -1 --pretty=%B', {\n\t\t\tcwd,\n\t\t})\n\t\tconst { stdout: date } = await execaCommand('git log -1 --format=%cI', {\n\t\t\tcwd,\n\t\t})\n\t\treturn { hash: hash.trim(), message: message.trim(), date: date.trim() }\n\t} catch (error) {\n\t\tconsole.error('Failed to get commit info:', getErrorMessage(error))\n\t\treturn null\n\t}\n}\n\nexport async function getLatestWorkshopAppVersion() {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout } = await execaCommand(\n\t\t\t'npm view @epic-web/workshop-app version',\n\t\t\t{ cwd },\n\t\t)\n\t\treturn stdout.trim()\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t'Failed to get latest workshop app version:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t\treturn null\n\t}\n}\n\nexport async function checkForExerciseChanges() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) return false\n\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout } = await execaCommand('git status --porcelain exercises/', {\n\t\t\tcwd,\n\t\t})\n\t\treturn stdout.trim().length > 0\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t'Failed to check for exercise changes:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t\treturn false\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@epic-web/workshop-utils","version":"6.12.
|
|
1
|
+
{"name":"@epic-web/workshop-utils","version":"6.12.1","publishConfig":{"access":"public"},"type":"module","tshy":{"project":"./tsconfig.build.json","dialects":["esm"],"exports":{"./package.json":"./package.json","./apps.server":"./src/apps.server.ts","./diff.server":"./src/diff.server.ts","./env.server":"./src/env.server.ts","./epic-api.server":"./src/epic-api.server.ts","./user.server":"./src/user.server.ts","./cache.server":"./src/cache.server.ts","./config.server":"./src/config.server.ts","./db.server":"./src/db.server.ts","./timing.server":"./src/timing.server.ts","./modified-time.server":"./src/modified-time.server.ts","./compile-mdx.server":"./src/compile-mdx.server.ts","./git.server":"./src/git.server.ts","./iframe-sync":"./src/iframe-sync.ts","./playwright.server":"./src/playwright.server.ts","./notifications.server":"./src/notifications.server.ts","./process-manager.server":"./src/process-manager.server.ts","./test":"./src/test.ts","./request-context.server":"./src/request-context.server.ts","./utils.server":"./src/utils.server.ts","./utils":"./src/utils.ts"}},"exports":{"./package.json":"./package.json","./apps.server":{"import":{"types":"./dist/esm/apps.server.d.ts","default":"./dist/esm/apps.server.js"}},"./diff.server":{"import":{"types":"./dist/esm/diff.server.d.ts","default":"./dist/esm/diff.server.js"}},"./env.server":{"import":{"types":"./dist/esm/env.server.d.ts","default":"./dist/esm/env.server.js"}},"./epic-api.server":{"import":{"types":"./dist/esm/epic-api.server.d.ts","default":"./dist/esm/epic-api.server.js"}},"./user.server":{"import":{"types":"./dist/esm/user.server.d.ts","default":"./dist/esm/user.server.js"}},"./cache.server":{"import":{"types":"./dist/esm/cache.server.d.ts","default":"./dist/esm/cache.server.js"}},"./config.server":{"import":{"types":"./dist/esm/config.server.d.ts","default":"./dist/esm/config.server.js"}},"./db.server":{"import":{"types":"./dist/esm/db.server.d.ts","default":"./dist/esm/db.server.js"}},"./timing.server":{"import":{"types":"./dist/esm/timing.server.d.ts","default":"./dist/esm/timing.server.js"}},"./modified-time.server":{"import":{"types":"./dist/esm/modified-time.server.d.ts","default":"./dist/esm/modified-time.server.js"}},"./compile-mdx.server":{"import":{"types":"./dist/esm/compile-mdx.server.d.ts","default":"./dist/esm/compile-mdx.server.js"}},"./git.server":{"import":{"types":"./dist/esm/git.server.d.ts","default":"./dist/esm/git.server.js"}},"./iframe-sync":{"import":{"types":"./dist/esm/iframe-sync.d.ts","default":"./dist/esm/iframe-sync.js"}},"./playwright.server":{"import":{"types":"./dist/esm/playwright.server.d.ts","default":"./dist/esm/playwright.server.js"}},"./notifications.server":{"import":{"types":"./dist/esm/notifications.server.d.ts","default":"./dist/esm/notifications.server.js"}},"./process-manager.server":{"import":{"types":"./dist/esm/process-manager.server.d.ts","default":"./dist/esm/process-manager.server.js"}},"./test":{"import":{"types":"./dist/esm/test.d.ts","default":"./dist/esm/test.js"}},"./request-context.server":{"import":{"types":"./dist/esm/request-context.server.d.ts","default":"./dist/esm/request-context.server.js"}},"./utils.server":{"import":{"types":"./dist/esm/utils.server.d.ts","default":"./dist/esm/utils.server.js"}},"./utils":{"import":{"types":"./dist/esm/utils.d.ts","default":"./dist/esm/utils.js"}}},"files":["dist"],"scripts":{"typecheck":"tsc --noEmit","build":"tshy","build:watch":"nx watch --projects=@epic-web/workshop-utils -- nx run \\$NX_PROJECT_NAME:build"},"dependencies":{"@epic-web/cachified":"^5.6.0","@epic-web/invariant":"^1.0.0","@epic-web/remember":"^1.1.0","@kentcdodds/md-temp":"^10.0.1","@mdx-js/mdx":"^3.1.0","@paralleldrive/cuid2":"^2.2.2","@playwright/test":"^1.53.2","@react-router/node":"^7.6.3","@testing-library/dom":"^10.4.0","@testing-library/jest-dom":"^6.6.3","@total-typescript/ts-reset":"^0.6.1","@types/chai":"^5.2.2","@types/chai-dom":"^1.11.3","@vitest/expect":"^3.2.4","chai":"^5.2.0","chai-dom":"^1.12.1","chalk":"^5.4.1","chokidar":"^4.0.3","close-with-grace":"^2.2.0","cookie":"^1.0.2","cross-spawn":"^7.0.6","dayjs":"^1.11.13","esbuild":"^0.25.5","execa":"^9.6.0","find-process":"^1.4.10","fkill":"^9.0.0","fs-extra":"^11.3.0","globby":"^14.1.0","ignore":"^7.0.5","json5":"^2.2.3","lru-cache":"^11.1.0","lz-string":"^1.5.0","md5-hex":"^5.0.0","mdast-util-mdx-jsx":"^3.2.0","mdx-bundler":"^10.1.1","p-queue":"^8.1.0","parse-git-diff":"^0.0.19","rehype":"^13.0.2","rehype-autolink-headings":"^7.1.0","remark":"^15.0.1","remark-emoji":"^5.0.1","remark-gfm":"^4.0.1","shiki":"^3.7.0","unified":"^11.0.5","unist-util-remove-position":"^5.0.0","unist-util-visit":"^5.0.0","zod":"^3.25.71"},"devDependencies":{"@types/hast":"^3.0.4","@types/mdast":"^4.0.4","@types/node":"^24.0.10","tshy":"^3.0.2"},"repository":{"type":"git","url":"https://github.com/epicweb-dev/epicshop.git","directory":"packages/workshop-utils"}}
|