@epic-web/workshop-utils 6.35.0 → 6.35.2
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/esm/apps.server.d.ts +1 -1
- package/dist/esm/apps.server.js +1 -1
- package/dist/esm/apps.server.js.map +1 -1
- package/dist/esm/git.server.d.ts +45 -1
- package/dist/esm/git.server.d.ts.map +1 -1
- package/dist/esm/git.server.js +41 -67
- package/dist/esm/git.server.js.map +1 -1
- package/package.json +1 -1
|
@@ -4485,7 +4485,7 @@ export declare function getWorkshopFinished({ request, }?: {
|
|
|
4485
4485
|
readonly error: string;
|
|
4486
4486
|
};
|
|
4487
4487
|
readonly file: string;
|
|
4488
|
-
readonly relativePath: "exercises/
|
|
4488
|
+
readonly relativePath: "exercises/FINISHED.mdx";
|
|
4489
4489
|
}>;
|
|
4490
4490
|
export declare function getRelativePath(filePath: string): string;
|
|
4491
4491
|
/**
|
package/dist/esm/apps.server.js
CHANGED
|
@@ -1201,7 +1201,7 @@ export async function getWorkshopFinished({ request, } = {}) {
|
|
|
1201
1201
|
return {
|
|
1202
1202
|
compiled,
|
|
1203
1203
|
file: finishedFilepath,
|
|
1204
|
-
relativePath: 'exercises/
|
|
1204
|
+
relativePath: 'exercises/FINISHED.mdx',
|
|
1205
1205
|
};
|
|
1206
1206
|
}
|
|
1207
1207
|
export function getRelativePath(filePath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.server.js","sourceRoot":"","sources":["../../src/apps.server.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { getEnv } from './init-env.js'\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { type CacheEntry } from '@epic-web/cachified'\nimport { invariant } from '@epic-web/invariant'\nimport { remember } from '@epic-web/remember'\nimport chokidar from 'chokidar'\n/// TODO: figure out why this import is necessary (without it tsc seems to not honor the boolean reset 🤷♂️)\nimport '@total-typescript/ts-reset'\nimport closeWithGrace from 'close-with-grace'\nimport { execa } from 'execa'\nimport fsExtra from 'fs-extra'\nimport { globby, isGitIgnored } from 'globby'\nimport { z } from 'zod'\nimport {\n\tcachified,\n\texampleAppCache,\n\tplaygroundAppCache,\n\tproblemAppCache,\n\tsolutionAppCache,\n\tdirectoryEmptyCache,\n} from './cache.server.js'\nimport { compileMdx } from './compile-mdx.server.js'\nimport { getAppConfig, getStackBlitzUrl } from './config.server.js'\nimport { getPreferences } from './db.server.js'\nimport { getDirModifiedTime } from './modified-time.server.js'\nimport {\n\tcloseProcess,\n\tisAppRunning,\n\trunAppDev,\n\twaitOnApp,\n} from './process-manager.server.js'\nimport { requestStorageify } from './request-context.server.js'\nimport { getServerTimeHeader, time, type Timings } from './timing.server.js'\nimport { getErrorMessage } from './utils.js'\nimport { dayjs } from './utils.server.js'\n\ndeclare global {\n\tvar __epicshop_apps_initialized__: boolean | undefined\n}\nglobal.__epicshop_apps_initialized__ ??= false\n\nexport function setWorkshopRoot(\n\troot: string = process.env.EPICSHOP_CONTEXT_CWD ?? process.cwd(),\n) {\n\tprocess.env.EPICSHOP_CONTEXT_CWD = root\n}\n\nexport function getWorkshopRoot() {\n\tif (!process.env.EPICSHOP_CONTEXT_CWD) setWorkshopRoot()\n\n\treturn process.env.EPICSHOP_CONTEXT_CWD\n}\n\nfunction getPlaygroundAppNameInfoPath() {\n\treturn path.join(\n\t\tgetWorkshopRoot(),\n\t\t'node_modules',\n\t\t'.cache',\n\t\t'epicshop',\n\t\t'playground.json',\n\t)\n}\n\ntype CachifiedOptions = { timings?: Timings; request?: Request }\n\nconst BaseAppSchema = z.object({\n\t/** a unique identifier for the app */\n\tname: z.string(),\n\t/** the title of the app used for display (comes from the package.json title prop) */\n\ttitle: z.string(),\n\t/** used when displaying the list of files to match the list of apps in the file system (comes the name of the directory of the app) */\n\tdirName: z.string(),\n\tfullPath: z.string(),\n\trelativePath: z.string(),\n\tinstructionsCode: z.string().optional(),\n\tepicVideoEmbeds: z.array(z.string()).optional(),\n\ttest: z.union([\n\t\tz.object({\n\t\t\ttype: z.literal('browser'),\n\t\t\tpathname: z.string(),\n\t\t\ttestFiles: z.array(z.string()),\n\t\t}),\n\t\tz.object({ type: z.literal('script'), script: z.string() }),\n\t\tz.object({ type: z.literal('none') }),\n\t]),\n\tdev: z.union([\n\t\tz.object({ type: z.literal('browser'), pathname: z.string() }),\n\t\tz.object({\n\t\t\ttype: z.literal('script'),\n\t\t\tportNumber: z.number(),\n\t\t\tinitialRoute: z.string(),\n\t\t}),\n\t\tz.object({ type: z.literal('none') }),\n\t]),\n\tstackBlitzUrl: z.string().nullable(),\n})\n\nconst BaseExerciseStepAppSchema = BaseAppSchema.extend({\n\texerciseNumber: z.number(),\n\tstepNumber: z.number(),\n})\n\nconst ProblemAppSchema = BaseExerciseStepAppSchema.extend({\n\ttype: z.literal('problem'),\n\tsolutionName: z.string().nullable(),\n})\n\nconst SolutionAppSchema = BaseExerciseStepAppSchema.extend({\n\ttype: z.literal('solution'),\n\tproblemName: z.string().nullable(),\n})\n\nconst ExampleAppSchema = BaseAppSchema.extend({\n\ttype: z.literal('example'),\n})\n\nconst PlaygroundAppSchema = BaseAppSchema.extend({\n\ttype: z.literal('playground'),\n\tappName: z.string(),\n\tisUpToDate: z.boolean(),\n})\n\nconst ExerciseSchema = z.object({\n\t/** the full path to the exercise directory */\n\tfullPath: z.string(),\n\t/** a unique identifier for the exercise */\n\texerciseNumber: z.number(),\n\t/** used when displaying the list of files to match the list of apps in the file system (comes the name of the directory of the app) */\n\tdirName: z.string(),\n\t/** the title of the app used for display (comes from the first h1 in the README) */\n\ttitle: z.string(),\n\tinstructionsCode: z.string().optional(),\n\tfinishedCode: z.string().optional(),\n\tinstructionsEpicVideoEmbeds: z.array(z.string()).optional(),\n\tfinishedEpicVideoEmbeds: z.array(z.string()).optional(),\n\tsteps: z\n\t\t.array(\n\t\t\tz.union([\n\t\t\t\tz.object({\n\t\t\t\t\tstepNumber: z.number(),\n\t\t\t\t\tproblem: ProblemAppSchema,\n\t\t\t\t\tsolution: SolutionAppSchema,\n\t\t\t\t}),\n\t\t\t\tz.object({\n\t\t\t\t\tstepNumber: z.number(),\n\t\t\t\t\tproblem: ProblemAppSchema,\n\t\t\t\t\tsolution: z.never().optional(),\n\t\t\t\t}),\n\t\t\t\tz.object({\n\t\t\t\t\tstepNumber: z.number(),\n\t\t\t\t\tproblem: z.never().optional(),\n\t\t\t\t\tsolution: SolutionAppSchema,\n\t\t\t\t}),\n\t\t\t\tz.undefined(),\n\t\t\t]),\n\t\t)\n\t\t.transform((steps) => steps.filter((step) => step !== undefined)),\n\tproblems: z.array(ProblemAppSchema),\n\tsolutions: z.array(SolutionAppSchema),\n})\n\nconst ExerciseStepAppSchema = z.union([ProblemAppSchema, SolutionAppSchema])\n\nconst AppSchema = z.union([\n\tExerciseStepAppSchema,\n\tPlaygroundAppSchema,\n\tExampleAppSchema,\n])\n\ntype BaseApp = z.infer<typeof BaseAppSchema>\n\nexport type BaseExerciseStepApp = z.infer<typeof BaseExerciseStepAppSchema>\nexport type ProblemApp = z.infer<typeof ProblemAppSchema>\nexport type SolutionApp = z.infer<typeof SolutionAppSchema>\nexport type ExampleApp = z.infer<typeof ExampleAppSchema>\nexport type PlaygroundApp = z.infer<typeof PlaygroundAppSchema>\nexport type ExerciseStepApp = z.infer<typeof ExerciseStepAppSchema>\nexport type App = z.infer<typeof AppSchema>\nexport type AppType = App['type']\n\ntype Exercise = z.infer<typeof ExerciseSchema>\n\nexport function isApp(app: any): app is App {\n\treturn AppSchema.safeParse(app).success\n}\n\nexport function isProblemApp(app: any): app is ProblemApp {\n\treturn ProblemAppSchema.safeParse(app).success\n}\n\nexport function isSolutionApp(app: any): app is SolutionApp {\n\treturn SolutionAppSchema.safeParse(app).success\n}\n\nexport function isFirstStepProblemApp(\n\tapp: App,\n): app is ProblemApp & { stepNumber: 1 } {\n\treturn isProblemApp(app) && app.stepNumber === 1\n}\n\nexport function isFirstStepSolutionApp(\n\tapp: App,\n): app is SolutionApp & { stepNumber: 1 } {\n\treturn isSolutionApp(app) && app.stepNumber === 1\n}\n\nexport function isPlaygroundApp(app: any): app is PlaygroundApp {\n\treturn isApp(app) && app.type === 'playground'\n}\n\nexport function isExampleApp(app: any): app is ExampleApp {\n\treturn isApp(app) && app.type === 'example'\n}\n\nexport function isExerciseStepApp(app: any): app is ExerciseStepApp {\n\treturn isProblemApp(app) || isSolutionApp(app)\n}\n\nfunction exists(file: string) {\n\treturn fs.promises.access(file, fs.constants.F_OK).then(\n\t\t() => true,\n\t\t() => false,\n\t)\n}\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n\treturn cachified({\n\t\tkey: dirPath,\n\t\tcache: directoryEmptyCache,\n\t\tttl: 1000 * 60 * 5,\n\t\tswr: 1000 * 60 * 20,\n\t\tforceFresh: await getForceFreshForDir(\n\t\t\tdirectoryEmptyCache.get(dirPath),\n\t\t\tdirPath,\n\t\t),\n\t\tgetFreshValue: async () => {\n\t\t\ttry {\n\t\t\t\tconst files = await fs.promises.readdir(dirPath)\n\t\t\t\tif (files.length === 0) return true\n\t\t\t\tconst isIgnored = await isGitIgnored({ cwd: dirPath })\n\t\t\t\tconst nonIgnoredFiles = files.filter((file) => !isIgnored(file))\n\t\t\t\treturn nonIgnoredFiles.length === 0\n\t\t\t} catch {\n\t\t\t\treturn true\n\t\t\t}\n\t\t},\n\t})\n}\n\nasync function firstToExist(...files: Array<string>) {\n\tconst results = await Promise.all(files.map(exists))\n\tconst index = results.findIndex(Boolean)\n\treturn index === -1 ? null : files[index]\n}\n\nexport const modifiedTimes = remember(\n\t'modified_times',\n\t() => new Map<string, number>(),\n)\n\nexport async function init(workshopRoot?: string) {\n\tsetWorkshopRoot(workshopRoot)\n\n\tif (global.__epicshop_apps_initialized__) return\n\n\tglobal.__epicshop_apps_initialized__ = true\n\n\tif (\n\t\t!getEnv().EPICSHOP_DEPLOYED &&\n\t\tprocess.env.EPICSHOP_ENABLE_WATCHER === 'true'\n\t) {\n\t\tconst isIgnored = await isGitIgnored({ cwd: getWorkshopRoot() })\n\n\t\t// watch the README, FINISHED, and package.json for changes that affect the apps\n\t\tconst filesToWatch = ['README.mdx', 'FINISHED.mdx', 'package.json']\n\t\tconst chok = chokidar.watch(['examples', 'playground', 'exercises'], {\n\t\t\tcwd: getWorkshopRoot(),\n\t\t\t// we want to load up the modified times immediately\n\t\t\tignoreInitial: false,\n\t\t\tignored(filePath, stats) {\n\t\t\t\tif (isIgnored(filePath)) return true\n\t\t\t\tif (filePath.includes('.git')) return true\n\n\t\t\t\tif (stats?.isDirectory()) {\n\t\t\t\t\tif (filePath.endsWith('playground')) return false\n\t\t\t\t\tconst pathParts = filePath.split(path.sep)\n\t\t\t\t\tif (pathParts.at(-2) === 'examples') return false\n\n\t\t\t\t\t// steps\n\t\t\t\t\tif (pathParts.at(-3) === 'exercises') return false\n\n\t\t\t\t\t// exercises\n\t\t\t\t\tif (pathParts.at(-2) === 'exercises') return false\n\n\t\t\t\t\t// the exercise dir itself\n\t\t\t\t\tif (pathParts.at(-1) === 'exercises') return false\n\t\t\t\t\treturn true\n\t\t\t\t}\n\n\t\t\t\treturn stats?.isFile()\n\t\t\t\t\t? !filesToWatch.some((file) => filePath.endsWith(file))\n\t\t\t\t\t: false\n\t\t\t},\n\t\t})\n\n\t\tchok.on('all', async (_event, filePath) => {\n\t\t\tconst modifiedAt = await getModifiedTimeForFile(\n\t\t\t\tpath.join(getWorkshopRoot(), filePath),\n\t\t\t)\n\t\t\tsetModifiedTimesForAppDirs(\n\t\t\t\tmodifiedAt ?? Date.now(),\n\t\t\t\tpath.join(getWorkshopRoot(), filePath),\n\t\t\t)\n\t\t})\n\n\t\tcloseWithGrace(() => chok.close())\n\t}\n}\n\nexport async function getModifiedTimeForFile(filepath?: string) {\n\tif (!filepath) return null\n\tconst modifiedAt = await fs.promises\n\t\t.stat(path.join(filepath))\n\t\t.catch(() => null)\n\treturn modifiedAt?.mtimeMs ?? null\n}\n\nexport function setModifiedTimesForAppDirs(\n\tmodifiedAt: number,\n\t...filePaths: Array<string>\n) {\n\tfor (const filePath of filePaths) {\n\t\tconst appDir = getAppPathFromFilePath(filePath)\n\t\tif (appDir) {\n\t\t\tconst existingModifiedTime = modifiedTimes.get(appDir)\n\t\t\tif (!existingModifiedTime || modifiedAt > existingModifiedTime) {\n\t\t\t\tmodifiedTimes.set(appDir, modifiedAt)\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function getForceFreshForDir(\n\tcacheEntry:\n\t\t| CacheEntry\n\t\t| null\n\t\t| undefined\n\t\t| Promise<CacheEntry | null | undefined>,\n\t...dirs: Array<string | undefined | null>\n) {\n\tconst truthyDirs = dirs.filter(Boolean)\n\tfor (const d of truthyDirs) {\n\t\tif (!path.isAbsolute(d)) {\n\t\t\tthrow new Error(`Trying to get force fresh for non-absolute path: ${d}`)\n\t\t}\n\t}\n\tconst resolvedCacheEntry = await cacheEntry\n\tif (!resolvedCacheEntry) return true\n\tconst latestModifiedTime = truthyDirs.reduce((latest, dir) => {\n\t\tconst modifiedTime = modifiedTimes.get(dir)\n\t\treturn modifiedTime && modifiedTime > latest ? modifiedTime : latest\n\t}, 0)\n\tif (!latestModifiedTime) return undefined\n\treturn latestModifiedTime > resolvedCacheEntry.metadata.createdTime\n\t\t? true\n\t\t: undefined\n}\n\nasync function readDir(dir: string) {\n\tif (await exists(dir)) {\n\t\treturn fs.promises.readdir(dir)\n\t}\n\treturn []\n}\n\nasync function compileMdxIfExists(\n\tfilepath: string,\n\t{ request }: { request?: Request } = {},\n) {\n\tfilepath = filepath.replace(/\\\\/g, '/')\n\tif (await exists(filepath)) {\n\t\tconst compiled = await compileMdx(filepath, { request }).catch((error) => {\n\t\t\tconsole.error(`Error compiling ${filepath}:`, error)\n\t\t\treturn null\n\t\t})\n\t\treturn compiled\n\t}\n\treturn null\n}\n\nfunction getAppDirInfo(appDir: string) {\n\tconst regex = /^(?<stepNumber>\\d+)\\.(problem|solution)(\\.(?<subtitle>.*))?$/\n\tconst match = regex.exec(appDir)\n\tif (!match?.groups) {\n\t\tconsole.info(\n\t\t\t`Ignoring directory \"${appDir}\" which does not match regex \"${regex}\"`,\n\t\t\tnew Error().stack,\n\t\t)\n\t\treturn null\n\t}\n\tconst { stepNumber: stepNumberString, subtitle } = match.groups\n\tconst stepNumber = Number(stepNumberString)\n\tif (!stepNumber || !Number.isFinite(stepNumber)) {\n\t\tthrow new Error(\n\t\t\t`Cannot identify the stepNumber for app directory \"${appDir}\" with regex \"${regex}\"`,\n\t\t)\n\t}\n\n\tconst type = match[2] as 'problem' | 'solution'\n\treturn { stepNumber, type, subtitle }\n}\n\nfunction extractExerciseNumber(dir: string) {\n\tconst regex = /^(?<number>\\d+)\\./\n\tconst number = regex.exec(dir)?.groups?.number\n\tif (!number) {\n\t\treturn null\n\t}\n\treturn Number(number)\n}\n\nasync function _getExercises({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<Array<Exercise>> {\n\tconst apps = await getApps({ request, timings })\n\tconst exerciseDirs = await readDir(path.join(getWorkshopRoot(), 'exercises'))\n\tconst exercises: Array<Exercise> = []\n\tfor (const dirName of exerciseDirs) {\n\t\tconst exerciseNumber = extractExerciseNumber(dirName)\n\t\tif (!exerciseNumber) continue\n\n\t\t// Skip empty exercise directories (excluding gitignored files)\n\t\tconst exerciseDir = path.join(getWorkshopRoot(), 'exercises', dirName)\n\t\tconst isEmpty = await isDirectoryEmpty(exerciseDir)\n\t\tif (isEmpty) continue\n\t\tconst compiledReadme = await compileMdxIfExists(\n\t\t\tpath.join(getWorkshopRoot(), 'exercises', dirName, 'README.mdx'),\n\t\t\t{ request },\n\t\t)\n\t\tconst compiledFinished = await compileMdxIfExists(\n\t\t\tpath.join(getWorkshopRoot(), 'exercises', dirName, 'FINISHED.mdx'),\n\t\t\t{ request },\n\t\t)\n\t\tconst steps: Exercise['steps'] = []\n\t\tconst exerciseApps = apps\n\t\t\t.filter(isExerciseStepApp)\n\t\t\t.filter((app) => app.exerciseNumber === exerciseNumber)\n\t\tfor (const app of exerciseApps) {\n\t\t\t// @ts-ignore meh 🤷♂️\n\t\t\tsteps[app.stepNumber - 1] = {\n\t\t\t\t...steps[app.stepNumber - 1],\n\t\t\t\t[app.type]: app,\n\t\t\t\tstepNumber: app.stepNumber,\n\t\t\t}\n\t\t}\n\t\tconst exercise = ExerciseSchema.parse({\n\t\t\tfullPath: path.join(getWorkshopRoot(), 'exercises', dirName),\n\t\t\texerciseNumber,\n\t\t\tdirName,\n\t\t\tinstructionsCode: compiledReadme?.code,\n\t\t\tfinishedCode: compiledFinished?.code,\n\t\t\ttitle: compiledReadme?.title ?? dirName,\n\t\t\tinstructionsEpicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\t\tfinishedEpicVideoEmbeds: compiledFinished?.epicVideoEmbeds,\n\t\t\tsteps,\n\t\t\tproblems: apps\n\t\t\t\t.filter(isProblemApp)\n\t\t\t\t.filter((app) => app.exerciseNumber === exerciseNumber),\n\t\t\tsolutions: apps\n\t\t\t\t.filter(isSolutionApp)\n\t\t\t\t.filter((app) => app.exerciseNumber === exerciseNumber),\n\t\t})\n\t\texercises.push(exercise)\n\t}\n\treturn exercises\n}\n\nexport const getExercises = requestStorageify(_getExercises)\n\nasync function _getApps({\n\ttimings,\n\trequest,\n}: CachifiedOptions & { forceFresh?: boolean } = {}): Promise<Array<App>> {\n\tawait init()\n\tconst apps = await time(\n\t\tasync () => {\n\t\t\tconst [playgroundApp, problemApps, solutionApps, exampleApps] =\n\t\t\t\tawait Promise.all([\n\t\t\t\t\ttime(() => getPlaygroundApp({ request, timings }), {\n\t\t\t\t\t\ttype: 'getPlaygroundApp',\n\t\t\t\t\t\ttimings,\n\t\t\t\t\t}),\n\t\t\t\t\ttime(() => getProblemApps({ request, timings }), {\n\t\t\t\t\t\ttype: 'getProblemApps',\n\t\t\t\t\t\ttimings,\n\t\t\t\t\t}),\n\t\t\t\t\ttime(() => getSolutionApps({ request, timings }), {\n\t\t\t\t\t\ttype: 'getSolutionApps',\n\t\t\t\t\t\ttimings,\n\t\t\t\t\t}),\n\t\t\t\t\ttime(() => getExampleApps({ request, timings }), {\n\t\t\t\t\t\ttype: 'getExampleApps',\n\t\t\t\t\t\ttimings,\n\t\t\t\t\t}),\n\t\t\t\t])\n\t\t\tconst sortedApps = [\n\t\t\t\tplaygroundApp,\n\t\t\t\t...problemApps,\n\t\t\t\t...solutionApps,\n\t\t\t\t...exampleApps,\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.sort((a, b) => {\n\t\t\t\t\tif (isPlaygroundApp(a)) {\n\t\t\t\t\t\tif (isPlaygroundApp(b)) return a.name.localeCompare(b.name)\n\t\t\t\t\t\telse return 1\n\t\t\t\t\t}\n\t\t\t\t\tif (isPlaygroundApp(b)) return 1\n\n\t\t\t\t\tif (isExampleApp(a)) {\n\t\t\t\t\t\tif (isExampleApp(b)) return a.name.localeCompare(b.name)\n\t\t\t\t\t\telse return 1\n\t\t\t\t\t}\n\t\t\t\t\tif (isExampleApp(b)) return -1\n\n\t\t\t\t\tif (a.type === b.type) {\n\t\t\t\t\t\tif (a.exerciseNumber === b.exerciseNumber) {\n\t\t\t\t\t\t\treturn a.stepNumber - b.stepNumber\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn a.exerciseNumber - b.exerciseNumber\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// at this point, we know that a and b are different types...\n\t\t\t\t\tif (isProblemApp(a)) {\n\t\t\t\t\t\tif (a.exerciseNumber === b.exerciseNumber) {\n\t\t\t\t\t\t\treturn a.stepNumber <= b.stepNumber ? 1 : -1\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn a.exerciseNumber <= b.exerciseNumber ? 1 : -1\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (isSolutionApp(a)) {\n\t\t\t\t\t\tif (a.exerciseNumber === b.exerciseNumber) {\n\t\t\t\t\t\t\treturn a.stepNumber < b.stepNumber ? -1 : 1\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn a.exerciseNumber < b.exerciseNumber ? -1 : 1\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconsole.error('unhandled sorting case', a, b)\n\t\t\t\t\treturn 0\n\t\t\t\t})\n\t\t\treturn sortedApps\n\t\t},\n\t\t{ type: 'get_apps', timings },\n\t)\n\treturn apps\n}\nexport const getApps = requestStorageify(_getApps)\n\nconst AppIdInfoSchema = z.object({\n\texerciseNumber: z.string(),\n\tstepNumber: z.string(),\n\ttype: z.union([z.literal('problem'), z.literal('solution')]),\n})\n\n/**\n * Handles both full paths and app names\n *\n * @example\n * extractNumbersAndTypeFromAppNameOrPath('02.01.problem') // { exerciseNumber: '02', stepNumber: '01', type: 'problem' }\n * extractNumbersAndTypeFromAppNameOrPath('/path/to/exercises/02.desc/01.problem.desc') // { exerciseNumber: '02', stepNumber: '01', type: 'problem' }\n */\nexport function extractNumbersAndTypeFromAppNameOrPath(\n\tfullPathOrAppName: string,\n) {\n\tconst info: { exerciseNumber?: string; stepNumber?: string; type?: string } =\n\t\t{}\n\tif (fullPathOrAppName.includes(path.sep)) {\n\t\tconst relativePath = fullPathOrAppName.replace(\n\t\t\tpath.join(getWorkshopRoot(), 'exercises', path.sep),\n\t\t\t'',\n\t\t)\n\t\tconst [exerciseNumberPart, stepNumberPart] = relativePath.split(path.sep)\n\t\tif (!exerciseNumberPart || !stepNumberPart) return null\n\t\tconst exerciseNumber = exerciseNumberPart.split('.')[0]\n\t\tconst stepNumber = stepNumberPart.split('.')[0]\n\t\tconst type = stepNumberPart.split('.')[1]?.split('.')[0]\n\t\tinfo.exerciseNumber = exerciseNumber\n\t\tinfo.stepNumber = stepNumber\n\t\tinfo.type = type\n\t} else {\n\t\tconst [exerciseNumber, stepNumber, type] = fullPathOrAppName.split('.')\n\t\tinfo.exerciseNumber = exerciseNumber\n\t\tinfo.stepNumber = stepNumber\n\t\tinfo.type = type\n\t}\n\tconst result = AppIdInfoSchema.safeParse(info)\n\tif (result.success) return result.data\n\treturn null\n}\n\nasync function getProblemDirs() {\n\tconst exercisesDir = path.join(getWorkshopRoot(), 'exercises')\n\tconst problemDirs = []\n\tconst exerciseSubDirs = await readDir(exercisesDir)\n\tfor (const subDir of exerciseSubDirs) {\n\t\tconst fullSubDir = path.join(exercisesDir, subDir)\n\t\t// catch handles non-directories without us having to bother checking\n\t\t// whether it's a directory\n\t\tconst subDirContents = await readDir(fullSubDir).catch(() => null)\n\t\tif (!subDirContents) continue\n\t\tconst problemSubDirs = subDirContents\n\t\t\t.filter((dir) => dir.includes('.problem'))\n\t\t\t.map((dir) => path.join(fullSubDir, dir))\n\n\t\t// Filter out empty directories (excluding gitignored files)\n\t\tconst nonEmptyProblemDirs = []\n\t\tfor (const problemDir of problemSubDirs) {\n\t\t\tconst isEmpty = await isDirectoryEmpty(problemDir)\n\t\t\tif (!isEmpty) {\n\t\t\t\tnonEmptyProblemDirs.push(problemDir)\n\t\t\t}\n\t\t}\n\t\tproblemDirs.push(...nonEmptyProblemDirs)\n\t}\n\treturn problemDirs\n}\n\nasync function getSolutionDirs() {\n\tconst exercisesDir = path.join(getWorkshopRoot(), 'exercises')\n\tconst solutionDirs = []\n\tconst exerciseSubDirs = await readDir(exercisesDir)\n\tfor (const subDir of exerciseSubDirs) {\n\t\tconst fullSubDir = path.join(exercisesDir, subDir)\n\t\t// catch handles non-directories without us having to bother checking\n\t\t// whether it's a directory\n\t\tconst subDirContents = await readDir(fullSubDir).catch(() => null)\n\t\tif (!subDirContents) continue\n\t\tconst solutionSubDirs = subDirContents\n\t\t\t.filter((dir) => dir.includes('.solution'))\n\t\t\t.map((dir) => path.join(fullSubDir, dir))\n\n\t\t// Filter out empty directories (excluding gitignored files)\n\t\tconst nonEmptySolutionDirs = []\n\t\tfor (const solutionDir of solutionSubDirs) {\n\t\t\tconst isEmpty = await isDirectoryEmpty(solutionDir)\n\t\t\tif (!isEmpty) {\n\t\t\t\tnonEmptySolutionDirs.push(solutionDir)\n\t\t\t}\n\t\t}\n\t\tsolutionDirs.push(...nonEmptySolutionDirs)\n\t}\n\treturn solutionDirs\n}\n\n/**\n * This is the pathname for the app in the browser\n */\nfunction getPathname(fullPath: string) {\n\tconst appName = getAppName(fullPath)\n\treturn `/app/${appName}/`\n}\n\nfunction getAppName(fullPath: string) {\n\tif (/playground\\/?$/.test(fullPath)) return 'playground'\n\tif (/examples\\/.+\\/?$/.test(fullPath)) {\n\t\tconst restOfPath = fullPath.replace(\n\t\t\t`${getWorkshopRoot()}${path.sep}examples${path.sep}`,\n\t\t\t'',\n\t\t)\n\t\treturn `example.${restOfPath.split(path.sep).join('__sep__')}`\n\t}\n\tconst appIdInfo = extractNumbersAndTypeFromAppNameOrPath(fullPath)\n\tif (appIdInfo) {\n\t\tconst { exerciseNumber, stepNumber, type } = appIdInfo\n\t\treturn `${exerciseNumber}.${stepNumber}.${type}`\n\t} else {\n\t\tconst relativePath = fullPath.replace(`${getWorkshopRoot()}${path.sep}`, '')\n\t\treturn relativePath.split(path.sep).join('__sep__')\n\t}\n}\n\nexport async function getFullPathFromAppName(appName: string) {\n\tif (appName === 'playground')\n\t\treturn path.join(getWorkshopRoot(), 'playground')\n\tif (appName.startsWith('.example')) {\n\t\tconst relativePath = appName\n\t\t\t.replace('.example', '')\n\t\t\t.split('__sep__')\n\t\t\t.join(path.sep)\n\t\treturn path.join(getWorkshopRoot(), 'examples', relativePath)\n\t}\n\tif (appName.includes('__sep__')) {\n\t\tconst relativePath = appName.replaceAll('__sep__', path.sep)\n\t\treturn path.join(getWorkshopRoot(), relativePath)\n\t}\n\tconst [exerciseNumber, stepNumber, type] = appName.split('.')\n\tconst appDirs =\n\t\ttype === 'problem'\n\t\t\t? await getProblemDirs()\n\t\t\t: type === 'solution'\n\t\t\t\t? await getSolutionDirs()\n\t\t\t\t: []\n\tconst dir = appDirs.find((dir) => {\n\t\tconst info = extractNumbersAndTypeFromAppNameOrPath(dir)\n\t\tif (!info) return false\n\t\treturn (\n\t\t\tinfo.exerciseNumber === exerciseNumber && info.stepNumber === stepNumber\n\t\t)\n\t})\n\treturn dir ?? appName\n}\n\nexport async function findSolutionDir({\n\tfullPath,\n}: {\n\tfullPath: string\n}): Promise<string | null> {\n\tconst dirName = path.basename(fullPath)\n\tif (dirName.includes('.problem')) {\n\t\tconst info = getAppDirInfo(dirName)\n\t\tif (!info) return null\n\t\tconst { stepNumber } = info\n\t\tconst paddedStepNumber = stepNumber.toString().padStart(2, '0')\n\t\tconst parentDir = path.dirname(fullPath)\n\t\tconst siblingDirs = await fs.promises.readdir(parentDir)\n\t\tconst solutionDir = siblingDirs.find((dir) =>\n\t\t\tdir.startsWith(`${paddedStepNumber}.solution`),\n\t\t)\n\t\tif (solutionDir) {\n\t\t\treturn path.join(parentDir, solutionDir)\n\t\t}\n\t} else if (fullPath.endsWith('playground')) {\n\t\tconst appName = await getPlaygroundAppName()\n\t\tif (appName) {\n\t\t\treturn findSolutionDir({\n\t\t\t\tfullPath: await getFullPathFromAppName(appName),\n\t\t\t})\n\t\t}\n\t}\n\treturn null\n}\n\nexport async function findProblemDir({\n\tfullPath,\n}: {\n\tfullPath: string\n}): Promise<string | null> {\n\tconst dirName = path.basename(fullPath)\n\tif (dirName.includes('.solution')) {\n\t\tconst info = getAppDirInfo(dirName)\n\t\tif (!info) return null\n\t\tconst { stepNumber } = info\n\t\tconst paddedStepNumber = stepNumber.toString().padStart(2, '0')\n\t\tconst parentDir = path.dirname(fullPath)\n\t\tconst siblingDirs = await fs.promises.readdir(parentDir)\n\t\tconst problemDir = siblingDirs.find(\n\t\t\t(dir) => dir.endsWith('problem') && dir.includes(paddedStepNumber),\n\t\t)\n\t\tif (problemDir) {\n\t\t\treturn path.join(parentDir, problemDir)\n\t\t}\n\t} else if (fullPath.endsWith('playground')) {\n\t\tconst appName = await getPlaygroundAppName()\n\t\tif (appName) {\n\t\t\treturn findProblemDir({ fullPath: await getFullPathFromAppName(appName) })\n\t\t}\n\t}\n\treturn null\n}\n\nasync function getTestInfo({\n\tfullPath,\n}: {\n\tfullPath: string\n}): Promise<BaseApp['test']> {\n\tconst {\n\t\ttestTab: { enabled },\n\t\tscripts: { test: testScript },\n\t} = await getAppConfig(fullPath)\n\tif (enabled === false) return { type: 'none' }\n\n\tif (testScript) {\n\t\treturn { type: 'script', script: testScript }\n\t}\n\n\t// tests are found in the corresponding solution directory\n\tconst testAppFullPath = (await findSolutionDir({ fullPath })) ?? fullPath\n\n\tconst dirList = await fs.promises.readdir(testAppFullPath)\n\tconst testFiles = dirList.filter((item) => item.includes('.test.'))\n\tif (testFiles.length) {\n\t\treturn {\n\t\t\ttype: 'browser',\n\t\t\tpathname: `${getPathname(fullPath)}test/`,\n\t\t\ttestFiles,\n\t\t}\n\t}\n\n\treturn { type: 'none' }\n}\n\nasync function getDevInfo({\n\tfullPath,\n\tportNumber,\n}: {\n\tfullPath: string\n\tportNumber: number\n}): Promise<BaseApp['dev']> {\n\tconst {\n\t\tscripts: { dev: devScript },\n\t\tinitialRoute,\n\t} = await getAppConfig(fullPath)\n\tconst hasDevScript = Boolean(devScript)\n\n\tif (hasDevScript) {\n\t\treturn { type: 'script', portNumber, initialRoute }\n\t}\n\tconst indexFiles = (await fsExtra.readdir(fullPath)).filter((file: string) =>\n\t\tfile.startsWith('index.'),\n\t)\n\tif (indexFiles.length) {\n\t\treturn { type: 'browser', pathname: getPathname(fullPath) }\n\t} else {\n\t\treturn { type: 'none' }\n\t}\n}\n\nexport async function getPlaygroundApp({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<PlaygroundApp | null> {\n\tconst playgroundDir = path.join(getWorkshopRoot(), 'playground')\n\tconst baseAppName = await getPlaygroundAppName()\n\tconst key = `playground-${baseAppName}`\n\n\tconst baseAppFullPath = baseAppName\n\t\t? await getFullPathFromAppName(baseAppName)\n\t\t: null\n\tconst playgroundCacheEntry = await playgroundAppCache.get(key)\n\treturn cachified({\n\t\tkey,\n\t\tcache: playgroundAppCache,\n\t\tttl: 1000 * 60 * 5,\n\t\tswr: 1000 * 60 * 60 * 24 * 30,\n\n\t\ttimings,\n\t\ttimingKey: playgroundDir.replace(`${playgroundDir}${path.sep}`, ''),\n\t\trequest,\n\t\tforceFresh: await getForceFreshForDir(\n\t\t\tplaygroundCacheEntry,\n\t\t\tplaygroundDir,\n\t\t\tbaseAppFullPath,\n\t\t),\n\t\tgetFreshValue: async () => {\n\t\t\tif (!(await exists(playgroundDir))) return null\n\t\t\tif (!baseAppName) return null\n\n\t\t\tconst dirName = path.basename(playgroundDir)\n\t\t\tconst name = getAppName(playgroundDir)\n\t\t\tconst portNumber = 4000\n\t\t\tconst [compiledReadme, test, dev] = await Promise.all([\n\t\t\t\tcompileMdxIfExists(path.join(playgroundDir, 'README.mdx'), { request }),\n\t\t\t\tgetTestInfo({ fullPath: playgroundDir }),\n\t\t\t\tgetDevInfo({ fullPath: playgroundDir, portNumber }),\n\t\t\t])\n\n\t\t\tconst appModifiedTime = await getDirModifiedTime(\n\t\t\t\tawait getFullPathFromAppName(baseAppName),\n\t\t\t)\n\t\t\tconst playgroundAppModifiedTime = await getDirModifiedTime(playgroundDir)\n\t\t\tconst type = 'playground'\n\n\t\t\tconst title = compiledReadme?.title ?? name\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\tappName: baseAppName,\n\t\t\t\ttype,\n\t\t\t\tisUpToDate: appModifiedTime <= playgroundAppModifiedTime,\n\t\t\t\tfullPath: playgroundDir,\n\t\t\t\trelativePath: playgroundDir.replace(\n\t\t\t\t\t`${getWorkshopRoot()}${path.sep}`,\n\t\t\t\t\t'',\n\t\t\t\t),\n\t\t\t\ttitle,\n\t\t\t\tepicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\t\t\tdirName,\n\t\t\t\tinstructionsCode: compiledReadme?.code,\n\t\t\t\ttest,\n\t\t\t\tdev,\n\t\t\t\tstackBlitzUrl: await getStackBlitzUrl({\n\t\t\t\t\tfullPath: playgroundDir,\n\t\t\t\t\ttitle,\n\t\t\t\t\ttype,\n\t\t\t\t}),\n\t\t\t} satisfies PlaygroundApp\n\t\t},\n\t}).catch((error) => {\n\t\tconsole.error(error)\n\t\treturn null\n\t})\n}\n\nasync function getExampleAppFromPath(\n\tfullPath: string,\n\tindex: number,\n\trequest?: Request,\n): Promise<ExampleApp> {\n\tconst dirName = path.basename(fullPath)\n\tconst compiledReadme = await compileMdxIfExists(\n\t\tpath.join(fullPath, 'README.mdx'),\n\t\t{ request },\n\t)\n\tconst name = getAppName(fullPath)\n\tconst portNumber = 8000 + index\n\tconst type = 'example'\n\tconst title = compiledReadme?.title ?? name\n\treturn {\n\t\tname,\n\t\ttype,\n\t\tfullPath,\n\t\trelativePath: fullPath.replace(`${getWorkshopRoot()}${path.sep}`, ''),\n\t\ttitle,\n\t\tepicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\tdirName,\n\t\tinstructionsCode: compiledReadme?.code,\n\t\ttest: await getTestInfo({ fullPath }),\n\t\tdev: await getDevInfo({ fullPath, portNumber }),\n\t\tstackBlitzUrl: await getStackBlitzUrl({\n\t\t\tfullPath,\n\t\t\ttitle,\n\t\t\ttype,\n\t\t}),\n\t} satisfies ExampleApp\n}\n\nasync function getExampleApps({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<Array<ExampleApp>> {\n\tconst examplesDir = path.join(getWorkshopRoot(), 'examples')\n\tconst exampleDirs = (await readDir(examplesDir)).map((p) =>\n\t\tpath.join(examplesDir, p),\n\t)\n\n\tconst exampleApps: Array<ExampleApp> = []\n\n\tfor (const exampleDir of exampleDirs) {\n\t\tconst index = exampleDirs.indexOf(exampleDir)\n\t\tconst key = `${exampleDir}-${index}`\n\t\tconst exampleApp = await cachified({\n\t\t\tkey,\n\t\t\tcache: exampleAppCache,\n\t\t\tttl: 1000 * 60 * 5,\n\t\t\tswr: 1000 * 60 * 60 * 24 * 30,\n\n\t\t\ttimings,\n\t\t\ttimingKey: exampleDir.replace(`${examplesDir}${path.sep}`, ''),\n\t\t\trequest,\n\t\t\tforceFresh: await getForceFreshForDir(\n\t\t\t\texampleAppCache.get(key),\n\t\t\t\texampleDir,\n\t\t\t),\n\t\t\tgetFreshValue: async () => {\n\t\t\t\treturn getExampleAppFromPath(exampleDir, index, request).catch(\n\t\t\t\t\t(error) => {\n\t\t\t\t\t\tconsole.error(error)\n\t\t\t\t\t\treturn null\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t},\n\t\t})\n\t\tif (exampleApp) exampleApps.push(exampleApp)\n\t}\n\n\treturn exampleApps\n}\n\nasync function getSolutionAppFromPath(\n\tfullPath: string,\n\trequest?: Request,\n): Promise<SolutionApp | null> {\n\tconst dirName = path.basename(fullPath)\n\tconst parentDirName = path.basename(path.dirname(fullPath))\n\tconst exerciseNumber = extractExerciseNumber(parentDirName)\n\tif (!exerciseNumber) return null\n\n\tconst name = getAppName(fullPath)\n\tconst info = getAppDirInfo(dirName)\n\tif (!info) return null\n\tconst { stepNumber } = info\n\tconst portNumber = 7000 + (exerciseNumber - 1) * 10 + stepNumber\n\tconst compiledReadme = await compileMdxIfExists(\n\t\tpath.join(fullPath, 'README.mdx'),\n\t\t{ request },\n\t)\n\tconst problemDir = await findProblemDir({\n\t\tfullPath,\n\t})\n\tconst problemName = problemDir ? getAppName(problemDir) : null\n\tconst [test, dev] = await Promise.all([\n\t\tgetTestInfo({ fullPath }),\n\t\tgetDevInfo({ fullPath, portNumber }),\n\t])\n\tconst title = compiledReadme?.title ?? name\n\treturn {\n\t\tname,\n\t\ttitle,\n\t\tepicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\ttype: 'solution',\n\t\tproblemName,\n\t\texerciseNumber,\n\t\tstepNumber,\n\t\tdirName,\n\t\tfullPath,\n\t\trelativePath: fullPath.replace(`${getWorkshopRoot()}${path.sep}`, ''),\n\t\tinstructionsCode: compiledReadme?.code,\n\t\ttest,\n\t\tdev,\n\t\tstackBlitzUrl: await getStackBlitzUrl({\n\t\t\tfullPath,\n\t\t\ttitle,\n\t\t\ttype: 'solution',\n\t\t}),\n\t} satisfies SolutionApp\n}\n\nasync function getSolutionApps({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<Array<SolutionApp>> {\n\tconst exercisesDir = path.join(getWorkshopRoot(), 'exercises')\n\tconst solutionDirs = await getSolutionDirs()\n\tconst solutionApps: Array<SolutionApp> = []\n\n\tfor (const solutionDir of solutionDirs) {\n\t\tconst solutionApp = await cachified({\n\t\t\tkey: solutionDir,\n\t\t\tcache: solutionAppCache,\n\t\t\ttimings,\n\t\t\ttimingKey: solutionDir.replace(`${exercisesDir}${path.sep}`, ''),\n\t\t\trequest,\n\t\t\tttl: 1000 * 60 * 5,\n\t\t\tswr: 1000 * 60 * 60 * 24 * 30,\n\n\t\t\tforceFresh: await getForceFreshForDir(\n\t\t\t\tsolutionAppCache.get(solutionDir),\n\t\t\t\tsolutionDir,\n\t\t\t),\n\t\t\tgetFreshValue: async () => {\n\t\t\t\treturn getSolutionAppFromPath(solutionDir, request).catch((error) => {\n\t\t\t\t\tconsole.error(error)\n\t\t\t\t\treturn null\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\t\tif (solutionApp) solutionApps.push(solutionApp)\n\t}\n\n\treturn solutionApps\n}\n\nasync function getProblemAppFromPath(\n\tfullPath: string,\n\trequest?: Request,\n): Promise<ProblemApp | null> {\n\tconst dirName = path.basename(fullPath)\n\tconst parentDirName = path.basename(path.dirname(fullPath))\n\tconst exerciseNumber = extractExerciseNumber(parentDirName)\n\tif (!exerciseNumber) return null\n\n\tconst name = getAppName(fullPath)\n\tconst info = getAppDirInfo(dirName)\n\tif (!info) return null\n\tconst { stepNumber } = info\n\tconst portNumber = 6000 + (exerciseNumber - 1) * 10 + stepNumber\n\tconst compiledReadme = await compileMdxIfExists(\n\t\tpath.join(fullPath, 'README.mdx'),\n\t\t{ request },\n\t)\n\tconst solutionDir = await findSolutionDir({\n\t\tfullPath,\n\t})\n\tconst solutionName = solutionDir ? getAppName(solutionDir) : null\n\tconst [test, dev] = await Promise.all([\n\t\tgetTestInfo({ fullPath }),\n\t\tgetDevInfo({ fullPath, portNumber }),\n\t])\n\tconst title = compiledReadme?.title ?? name\n\treturn {\n\t\tsolutionName,\n\t\tname,\n\t\ttitle,\n\t\tepicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\ttype: 'problem',\n\t\texerciseNumber,\n\t\tstepNumber,\n\t\tdirName,\n\t\tfullPath,\n\t\trelativePath: fullPath.replace(`${getWorkshopRoot()}${path.sep}`, ''),\n\t\tinstructionsCode: compiledReadme?.code,\n\t\ttest,\n\t\tdev,\n\t\tstackBlitzUrl: await getStackBlitzUrl({\n\t\t\tfullPath,\n\t\t\ttitle,\n\t\t\ttype: 'problem',\n\t\t}),\n\t} satisfies ProblemApp\n}\n\nasync function getProblemApps({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<Array<ProblemApp>> {\n\tconst exercisesDir = path.join(getWorkshopRoot(), 'exercises')\n\tconst problemDirs = await getProblemDirs()\n\tconst problemApps: Array<ProblemApp> = []\n\tfor (const problemDir of problemDirs) {\n\t\tconst solutionDir = await findSolutionDir({ fullPath: problemDir })\n\t\tconst problemApp = await cachified({\n\t\t\tkey: problemDir,\n\t\t\tcache: problemAppCache,\n\t\t\ttimings,\n\t\t\ttimingKey: problemDir.replace(`${exercisesDir}${path.sep}`, ''),\n\t\t\trequest,\n\t\t\tttl: 1000 * 60 * 5,\n\t\t\tswr: 1000 * 60 * 60 * 24 * 30,\n\n\t\t\tforceFresh: await getForceFreshForDir(\n\t\t\t\tproblemAppCache.get(problemDir),\n\t\t\t\tproblemDir,\n\t\t\t\tsolutionDir,\n\t\t\t),\n\t\t\tgetFreshValue: async () => {\n\t\t\t\treturn getProblemAppFromPath(problemDir).catch((error) => {\n\t\t\t\t\tconsole.error(error)\n\t\t\t\t\treturn null\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\t\tif (problemApp) problemApps.push(problemApp)\n\t}\n\treturn problemApps\n}\n\nexport async function getExercise(\n\texerciseNumber: number | string,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst exercises = await getExercises({ request, timings })\n\treturn exercises.find((s) => s.exerciseNumber === Number(exerciseNumber))\n}\n\nexport async function requireExercise(\n\texerciseNumber: number | string,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst exercise = await getExercise(exerciseNumber, { request, timings })\n\tif (!exercise) {\n\t\tthrow new Response('Not found', {\n\t\t\tstatus: 404,\n\t\t\theaders: { 'Server-Timing': getServerTimeHeader(timings) },\n\t\t})\n\t}\n\treturn exercise\n}\n\nexport async function requireExerciseApp(\n\tparams: Parameters<typeof getExerciseApp>[0],\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst app = await getExerciseApp(params, { request, timings })\n\tif (!app) {\n\t\tthrow new Response('Not found', { status: 404 })\n\t}\n\treturn app\n}\n\nconst ExerciseAppParamsSchema = z.object({\n\ttype: z.union([z.literal('problem'), z.literal('solution')]),\n\texerciseNumber: z.coerce.number().finite(),\n\tstepNumber: z.coerce.number().finite(),\n})\n\nexport async function getExerciseApp(\n\tparams: {\n\t\ttype?: string\n\t\texerciseNumber?: string\n\t\tstepNumber?: string\n\t},\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst result = ExerciseAppParamsSchema.safeParse(params)\n\tif (!result.success) {\n\t\treturn null\n\t}\n\tconst { type, exerciseNumber, stepNumber } = result.data\n\n\tconst apps = (await getApps({ request, timings })).filter(isExerciseStepApp)\n\tconst exerciseApp = apps.find((app) => {\n\t\tif (isExampleApp(app)) return false\n\t\treturn (\n\t\t\tapp.exerciseNumber === exerciseNumber &&\n\t\t\tapp.stepNumber === stepNumber &&\n\t\t\tapp.type === type\n\t\t)\n\t})\n\tif (!exerciseApp) {\n\t\treturn null\n\t}\n\treturn exerciseApp\n}\n\nexport async function getAppByName(\n\tname: string,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst apps = await getApps({ request, timings })\n\treturn apps.find((a) => a.name === name)\n}\n\nexport async function getNextExerciseApp(\n\tapp: ExerciseStepApp,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst apps = (await getApps({ request, timings })).filter(isExerciseStepApp)\n\tconst index = apps.findIndex((a) => a.name === app.name)\n\tif (index === -1) {\n\t\tthrow new Error(`Could not find app ${app.name}`)\n\t}\n\tconst nextApp = apps[index + 1]\n\treturn nextApp ? nextApp : null\n}\n\nexport async function getPrevExerciseApp(\n\tapp: ExerciseStepApp,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst apps = (await getApps({ request, timings })).filter(isExerciseStepApp)\n\n\tconst index = apps.findIndex((a) => a.name === app.name)\n\tif (index === -1) {\n\t\tthrow new Error(`Could not find app ${app.name}`)\n\t}\n\tconst prevApp = apps[index - 1]\n\treturn prevApp ? prevApp : null\n}\nexport function getAppPageRoute(\n\tapp: ExerciseStepApp,\n\t{\n\t\tsubroute,\n\t\tsearchParams,\n\t}: { subroute?: string; searchParams?: URLSearchParams } = {},\n) {\n\tconst exerciseNumber = app.exerciseNumber.toString().padStart(2, '0')\n\tconst stepNumber = app.stepNumber.toString().padStart(2, '0')\n\tconst baseUrl = `/exercise/${exerciseNumber}/${stepNumber}/${app.type}`\n\tconst subrouteUrl = subroute ? `/${subroute}` : ''\n\n\tif (searchParams) {\n\t\t// these are used on the diff tab and if we preserve them then the user will\n\t\t// be confused why the diff is never changing as they advance through the workshop.\n\t\tsearchParams.delete('app1')\n\t\tsearchParams.delete('app2')\n\t}\n\n\tconst searchString = searchParams?.toString()\n\treturn `${baseUrl}${subrouteUrl}${searchString ? `?${searchString}` : ''}`\n}\n\n/**\n * Given a file path, this will find the app that file path belongs to.\n */\nexport async function getAppFromFile(filePath: string) {\n\tconst apps = await getApps()\n\treturn apps.find((app) => filePath.startsWith(app.fullPath))\n}\n\nexport async function savePlayground() {\n\tconst playgroundApp = await getAppByName('playground')\n\tinvariant(playgroundApp, 'app with name \"playground\" does not exist')\n\n\tinvariant(\n\t\tisPlaygroundApp(playgroundApp),\n\t\t'app with name \"playground\" exists, but it is not a playground type app',\n\t)\n\n\tconst playgroundDir = path.join(getWorkshopRoot(), 'playground')\n\tconst savedPlaygroundsDir = path.join(getWorkshopRoot(), 'saved-playgrounds')\n\tawait fsExtra.ensureDir(savedPlaygroundsDir)\n\tconst now = dayjs()\n\t// note: the format must be filename safe\n\tconst timestamp = now.format('YYYY.MM.DD_HH.mm.ss')\n\tconst savedPlaygroundDirName = `${timestamp}_${playgroundApp.appName}`\n\n\tconst persistedPlaygroundReadmePath = path.join(\n\t\tsavedPlaygroundsDir,\n\t\t'README.md',\n\t)\n\tif (!(await exists(persistedPlaygroundReadmePath))) {\n\t\tawait fsExtra.writeFile(\n\t\t\tpersistedPlaygroundReadmePath,\n\t\t\t`\n# Saved Playgrounds\n\nThis directory stores the playground directory each time you click \"Set to\nPlayground.\" If you do not wish to do this, go to\n[your preferences](http://localhost:5639/preferences) when the app is running\nlocally and uncheck \"Enable saving playground.\"\n\t\t\t`.trim(),\n\t\t)\n\t}\n\tawait fsExtra.copy(\n\t\tplaygroundDir,\n\t\tpath.join(savedPlaygroundsDir, savedPlaygroundDirName),\n\t)\n}\n\nexport async function setPlayground(\n\tsrcDir: string,\n\t{ reset }: { reset?: boolean } = {},\n) {\n\tconst preferences = await getPreferences()\n\tconst playgroundApp = await getAppByName('playground')\n\tconst playgroundDir = path.join(getWorkshopRoot(), 'playground')\n\n\tif (playgroundApp && preferences?.playground?.persist) {\n\t\tawait savePlayground()\n\t}\n\n\tconst isIgnored = await isGitIgnored({ cwd: srcDir })\n\tconst playgroundWasRunning = playgroundApp\n\t\t? await isAppRunning(playgroundApp)\n\t\t: false\n\tif (playgroundApp && reset) {\n\t\tawait closeProcess(playgroundApp.name)\n\t\tawait fsExtra.remove(playgroundDir)\n\t}\n\tconst setPlaygroundTimestamp = Date.now()\n\n\t// run prepare-playground script if it exists\n\tconst preSetPlaygroundPath = await firstToExist(\n\t\tpath.join(srcDir, 'epicshop', 'pre-set-playground.js'),\n\t\tpath.join(getWorkshopRoot(), 'epicshop', 'pre-set-playground.js'),\n\t)\n\tif (preSetPlaygroundPath) {\n\t\tawait execa('node', [preSetPlaygroundPath], {\n\t\t\tcwd: getWorkshopRoot(),\n\t\t\tstdio: 'inherit',\n\n\t\t\tenv: {\n\t\t\t\tEPICSHOP_PLAYGROUND_TIMESTAMP: setPlaygroundTimestamp.toString(),\n\t\t\t\tEPICSHOP_PLAYGROUND_DEST_DIR: playgroundDir,\n\t\t\t\tEPICSHOP_PLAYGROUND_SRC_DIR: srcDir,\n\t\t\t\tEPICSHOP_PLAYGROUND_WAS_RUNNING: playgroundWasRunning.toString(),\n\t\t\t} as any,\n\t\t})\n\t}\n\n\tconst basename = path.basename(srcDir)\n\t// If we don't delete the destination node_modules first then copying the new\n\t// node_modules has issues.\n\tawait fsExtra.remove(path.join(playgroundDir, 'node_modules'))\n\t// Copy the contents of the source directory to the destination directory recursively\n\tawait fsExtra.copy(srcDir, playgroundDir, {\n\t\tfilter: async (srcFile, destFile) => {\n\t\t\tif (\n\t\t\t\tsrcFile.includes(`${basename}${path.sep}build`) ||\n\t\t\t\tsrcFile.includes(`${basename}${path.sep}public${path.sep}build`)\n\t\t\t) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (srcFile === srcDir) return true\n\t\t\t// we copy node_modules even though it's .gitignored\n\t\t\tif (srcFile.includes('node_modules')) return true\n\t\t\t// make sure .env is copied whether it's .gitignored or not\n\t\t\tif (srcFile.endsWith('.env')) return true\n\t\t\tif (isIgnored(srcFile)) return false\n\n\t\t\ttry {\n\t\t\t\tconst isDir = (await fsExtra.stat(srcFile)).isDirectory()\n\t\t\t\tif (isDir) return true\n\t\t\t\tconst destIsDir = (await fsExtra.stat(destFile)).isDirectory()\n\t\t\t\t// weird, but ok\n\t\t\t\tif (destIsDir) return true\n\n\t\t\t\t// it's better to check if the contents are the same before copying\n\t\t\t\t// because it avoids unnecessary writes and reduces the impact on any\n\t\t\t\t// file watchers (like the remix dev server). In practice, it's definitely\n\t\t\t\t// slower, but it's better because it doesn't cause the dev server to\n\t\t\t\t// crash as often.\n\t\t\t\tconst currentContents = await fsExtra.readFile(destFile)\n\t\t\t\tconst newContents = await fsExtra.readFile(srcFile)\n\t\t\t\tif (currentContents.equals(newContents)) return false\n\n\t\t\t\treturn true\n\t\t\t} catch {\n\t\t\t\t// 🤷♂️ should probably copy it in this case\n\t\t\t\treturn true\n\t\t\t}\n\t\t},\n\t})\n\n\tasync function getFiles(dir: string) {\n\t\t// make globby friendly to windows\n\t\tconst dirPath = dir.replace(/\\\\/g, '/')\n\t\tconst files = await globby([`${dirPath}/**/*`, '!**/build/**/*'], {\n\t\t\tonlyFiles: false,\n\t\t\tdot: true,\n\t\t})\n\t\treturn files.map((f) => f.replace(dirPath, ''))\n\t}\n\n\t// Remove files from destDir that were in destDir before but are not in srcDir\n\tconst srcFiles = await getFiles(srcDir)\n\tconst destFiles = await getFiles(playgroundDir)\n\tconst filesToDelete = destFiles.filter(\n\t\t(fileName) => !srcFiles.includes(fileName),\n\t)\n\n\tfor (const fileToDelete of filesToDelete) {\n\t\tawait fsExtra.remove(path.join(playgroundDir, fileToDelete))\n\t}\n\n\tconst appName = getAppName(srcDir)\n\tawait fsExtra.ensureDir(path.dirname(getPlaygroundAppNameInfoPath()))\n\tawait fsExtra.writeJSON(getPlaygroundAppNameInfoPath(), { appName })\n\n\tconst playgroundIsStillRunning = playgroundApp\n\t\t? isAppRunning(playgroundApp)\n\t\t: false\n\tconst restartPlayground = playgroundWasRunning && !playgroundIsStillRunning\n\n\t// run postSet-playground script if it exists\n\tconst postSetPlaygroundPath = await firstToExist(\n\t\tpath.join(srcDir, 'epicshop', 'post-set-playground.js'),\n\t\tpath.join(getWorkshopRoot(), 'epicshop', 'post-set-playground.js'),\n\t)\n\tif (postSetPlaygroundPath) {\n\t\tawait execa('node', [postSetPlaygroundPath], {\n\t\t\tcwd: getWorkshopRoot(),\n\t\t\tstdio: 'inherit',\n\n\t\t\tenv: {\n\t\t\t\tEPICSHOP_PLAYGROUND_TIMESTAMP: setPlaygroundTimestamp.toString(),\n\t\t\t\tEPICSHOP_PLAYGROUND_SRC_DIR: srcDir,\n\t\t\t\tEPICSHOP_PLAYGROUND_DEST_DIR: playgroundDir,\n\t\t\t\tEPICSHOP_PLAYGROUND_WAS_RUNNING: playgroundWasRunning.toString(),\n\t\t\t\tEPICSHOP_PLAYGROUND_IS_STILL_RUNNING:\n\t\t\t\t\tplaygroundIsStillRunning.toString(),\n\t\t\t\tEPICSHOP_PLAYGROUND_RESTART_PLAYGROUND: restartPlayground.toString(),\n\t\t\t} as any,\n\t\t})\n\t}\n\n\t// since we are running without the watcher we need to set the modified time\n\tmodifiedTimes.set(playgroundDir, Date.now())\n\n\tif (playgroundApp && restartPlayground) {\n\t\tawait runAppDev(playgroundApp)\n\t\tawait waitOnApp(playgroundApp)\n\t}\n}\n\n/**\n * The playground is based on another app. This returns the app the playground\n * is based on.\n */\nexport async function getPlaygroundAppName() {\n\tif (!(await exists(getPlaygroundAppNameInfoPath()))) {\n\t\treturn null\n\t}\n\ttry {\n\t\tconst jsonString = await fs.promises.readFile(\n\t\t\tgetPlaygroundAppNameInfoPath(),\n\t\t\t'utf8',\n\t\t)\n\n\t\tconst { appName } = JSON.parse(jsonString) as any\n\t\tif (typeof appName !== 'string') return null\n\t\treturn appName\n\t} catch {\n\t\treturn null\n\t}\n}\n\nexport function getAppDisplayName(a: App, allApps: Array<App>) {\n\tlet displayName = `${a.title} (${a.type})`\n\tif (isExerciseStepApp(a)) {\n\t\tconst typeLabel = { problem: '💪', solution: '🏁' }[a.type]\n\t\tdisplayName = `${a.exerciseNumber}.${a.stepNumber} ${a.title} (${typeLabel} ${a.type})`\n\t} else if (isPlaygroundApp(a)) {\n\t\tconst playgroundAppBasis = allApps.find(\n\t\t\t(otherApp) => a.appName === otherApp.name,\n\t\t)\n\t\tif (playgroundAppBasis) {\n\t\t\tconst basisDisplayName = getAppDisplayName(playgroundAppBasis, allApps)\n\t\t\tdisplayName = `🛝 ${basisDisplayName}`\n\t\t} else {\n\t\t\tdisplayName = `🛝 ${a.appName}`\n\t\t}\n\t} else if (isExampleApp(a)) {\n\t\tdisplayName = `📚 ${a.title} (example)`\n\t}\n\treturn displayName\n}\n\nexport async function getWorkshopInstructions({\n\trequest,\n}: { request?: Request } = {}) {\n\tconst readmeFilepath = path.join(getWorkshopRoot(), 'exercises', 'README.mdx')\n\tconst compiled = await compileMdx(readmeFilepath, { request }).then(\n\t\t(r) => ({ ...r, status: 'success' }) as const,\n\t\t(e) => {\n\t\t\tconsole.error(\n\t\t\t\t`There was an error compiling the workshop readme`,\n\t\t\t\treadmeFilepath,\n\t\t\t\te,\n\t\t\t)\n\t\t\treturn { status: 'error', error: getErrorMessage(e) } as const\n\t\t},\n\t)\n\treturn { compiled, file: readmeFilepath, relativePath: 'exercises' } as const\n}\n\nexport async function getWorkshopFinished({\n\trequest,\n}: { request?: Request } = {}) {\n\tconst finishedFilepath = path.join(\n\t\tgetWorkshopRoot(),\n\t\t'exercises',\n\t\t'FINISHED.mdx',\n\t)\n\tconst compiled = await compileMdx(finishedFilepath, { request }).then(\n\t\t(r) => ({ ...r, status: 'success' }) as const,\n\t\t(e) => {\n\t\t\tconsole.error(\n\t\t\t\t`There was an error compiling the workshop finished.mdx`,\n\t\t\t\tfinishedFilepath,\n\t\t\t\te,\n\t\t\t)\n\t\t\treturn { status: 'error', error: getErrorMessage(e) } as const\n\t\t},\n\t)\n\treturn {\n\t\tcompiled,\n\t\tfile: finishedFilepath,\n\t\trelativePath: 'exercises/finished.mdx',\n\t} as const\n}\n\nexport function getRelativePath(filePath: string) {\n\tconst exercisesPath = path.join(getWorkshopRoot(), 'exercises/')\n\tconst playgroundPath = path.join(getWorkshopRoot(), 'playground/')\n\n\treturn path\n\t\t.normalize(filePath.replace(/^(\"|')|(\"|')$/g, ''))\n\t\t.replace(playgroundPath, `playground${path.sep}`)\n\t\t.replace(exercisesPath, '')\n}\n\n/**\n * Given a file path, this will determine the path to the app that file belongs to.\n */\nexport function getAppPathFromFilePath(filePath: string): string | null {\n\tconst [, withinWorkshopRootHalf] = filePath.split(getWorkshopRoot())\n\tif (!withinWorkshopRootHalf) {\n\t\treturn null\n\t}\n\n\tconst [part1, part2, part3] = withinWorkshopRootHalf\n\t\t.split(path.sep)\n\t\t.filter(Boolean)\n\n\t// Check if the file is in the playground\n\tif (part1 === 'playground') {\n\t\treturn path.join(getWorkshopRoot(), 'playground')\n\t}\n\n\t// Check if the file is in an example\n\tif (part1 === 'examples' && part2) {\n\t\treturn path.join(getWorkshopRoot(), 'examples', part2)\n\t}\n\n\t// Check if the file is in an exercise\n\tif (part1 === 'exercises' && part2 && part3) {\n\t\treturn path.join(getWorkshopRoot(), 'exercises', part2, part3)\n\t}\n\n\t// If we couldn't determine the app path, return null\n\treturn null\n}\n"]}
|
|
1
|
+
{"version":3,"file":"apps.server.js","sourceRoot":"","sources":["../../src/apps.server.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { getEnv } from './init-env.js'\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { type CacheEntry } from '@epic-web/cachified'\nimport { invariant } from '@epic-web/invariant'\nimport { remember } from '@epic-web/remember'\nimport chokidar from 'chokidar'\n/// TODO: figure out why this import is necessary (without it tsc seems to not honor the boolean reset 🤷♂️)\nimport '@total-typescript/ts-reset'\nimport closeWithGrace from 'close-with-grace'\nimport { execa } from 'execa'\nimport fsExtra from 'fs-extra'\nimport { globby, isGitIgnored } from 'globby'\nimport { z } from 'zod'\nimport {\n\tcachified,\n\texampleAppCache,\n\tplaygroundAppCache,\n\tproblemAppCache,\n\tsolutionAppCache,\n\tdirectoryEmptyCache,\n} from './cache.server.js'\nimport { compileMdx } from './compile-mdx.server.js'\nimport { getAppConfig, getStackBlitzUrl } from './config.server.js'\nimport { getPreferences } from './db.server.js'\nimport { getDirModifiedTime } from './modified-time.server.js'\nimport {\n\tcloseProcess,\n\tisAppRunning,\n\trunAppDev,\n\twaitOnApp,\n} from './process-manager.server.js'\nimport { requestStorageify } from './request-context.server.js'\nimport { getServerTimeHeader, time, type Timings } from './timing.server.js'\nimport { getErrorMessage } from './utils.js'\nimport { dayjs } from './utils.server.js'\n\ndeclare global {\n\tvar __epicshop_apps_initialized__: boolean | undefined\n}\nglobal.__epicshop_apps_initialized__ ??= false\n\nexport function setWorkshopRoot(\n\troot: string = process.env.EPICSHOP_CONTEXT_CWD ?? process.cwd(),\n) {\n\tprocess.env.EPICSHOP_CONTEXT_CWD = root\n}\n\nexport function getWorkshopRoot() {\n\tif (!process.env.EPICSHOP_CONTEXT_CWD) setWorkshopRoot()\n\n\treturn process.env.EPICSHOP_CONTEXT_CWD\n}\n\nfunction getPlaygroundAppNameInfoPath() {\n\treturn path.join(\n\t\tgetWorkshopRoot(),\n\t\t'node_modules',\n\t\t'.cache',\n\t\t'epicshop',\n\t\t'playground.json',\n\t)\n}\n\ntype CachifiedOptions = { timings?: Timings; request?: Request }\n\nconst BaseAppSchema = z.object({\n\t/** a unique identifier for the app */\n\tname: z.string(),\n\t/** the title of the app used for display (comes from the package.json title prop) */\n\ttitle: z.string(),\n\t/** used when displaying the list of files to match the list of apps in the file system (comes the name of the directory of the app) */\n\tdirName: z.string(),\n\tfullPath: z.string(),\n\trelativePath: z.string(),\n\tinstructionsCode: z.string().optional(),\n\tepicVideoEmbeds: z.array(z.string()).optional(),\n\ttest: z.union([\n\t\tz.object({\n\t\t\ttype: z.literal('browser'),\n\t\t\tpathname: z.string(),\n\t\t\ttestFiles: z.array(z.string()),\n\t\t}),\n\t\tz.object({ type: z.literal('script'), script: z.string() }),\n\t\tz.object({ type: z.literal('none') }),\n\t]),\n\tdev: z.union([\n\t\tz.object({ type: z.literal('browser'), pathname: z.string() }),\n\t\tz.object({\n\t\t\ttype: z.literal('script'),\n\t\t\tportNumber: z.number(),\n\t\t\tinitialRoute: z.string(),\n\t\t}),\n\t\tz.object({ type: z.literal('none') }),\n\t]),\n\tstackBlitzUrl: z.string().nullable(),\n})\n\nconst BaseExerciseStepAppSchema = BaseAppSchema.extend({\n\texerciseNumber: z.number(),\n\tstepNumber: z.number(),\n})\n\nconst ProblemAppSchema = BaseExerciseStepAppSchema.extend({\n\ttype: z.literal('problem'),\n\tsolutionName: z.string().nullable(),\n})\n\nconst SolutionAppSchema = BaseExerciseStepAppSchema.extend({\n\ttype: z.literal('solution'),\n\tproblemName: z.string().nullable(),\n})\n\nconst ExampleAppSchema = BaseAppSchema.extend({\n\ttype: z.literal('example'),\n})\n\nconst PlaygroundAppSchema = BaseAppSchema.extend({\n\ttype: z.literal('playground'),\n\tappName: z.string(),\n\tisUpToDate: z.boolean(),\n})\n\nconst ExerciseSchema = z.object({\n\t/** the full path to the exercise directory */\n\tfullPath: z.string(),\n\t/** a unique identifier for the exercise */\n\texerciseNumber: z.number(),\n\t/** used when displaying the list of files to match the list of apps in the file system (comes the name of the directory of the app) */\n\tdirName: z.string(),\n\t/** the title of the app used for display (comes from the first h1 in the README) */\n\ttitle: z.string(),\n\tinstructionsCode: z.string().optional(),\n\tfinishedCode: z.string().optional(),\n\tinstructionsEpicVideoEmbeds: z.array(z.string()).optional(),\n\tfinishedEpicVideoEmbeds: z.array(z.string()).optional(),\n\tsteps: z\n\t\t.array(\n\t\t\tz.union([\n\t\t\t\tz.object({\n\t\t\t\t\tstepNumber: z.number(),\n\t\t\t\t\tproblem: ProblemAppSchema,\n\t\t\t\t\tsolution: SolutionAppSchema,\n\t\t\t\t}),\n\t\t\t\tz.object({\n\t\t\t\t\tstepNumber: z.number(),\n\t\t\t\t\tproblem: ProblemAppSchema,\n\t\t\t\t\tsolution: z.never().optional(),\n\t\t\t\t}),\n\t\t\t\tz.object({\n\t\t\t\t\tstepNumber: z.number(),\n\t\t\t\t\tproblem: z.never().optional(),\n\t\t\t\t\tsolution: SolutionAppSchema,\n\t\t\t\t}),\n\t\t\t\tz.undefined(),\n\t\t\t]),\n\t\t)\n\t\t.transform((steps) => steps.filter((step) => step !== undefined)),\n\tproblems: z.array(ProblemAppSchema),\n\tsolutions: z.array(SolutionAppSchema),\n})\n\nconst ExerciseStepAppSchema = z.union([ProblemAppSchema, SolutionAppSchema])\n\nconst AppSchema = z.union([\n\tExerciseStepAppSchema,\n\tPlaygroundAppSchema,\n\tExampleAppSchema,\n])\n\ntype BaseApp = z.infer<typeof BaseAppSchema>\n\nexport type BaseExerciseStepApp = z.infer<typeof BaseExerciseStepAppSchema>\nexport type ProblemApp = z.infer<typeof ProblemAppSchema>\nexport type SolutionApp = z.infer<typeof SolutionAppSchema>\nexport type ExampleApp = z.infer<typeof ExampleAppSchema>\nexport type PlaygroundApp = z.infer<typeof PlaygroundAppSchema>\nexport type ExerciseStepApp = z.infer<typeof ExerciseStepAppSchema>\nexport type App = z.infer<typeof AppSchema>\nexport type AppType = App['type']\n\ntype Exercise = z.infer<typeof ExerciseSchema>\n\nexport function isApp(app: any): app is App {\n\treturn AppSchema.safeParse(app).success\n}\n\nexport function isProblemApp(app: any): app is ProblemApp {\n\treturn ProblemAppSchema.safeParse(app).success\n}\n\nexport function isSolutionApp(app: any): app is SolutionApp {\n\treturn SolutionAppSchema.safeParse(app).success\n}\n\nexport function isFirstStepProblemApp(\n\tapp: App,\n): app is ProblemApp & { stepNumber: 1 } {\n\treturn isProblemApp(app) && app.stepNumber === 1\n}\n\nexport function isFirstStepSolutionApp(\n\tapp: App,\n): app is SolutionApp & { stepNumber: 1 } {\n\treturn isSolutionApp(app) && app.stepNumber === 1\n}\n\nexport function isPlaygroundApp(app: any): app is PlaygroundApp {\n\treturn isApp(app) && app.type === 'playground'\n}\n\nexport function isExampleApp(app: any): app is ExampleApp {\n\treturn isApp(app) && app.type === 'example'\n}\n\nexport function isExerciseStepApp(app: any): app is ExerciseStepApp {\n\treturn isProblemApp(app) || isSolutionApp(app)\n}\n\nfunction exists(file: string) {\n\treturn fs.promises.access(file, fs.constants.F_OK).then(\n\t\t() => true,\n\t\t() => false,\n\t)\n}\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n\treturn cachified({\n\t\tkey: dirPath,\n\t\tcache: directoryEmptyCache,\n\t\tttl: 1000 * 60 * 5,\n\t\tswr: 1000 * 60 * 20,\n\t\tforceFresh: await getForceFreshForDir(\n\t\t\tdirectoryEmptyCache.get(dirPath),\n\t\t\tdirPath,\n\t\t),\n\t\tgetFreshValue: async () => {\n\t\t\ttry {\n\t\t\t\tconst files = await fs.promises.readdir(dirPath)\n\t\t\t\tif (files.length === 0) return true\n\t\t\t\tconst isIgnored = await isGitIgnored({ cwd: dirPath })\n\t\t\t\tconst nonIgnoredFiles = files.filter((file) => !isIgnored(file))\n\t\t\t\treturn nonIgnoredFiles.length === 0\n\t\t\t} catch {\n\t\t\t\treturn true\n\t\t\t}\n\t\t},\n\t})\n}\n\nasync function firstToExist(...files: Array<string>) {\n\tconst results = await Promise.all(files.map(exists))\n\tconst index = results.findIndex(Boolean)\n\treturn index === -1 ? null : files[index]\n}\n\nexport const modifiedTimes = remember(\n\t'modified_times',\n\t() => new Map<string, number>(),\n)\n\nexport async function init(workshopRoot?: string) {\n\tsetWorkshopRoot(workshopRoot)\n\n\tif (global.__epicshop_apps_initialized__) return\n\n\tglobal.__epicshop_apps_initialized__ = true\n\n\tif (\n\t\t!getEnv().EPICSHOP_DEPLOYED &&\n\t\tprocess.env.EPICSHOP_ENABLE_WATCHER === 'true'\n\t) {\n\t\tconst isIgnored = await isGitIgnored({ cwd: getWorkshopRoot() })\n\n\t\t// watch the README, FINISHED, and package.json for changes that affect the apps\n\t\tconst filesToWatch = ['README.mdx', 'FINISHED.mdx', 'package.json']\n\t\tconst chok = chokidar.watch(['examples', 'playground', 'exercises'], {\n\t\t\tcwd: getWorkshopRoot(),\n\t\t\t// we want to load up the modified times immediately\n\t\t\tignoreInitial: false,\n\t\t\tignored(filePath, stats) {\n\t\t\t\tif (isIgnored(filePath)) return true\n\t\t\t\tif (filePath.includes('.git')) return true\n\n\t\t\t\tif (stats?.isDirectory()) {\n\t\t\t\t\tif (filePath.endsWith('playground')) return false\n\t\t\t\t\tconst pathParts = filePath.split(path.sep)\n\t\t\t\t\tif (pathParts.at(-2) === 'examples') return false\n\n\t\t\t\t\t// steps\n\t\t\t\t\tif (pathParts.at(-3) === 'exercises') return false\n\n\t\t\t\t\t// exercises\n\t\t\t\t\tif (pathParts.at(-2) === 'exercises') return false\n\n\t\t\t\t\t// the exercise dir itself\n\t\t\t\t\tif (pathParts.at(-1) === 'exercises') return false\n\t\t\t\t\treturn true\n\t\t\t\t}\n\n\t\t\t\treturn stats?.isFile()\n\t\t\t\t\t? !filesToWatch.some((file) => filePath.endsWith(file))\n\t\t\t\t\t: false\n\t\t\t},\n\t\t})\n\n\t\tchok.on('all', async (_event, filePath) => {\n\t\t\tconst modifiedAt = await getModifiedTimeForFile(\n\t\t\t\tpath.join(getWorkshopRoot(), filePath),\n\t\t\t)\n\t\t\tsetModifiedTimesForAppDirs(\n\t\t\t\tmodifiedAt ?? Date.now(),\n\t\t\t\tpath.join(getWorkshopRoot(), filePath),\n\t\t\t)\n\t\t})\n\n\t\tcloseWithGrace(() => chok.close())\n\t}\n}\n\nexport async function getModifiedTimeForFile(filepath?: string) {\n\tif (!filepath) return null\n\tconst modifiedAt = await fs.promises\n\t\t.stat(path.join(filepath))\n\t\t.catch(() => null)\n\treturn modifiedAt?.mtimeMs ?? null\n}\n\nexport function setModifiedTimesForAppDirs(\n\tmodifiedAt: number,\n\t...filePaths: Array<string>\n) {\n\tfor (const filePath of filePaths) {\n\t\tconst appDir = getAppPathFromFilePath(filePath)\n\t\tif (appDir) {\n\t\t\tconst existingModifiedTime = modifiedTimes.get(appDir)\n\t\t\tif (!existingModifiedTime || modifiedAt > existingModifiedTime) {\n\t\t\t\tmodifiedTimes.set(appDir, modifiedAt)\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function getForceFreshForDir(\n\tcacheEntry:\n\t\t| CacheEntry\n\t\t| null\n\t\t| undefined\n\t\t| Promise<CacheEntry | null | undefined>,\n\t...dirs: Array<string | undefined | null>\n) {\n\tconst truthyDirs = dirs.filter(Boolean)\n\tfor (const d of truthyDirs) {\n\t\tif (!path.isAbsolute(d)) {\n\t\t\tthrow new Error(`Trying to get force fresh for non-absolute path: ${d}`)\n\t\t}\n\t}\n\tconst resolvedCacheEntry = await cacheEntry\n\tif (!resolvedCacheEntry) return true\n\tconst latestModifiedTime = truthyDirs.reduce((latest, dir) => {\n\t\tconst modifiedTime = modifiedTimes.get(dir)\n\t\treturn modifiedTime && modifiedTime > latest ? modifiedTime : latest\n\t}, 0)\n\tif (!latestModifiedTime) return undefined\n\treturn latestModifiedTime > resolvedCacheEntry.metadata.createdTime\n\t\t? true\n\t\t: undefined\n}\n\nasync function readDir(dir: string) {\n\tif (await exists(dir)) {\n\t\treturn fs.promises.readdir(dir)\n\t}\n\treturn []\n}\n\nasync function compileMdxIfExists(\n\tfilepath: string,\n\t{ request }: { request?: Request } = {},\n) {\n\tfilepath = filepath.replace(/\\\\/g, '/')\n\tif (await exists(filepath)) {\n\t\tconst compiled = await compileMdx(filepath, { request }).catch((error) => {\n\t\t\tconsole.error(`Error compiling ${filepath}:`, error)\n\t\t\treturn null\n\t\t})\n\t\treturn compiled\n\t}\n\treturn null\n}\n\nfunction getAppDirInfo(appDir: string) {\n\tconst regex = /^(?<stepNumber>\\d+)\\.(problem|solution)(\\.(?<subtitle>.*))?$/\n\tconst match = regex.exec(appDir)\n\tif (!match?.groups) {\n\t\tconsole.info(\n\t\t\t`Ignoring directory \"${appDir}\" which does not match regex \"${regex}\"`,\n\t\t\tnew Error().stack,\n\t\t)\n\t\treturn null\n\t}\n\tconst { stepNumber: stepNumberString, subtitle } = match.groups\n\tconst stepNumber = Number(stepNumberString)\n\tif (!stepNumber || !Number.isFinite(stepNumber)) {\n\t\tthrow new Error(\n\t\t\t`Cannot identify the stepNumber for app directory \"${appDir}\" with regex \"${regex}\"`,\n\t\t)\n\t}\n\n\tconst type = match[2] as 'problem' | 'solution'\n\treturn { stepNumber, type, subtitle }\n}\n\nfunction extractExerciseNumber(dir: string) {\n\tconst regex = /^(?<number>\\d+)\\./\n\tconst number = regex.exec(dir)?.groups?.number\n\tif (!number) {\n\t\treturn null\n\t}\n\treturn Number(number)\n}\n\nasync function _getExercises({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<Array<Exercise>> {\n\tconst apps = await getApps({ request, timings })\n\tconst exerciseDirs = await readDir(path.join(getWorkshopRoot(), 'exercises'))\n\tconst exercises: Array<Exercise> = []\n\tfor (const dirName of exerciseDirs) {\n\t\tconst exerciseNumber = extractExerciseNumber(dirName)\n\t\tif (!exerciseNumber) continue\n\n\t\t// Skip empty exercise directories (excluding gitignored files)\n\t\tconst exerciseDir = path.join(getWorkshopRoot(), 'exercises', dirName)\n\t\tconst isEmpty = await isDirectoryEmpty(exerciseDir)\n\t\tif (isEmpty) continue\n\t\tconst compiledReadme = await compileMdxIfExists(\n\t\t\tpath.join(getWorkshopRoot(), 'exercises', dirName, 'README.mdx'),\n\t\t\t{ request },\n\t\t)\n\t\tconst compiledFinished = await compileMdxIfExists(\n\t\t\tpath.join(getWorkshopRoot(), 'exercises', dirName, 'FINISHED.mdx'),\n\t\t\t{ request },\n\t\t)\n\t\tconst steps: Exercise['steps'] = []\n\t\tconst exerciseApps = apps\n\t\t\t.filter(isExerciseStepApp)\n\t\t\t.filter((app) => app.exerciseNumber === exerciseNumber)\n\t\tfor (const app of exerciseApps) {\n\t\t\t// @ts-ignore meh 🤷♂️\n\t\t\tsteps[app.stepNumber - 1] = {\n\t\t\t\t...steps[app.stepNumber - 1],\n\t\t\t\t[app.type]: app,\n\t\t\t\tstepNumber: app.stepNumber,\n\t\t\t}\n\t\t}\n\t\tconst exercise = ExerciseSchema.parse({\n\t\t\tfullPath: path.join(getWorkshopRoot(), 'exercises', dirName),\n\t\t\texerciseNumber,\n\t\t\tdirName,\n\t\t\tinstructionsCode: compiledReadme?.code,\n\t\t\tfinishedCode: compiledFinished?.code,\n\t\t\ttitle: compiledReadme?.title ?? dirName,\n\t\t\tinstructionsEpicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\t\tfinishedEpicVideoEmbeds: compiledFinished?.epicVideoEmbeds,\n\t\t\tsteps,\n\t\t\tproblems: apps\n\t\t\t\t.filter(isProblemApp)\n\t\t\t\t.filter((app) => app.exerciseNumber === exerciseNumber),\n\t\t\tsolutions: apps\n\t\t\t\t.filter(isSolutionApp)\n\t\t\t\t.filter((app) => app.exerciseNumber === exerciseNumber),\n\t\t})\n\t\texercises.push(exercise)\n\t}\n\treturn exercises\n}\n\nexport const getExercises = requestStorageify(_getExercises)\n\nasync function _getApps({\n\ttimings,\n\trequest,\n}: CachifiedOptions & { forceFresh?: boolean } = {}): Promise<Array<App>> {\n\tawait init()\n\tconst apps = await time(\n\t\tasync () => {\n\t\t\tconst [playgroundApp, problemApps, solutionApps, exampleApps] =\n\t\t\t\tawait Promise.all([\n\t\t\t\t\ttime(() => getPlaygroundApp({ request, timings }), {\n\t\t\t\t\t\ttype: 'getPlaygroundApp',\n\t\t\t\t\t\ttimings,\n\t\t\t\t\t}),\n\t\t\t\t\ttime(() => getProblemApps({ request, timings }), {\n\t\t\t\t\t\ttype: 'getProblemApps',\n\t\t\t\t\t\ttimings,\n\t\t\t\t\t}),\n\t\t\t\t\ttime(() => getSolutionApps({ request, timings }), {\n\t\t\t\t\t\ttype: 'getSolutionApps',\n\t\t\t\t\t\ttimings,\n\t\t\t\t\t}),\n\t\t\t\t\ttime(() => getExampleApps({ request, timings }), {\n\t\t\t\t\t\ttype: 'getExampleApps',\n\t\t\t\t\t\ttimings,\n\t\t\t\t\t}),\n\t\t\t\t])\n\t\t\tconst sortedApps = [\n\t\t\t\tplaygroundApp,\n\t\t\t\t...problemApps,\n\t\t\t\t...solutionApps,\n\t\t\t\t...exampleApps,\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.sort((a, b) => {\n\t\t\t\t\tif (isPlaygroundApp(a)) {\n\t\t\t\t\t\tif (isPlaygroundApp(b)) return a.name.localeCompare(b.name)\n\t\t\t\t\t\telse return 1\n\t\t\t\t\t}\n\t\t\t\t\tif (isPlaygroundApp(b)) return 1\n\n\t\t\t\t\tif (isExampleApp(a)) {\n\t\t\t\t\t\tif (isExampleApp(b)) return a.name.localeCompare(b.name)\n\t\t\t\t\t\telse return 1\n\t\t\t\t\t}\n\t\t\t\t\tif (isExampleApp(b)) return -1\n\n\t\t\t\t\tif (a.type === b.type) {\n\t\t\t\t\t\tif (a.exerciseNumber === b.exerciseNumber) {\n\t\t\t\t\t\t\treturn a.stepNumber - b.stepNumber\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn a.exerciseNumber - b.exerciseNumber\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// at this point, we know that a and b are different types...\n\t\t\t\t\tif (isProblemApp(a)) {\n\t\t\t\t\t\tif (a.exerciseNumber === b.exerciseNumber) {\n\t\t\t\t\t\t\treturn a.stepNumber <= b.stepNumber ? 1 : -1\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn a.exerciseNumber <= b.exerciseNumber ? 1 : -1\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (isSolutionApp(a)) {\n\t\t\t\t\t\tif (a.exerciseNumber === b.exerciseNumber) {\n\t\t\t\t\t\t\treturn a.stepNumber < b.stepNumber ? -1 : 1\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn a.exerciseNumber < b.exerciseNumber ? -1 : 1\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconsole.error('unhandled sorting case', a, b)\n\t\t\t\t\treturn 0\n\t\t\t\t})\n\t\t\treturn sortedApps\n\t\t},\n\t\t{ type: 'get_apps', timings },\n\t)\n\treturn apps\n}\nexport const getApps = requestStorageify(_getApps)\n\nconst AppIdInfoSchema = z.object({\n\texerciseNumber: z.string(),\n\tstepNumber: z.string(),\n\ttype: z.union([z.literal('problem'), z.literal('solution')]),\n})\n\n/**\n * Handles both full paths and app names\n *\n * @example\n * extractNumbersAndTypeFromAppNameOrPath('02.01.problem') // { exerciseNumber: '02', stepNumber: '01', type: 'problem' }\n * extractNumbersAndTypeFromAppNameOrPath('/path/to/exercises/02.desc/01.problem.desc') // { exerciseNumber: '02', stepNumber: '01', type: 'problem' }\n */\nexport function extractNumbersAndTypeFromAppNameOrPath(\n\tfullPathOrAppName: string,\n) {\n\tconst info: { exerciseNumber?: string; stepNumber?: string; type?: string } =\n\t\t{}\n\tif (fullPathOrAppName.includes(path.sep)) {\n\t\tconst relativePath = fullPathOrAppName.replace(\n\t\t\tpath.join(getWorkshopRoot(), 'exercises', path.sep),\n\t\t\t'',\n\t\t)\n\t\tconst [exerciseNumberPart, stepNumberPart] = relativePath.split(path.sep)\n\t\tif (!exerciseNumberPart || !stepNumberPart) return null\n\t\tconst exerciseNumber = exerciseNumberPart.split('.')[0]\n\t\tconst stepNumber = stepNumberPart.split('.')[0]\n\t\tconst type = stepNumberPart.split('.')[1]?.split('.')[0]\n\t\tinfo.exerciseNumber = exerciseNumber\n\t\tinfo.stepNumber = stepNumber\n\t\tinfo.type = type\n\t} else {\n\t\tconst [exerciseNumber, stepNumber, type] = fullPathOrAppName.split('.')\n\t\tinfo.exerciseNumber = exerciseNumber\n\t\tinfo.stepNumber = stepNumber\n\t\tinfo.type = type\n\t}\n\tconst result = AppIdInfoSchema.safeParse(info)\n\tif (result.success) return result.data\n\treturn null\n}\n\nasync function getProblemDirs() {\n\tconst exercisesDir = path.join(getWorkshopRoot(), 'exercises')\n\tconst problemDirs = []\n\tconst exerciseSubDirs = await readDir(exercisesDir)\n\tfor (const subDir of exerciseSubDirs) {\n\t\tconst fullSubDir = path.join(exercisesDir, subDir)\n\t\t// catch handles non-directories without us having to bother checking\n\t\t// whether it's a directory\n\t\tconst subDirContents = await readDir(fullSubDir).catch(() => null)\n\t\tif (!subDirContents) continue\n\t\tconst problemSubDirs = subDirContents\n\t\t\t.filter((dir) => dir.includes('.problem'))\n\t\t\t.map((dir) => path.join(fullSubDir, dir))\n\n\t\t// Filter out empty directories (excluding gitignored files)\n\t\tconst nonEmptyProblemDirs = []\n\t\tfor (const problemDir of problemSubDirs) {\n\t\t\tconst isEmpty = await isDirectoryEmpty(problemDir)\n\t\t\tif (!isEmpty) {\n\t\t\t\tnonEmptyProblemDirs.push(problemDir)\n\t\t\t}\n\t\t}\n\t\tproblemDirs.push(...nonEmptyProblemDirs)\n\t}\n\treturn problemDirs\n}\n\nasync function getSolutionDirs() {\n\tconst exercisesDir = path.join(getWorkshopRoot(), 'exercises')\n\tconst solutionDirs = []\n\tconst exerciseSubDirs = await readDir(exercisesDir)\n\tfor (const subDir of exerciseSubDirs) {\n\t\tconst fullSubDir = path.join(exercisesDir, subDir)\n\t\t// catch handles non-directories without us having to bother checking\n\t\t// whether it's a directory\n\t\tconst subDirContents = await readDir(fullSubDir).catch(() => null)\n\t\tif (!subDirContents) continue\n\t\tconst solutionSubDirs = subDirContents\n\t\t\t.filter((dir) => dir.includes('.solution'))\n\t\t\t.map((dir) => path.join(fullSubDir, dir))\n\n\t\t// Filter out empty directories (excluding gitignored files)\n\t\tconst nonEmptySolutionDirs = []\n\t\tfor (const solutionDir of solutionSubDirs) {\n\t\t\tconst isEmpty = await isDirectoryEmpty(solutionDir)\n\t\t\tif (!isEmpty) {\n\t\t\t\tnonEmptySolutionDirs.push(solutionDir)\n\t\t\t}\n\t\t}\n\t\tsolutionDirs.push(...nonEmptySolutionDirs)\n\t}\n\treturn solutionDirs\n}\n\n/**\n * This is the pathname for the app in the browser\n */\nfunction getPathname(fullPath: string) {\n\tconst appName = getAppName(fullPath)\n\treturn `/app/${appName}/`\n}\n\nfunction getAppName(fullPath: string) {\n\tif (/playground\\/?$/.test(fullPath)) return 'playground'\n\tif (/examples\\/.+\\/?$/.test(fullPath)) {\n\t\tconst restOfPath = fullPath.replace(\n\t\t\t`${getWorkshopRoot()}${path.sep}examples${path.sep}`,\n\t\t\t'',\n\t\t)\n\t\treturn `example.${restOfPath.split(path.sep).join('__sep__')}`\n\t}\n\tconst appIdInfo = extractNumbersAndTypeFromAppNameOrPath(fullPath)\n\tif (appIdInfo) {\n\t\tconst { exerciseNumber, stepNumber, type } = appIdInfo\n\t\treturn `${exerciseNumber}.${stepNumber}.${type}`\n\t} else {\n\t\tconst relativePath = fullPath.replace(`${getWorkshopRoot()}${path.sep}`, '')\n\t\treturn relativePath.split(path.sep).join('__sep__')\n\t}\n}\n\nexport async function getFullPathFromAppName(appName: string) {\n\tif (appName === 'playground')\n\t\treturn path.join(getWorkshopRoot(), 'playground')\n\tif (appName.startsWith('.example')) {\n\t\tconst relativePath = appName\n\t\t\t.replace('.example', '')\n\t\t\t.split('__sep__')\n\t\t\t.join(path.sep)\n\t\treturn path.join(getWorkshopRoot(), 'examples', relativePath)\n\t}\n\tif (appName.includes('__sep__')) {\n\t\tconst relativePath = appName.replaceAll('__sep__', path.sep)\n\t\treturn path.join(getWorkshopRoot(), relativePath)\n\t}\n\tconst [exerciseNumber, stepNumber, type] = appName.split('.')\n\tconst appDirs =\n\t\ttype === 'problem'\n\t\t\t? await getProblemDirs()\n\t\t\t: type === 'solution'\n\t\t\t\t? await getSolutionDirs()\n\t\t\t\t: []\n\tconst dir = appDirs.find((dir) => {\n\t\tconst info = extractNumbersAndTypeFromAppNameOrPath(dir)\n\t\tif (!info) return false\n\t\treturn (\n\t\t\tinfo.exerciseNumber === exerciseNumber && info.stepNumber === stepNumber\n\t\t)\n\t})\n\treturn dir ?? appName\n}\n\nexport async function findSolutionDir({\n\tfullPath,\n}: {\n\tfullPath: string\n}): Promise<string | null> {\n\tconst dirName = path.basename(fullPath)\n\tif (dirName.includes('.problem')) {\n\t\tconst info = getAppDirInfo(dirName)\n\t\tif (!info) return null\n\t\tconst { stepNumber } = info\n\t\tconst paddedStepNumber = stepNumber.toString().padStart(2, '0')\n\t\tconst parentDir = path.dirname(fullPath)\n\t\tconst siblingDirs = await fs.promises.readdir(parentDir)\n\t\tconst solutionDir = siblingDirs.find((dir) =>\n\t\t\tdir.startsWith(`${paddedStepNumber}.solution`),\n\t\t)\n\t\tif (solutionDir) {\n\t\t\treturn path.join(parentDir, solutionDir)\n\t\t}\n\t} else if (fullPath.endsWith('playground')) {\n\t\tconst appName = await getPlaygroundAppName()\n\t\tif (appName) {\n\t\t\treturn findSolutionDir({\n\t\t\t\tfullPath: await getFullPathFromAppName(appName),\n\t\t\t})\n\t\t}\n\t}\n\treturn null\n}\n\nexport async function findProblemDir({\n\tfullPath,\n}: {\n\tfullPath: string\n}): Promise<string | null> {\n\tconst dirName = path.basename(fullPath)\n\tif (dirName.includes('.solution')) {\n\t\tconst info = getAppDirInfo(dirName)\n\t\tif (!info) return null\n\t\tconst { stepNumber } = info\n\t\tconst paddedStepNumber = stepNumber.toString().padStart(2, '0')\n\t\tconst parentDir = path.dirname(fullPath)\n\t\tconst siblingDirs = await fs.promises.readdir(parentDir)\n\t\tconst problemDir = siblingDirs.find(\n\t\t\t(dir) => dir.endsWith('problem') && dir.includes(paddedStepNumber),\n\t\t)\n\t\tif (problemDir) {\n\t\t\treturn path.join(parentDir, problemDir)\n\t\t}\n\t} else if (fullPath.endsWith('playground')) {\n\t\tconst appName = await getPlaygroundAppName()\n\t\tif (appName) {\n\t\t\treturn findProblemDir({ fullPath: await getFullPathFromAppName(appName) })\n\t\t}\n\t}\n\treturn null\n}\n\nasync function getTestInfo({\n\tfullPath,\n}: {\n\tfullPath: string\n}): Promise<BaseApp['test']> {\n\tconst {\n\t\ttestTab: { enabled },\n\t\tscripts: { test: testScript },\n\t} = await getAppConfig(fullPath)\n\tif (enabled === false) return { type: 'none' }\n\n\tif (testScript) {\n\t\treturn { type: 'script', script: testScript }\n\t}\n\n\t// tests are found in the corresponding solution directory\n\tconst testAppFullPath = (await findSolutionDir({ fullPath })) ?? fullPath\n\n\tconst dirList = await fs.promises.readdir(testAppFullPath)\n\tconst testFiles = dirList.filter((item) => item.includes('.test.'))\n\tif (testFiles.length) {\n\t\treturn {\n\t\t\ttype: 'browser',\n\t\t\tpathname: `${getPathname(fullPath)}test/`,\n\t\t\ttestFiles,\n\t\t}\n\t}\n\n\treturn { type: 'none' }\n}\n\nasync function getDevInfo({\n\tfullPath,\n\tportNumber,\n}: {\n\tfullPath: string\n\tportNumber: number\n}): Promise<BaseApp['dev']> {\n\tconst {\n\t\tscripts: { dev: devScript },\n\t\tinitialRoute,\n\t} = await getAppConfig(fullPath)\n\tconst hasDevScript = Boolean(devScript)\n\n\tif (hasDevScript) {\n\t\treturn { type: 'script', portNumber, initialRoute }\n\t}\n\tconst indexFiles = (await fsExtra.readdir(fullPath)).filter((file: string) =>\n\t\tfile.startsWith('index.'),\n\t)\n\tif (indexFiles.length) {\n\t\treturn { type: 'browser', pathname: getPathname(fullPath) }\n\t} else {\n\t\treturn { type: 'none' }\n\t}\n}\n\nexport async function getPlaygroundApp({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<PlaygroundApp | null> {\n\tconst playgroundDir = path.join(getWorkshopRoot(), 'playground')\n\tconst baseAppName = await getPlaygroundAppName()\n\tconst key = `playground-${baseAppName}`\n\n\tconst baseAppFullPath = baseAppName\n\t\t? await getFullPathFromAppName(baseAppName)\n\t\t: null\n\tconst playgroundCacheEntry = await playgroundAppCache.get(key)\n\treturn cachified({\n\t\tkey,\n\t\tcache: playgroundAppCache,\n\t\tttl: 1000 * 60 * 5,\n\t\tswr: 1000 * 60 * 60 * 24 * 30,\n\n\t\ttimings,\n\t\ttimingKey: playgroundDir.replace(`${playgroundDir}${path.sep}`, ''),\n\t\trequest,\n\t\tforceFresh: await getForceFreshForDir(\n\t\t\tplaygroundCacheEntry,\n\t\t\tplaygroundDir,\n\t\t\tbaseAppFullPath,\n\t\t),\n\t\tgetFreshValue: async () => {\n\t\t\tif (!(await exists(playgroundDir))) return null\n\t\t\tif (!baseAppName) return null\n\n\t\t\tconst dirName = path.basename(playgroundDir)\n\t\t\tconst name = getAppName(playgroundDir)\n\t\t\tconst portNumber = 4000\n\t\t\tconst [compiledReadme, test, dev] = await Promise.all([\n\t\t\t\tcompileMdxIfExists(path.join(playgroundDir, 'README.mdx'), { request }),\n\t\t\t\tgetTestInfo({ fullPath: playgroundDir }),\n\t\t\t\tgetDevInfo({ fullPath: playgroundDir, portNumber }),\n\t\t\t])\n\n\t\t\tconst appModifiedTime = await getDirModifiedTime(\n\t\t\t\tawait getFullPathFromAppName(baseAppName),\n\t\t\t)\n\t\t\tconst playgroundAppModifiedTime = await getDirModifiedTime(playgroundDir)\n\t\t\tconst type = 'playground'\n\n\t\t\tconst title = compiledReadme?.title ?? name\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\tappName: baseAppName,\n\t\t\t\ttype,\n\t\t\t\tisUpToDate: appModifiedTime <= playgroundAppModifiedTime,\n\t\t\t\tfullPath: playgroundDir,\n\t\t\t\trelativePath: playgroundDir.replace(\n\t\t\t\t\t`${getWorkshopRoot()}${path.sep}`,\n\t\t\t\t\t'',\n\t\t\t\t),\n\t\t\t\ttitle,\n\t\t\t\tepicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\t\t\tdirName,\n\t\t\t\tinstructionsCode: compiledReadme?.code,\n\t\t\t\ttest,\n\t\t\t\tdev,\n\t\t\t\tstackBlitzUrl: await getStackBlitzUrl({\n\t\t\t\t\tfullPath: playgroundDir,\n\t\t\t\t\ttitle,\n\t\t\t\t\ttype,\n\t\t\t\t}),\n\t\t\t} satisfies PlaygroundApp\n\t\t},\n\t}).catch((error) => {\n\t\tconsole.error(error)\n\t\treturn null\n\t})\n}\n\nasync function getExampleAppFromPath(\n\tfullPath: string,\n\tindex: number,\n\trequest?: Request,\n): Promise<ExampleApp> {\n\tconst dirName = path.basename(fullPath)\n\tconst compiledReadme = await compileMdxIfExists(\n\t\tpath.join(fullPath, 'README.mdx'),\n\t\t{ request },\n\t)\n\tconst name = getAppName(fullPath)\n\tconst portNumber = 8000 + index\n\tconst type = 'example'\n\tconst title = compiledReadme?.title ?? name\n\treturn {\n\t\tname,\n\t\ttype,\n\t\tfullPath,\n\t\trelativePath: fullPath.replace(`${getWorkshopRoot()}${path.sep}`, ''),\n\t\ttitle,\n\t\tepicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\tdirName,\n\t\tinstructionsCode: compiledReadme?.code,\n\t\ttest: await getTestInfo({ fullPath }),\n\t\tdev: await getDevInfo({ fullPath, portNumber }),\n\t\tstackBlitzUrl: await getStackBlitzUrl({\n\t\t\tfullPath,\n\t\t\ttitle,\n\t\t\ttype,\n\t\t}),\n\t} satisfies ExampleApp\n}\n\nasync function getExampleApps({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<Array<ExampleApp>> {\n\tconst examplesDir = path.join(getWorkshopRoot(), 'examples')\n\tconst exampleDirs = (await readDir(examplesDir)).map((p) =>\n\t\tpath.join(examplesDir, p),\n\t)\n\n\tconst exampleApps: Array<ExampleApp> = []\n\n\tfor (const exampleDir of exampleDirs) {\n\t\tconst index = exampleDirs.indexOf(exampleDir)\n\t\tconst key = `${exampleDir}-${index}`\n\t\tconst exampleApp = await cachified({\n\t\t\tkey,\n\t\t\tcache: exampleAppCache,\n\t\t\tttl: 1000 * 60 * 5,\n\t\t\tswr: 1000 * 60 * 60 * 24 * 30,\n\n\t\t\ttimings,\n\t\t\ttimingKey: exampleDir.replace(`${examplesDir}${path.sep}`, ''),\n\t\t\trequest,\n\t\t\tforceFresh: await getForceFreshForDir(\n\t\t\t\texampleAppCache.get(key),\n\t\t\t\texampleDir,\n\t\t\t),\n\t\t\tgetFreshValue: async () => {\n\t\t\t\treturn getExampleAppFromPath(exampleDir, index, request).catch(\n\t\t\t\t\t(error) => {\n\t\t\t\t\t\tconsole.error(error)\n\t\t\t\t\t\treturn null\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t},\n\t\t})\n\t\tif (exampleApp) exampleApps.push(exampleApp)\n\t}\n\n\treturn exampleApps\n}\n\nasync function getSolutionAppFromPath(\n\tfullPath: string,\n\trequest?: Request,\n): Promise<SolutionApp | null> {\n\tconst dirName = path.basename(fullPath)\n\tconst parentDirName = path.basename(path.dirname(fullPath))\n\tconst exerciseNumber = extractExerciseNumber(parentDirName)\n\tif (!exerciseNumber) return null\n\n\tconst name = getAppName(fullPath)\n\tconst info = getAppDirInfo(dirName)\n\tif (!info) return null\n\tconst { stepNumber } = info\n\tconst portNumber = 7000 + (exerciseNumber - 1) * 10 + stepNumber\n\tconst compiledReadme = await compileMdxIfExists(\n\t\tpath.join(fullPath, 'README.mdx'),\n\t\t{ request },\n\t)\n\tconst problemDir = await findProblemDir({\n\t\tfullPath,\n\t})\n\tconst problemName = problemDir ? getAppName(problemDir) : null\n\tconst [test, dev] = await Promise.all([\n\t\tgetTestInfo({ fullPath }),\n\t\tgetDevInfo({ fullPath, portNumber }),\n\t])\n\tconst title = compiledReadme?.title ?? name\n\treturn {\n\t\tname,\n\t\ttitle,\n\t\tepicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\ttype: 'solution',\n\t\tproblemName,\n\t\texerciseNumber,\n\t\tstepNumber,\n\t\tdirName,\n\t\tfullPath,\n\t\trelativePath: fullPath.replace(`${getWorkshopRoot()}${path.sep}`, ''),\n\t\tinstructionsCode: compiledReadme?.code,\n\t\ttest,\n\t\tdev,\n\t\tstackBlitzUrl: await getStackBlitzUrl({\n\t\t\tfullPath,\n\t\t\ttitle,\n\t\t\ttype: 'solution',\n\t\t}),\n\t} satisfies SolutionApp\n}\n\nasync function getSolutionApps({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<Array<SolutionApp>> {\n\tconst exercisesDir = path.join(getWorkshopRoot(), 'exercises')\n\tconst solutionDirs = await getSolutionDirs()\n\tconst solutionApps: Array<SolutionApp> = []\n\n\tfor (const solutionDir of solutionDirs) {\n\t\tconst solutionApp = await cachified({\n\t\t\tkey: solutionDir,\n\t\t\tcache: solutionAppCache,\n\t\t\ttimings,\n\t\t\ttimingKey: solutionDir.replace(`${exercisesDir}${path.sep}`, ''),\n\t\t\trequest,\n\t\t\tttl: 1000 * 60 * 5,\n\t\t\tswr: 1000 * 60 * 60 * 24 * 30,\n\n\t\t\tforceFresh: await getForceFreshForDir(\n\t\t\t\tsolutionAppCache.get(solutionDir),\n\t\t\t\tsolutionDir,\n\t\t\t),\n\t\t\tgetFreshValue: async () => {\n\t\t\t\treturn getSolutionAppFromPath(solutionDir, request).catch((error) => {\n\t\t\t\t\tconsole.error(error)\n\t\t\t\t\treturn null\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\t\tif (solutionApp) solutionApps.push(solutionApp)\n\t}\n\n\treturn solutionApps\n}\n\nasync function getProblemAppFromPath(\n\tfullPath: string,\n\trequest?: Request,\n): Promise<ProblemApp | null> {\n\tconst dirName = path.basename(fullPath)\n\tconst parentDirName = path.basename(path.dirname(fullPath))\n\tconst exerciseNumber = extractExerciseNumber(parentDirName)\n\tif (!exerciseNumber) return null\n\n\tconst name = getAppName(fullPath)\n\tconst info = getAppDirInfo(dirName)\n\tif (!info) return null\n\tconst { stepNumber } = info\n\tconst portNumber = 6000 + (exerciseNumber - 1) * 10 + stepNumber\n\tconst compiledReadme = await compileMdxIfExists(\n\t\tpath.join(fullPath, 'README.mdx'),\n\t\t{ request },\n\t)\n\tconst solutionDir = await findSolutionDir({\n\t\tfullPath,\n\t})\n\tconst solutionName = solutionDir ? getAppName(solutionDir) : null\n\tconst [test, dev] = await Promise.all([\n\t\tgetTestInfo({ fullPath }),\n\t\tgetDevInfo({ fullPath, portNumber }),\n\t])\n\tconst title = compiledReadme?.title ?? name\n\treturn {\n\t\tsolutionName,\n\t\tname,\n\t\ttitle,\n\t\tepicVideoEmbeds: compiledReadme?.epicVideoEmbeds,\n\t\ttype: 'problem',\n\t\texerciseNumber,\n\t\tstepNumber,\n\t\tdirName,\n\t\tfullPath,\n\t\trelativePath: fullPath.replace(`${getWorkshopRoot()}${path.sep}`, ''),\n\t\tinstructionsCode: compiledReadme?.code,\n\t\ttest,\n\t\tdev,\n\t\tstackBlitzUrl: await getStackBlitzUrl({\n\t\t\tfullPath,\n\t\t\ttitle,\n\t\t\ttype: 'problem',\n\t\t}),\n\t} satisfies ProblemApp\n}\n\nasync function getProblemApps({\n\ttimings,\n\trequest,\n}: CachifiedOptions = {}): Promise<Array<ProblemApp>> {\n\tconst exercisesDir = path.join(getWorkshopRoot(), 'exercises')\n\tconst problemDirs = await getProblemDirs()\n\tconst problemApps: Array<ProblemApp> = []\n\tfor (const problemDir of problemDirs) {\n\t\tconst solutionDir = await findSolutionDir({ fullPath: problemDir })\n\t\tconst problemApp = await cachified({\n\t\t\tkey: problemDir,\n\t\t\tcache: problemAppCache,\n\t\t\ttimings,\n\t\t\ttimingKey: problemDir.replace(`${exercisesDir}${path.sep}`, ''),\n\t\t\trequest,\n\t\t\tttl: 1000 * 60 * 5,\n\t\t\tswr: 1000 * 60 * 60 * 24 * 30,\n\n\t\t\tforceFresh: await getForceFreshForDir(\n\t\t\t\tproblemAppCache.get(problemDir),\n\t\t\t\tproblemDir,\n\t\t\t\tsolutionDir,\n\t\t\t),\n\t\t\tgetFreshValue: async () => {\n\t\t\t\treturn getProblemAppFromPath(problemDir).catch((error) => {\n\t\t\t\t\tconsole.error(error)\n\t\t\t\t\treturn null\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\t\tif (problemApp) problemApps.push(problemApp)\n\t}\n\treturn problemApps\n}\n\nexport async function getExercise(\n\texerciseNumber: number | string,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst exercises = await getExercises({ request, timings })\n\treturn exercises.find((s) => s.exerciseNumber === Number(exerciseNumber))\n}\n\nexport async function requireExercise(\n\texerciseNumber: number | string,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst exercise = await getExercise(exerciseNumber, { request, timings })\n\tif (!exercise) {\n\t\tthrow new Response('Not found', {\n\t\t\tstatus: 404,\n\t\t\theaders: { 'Server-Timing': getServerTimeHeader(timings) },\n\t\t})\n\t}\n\treturn exercise\n}\n\nexport async function requireExerciseApp(\n\tparams: Parameters<typeof getExerciseApp>[0],\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst app = await getExerciseApp(params, { request, timings })\n\tif (!app) {\n\t\tthrow new Response('Not found', { status: 404 })\n\t}\n\treturn app\n}\n\nconst ExerciseAppParamsSchema = z.object({\n\ttype: z.union([z.literal('problem'), z.literal('solution')]),\n\texerciseNumber: z.coerce.number().finite(),\n\tstepNumber: z.coerce.number().finite(),\n})\n\nexport async function getExerciseApp(\n\tparams: {\n\t\ttype?: string\n\t\texerciseNumber?: string\n\t\tstepNumber?: string\n\t},\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst result = ExerciseAppParamsSchema.safeParse(params)\n\tif (!result.success) {\n\t\treturn null\n\t}\n\tconst { type, exerciseNumber, stepNumber } = result.data\n\n\tconst apps = (await getApps({ request, timings })).filter(isExerciseStepApp)\n\tconst exerciseApp = apps.find((app) => {\n\t\tif (isExampleApp(app)) return false\n\t\treturn (\n\t\t\tapp.exerciseNumber === exerciseNumber &&\n\t\t\tapp.stepNumber === stepNumber &&\n\t\t\tapp.type === type\n\t\t)\n\t})\n\tif (!exerciseApp) {\n\t\treturn null\n\t}\n\treturn exerciseApp\n}\n\nexport async function getAppByName(\n\tname: string,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst apps = await getApps({ request, timings })\n\treturn apps.find((a) => a.name === name)\n}\n\nexport async function getNextExerciseApp(\n\tapp: ExerciseStepApp,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst apps = (await getApps({ request, timings })).filter(isExerciseStepApp)\n\tconst index = apps.findIndex((a) => a.name === app.name)\n\tif (index === -1) {\n\t\tthrow new Error(`Could not find app ${app.name}`)\n\t}\n\tconst nextApp = apps[index + 1]\n\treturn nextApp ? nextApp : null\n}\n\nexport async function getPrevExerciseApp(\n\tapp: ExerciseStepApp,\n\t{ request, timings }: CachifiedOptions = {},\n) {\n\tconst apps = (await getApps({ request, timings })).filter(isExerciseStepApp)\n\n\tconst index = apps.findIndex((a) => a.name === app.name)\n\tif (index === -1) {\n\t\tthrow new Error(`Could not find app ${app.name}`)\n\t}\n\tconst prevApp = apps[index - 1]\n\treturn prevApp ? prevApp : null\n}\nexport function getAppPageRoute(\n\tapp: ExerciseStepApp,\n\t{\n\t\tsubroute,\n\t\tsearchParams,\n\t}: { subroute?: string; searchParams?: URLSearchParams } = {},\n) {\n\tconst exerciseNumber = app.exerciseNumber.toString().padStart(2, '0')\n\tconst stepNumber = app.stepNumber.toString().padStart(2, '0')\n\tconst baseUrl = `/exercise/${exerciseNumber}/${stepNumber}/${app.type}`\n\tconst subrouteUrl = subroute ? `/${subroute}` : ''\n\n\tif (searchParams) {\n\t\t// these are used on the diff tab and if we preserve them then the user will\n\t\t// be confused why the diff is never changing as they advance through the workshop.\n\t\tsearchParams.delete('app1')\n\t\tsearchParams.delete('app2')\n\t}\n\n\tconst searchString = searchParams?.toString()\n\treturn `${baseUrl}${subrouteUrl}${searchString ? `?${searchString}` : ''}`\n}\n\n/**\n * Given a file path, this will find the app that file path belongs to.\n */\nexport async function getAppFromFile(filePath: string) {\n\tconst apps = await getApps()\n\treturn apps.find((app) => filePath.startsWith(app.fullPath))\n}\n\nexport async function savePlayground() {\n\tconst playgroundApp = await getAppByName('playground')\n\tinvariant(playgroundApp, 'app with name \"playground\" does not exist')\n\n\tinvariant(\n\t\tisPlaygroundApp(playgroundApp),\n\t\t'app with name \"playground\" exists, but it is not a playground type app',\n\t)\n\n\tconst playgroundDir = path.join(getWorkshopRoot(), 'playground')\n\tconst savedPlaygroundsDir = path.join(getWorkshopRoot(), 'saved-playgrounds')\n\tawait fsExtra.ensureDir(savedPlaygroundsDir)\n\tconst now = dayjs()\n\t// note: the format must be filename safe\n\tconst timestamp = now.format('YYYY.MM.DD_HH.mm.ss')\n\tconst savedPlaygroundDirName = `${timestamp}_${playgroundApp.appName}`\n\n\tconst persistedPlaygroundReadmePath = path.join(\n\t\tsavedPlaygroundsDir,\n\t\t'README.md',\n\t)\n\tif (!(await exists(persistedPlaygroundReadmePath))) {\n\t\tawait fsExtra.writeFile(\n\t\t\tpersistedPlaygroundReadmePath,\n\t\t\t`\n# Saved Playgrounds\n\nThis directory stores the playground directory each time you click \"Set to\nPlayground.\" If you do not wish to do this, go to\n[your preferences](http://localhost:5639/preferences) when the app is running\nlocally and uncheck \"Enable saving playground.\"\n\t\t\t`.trim(),\n\t\t)\n\t}\n\tawait fsExtra.copy(\n\t\tplaygroundDir,\n\t\tpath.join(savedPlaygroundsDir, savedPlaygroundDirName),\n\t)\n}\n\nexport async function setPlayground(\n\tsrcDir: string,\n\t{ reset }: { reset?: boolean } = {},\n) {\n\tconst preferences = await getPreferences()\n\tconst playgroundApp = await getAppByName('playground')\n\tconst playgroundDir = path.join(getWorkshopRoot(), 'playground')\n\n\tif (playgroundApp && preferences?.playground?.persist) {\n\t\tawait savePlayground()\n\t}\n\n\tconst isIgnored = await isGitIgnored({ cwd: srcDir })\n\tconst playgroundWasRunning = playgroundApp\n\t\t? await isAppRunning(playgroundApp)\n\t\t: false\n\tif (playgroundApp && reset) {\n\t\tawait closeProcess(playgroundApp.name)\n\t\tawait fsExtra.remove(playgroundDir)\n\t}\n\tconst setPlaygroundTimestamp = Date.now()\n\n\t// run prepare-playground script if it exists\n\tconst preSetPlaygroundPath = await firstToExist(\n\t\tpath.join(srcDir, 'epicshop', 'pre-set-playground.js'),\n\t\tpath.join(getWorkshopRoot(), 'epicshop', 'pre-set-playground.js'),\n\t)\n\tif (preSetPlaygroundPath) {\n\t\tawait execa('node', [preSetPlaygroundPath], {\n\t\t\tcwd: getWorkshopRoot(),\n\t\t\tstdio: 'inherit',\n\n\t\t\tenv: {\n\t\t\t\tEPICSHOP_PLAYGROUND_TIMESTAMP: setPlaygroundTimestamp.toString(),\n\t\t\t\tEPICSHOP_PLAYGROUND_DEST_DIR: playgroundDir,\n\t\t\t\tEPICSHOP_PLAYGROUND_SRC_DIR: srcDir,\n\t\t\t\tEPICSHOP_PLAYGROUND_WAS_RUNNING: playgroundWasRunning.toString(),\n\t\t\t} as any,\n\t\t})\n\t}\n\n\tconst basename = path.basename(srcDir)\n\t// If we don't delete the destination node_modules first then copying the new\n\t// node_modules has issues.\n\tawait fsExtra.remove(path.join(playgroundDir, 'node_modules'))\n\t// Copy the contents of the source directory to the destination directory recursively\n\tawait fsExtra.copy(srcDir, playgroundDir, {\n\t\tfilter: async (srcFile, destFile) => {\n\t\t\tif (\n\t\t\t\tsrcFile.includes(`${basename}${path.sep}build`) ||\n\t\t\t\tsrcFile.includes(`${basename}${path.sep}public${path.sep}build`)\n\t\t\t) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (srcFile === srcDir) return true\n\t\t\t// we copy node_modules even though it's .gitignored\n\t\t\tif (srcFile.includes('node_modules')) return true\n\t\t\t// make sure .env is copied whether it's .gitignored or not\n\t\t\tif (srcFile.endsWith('.env')) return true\n\t\t\tif (isIgnored(srcFile)) return false\n\n\t\t\ttry {\n\t\t\t\tconst isDir = (await fsExtra.stat(srcFile)).isDirectory()\n\t\t\t\tif (isDir) return true\n\t\t\t\tconst destIsDir = (await fsExtra.stat(destFile)).isDirectory()\n\t\t\t\t// weird, but ok\n\t\t\t\tif (destIsDir) return true\n\n\t\t\t\t// it's better to check if the contents are the same before copying\n\t\t\t\t// because it avoids unnecessary writes and reduces the impact on any\n\t\t\t\t// file watchers (like the remix dev server). In practice, it's definitely\n\t\t\t\t// slower, but it's better because it doesn't cause the dev server to\n\t\t\t\t// crash as often.\n\t\t\t\tconst currentContents = await fsExtra.readFile(destFile)\n\t\t\t\tconst newContents = await fsExtra.readFile(srcFile)\n\t\t\t\tif (currentContents.equals(newContents)) return false\n\n\t\t\t\treturn true\n\t\t\t} catch {\n\t\t\t\t// 🤷♂️ should probably copy it in this case\n\t\t\t\treturn true\n\t\t\t}\n\t\t},\n\t})\n\n\tasync function getFiles(dir: string) {\n\t\t// make globby friendly to windows\n\t\tconst dirPath = dir.replace(/\\\\/g, '/')\n\t\tconst files = await globby([`${dirPath}/**/*`, '!**/build/**/*'], {\n\t\t\tonlyFiles: false,\n\t\t\tdot: true,\n\t\t})\n\t\treturn files.map((f) => f.replace(dirPath, ''))\n\t}\n\n\t// Remove files from destDir that were in destDir before but are not in srcDir\n\tconst srcFiles = await getFiles(srcDir)\n\tconst destFiles = await getFiles(playgroundDir)\n\tconst filesToDelete = destFiles.filter(\n\t\t(fileName) => !srcFiles.includes(fileName),\n\t)\n\n\tfor (const fileToDelete of filesToDelete) {\n\t\tawait fsExtra.remove(path.join(playgroundDir, fileToDelete))\n\t}\n\n\tconst appName = getAppName(srcDir)\n\tawait fsExtra.ensureDir(path.dirname(getPlaygroundAppNameInfoPath()))\n\tawait fsExtra.writeJSON(getPlaygroundAppNameInfoPath(), { appName })\n\n\tconst playgroundIsStillRunning = playgroundApp\n\t\t? isAppRunning(playgroundApp)\n\t\t: false\n\tconst restartPlayground = playgroundWasRunning && !playgroundIsStillRunning\n\n\t// run postSet-playground script if it exists\n\tconst postSetPlaygroundPath = await firstToExist(\n\t\tpath.join(srcDir, 'epicshop', 'post-set-playground.js'),\n\t\tpath.join(getWorkshopRoot(), 'epicshop', 'post-set-playground.js'),\n\t)\n\tif (postSetPlaygroundPath) {\n\t\tawait execa('node', [postSetPlaygroundPath], {\n\t\t\tcwd: getWorkshopRoot(),\n\t\t\tstdio: 'inherit',\n\n\t\t\tenv: {\n\t\t\t\tEPICSHOP_PLAYGROUND_TIMESTAMP: setPlaygroundTimestamp.toString(),\n\t\t\t\tEPICSHOP_PLAYGROUND_SRC_DIR: srcDir,\n\t\t\t\tEPICSHOP_PLAYGROUND_DEST_DIR: playgroundDir,\n\t\t\t\tEPICSHOP_PLAYGROUND_WAS_RUNNING: playgroundWasRunning.toString(),\n\t\t\t\tEPICSHOP_PLAYGROUND_IS_STILL_RUNNING:\n\t\t\t\t\tplaygroundIsStillRunning.toString(),\n\t\t\t\tEPICSHOP_PLAYGROUND_RESTART_PLAYGROUND: restartPlayground.toString(),\n\t\t\t} as any,\n\t\t})\n\t}\n\n\t// since we are running without the watcher we need to set the modified time\n\tmodifiedTimes.set(playgroundDir, Date.now())\n\n\tif (playgroundApp && restartPlayground) {\n\t\tawait runAppDev(playgroundApp)\n\t\tawait waitOnApp(playgroundApp)\n\t}\n}\n\n/**\n * The playground is based on another app. This returns the app the playground\n * is based on.\n */\nexport async function getPlaygroundAppName() {\n\tif (!(await exists(getPlaygroundAppNameInfoPath()))) {\n\t\treturn null\n\t}\n\ttry {\n\t\tconst jsonString = await fs.promises.readFile(\n\t\t\tgetPlaygroundAppNameInfoPath(),\n\t\t\t'utf8',\n\t\t)\n\n\t\tconst { appName } = JSON.parse(jsonString) as any\n\t\tif (typeof appName !== 'string') return null\n\t\treturn appName\n\t} catch {\n\t\treturn null\n\t}\n}\n\nexport function getAppDisplayName(a: App, allApps: Array<App>) {\n\tlet displayName = `${a.title} (${a.type})`\n\tif (isExerciseStepApp(a)) {\n\t\tconst typeLabel = { problem: '💪', solution: '🏁' }[a.type]\n\t\tdisplayName = `${a.exerciseNumber}.${a.stepNumber} ${a.title} (${typeLabel} ${a.type})`\n\t} else if (isPlaygroundApp(a)) {\n\t\tconst playgroundAppBasis = allApps.find(\n\t\t\t(otherApp) => a.appName === otherApp.name,\n\t\t)\n\t\tif (playgroundAppBasis) {\n\t\t\tconst basisDisplayName = getAppDisplayName(playgroundAppBasis, allApps)\n\t\t\tdisplayName = `🛝 ${basisDisplayName}`\n\t\t} else {\n\t\t\tdisplayName = `🛝 ${a.appName}`\n\t\t}\n\t} else if (isExampleApp(a)) {\n\t\tdisplayName = `📚 ${a.title} (example)`\n\t}\n\treturn displayName\n}\n\nexport async function getWorkshopInstructions({\n\trequest,\n}: { request?: Request } = {}) {\n\tconst readmeFilepath = path.join(getWorkshopRoot(), 'exercises', 'README.mdx')\n\tconst compiled = await compileMdx(readmeFilepath, { request }).then(\n\t\t(r) => ({ ...r, status: 'success' }) as const,\n\t\t(e) => {\n\t\t\tconsole.error(\n\t\t\t\t`There was an error compiling the workshop readme`,\n\t\t\t\treadmeFilepath,\n\t\t\t\te,\n\t\t\t)\n\t\t\treturn { status: 'error', error: getErrorMessage(e) } as const\n\t\t},\n\t)\n\treturn { compiled, file: readmeFilepath, relativePath: 'exercises' } as const\n}\n\nexport async function getWorkshopFinished({\n\trequest,\n}: { request?: Request } = {}) {\n\tconst finishedFilepath = path.join(\n\t\tgetWorkshopRoot(),\n\t\t'exercises',\n\t\t'FINISHED.mdx',\n\t)\n\tconst compiled = await compileMdx(finishedFilepath, { request }).then(\n\t\t(r) => ({ ...r, status: 'success' }) as const,\n\t\t(e) => {\n\t\t\tconsole.error(\n\t\t\t\t`There was an error compiling the workshop finished.mdx`,\n\t\t\t\tfinishedFilepath,\n\t\t\t\te,\n\t\t\t)\n\t\t\treturn { status: 'error', error: getErrorMessage(e) } as const\n\t\t},\n\t)\n\treturn {\n\t\tcompiled,\n\t\tfile: finishedFilepath,\n\t\trelativePath: 'exercises/FINISHED.mdx',\n\t} as const\n}\n\nexport function getRelativePath(filePath: string) {\n\tconst exercisesPath = path.join(getWorkshopRoot(), 'exercises/')\n\tconst playgroundPath = path.join(getWorkshopRoot(), 'playground/')\n\n\treturn path\n\t\t.normalize(filePath.replace(/^(\"|')|(\"|')$/g, ''))\n\t\t.replace(playgroundPath, `playground${path.sep}`)\n\t\t.replace(exercisesPath, '')\n}\n\n/**\n * Given a file path, this will determine the path to the app that file belongs to.\n */\nexport function getAppPathFromFilePath(filePath: string): string | null {\n\tconst [, withinWorkshopRootHalf] = filePath.split(getWorkshopRoot())\n\tif (!withinWorkshopRootHalf) {\n\t\treturn null\n\t}\n\n\tconst [part1, part2, part3] = withinWorkshopRootHalf\n\t\t.split(path.sep)\n\t\t.filter(Boolean)\n\n\t// Check if the file is in the playground\n\tif (part1 === 'playground') {\n\t\treturn path.join(getWorkshopRoot(), 'playground')\n\t}\n\n\t// Check if the file is in an example\n\tif (part1 === 'examples' && part2) {\n\t\treturn path.join(getWorkshopRoot(), 'examples', part2)\n\t}\n\n\t// Check if the file is in an exercise\n\tif (part1 === 'exercises' && part2 && part3) {\n\t\treturn path.join(getWorkshopRoot(), 'exercises', part2, part3)\n\t}\n\n\t// If we couldn't determine the app path, return null\n\treturn null\n}\n"]}
|
package/dist/esm/git.server.d.ts
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import './init-env.js';
|
|
2
2
|
export declare function checkForUpdates(): Promise<{
|
|
3
3
|
readonly updatesAvailable: false;
|
|
4
|
+
readonly message: "The app is deployed";
|
|
5
|
+
readonly localCommit?: undefined;
|
|
6
|
+
readonly remoteCommit?: undefined;
|
|
7
|
+
readonly diffLink?: undefined;
|
|
8
|
+
} | {
|
|
9
|
+
readonly updatesAvailable: false;
|
|
10
|
+
readonly message: "You are offline";
|
|
11
|
+
readonly localCommit?: undefined;
|
|
12
|
+
readonly remoteCommit?: undefined;
|
|
13
|
+
readonly diffLink?: undefined;
|
|
14
|
+
} | {
|
|
15
|
+
readonly updatesAvailable: false;
|
|
16
|
+
readonly message: "Not in a git repo";
|
|
17
|
+
readonly localCommit?: undefined;
|
|
18
|
+
readonly remoteCommit?: undefined;
|
|
19
|
+
readonly diffLink?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
readonly updatesAvailable: false;
|
|
22
|
+
readonly message: "Cannot find remote";
|
|
4
23
|
readonly localCommit?: undefined;
|
|
5
24
|
readonly remoteCommit?: undefined;
|
|
6
25
|
readonly diffLink?: undefined;
|
|
@@ -9,14 +28,35 @@ export declare function checkForUpdates(): Promise<{
|
|
|
9
28
|
readonly localCommit: string;
|
|
10
29
|
readonly remoteCommit: string;
|
|
11
30
|
readonly diffLink: string | null;
|
|
31
|
+
readonly message: null;
|
|
12
32
|
} | {
|
|
13
33
|
readonly updatesAvailable: false;
|
|
14
34
|
readonly localCommit: string | undefined;
|
|
15
35
|
readonly remoteCommit: string | undefined;
|
|
16
36
|
readonly diffLink: string | null;
|
|
37
|
+
readonly message?: undefined;
|
|
17
38
|
}>;
|
|
18
39
|
export declare function checkForUpdatesCached(): Promise<{
|
|
19
40
|
readonly updatesAvailable: false;
|
|
41
|
+
readonly message: "The app is deployed";
|
|
42
|
+
readonly localCommit?: undefined;
|
|
43
|
+
readonly remoteCommit?: undefined;
|
|
44
|
+
readonly diffLink?: undefined;
|
|
45
|
+
} | {
|
|
46
|
+
readonly updatesAvailable: false;
|
|
47
|
+
readonly message: "You are offline";
|
|
48
|
+
readonly localCommit?: undefined;
|
|
49
|
+
readonly remoteCommit?: undefined;
|
|
50
|
+
readonly diffLink?: undefined;
|
|
51
|
+
} | {
|
|
52
|
+
readonly updatesAvailable: false;
|
|
53
|
+
readonly message: "Not in a git repo";
|
|
54
|
+
readonly localCommit?: undefined;
|
|
55
|
+
readonly remoteCommit?: undefined;
|
|
56
|
+
readonly diffLink?: undefined;
|
|
57
|
+
} | {
|
|
58
|
+
readonly updatesAvailable: false;
|
|
59
|
+
readonly message: "Cannot find remote";
|
|
20
60
|
readonly localCommit?: undefined;
|
|
21
61
|
readonly remoteCommit?: undefined;
|
|
22
62
|
readonly diffLink?: undefined;
|
|
@@ -25,15 +65,19 @@ export declare function checkForUpdatesCached(): Promise<{
|
|
|
25
65
|
readonly localCommit: string;
|
|
26
66
|
readonly remoteCommit: string;
|
|
27
67
|
readonly diffLink: string | null;
|
|
68
|
+
readonly message: null;
|
|
28
69
|
} | {
|
|
29
70
|
readonly updatesAvailable: false;
|
|
30
71
|
readonly localCommit: string | undefined;
|
|
31
72
|
readonly remoteCommit: string | undefined;
|
|
32
73
|
readonly diffLink: string | null;
|
|
74
|
+
readonly message?: undefined;
|
|
75
|
+
} | {
|
|
76
|
+
readonly updatesAvailable: false;
|
|
33
77
|
}>;
|
|
34
78
|
export declare function updateLocalRepo(): Promise<{
|
|
35
79
|
readonly status: "success";
|
|
36
|
-
readonly message: "No updates available.";
|
|
80
|
+
readonly message: "The app is deployed" | "You are offline" | "Not in a git repo" | "Cannot find remote" | "No updates available.";
|
|
37
81
|
} | {
|
|
38
82
|
readonly status: "success";
|
|
39
83
|
readonly message: "Updated successfully.";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.server.d.ts","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"git.server.d.ts","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAiFtB,wBAAsB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEpC;AAED,wBAAsB,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAc1C;AAED,wBAAsB,eAAe;;;;;;;;;GAmDpC;AAED,wBAAsB,aAAa;;;;UAelC;AAED,wBAAsB,2BAA2B,2BAehD;AAED,wBAAsB,uBAAuB,qBAiB5C"}
|
package/dist/esm/git.server.js
CHANGED
|
@@ -6,76 +6,45 @@ import { getWorkshopRoot } from './apps.server.js';
|
|
|
6
6
|
import { cachified, checkForUpdatesCache } from './cache.server.js';
|
|
7
7
|
import { getWorkshopConfig } from './config.server.js';
|
|
8
8
|
import { getEnv } from './env.server.js';
|
|
9
|
+
import { logger } from './logger.js';
|
|
9
10
|
import { getErrorMessage } from './utils.js';
|
|
10
11
|
import { checkConnection } from './utils.server.js';
|
|
12
|
+
const gitLog = logger('epic:git');
|
|
13
|
+
function dirHasTrackedFiles(cwd, dirPath) {
|
|
14
|
+
return execa('git', ['ls-files', dirPath], { cwd }).then((s) => s.stdout.trim().length > 0, () => true);
|
|
15
|
+
}
|
|
16
|
+
function isDirectory(dirPath) {
|
|
17
|
+
return fs.stat(dirPath).then((s) => s.isDirectory(), () => false);
|
|
18
|
+
}
|
|
11
19
|
async function cleanupEmptyExerciseDirectories(cwd) {
|
|
20
|
+
console.log('🧹 Cleaning up empty exercise directories...');
|
|
12
21
|
try {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
let deletedCount = 0;
|
|
24
|
-
// Determine which directories contain any files (tracked or untracked), and
|
|
25
|
-
// which are "fileless" (contain only subdirectories or are empty).
|
|
26
|
-
const hasFilesMap = new Map();
|
|
27
|
-
for (const dir of directories) {
|
|
28
|
-
if (dir === 'exercises')
|
|
29
|
-
continue; // Skip the root exercises directory
|
|
30
|
-
const [trackedFiles, untrackedFiles] = await Promise.all([
|
|
31
|
-
execa('git', ['ls-files', dir], { cwd, reject: false }).catch(() => ({
|
|
32
|
-
stdout: '',
|
|
33
|
-
})),
|
|
34
|
-
execa('git', ['ls-files', '--others', '--exclude-standard', dir], {
|
|
35
|
-
cwd,
|
|
36
|
-
reject: false,
|
|
37
|
-
}).catch(() => ({ stdout: '' })),
|
|
38
|
-
]);
|
|
39
|
-
const hasTrackedFiles = trackedFiles.stdout.trim().length > 0;
|
|
40
|
-
const hasUntrackedFiles = untrackedFiles.stdout.trim().length > 0;
|
|
41
|
-
hasFilesMap.set(dir, hasTrackedFiles || hasUntrackedFiles);
|
|
42
|
-
}
|
|
43
|
-
// Build a set of directories that have no files anywhere in their subtree
|
|
44
|
-
const emptyDirs = directories.filter((dir) => dir !== 'exercises' && hasFilesMap.get(dir) === false);
|
|
45
|
-
const emptySet = new Set(emptyDirs);
|
|
46
|
-
// From the empty directories, pick only the top-most ones (those that do not
|
|
47
|
-
// have an ancestor also in the empty set). Deleting these recursively is
|
|
48
|
-
// faster and removes entire empty trees in one go.
|
|
49
|
-
const topLevelEmptyDirs = emptyDirs.filter((dir) => {
|
|
50
|
-
let parent = path.posix.dirname(dir);
|
|
51
|
-
while (parent && parent !== '.' && parent !== 'exercises') {
|
|
52
|
-
if (emptySet.has(parent))
|
|
53
|
-
return false;
|
|
54
|
-
parent = path.posix.dirname(parent);
|
|
22
|
+
const exercisesDirPath = path.join(cwd, 'exercises');
|
|
23
|
+
const exercisesDirs = (await fs.readdir(exercisesDirPath)).sort();
|
|
24
|
+
for (const exerciseDir of exercisesDirs) {
|
|
25
|
+
const exerciseDirPath = path.join(exercisesDirPath, exerciseDir);
|
|
26
|
+
if (!(await isDirectory(exerciseDirPath)))
|
|
27
|
+
continue;
|
|
28
|
+
if (!(await dirHasTrackedFiles(cwd, exerciseDirPath))) {
|
|
29
|
+
gitLog.info(`Deleting empty exercise directory: ${exerciseDirPath}`);
|
|
30
|
+
await fs.rm(exerciseDirPath, { recursive: true, force: true });
|
|
31
|
+
continue;
|
|
55
32
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
catch {
|
|
67
|
-
// Directory might not exist due to race conditions; continue.
|
|
33
|
+
const stepDirs = (await fs.readdir(exerciseDirPath)).sort();
|
|
34
|
+
for (const stepDir of stepDirs) {
|
|
35
|
+
const stepDirPath = path.join(exerciseDirPath, stepDir);
|
|
36
|
+
if (!(await isDirectory(stepDirPath)))
|
|
37
|
+
continue;
|
|
38
|
+
if (!(await dirHasTrackedFiles(cwd, stepDirPath))) {
|
|
39
|
+
gitLog.info(`Deleting empty step directory: ${stepDirPath}`);
|
|
40
|
+
await fs.rm(stepDirPath, { recursive: true, force: true });
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
68
43
|
}
|
|
69
44
|
}
|
|
70
|
-
if (deletedCount > 0) {
|
|
71
|
-
console.log(` Deleted ${deletedCount} empty directory tree(s).`);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
console.log(' No empty directories found.');
|
|
75
|
-
}
|
|
76
45
|
}
|
|
77
46
|
catch (error) {
|
|
78
|
-
console.warn('
|
|
47
|
+
console.warn('⚠️ Warning: Failed to cleanup empty directories:', getErrorMessage(error));
|
|
79
48
|
}
|
|
80
49
|
}
|
|
81
50
|
async function getDiffUrl(commitBefore, commitAfter) {
|
|
@@ -94,21 +63,22 @@ async function getDiffUrl(commitBefore, commitAfter) {
|
|
|
94
63
|
export async function checkForUpdates() {
|
|
95
64
|
const ENV = getEnv();
|
|
96
65
|
if (ENV.EPICSHOP_DEPLOYED) {
|
|
97
|
-
return { updatesAvailable: false };
|
|
66
|
+
return { updatesAvailable: false, message: 'The app is deployed' };
|
|
98
67
|
}
|
|
99
68
|
const cwd = getWorkshopRoot();
|
|
100
69
|
const online = await checkConnection();
|
|
101
|
-
if (!online)
|
|
102
|
-
return { updatesAvailable: false };
|
|
70
|
+
if (!online) {
|
|
71
|
+
return { updatesAvailable: false, message: 'You are offline' };
|
|
72
|
+
}
|
|
103
73
|
const isInRepo = await execaCommand('git rev-parse --is-inside-work-tree', {
|
|
104
74
|
cwd,
|
|
105
75
|
}).then(() => true, () => false);
|
|
106
76
|
if (!isInRepo) {
|
|
107
|
-
return { updatesAvailable: false };
|
|
77
|
+
return { updatesAvailable: false, message: 'Not in a git repo' };
|
|
108
78
|
}
|
|
109
79
|
const { stdout: remote } = await execaCommand('git remote', { cwd });
|
|
110
80
|
if (!remote) {
|
|
111
|
-
return { updatesAvailable: false };
|
|
81
|
+
return { updatesAvailable: false, message: 'Cannot find remote' };
|
|
112
82
|
}
|
|
113
83
|
let localCommit, remoteCommit;
|
|
114
84
|
try {
|
|
@@ -126,6 +96,7 @@ export async function checkForUpdates() {
|
|
|
126
96
|
localCommit,
|
|
127
97
|
remoteCommit,
|
|
128
98
|
diffLink: await getDiffUrl(localCommit, remoteCommit),
|
|
99
|
+
message: null,
|
|
129
100
|
};
|
|
130
101
|
}
|
|
131
102
|
catch (error) {
|
|
@@ -166,7 +137,10 @@ export async function updateLocalRepo() {
|
|
|
166
137
|
try {
|
|
167
138
|
const updates = await checkForUpdates();
|
|
168
139
|
if (!updates.updatesAvailable) {
|
|
169
|
-
return {
|
|
140
|
+
return {
|
|
141
|
+
status: 'success',
|
|
142
|
+
message: updates.message ?? 'No updates available.',
|
|
143
|
+
};
|
|
170
144
|
}
|
|
171
145
|
const uncommittedChanges = (await execaCommand('git status --porcelain', { cwd })).stdout.trim()
|
|
172
146
|
.length > 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.server.js","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport 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\t// Determine which directories contain any files (tracked or untracked), and\n\t\t// which are \"fileless\" (contain only subdirectories or are empty).\n\t\tconst hasFilesMap = new Map<string, boolean>()\n\t\tfor (const dir of directories) {\n\t\t\tif (dir === 'exercises') continue // Skip the root exercises directory\n\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\tconst hasTrackedFiles = trackedFiles.stdout.trim().length > 0\n\t\t\tconst hasUntrackedFiles = untrackedFiles.stdout.trim().length > 0\n\t\t\thasFilesMap.set(dir, hasTrackedFiles || hasUntrackedFiles)\n\t\t}\n\n\t\t// Build a set of directories that have no files anywhere in their subtree\n\t\tconst emptyDirs = directories.filter(\n\t\t\t(dir) => dir !== 'exercises' && hasFilesMap.get(dir) === false,\n\t\t)\n\t\tconst emptySet = new Set(emptyDirs)\n\n\t\t// From the empty directories, pick only the top-most ones (those that do not\n\t\t// have an ancestor also in the empty set). Deleting these recursively is\n\t\t// faster and removes entire empty trees in one go.\n\t\tconst topLevelEmptyDirs = emptyDirs.filter((dir) => {\n\t\t\tlet parent = path.posix.dirname(dir)\n\t\t\twhile (parent && parent !== '.' && parent !== 'exercises') {\n\t\t\t\tif (emptySet.has(parent)) return false\n\t\t\t\tparent = path.posix.dirname(parent)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\n\t\tfor (const dir of topLevelEmptyDirs) {\n\t\t\tconsole.log(` Deleting empty directory tree: ${dir}`)\n\t\t\ttry {\n\t\t\t\t// Recursively remove the directory tree. This is safe because we've\n\t\t\t\t// confirmed there are no files (tracked or untracked) anywhere within.\n\t\t\t\tawait fs.rm(path.join(cwd, dir), { recursive: true, force: true })\n\t\t\t\tdeletedCount++\n\t\t\t} catch {\n\t\t\t\t// Directory might not exist due to race conditions; continue.\n\t\t\t}\n\t\t}\n\n\t\tif (deletedCount > 0) {\n\t\t\tconsole.log(` Deleted ${deletedCount} empty directory tree(s).`)\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"]}
|
|
1
|
+
{"version":3,"file":"git.server.js","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport 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 { logger } from './logger.js'\nimport { getErrorMessage } from './utils.js'\nimport { checkConnection } from './utils.server.js'\n\nconst gitLog = logger('epic:git')\n\nfunction dirHasTrackedFiles(cwd: string, dirPath: string) {\n\treturn execa('git', ['ls-files', dirPath], { cwd }).then(\n\t\t(s) => s.stdout.trim().length > 0,\n\t\t() => true,\n\t)\n}\n\nfunction isDirectory(dirPath: string) {\n\treturn fs.stat(dirPath).then(\n\t\t(s) => s.isDirectory(),\n\t\t() => false,\n\t)\n}\n\nasync function cleanupEmptyExerciseDirectories(cwd: string) {\n\tconsole.log('🧹 Cleaning up empty exercise directories...')\n\ttry {\n\t\tconst exercisesDirPath = path.join(cwd, 'exercises')\n\t\tconst exercisesDirs = (await fs.readdir(exercisesDirPath)).sort()\n\t\tfor (const exerciseDir of exercisesDirs) {\n\t\t\tconst exerciseDirPath = path.join(exercisesDirPath, exerciseDir)\n\t\t\tif (!(await isDirectory(exerciseDirPath))) continue\n\n\t\t\tif (!(await dirHasTrackedFiles(cwd, exerciseDirPath))) {\n\t\t\t\tgitLog.info(`Deleting empty exercise directory: ${exerciseDirPath}`)\n\t\t\t\tawait fs.rm(exerciseDirPath, { recursive: true, force: true })\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst stepDirs = (await fs.readdir(exerciseDirPath)).sort()\n\t\t\tfor (const stepDir of stepDirs) {\n\t\t\t\tconst stepDirPath = path.join(exerciseDirPath, stepDir)\n\t\t\t\tif (!(await isDirectory(stepDirPath))) continue\n\n\t\t\t\tif (!(await dirHasTrackedFiles(cwd, stepDirPath))) {\n\t\t\t\t\tgitLog.info(`Deleting empty step directory: ${stepDirPath}`)\n\t\t\t\t\tawait fs.rm(stepDirPath, { recursive: true, force: true })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\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, message: 'The app is deployed' } as const\n\t}\n\n\tconst cwd = getWorkshopRoot()\n\tconst online = await checkConnection()\n\tif (!online) {\n\t\treturn { updatesAvailable: false, message: 'You are offline' } as const\n\t}\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, message: 'Not in a git repo' } as const\n\t}\n\n\tconst { stdout: remote } = await execaCommand('git remote', { cwd })\n\tif (!remote) {\n\t\treturn { updatesAvailable: false, message: 'Cannot find remote' } 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\tmessage: null,\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 {\n\t\t\t\tstatus: 'success',\n\t\t\t\tmessage: updates.message ?? 'No updates available.',\n\t\t\t} 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"]}
|