@epic-web/workshop-utils 5.12.2 → 5.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/apps.server.d.ts +7 -0
- package/dist/esm/apps.server.d.ts.map +1 -1
- package/dist/esm/apps.server.js +3 -3
- package/dist/esm/apps.server.js.map +1 -1
- package/dist/esm/diff.server.d.ts +18 -0
- package/dist/esm/diff.server.d.ts.map +1 -0
- package/dist/esm/diff.server.js +437 -0
- package/dist/esm/diff.server.js.map +1 -0
- package/package.json +11 -1
|
@@ -3160,6 +3160,13 @@ export declare function extractNumbersAndTypeFromAppNameOrPath(fullPathOrAppName
|
|
|
3160
3160
|
exerciseNumber: string;
|
|
3161
3161
|
stepNumber: string;
|
|
3162
3162
|
} | null;
|
|
3163
|
+
export declare function getFullPathFromAppName(appName: string): Promise<string>;
|
|
3164
|
+
export declare function findSolutionDir({ fullPath, }: {
|
|
3165
|
+
fullPath: string;
|
|
3166
|
+
}): Promise<string | null>;
|
|
3167
|
+
export declare function findProblemDir({ fullPath, }: {
|
|
3168
|
+
fullPath: string;
|
|
3169
|
+
}): Promise<string | null>;
|
|
3163
3170
|
export declare function getPlaygroundApp({ timings, request, }?: CachifiedOptions): Promise<PlaygroundApp | null>;
|
|
3164
3171
|
export declare function getExercise(exerciseNumber: number | string, { request, timings }?: CachifiedOptions): Promise<{
|
|
3165
3172
|
title: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.server.d.ts","sourceRoot":"","sources":["../../src/apps.server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAKrD,OAAO,4BAA4B,CAAA;AAKnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAwBvB,OAAO,EAA6B,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAI5E,OAAO,CAAC,MAAM,CAAC;IACd,IAAI,6BAA6B,EAAE,OAAO,GAAG,SAAS,CAAA;CACtD;AAGD,eAAO,MAAM,YAAY,QAC0B,CAAA;AAUnD,KAAK,gBAAgB,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAkChE,QAAA,MAAM,yBAAyB;IA/B9B,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BtI,CAAA;AAEF,QAAA,MAAM,gBAAgB;IApCrB,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCtI,CAAA;AAEF,QAAA,MAAM,iBAAiB;IAzCtB,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCtI,CAAA;AAEF,QAAA,MAAM,gBAAgB;IA9CrB,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CtI,CAAA;AAEF,QAAA,MAAM,mBAAmB;IAlDxB,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDtI,CAAA;AAEF,QAAA,MAAM,cAAc;IACnB,2CAA2C;;IAE3C,uIAAuI;;IAEvI,oFAAoF;;;;;;;;;YA7DpF,sCAAsC;;YAEtC,qFAAqF;;YAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAJvI,sCAAsC;;YAEtC,qFAAqF;;YAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAJvI,sCAAsC;;YAEtC,qFAAqF;;YAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAJvI,sCAAsC;;YAEtC,qFAAqF;;YAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAJvI,sCAAsC;;QAEtC,qFAAqF;;QAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAJvI,sCAAsC;;QAEtC,qFAAqF;;QAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoFtI,CAAA;AAEF,QAAA,MAAM,qBAAqB;IA1F1B,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJvI,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsF5D,CAAA;AAE5E,QAAA,MAAM,SAAS;IA5Fd,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJvI,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJvI,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAJvI,sCAAsC;;IAEtC,qFAAqF;;IAErF,uIAAuI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4FtI,CAAA;AAIF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAC3E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AACzD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACnE,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAC3C,MAAM,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;AAEjC,KAAK,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE9C,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,GAAG,CAE1C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,UAAU,CAExD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,WAAW,CAE1D;AAED,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,GAAG,GACN,GAAG,IAAI,UAAU,GAAG;IAAE,UAAU,EAAE,CAAC,CAAA;CAAE,CAEvC;AAED,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,GAAG,GACN,GAAG,IAAI,WAAW,GAAG;IAAE,UAAU,EAAE,CAAC,CAAA;CAAE,CAExC;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,aAAa,CAE9D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,UAAU,CAExD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,eAAe,CAElE;AAeD,eAAO,MAAM,aAAa,qBAGzB,CAAA;AAED,wBAAsB,IAAI,kBAuDzB;AASD,wBAAgB,0BAA0B,CAAC,GAAG,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,QAUrE;AAED,wBAAgB,mBAAmB,CAClC,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACzC,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,oBAezC;AAuDD,wBAAsB,YAAY,CAAC,EAClC,OAAO,EACP,OAAO,GACP,GAAE,gBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CA8ClD;AAID,wBAAsB,OAAO,CAAC,EAC7B,OAAO,EACP,OAAO,EACP,UAAU,GACV,GAAE,gBAAgB,GAAG;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAoFxE;AAQD;;;;;;GAMG;AACH,wBAAgB,sCAAsC,CACrD,iBAAiB,EAAE,MAAM;;;;SA0BzB;
|
|
1
|
+
{"version":3,"file":"apps.server.d.ts","sourceRoot":"","sources":["../../src/apps.server.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/apps.server.js
CHANGED
|
@@ -501,7 +501,7 @@ function getAppName(fullPath) {
|
|
|
501
501
|
return relativePath.split(path.sep).join('__sep__');
|
|
502
502
|
}
|
|
503
503
|
}
|
|
504
|
-
async function getFullPathFromAppName(appName) {
|
|
504
|
+
export async function getFullPathFromAppName(appName) {
|
|
505
505
|
if (appName === 'playground')
|
|
506
506
|
return path.join(workshopRoot, 'playground');
|
|
507
507
|
if (appName.startsWith('.example')) {
|
|
@@ -529,7 +529,7 @@ async function getFullPathFromAppName(appName) {
|
|
|
529
529
|
});
|
|
530
530
|
return dir ?? appName;
|
|
531
531
|
}
|
|
532
|
-
async function findSolutionDir({ fullPath, }) {
|
|
532
|
+
export async function findSolutionDir({ fullPath, }) {
|
|
533
533
|
const dirName = path.basename(fullPath);
|
|
534
534
|
if (dirName.includes('.problem')) {
|
|
535
535
|
const info = getAppDirInfo(dirName);
|
|
@@ -554,7 +554,7 @@ async function findSolutionDir({ fullPath, }) {
|
|
|
554
554
|
}
|
|
555
555
|
return null;
|
|
556
556
|
}
|
|
557
|
-
async function findProblemDir({ fullPath, }) {
|
|
557
|
+
export async function findProblemDir({ fullPath, }) {
|
|
558
558
|
const dirName = path.basename(fullPath);
|
|
559
559
|
if (dirName.includes('.solution')) {
|
|
560
560
|
const info = getAppDirInfo(dirName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.server.js","sourceRoot":"","sources":["../../src/apps.server.ts"],"names":[],"mappings":"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","sourcesContent":["import 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\tappsCache,\n\tcachified,\n\texampleAppCache,\n\tplaygroundAppCache,\n\tproblemAppCache,\n\tsolutionAppCache,\n} from './cache.server.js'\nimport { compileMdx } from './compile-mdx.server.js'\nimport {\n\tgetAppConfig,\n\tgetStackBlitzUrl,\n\tgetWorkshopConfig,\n} from './config.server.js'\nimport { getPreferences } from './db.server.js'\nimport { getEnv, init as initEnv } from './env.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 { 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 const workshopRoot = (process.env.EPICSHOP_CONTEXT_CWD =\n\tprocess.env.EPICSHOP_CONTEXT_CWD ?? process.cwd())\n\nconst playgroundAppNameInfoPath = path.join(\n\tworkshopRoot,\n\t'node_modules',\n\t'.cache',\n\t'epicshop',\n\t'playground.json',\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/** 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.array(\n\t\tz.union([\n\t\t\tz.object({\n\t\t\t\tstepNumber: z.number(),\n\t\t\t\tproblem: ProblemAppSchema,\n\t\t\t\tsolution: SolutionAppSchema,\n\t\t\t}),\n\t\t\tz.object({\n\t\t\t\tstepNumber: z.number(),\n\t\t\t\tproblem: ProblemAppSchema,\n\t\t\t\tsolution: z.never().optional(),\n\t\t\t}),\n\t\t\tz.object({\n\t\t\t\tstepNumber: z.number(),\n\t\t\t\tproblem: z.never().optional(),\n\t\t\t\tsolution: SolutionAppSchema,\n\t\t\t}),\n\t\t]),\n\t),\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 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() {\n\tif (global.__epicshop_apps_initialized__) return\n\n\tglobal.__epicshop_apps_initialized__ = true\n\tconst config = getWorkshopConfig()\n\tprocess.env.EPICSHOP_GITHUB_REPO = config.githubRepo\n\tprocess.env.EPICSHOP_GITHUB_ROOT = config.githubRoot\n\n\tinitEnv()\n\n\tglobal.ENV = getEnv()\n\n\tif (\n\t\t!ENV.EPICSHOP_DEPLOYED &&\n\t\tprocess.env.EPICSHOP_ENABLE_WATCHER === 'true'\n\t) {\n\t\tconst isIgnored = await isGitIgnored({ cwd: workshopRoot })\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: workshopRoot,\n\t\t\tignoreInitial: true,\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', (_event, filePath) => {\n\t\t\tsetModifiedTimesForAppDirs(path.join(workshopRoot, filePath))\n\t\t})\n\n\t\tcloseWithGrace(() => chok.close())\n\t}\n}\n\nfunction getForceFresh(cacheEntry: CacheEntry | null | undefined) {\n\tif (!cacheEntry) return true\n\tconst latestModifiedTime = Math.max(...Array.from(modifiedTimes.values()))\n\tif (!latestModifiedTime) return undefined\n\treturn latestModifiedTime > cacheEntry.metadata.createdTime ? true : undefined\n}\n\nexport function setModifiedTimesForAppDirs(...filePaths: Array<string>) {\n\tconst now = Date.now()\n\tfor (const filePath of filePaths) {\n\t\tconst appDir = getAppPathFromFilePath(filePath)\n\t\tif (appDir) {\n\t\t\tmodifiedTimes.set(appDir, now)\n\t\t} else {\n\t\t\tconsole.warn(`filePath ${filePath} does not match any app dir`)\n\t\t}\n\t}\n}\n\nexport function getForceFreshForDir(\n\tcacheEntry: 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\tif (!cacheEntry) 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 > cacheEntry.metadata.createdTime ? true : 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\nexport async 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(workshopRoot, 'exercises'))\n\tconst exercises: Array<Exercise> = []\n\tfor (const dirName of exerciseDirs) {\n\t\tconst exerciseNumber = extractExerciseNumber(dirName)\n\t\tif (!exerciseNumber) continue\n\t\tconst compiledReadme = await compileMdxIfExists(\n\t\t\tpath.join(workshopRoot, 'exercises', dirName, 'README.mdx'),\n\t\t\t{ request },\n\t\t)\n\t\tconst compiledFinished = await compileMdxIfExists(\n\t\t\tpath.join(workshopRoot, '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\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\nlet appCallCount = 0\n\nexport async function getApps({\n\ttimings,\n\trequest,\n\tforceFresh,\n}: CachifiedOptions & { forceFresh?: boolean } = {}): Promise<Array<App>> {\n\tawait init()\n\n\tconst key = 'apps'\n\tconst apps = await cachified({\n\t\tkey,\n\t\tcache: appsCache,\n\t\ttimings,\n\t\ttimingKey: `apps_${appCallCount++}`,\n\t\trequest,\n\t\t// This entire cache is to avoid a single request getting a fresh value\n\t\t// multiple times unnecessarily (because getApps is called many times)\n\t\tttl: 1000 * 60 * 60 * 24,\n\t\tforceFresh: forceFresh ?? getForceFresh(appsCache.get(key)),\n\t\tgetFreshValue: async () => {\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})\n\treturn apps\n}\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(workshopRoot, '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(workshopRoot, '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\t\tproblemDirs.push(...problemSubDirs)\n\t}\n\treturn problemDirs\n}\n\nasync function getSolutionDirs() {\n\tconst exercisesDir = path.join(workshopRoot, '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\t\tsolutionDirs.push(...solutionSubDirs)\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`${workshopRoot}${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(`${workshopRoot}${path.sep}`, '')\n\t\treturn relativePath.split(path.sep).join('__sep__')\n\t}\n}\n\nasync function getFullPathFromAppName(appName: string) {\n\tif (appName === 'playground') return path.join(workshopRoot, '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(workshopRoot, 'examples', relativePath)\n\t}\n\tif (appName.includes('__sep__')) {\n\t\tconst relativePath = appName.replaceAll('__sep__', path.sep)\n\t\treturn path.join(workshopRoot, 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\nasync 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\nasync 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(workshopRoot, '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 = playgroundAppCache.get(key)\n\treturn cachified({\n\t\tkey,\n\t\tcache: playgroundAppCache,\n\t\tttl: 1000 * 60 * 60 * 24,\n\n\t\ttimings,\n\t\ttimingKey: playgroundDir.replace(`${playgroundDir}${path.sep}`, ''),\n\t\trequest,\n\t\tforceFresh: 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(`${workshopRoot}${path.sep}`, ''),\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(`${workshopRoot}${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(workshopRoot, '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 * 60 * 24,\n\n\t\t\ttimings,\n\t\t\ttimingKey: exampleDir.replace(`${examplesDir}${path.sep}`, ''),\n\t\t\trequest,\n\t\t\tforceFresh: getForceFreshForDir(exampleAppCache.get(key), exampleDir),\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(`${workshopRoot}${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(workshopRoot, '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 * 60 * 24,\n\n\t\t\tforceFresh: 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(`${workshopRoot}${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(workshopRoot, '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 * 60 * 24,\n\n\t\t\tforceFresh: 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(workshopRoot, 'playground')\n\tconst savedPlaygroundsDir = path.join(workshopRoot, '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(workshopRoot, '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? 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(workshopRoot, 'epicshop', 'pre-set-playground.js'),\n\t)\n\tif (preSetPlaygroundPath) {\n\t\tawait execa('node', [preSetPlaygroundPath], {\n\t\t\tcwd: workshopRoot,\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(playgroundAppNameInfoPath))\n\tawait fsExtra.writeJSON(playgroundAppNameInfoPath, { 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(workshopRoot, 'epicshop', 'post-set-playground.js'),\n\t)\n\tif (postSetPlaygroundPath) {\n\t\tawait execa('node', [postSetPlaygroundPath], {\n\t\t\tcwd: workshopRoot,\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(playgroundAppNameInfoPath))) {\n\t\treturn null\n\t}\n\ttry {\n\t\tconst jsonString = await fs.promises.readFile(\n\t\t\tplaygroundAppNameInfoPath,\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(workshopRoot, '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(workshopRoot, 'exercises', 'FINISHED.mdx')\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\nconst exercisesPath = path.join(workshopRoot, 'exercises/')\nconst playgroundPath = path.join(workshopRoot, 'playground/')\nexport function getRelativePath(filePath: string) {\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(workshopRoot)\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(workshopRoot, 'playground')\n\t}\n\n\t// Check if the file is in an example\n\tif (part1 === 'examples' && part2) {\n\t\treturn path.join(workshopRoot, '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(workshopRoot, '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":["import 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\tappsCache,\n\tcachified,\n\texampleAppCache,\n\tplaygroundAppCache,\n\tproblemAppCache,\n\tsolutionAppCache,\n} from './cache.server.js'\nimport { compileMdx } from './compile-mdx.server.js'\nimport {\n\tgetAppConfig,\n\tgetStackBlitzUrl,\n\tgetWorkshopConfig,\n} from './config.server.js'\nimport { getPreferences } from './db.server.js'\nimport { getEnv, init as initEnv } from './env.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 { 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 const workshopRoot = (process.env.EPICSHOP_CONTEXT_CWD =\n\tprocess.env.EPICSHOP_CONTEXT_CWD ?? process.cwd())\n\nconst playgroundAppNameInfoPath = path.join(\n\tworkshopRoot,\n\t'node_modules',\n\t'.cache',\n\t'epicshop',\n\t'playground.json',\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/** 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.array(\n\t\tz.union([\n\t\t\tz.object({\n\t\t\t\tstepNumber: z.number(),\n\t\t\t\tproblem: ProblemAppSchema,\n\t\t\t\tsolution: SolutionAppSchema,\n\t\t\t}),\n\t\t\tz.object({\n\t\t\t\tstepNumber: z.number(),\n\t\t\t\tproblem: ProblemAppSchema,\n\t\t\t\tsolution: z.never().optional(),\n\t\t\t}),\n\t\t\tz.object({\n\t\t\t\tstepNumber: z.number(),\n\t\t\t\tproblem: z.never().optional(),\n\t\t\t\tsolution: SolutionAppSchema,\n\t\t\t}),\n\t\t]),\n\t),\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 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() {\n\tif (global.__epicshop_apps_initialized__) return\n\n\tglobal.__epicshop_apps_initialized__ = true\n\tconst config = getWorkshopConfig()\n\tprocess.env.EPICSHOP_GITHUB_REPO = config.githubRepo\n\tprocess.env.EPICSHOP_GITHUB_ROOT = config.githubRoot\n\n\tinitEnv()\n\n\tglobal.ENV = getEnv()\n\n\tif (\n\t\t!ENV.EPICSHOP_DEPLOYED &&\n\t\tprocess.env.EPICSHOP_ENABLE_WATCHER === 'true'\n\t) {\n\t\tconst isIgnored = await isGitIgnored({ cwd: workshopRoot })\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: workshopRoot,\n\t\t\tignoreInitial: true,\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', (_event, filePath) => {\n\t\t\tsetModifiedTimesForAppDirs(path.join(workshopRoot, filePath))\n\t\t})\n\n\t\tcloseWithGrace(() => chok.close())\n\t}\n}\n\nfunction getForceFresh(cacheEntry: CacheEntry | null | undefined) {\n\tif (!cacheEntry) return true\n\tconst latestModifiedTime = Math.max(...Array.from(modifiedTimes.values()))\n\tif (!latestModifiedTime) return undefined\n\treturn latestModifiedTime > cacheEntry.metadata.createdTime ? true : undefined\n}\n\nexport function setModifiedTimesForAppDirs(...filePaths: Array<string>) {\n\tconst now = Date.now()\n\tfor (const filePath of filePaths) {\n\t\tconst appDir = getAppPathFromFilePath(filePath)\n\t\tif (appDir) {\n\t\t\tmodifiedTimes.set(appDir, now)\n\t\t} else {\n\t\t\tconsole.warn(`filePath ${filePath} does not match any app dir`)\n\t\t}\n\t}\n}\n\nexport function getForceFreshForDir(\n\tcacheEntry: 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\tif (!cacheEntry) 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 > cacheEntry.metadata.createdTime ? true : 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\nexport async 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(workshopRoot, 'exercises'))\n\tconst exercises: Array<Exercise> = []\n\tfor (const dirName of exerciseDirs) {\n\t\tconst exerciseNumber = extractExerciseNumber(dirName)\n\t\tif (!exerciseNumber) continue\n\t\tconst compiledReadme = await compileMdxIfExists(\n\t\t\tpath.join(workshopRoot, 'exercises', dirName, 'README.mdx'),\n\t\t\t{ request },\n\t\t)\n\t\tconst compiledFinished = await compileMdxIfExists(\n\t\t\tpath.join(workshopRoot, '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\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\nlet appCallCount = 0\n\nexport async function getApps({\n\ttimings,\n\trequest,\n\tforceFresh,\n}: CachifiedOptions & { forceFresh?: boolean } = {}): Promise<Array<App>> {\n\tawait init()\n\n\tconst key = 'apps'\n\tconst apps = await cachified({\n\t\tkey,\n\t\tcache: appsCache,\n\t\ttimings,\n\t\ttimingKey: `apps_${appCallCount++}`,\n\t\trequest,\n\t\t// This entire cache is to avoid a single request getting a fresh value\n\t\t// multiple times unnecessarily (because getApps is called many times)\n\t\tttl: 1000 * 60 * 60 * 24,\n\t\tforceFresh: forceFresh ?? getForceFresh(appsCache.get(key)),\n\t\tgetFreshValue: async () => {\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})\n\treturn apps\n}\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(workshopRoot, '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(workshopRoot, '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\t\tproblemDirs.push(...problemSubDirs)\n\t}\n\treturn problemDirs\n}\n\nasync function getSolutionDirs() {\n\tconst exercisesDir = path.join(workshopRoot, '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\t\tsolutionDirs.push(...solutionSubDirs)\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`${workshopRoot}${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(`${workshopRoot}${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') return path.join(workshopRoot, '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(workshopRoot, 'examples', relativePath)\n\t}\n\tif (appName.includes('__sep__')) {\n\t\tconst relativePath = appName.replaceAll('__sep__', path.sep)\n\t\treturn path.join(workshopRoot, 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(workshopRoot, '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 = playgroundAppCache.get(key)\n\treturn cachified({\n\t\tkey,\n\t\tcache: playgroundAppCache,\n\t\tttl: 1000 * 60 * 60 * 24,\n\n\t\ttimings,\n\t\ttimingKey: playgroundDir.replace(`${playgroundDir}${path.sep}`, ''),\n\t\trequest,\n\t\tforceFresh: 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(`${workshopRoot}${path.sep}`, ''),\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(`${workshopRoot}${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(workshopRoot, '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 * 60 * 24,\n\n\t\t\ttimings,\n\t\t\ttimingKey: exampleDir.replace(`${examplesDir}${path.sep}`, ''),\n\t\t\trequest,\n\t\t\tforceFresh: getForceFreshForDir(exampleAppCache.get(key), exampleDir),\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(`${workshopRoot}${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(workshopRoot, '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 * 60 * 24,\n\n\t\t\tforceFresh: 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(`${workshopRoot}${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(workshopRoot, '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 * 60 * 24,\n\n\t\t\tforceFresh: 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(workshopRoot, 'playground')\n\tconst savedPlaygroundsDir = path.join(workshopRoot, '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(workshopRoot, '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? 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(workshopRoot, 'epicshop', 'pre-set-playground.js'),\n\t)\n\tif (preSetPlaygroundPath) {\n\t\tawait execa('node', [preSetPlaygroundPath], {\n\t\t\tcwd: workshopRoot,\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(playgroundAppNameInfoPath))\n\tawait fsExtra.writeJSON(playgroundAppNameInfoPath, { 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(workshopRoot, 'epicshop', 'post-set-playground.js'),\n\t)\n\tif (postSetPlaygroundPath) {\n\t\tawait execa('node', [postSetPlaygroundPath], {\n\t\t\tcwd: workshopRoot,\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(playgroundAppNameInfoPath))) {\n\t\treturn null\n\t}\n\ttry {\n\t\tconst jsonString = await fs.promises.readFile(\n\t\t\tplaygroundAppNameInfoPath,\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(workshopRoot, '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(workshopRoot, 'exercises', 'FINISHED.mdx')\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\nconst exercisesPath = path.join(workshopRoot, 'exercises/')\nconst playgroundPath = path.join(workshopRoot, 'playground/')\nexport function getRelativePath(filePath: string) {\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(workshopRoot)\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(workshopRoot, 'playground')\n\t}\n\n\t// Check if the file is in an example\n\tif (part1 === 'examples' && part2) {\n\t\treturn path.join(workshopRoot, '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(workshopRoot, 'exercises', part2, part3)\n\t}\n\n\t// If we couldn't determine the app path, return null\n\treturn null\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type App } from './apps.server.js';
|
|
2
|
+
import { type Timings } from './timing.server.js';
|
|
3
|
+
export declare function getDiffFiles(app1: App, app2: App, { forceFresh, timings, request, }?: {
|
|
4
|
+
forceFresh?: boolean;
|
|
5
|
+
timings?: Timings;
|
|
6
|
+
request?: Request;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
status: "renamed" | "modified" | "deleted" | "added" | "unknown";
|
|
9
|
+
path: string;
|
|
10
|
+
line: number;
|
|
11
|
+
}[]>;
|
|
12
|
+
export declare function getDiffCode(app1: App, app2: App, { forceFresh, timings, request, }?: {
|
|
13
|
+
forceFresh?: boolean;
|
|
14
|
+
timings?: Timings;
|
|
15
|
+
request?: Request;
|
|
16
|
+
}): Promise<string>;
|
|
17
|
+
export declare function getDiffOutputWithRelativePaths(app1: App, app2: App): Promise<string>;
|
|
18
|
+
//# sourceMappingURL=diff.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.server.d.ts","sourceRoot":"","sources":["../../src/diff.server.ts"],"names":[],"mappings":"AAQA,OAAO,EAKN,KAAK,GAAG,EACR,MAAM,kBAAkB,CAAA;AAIzB,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAA;AA8TjD,wBAAsB,YAAY,CACjC,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,GAAG,EACT,EACC,UAAU,EACV,OAAO,EACP,OAAO,GACP,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO;YAwEtB,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS;;;KA1DxG;AAmED,wBAAsB,WAAW,CAChC,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,GAAG,EACT,EACC,UAAU,EACV,OAAO,EACP,OAAO,GACP,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,mBActE;AAiHD,wBAAsB,8BAA8B,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,mBA0BxE"}
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
import fsExtra from 'fs-extra';
|
|
5
|
+
import ignore from 'ignore';
|
|
6
|
+
import parseGitDiff from 'parse-git-diff';
|
|
7
|
+
import { bundledLanguagesInfo } from 'shiki/langs';
|
|
8
|
+
import { getForceFreshForDir, getRelativePath, workshopRoot, modifiedTimes, } from './apps.server.js';
|
|
9
|
+
import { cachified, diffCodeCache, diffFilesCache } from './cache.server.js';
|
|
10
|
+
import { compileMarkdownString } from './compile-mdx.server.js';
|
|
11
|
+
import { modifiedMoreRecentlyThan } from './modified-time.server.js';
|
|
12
|
+
const epicshopTempDir = path.join(os.tmpdir(), 'epicshop');
|
|
13
|
+
const isDeployed = ENV.EPICSHOP_DEPLOYED;
|
|
14
|
+
const diffTmpDir = path.join(epicshopTempDir, 'diff');
|
|
15
|
+
function diffPathToRelative(filePath) {
|
|
16
|
+
let normalizedPath = path.normalize(filePath.replace(/^("|')|("|')$/g, ''));
|
|
17
|
+
if (normalizedPath.startsWith('a\\') ||
|
|
18
|
+
normalizedPath.startsWith('b\\') ||
|
|
19
|
+
normalizedPath.startsWith('a/') ||
|
|
20
|
+
normalizedPath.startsWith('b/')) {
|
|
21
|
+
normalizedPath = normalizedPath.slice(2);
|
|
22
|
+
}
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
24
|
+
const [workshopRootDirname, appId, id, ...relativePath] = normalizedPath
|
|
25
|
+
.replace(process.platform === 'win32' || normalizedPath.startsWith(path.sep)
|
|
26
|
+
? `${diffTmpDir}${path.sep}`
|
|
27
|
+
: `${diffTmpDir.slice(1)}${path.sep}`, '')
|
|
28
|
+
.split(path.sep);
|
|
29
|
+
return relativePath.join(path.sep);
|
|
30
|
+
}
|
|
31
|
+
function getLanguage(ext) {
|
|
32
|
+
return (bundledLanguagesInfo.find((l) => l.id === ext || l.aliases?.includes(ext))
|
|
33
|
+
?.id ?? 'text');
|
|
34
|
+
}
|
|
35
|
+
function getFileCodeblocks(file, filePathApp1, filePathApp2, type) {
|
|
36
|
+
if (!file.chunks.length) {
|
|
37
|
+
return [
|
|
38
|
+
`<p className="m-0 p-4 border-b text-muted-foreground">No changes</p>`,
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
const filepath = diffPathToRelative(file.type === 'RenamedFile' ? file.pathAfter : file.path);
|
|
42
|
+
const extension = path.extname(filepath).slice(1);
|
|
43
|
+
const lang = getLanguage(extension);
|
|
44
|
+
const pathToCopy = file.type === 'RenamedFile' ? file.pathBefore : file.path;
|
|
45
|
+
const relativePath = diffPathToRelative(pathToCopy);
|
|
46
|
+
const markdownLines = [];
|
|
47
|
+
for (const chunk of file.chunks) {
|
|
48
|
+
const removedLineNumbers = [];
|
|
49
|
+
const addedLineNumbers = [];
|
|
50
|
+
const lines = [];
|
|
51
|
+
let toStartLine = 0;
|
|
52
|
+
let startLine = 1;
|
|
53
|
+
if (chunk.type === 'BinaryFilesChunk') {
|
|
54
|
+
lines.push(type === 'AddedFile'
|
|
55
|
+
? `Binary file added`
|
|
56
|
+
: type === 'DeletedFile'
|
|
57
|
+
? 'Binary file deleted'
|
|
58
|
+
: 'Binary file changed');
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
startLine =
|
|
62
|
+
chunk.type === 'Chunk'
|
|
63
|
+
? chunk.fromFileRange.start
|
|
64
|
+
: chunk.type === 'CombinedChunk'
|
|
65
|
+
? chunk.fromFileRangeA.start
|
|
66
|
+
: 1;
|
|
67
|
+
toStartLine = chunk.toFileRange.start;
|
|
68
|
+
for (let lineNumber = 0; lineNumber < chunk.changes.length; lineNumber++) {
|
|
69
|
+
const change = chunk.changes[lineNumber];
|
|
70
|
+
if (!change)
|
|
71
|
+
continue;
|
|
72
|
+
lines.push(change.content);
|
|
73
|
+
switch (change.type) {
|
|
74
|
+
case 'AddedLine': {
|
|
75
|
+
addedLineNumbers.push(startLine + lineNumber);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case 'DeletedLine': {
|
|
79
|
+
removedLineNumbers.push(startLine + lineNumber);
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
default: {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const params = [
|
|
89
|
+
['filename', relativePath.replace(/\\/g, '\\\\')],
|
|
90
|
+
['start', startLine.toString()],
|
|
91
|
+
removedLineNumbers.length
|
|
92
|
+
? ['remove', removedLineNumbers.join(',')]
|
|
93
|
+
: null,
|
|
94
|
+
addedLineNumbers.length ? ['add', addedLineNumbers.join(',')] : null,
|
|
95
|
+
]
|
|
96
|
+
.filter(Boolean)
|
|
97
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
98
|
+
.join(' ');
|
|
99
|
+
const launchEditorClassName = 'border hover:bg-foreground/20 rounded px-2 py-0.5 font-mono text-xs font-semibold';
|
|
100
|
+
function launchEditor(appNum, line) {
|
|
101
|
+
if (isDeployed) {
|
|
102
|
+
if (type === 'DeletedFile' && appNum === 2)
|
|
103
|
+
return '';
|
|
104
|
+
if (type === 'AddedFile' && appNum === 1)
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
const label = (type === 'AddedFile' && appNum === 1) ||
|
|
108
|
+
(type === 'DeletedFile' && appNum === 2)
|
|
109
|
+
? `CREATE in APP ${appNum}`
|
|
110
|
+
: `OPEN in APP ${appNum}`;
|
|
111
|
+
const file = JSON.stringify(appNum === 1 ? filePathApp1 : filePathApp2);
|
|
112
|
+
const fixedTitle = getRelativePath(file);
|
|
113
|
+
return `
|
|
114
|
+
<LaunchEditor file=${file} line={${line}}>
|
|
115
|
+
<span title="${fixedTitle}" className="${launchEditorClassName}">${label}</span>
|
|
116
|
+
</LaunchEditor>`;
|
|
117
|
+
}
|
|
118
|
+
markdownLines.push(`
|
|
119
|
+
<div className="relative">
|
|
120
|
+
|
|
121
|
+
\`\`\`${lang} ${params}
|
|
122
|
+
${lines.join('\n')}
|
|
123
|
+
\`\`\`
|
|
124
|
+
|
|
125
|
+
<div className="flex gap-4 absolute top-1 right-3 items-center">
|
|
126
|
+
${launchEditor(1, startLine)}
|
|
127
|
+
<div className="display-alt-down flex gap-2">
|
|
128
|
+
<LaunchEditor file=${JSON.stringify(filePathApp1)} syncTo={{file: ${JSON.stringify(filePathApp2)}}}>
|
|
129
|
+
<span className="block ${launchEditorClassName}">
|
|
130
|
+
<Icon name="ArrowLeft" title="Copy app 2 file to app 1" />
|
|
131
|
+
</span>
|
|
132
|
+
</LaunchEditor>
|
|
133
|
+
<LaunchEditor file=${JSON.stringify(filePathApp2)} syncTo={{file: ${JSON.stringify(filePathApp1)}}}>
|
|
134
|
+
<span className="block ${launchEditorClassName}">
|
|
135
|
+
<Icon name="ArrowRight" title="Copy app 1 file to app 2" />
|
|
136
|
+
</span>
|
|
137
|
+
</LaunchEditor>
|
|
138
|
+
</div>
|
|
139
|
+
${launchEditor(2, toStartLine)}
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
</div>
|
|
143
|
+
`);
|
|
144
|
+
}
|
|
145
|
+
return markdownLines;
|
|
146
|
+
}
|
|
147
|
+
const DEFAULT_IGNORE_PATTERNS = [
|
|
148
|
+
'**/README.*',
|
|
149
|
+
'**/package-lock.json',
|
|
150
|
+
'**/.DS_Store',
|
|
151
|
+
'**/.vscode',
|
|
152
|
+
'**/.idea',
|
|
153
|
+
'**/.git',
|
|
154
|
+
'**/*.db',
|
|
155
|
+
'**/epicshop/**',
|
|
156
|
+
];
|
|
157
|
+
async function copyUnignoredFiles(srcDir, destDir, ignoreList) {
|
|
158
|
+
const key = `COPY_${srcDir}__${destDir}__${ignoreList.join('_')}`;
|
|
159
|
+
await cachified({
|
|
160
|
+
key,
|
|
161
|
+
cache: diffCodeCache,
|
|
162
|
+
forceFresh: getForceFreshForDir(diffCodeCache.get(key), srcDir),
|
|
163
|
+
async getFreshValue() {
|
|
164
|
+
// @ts-ignore 🤷♂️ weird module stuff
|
|
165
|
+
const ig = ignore().add(ignoreList);
|
|
166
|
+
await fsExtra.remove(destDir);
|
|
167
|
+
await fsExtra.copy(srcDir, destDir, {
|
|
168
|
+
filter: async (file) => {
|
|
169
|
+
if (file === srcDir)
|
|
170
|
+
return true;
|
|
171
|
+
return !ig.ignores(path.relative(srcDir, file));
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
async function prepareForDiff(app1, app2) {
|
|
178
|
+
const id = Math.random().toString(36).slice(2);
|
|
179
|
+
const app1CopyPath = path.join(diffTmpDir, path.basename(workshopRoot), app1.name, id);
|
|
180
|
+
const app2CopyPath = path.join(diffTmpDir, path.basename(workshopRoot), app2.name, id);
|
|
181
|
+
// if everything except the `name` property of the `package.json` is the same
|
|
182
|
+
// the don't bother copying it
|
|
183
|
+
const comparePkgJson = (pkg1, pkg2) => {
|
|
184
|
+
const { name, ...rest1 } = pkg1;
|
|
185
|
+
const { name: name2, ...rest2 } = pkg2;
|
|
186
|
+
return JSON.stringify(rest1) === JSON.stringify(rest2);
|
|
187
|
+
};
|
|
188
|
+
const app1PkgJson = app1.dev.type === 'script'
|
|
189
|
+
? await fsExtra
|
|
190
|
+
.readJSON(path.join(app1.fullPath, 'package.json'))
|
|
191
|
+
.catch(() => ({}))
|
|
192
|
+
: {};
|
|
193
|
+
const app2PkgJson = app1.dev.type === 'script'
|
|
194
|
+
? await fsExtra
|
|
195
|
+
.readJSON(path.join(app2.fullPath, 'package.json'))
|
|
196
|
+
.catch(() => ({}))
|
|
197
|
+
: {};
|
|
198
|
+
const pkgJsonIgnore = comparePkgJson(app1PkgJson, app2PkgJson)
|
|
199
|
+
? ['package.json']
|
|
200
|
+
: [];
|
|
201
|
+
const workshopIgnore = [
|
|
202
|
+
...(await getDiffIgnore(path.join(workshopRoot, '.gitignore'))),
|
|
203
|
+
...(await getDiffIgnore(path.join(workshopRoot, 'epicshop', '.diffignore'))),
|
|
204
|
+
];
|
|
205
|
+
await Promise.all([
|
|
206
|
+
copyUnignoredFiles(app1.fullPath, app1CopyPath, [
|
|
207
|
+
...DEFAULT_IGNORE_PATTERNS,
|
|
208
|
+
...pkgJsonIgnore,
|
|
209
|
+
...workshopIgnore,
|
|
210
|
+
...(await getDiffIgnore(path.join(app1.fullPath, '.gitignore'))),
|
|
211
|
+
...(await getDiffIgnore(path.join(app1.fullPath, 'epicshop', '.diffignore'))),
|
|
212
|
+
]),
|
|
213
|
+
copyUnignoredFiles(app2.fullPath, app2CopyPath, [
|
|
214
|
+
...DEFAULT_IGNORE_PATTERNS,
|
|
215
|
+
...pkgJsonIgnore,
|
|
216
|
+
...workshopIgnore,
|
|
217
|
+
...(await getDiffIgnore(path.join(app2.fullPath, '.gitignore'))),
|
|
218
|
+
...(await getDiffIgnore(path.join(app2.fullPath, 'epicshop', '.diffignore'))),
|
|
219
|
+
]),
|
|
220
|
+
]);
|
|
221
|
+
return { app1CopyPath, app2CopyPath };
|
|
222
|
+
}
|
|
223
|
+
async function getDiffIgnore(filePath) {
|
|
224
|
+
return (await fsExtra.pathExists(filePath))
|
|
225
|
+
? fsExtra.readFile(filePath, 'utf8').then((content) => content
|
|
226
|
+
.split('\n')
|
|
227
|
+
.map((line) => line.trim())
|
|
228
|
+
.filter((line) => !line.startsWith('#'))
|
|
229
|
+
.filter(Boolean))
|
|
230
|
+
: [];
|
|
231
|
+
}
|
|
232
|
+
async function getForceFreshForDiff(app1, app2, cacheEntry) {
|
|
233
|
+
// don't know when the cache was created? force refresh
|
|
234
|
+
const cacheModified = cacheEntry?.metadata.createdTime;
|
|
235
|
+
if (!cacheModified)
|
|
236
|
+
return true;
|
|
237
|
+
// app1 modified after cache? force refresh
|
|
238
|
+
const app1Modified = modifiedTimes.get(app1.fullPath) ?? 0;
|
|
239
|
+
if (app1Modified > cacheModified)
|
|
240
|
+
return true;
|
|
241
|
+
// app2 modified after cache? force refresh
|
|
242
|
+
const app2Modified = modifiedTimes.get(app2.fullPath) ?? 0;
|
|
243
|
+
if (app2Modified > cacheModified)
|
|
244
|
+
return true;
|
|
245
|
+
// ok, now let's actually check the modified times of all files in the
|
|
246
|
+
// directories and as soon as we find a file that was modified more recently
|
|
247
|
+
// then we know we need to force refresh
|
|
248
|
+
const modifiedMoreRecently = await modifiedMoreRecentlyThan(cacheModified, app1.fullPath, app2.fullPath);
|
|
249
|
+
if (modifiedMoreRecently)
|
|
250
|
+
return true;
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
export async function getDiffFiles(app1, app2, { forceFresh, timings, request, } = {}) {
|
|
254
|
+
const key = `${app1.relativePath}__vs__${app2.relativePath}`;
|
|
255
|
+
const cacheEntry = diffFilesCache.get(key);
|
|
256
|
+
const result = await cachified({
|
|
257
|
+
key,
|
|
258
|
+
cache: diffFilesCache,
|
|
259
|
+
forceFresh: forceFresh || (await getForceFreshForDiff(app1, app2, cacheEntry)),
|
|
260
|
+
timings,
|
|
261
|
+
request,
|
|
262
|
+
getFreshValue: () => getDiffFilesImpl(app1, app2),
|
|
263
|
+
});
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
function getAppTestFiles(app) {
|
|
267
|
+
return app.test.type === 'browser' ? app.test.testFiles : [];
|
|
268
|
+
}
|
|
269
|
+
async function getDiffFilesImpl(app1, app2) {
|
|
270
|
+
if (app1.name === app2.name) {
|
|
271
|
+
return [];
|
|
272
|
+
}
|
|
273
|
+
const { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2);
|
|
274
|
+
const { stdout: diffOutput } = await execa('git', [
|
|
275
|
+
'diff',
|
|
276
|
+
'--no-index',
|
|
277
|
+
'--ignore-blank-lines',
|
|
278
|
+
'--ignore-space-change',
|
|
279
|
+
app1CopyPath,
|
|
280
|
+
app2CopyPath,
|
|
281
|
+
], { cwd: diffTmpDir }).catch((e) => e);
|
|
282
|
+
void fsExtra.remove(app1CopyPath);
|
|
283
|
+
void fsExtra.remove(app2CopyPath);
|
|
284
|
+
const typesMap = {
|
|
285
|
+
ChangedFile: 'modified',
|
|
286
|
+
AddedFile: 'added',
|
|
287
|
+
DeletedFile: 'deleted',
|
|
288
|
+
RenamedFile: 'renamed',
|
|
289
|
+
};
|
|
290
|
+
const parsed = parseGitDiff(diffOutput, { noPrefix: true });
|
|
291
|
+
const testFiles = Array.from(new Set([...getAppTestFiles(app1), ...getAppTestFiles(app2)]));
|
|
292
|
+
const startLine = (file) => {
|
|
293
|
+
const chunk = file.type === 'ChangedFile' && file.chunks[0];
|
|
294
|
+
if (chunk) {
|
|
295
|
+
return chunk.type === 'Chunk'
|
|
296
|
+
? chunk.fromFileRange.start
|
|
297
|
+
: chunk.type === 'CombinedChunk'
|
|
298
|
+
? chunk.fromFileRangeA.start
|
|
299
|
+
: 1;
|
|
300
|
+
}
|
|
301
|
+
return 1;
|
|
302
|
+
};
|
|
303
|
+
return parsed.files
|
|
304
|
+
.map((file) => ({
|
|
305
|
+
// prettier-ignore
|
|
306
|
+
status: (typesMap[file.type] ?? 'unknown'),
|
|
307
|
+
path: diffPathToRelative(file.type === 'RenamedFile' ? file.pathBefore : file.path),
|
|
308
|
+
line: startLine(file),
|
|
309
|
+
}))
|
|
310
|
+
.filter((file) => !testFiles.includes(file.path));
|
|
311
|
+
}
|
|
312
|
+
export async function getDiffCode(app1, app2, { forceFresh, timings, request, } = {}) {
|
|
313
|
+
const key = `${app1.relativePath}__vs__${app2.relativePath}`;
|
|
314
|
+
const cacheEntry = diffCodeCache.get(key);
|
|
315
|
+
const result = await cachified({
|
|
316
|
+
key,
|
|
317
|
+
cache: diffCodeCache,
|
|
318
|
+
forceFresh: forceFresh || (await getForceFreshForDiff(app1, app2, cacheEntry)),
|
|
319
|
+
timings,
|
|
320
|
+
request,
|
|
321
|
+
getFreshValue: () => getDiffCodeImpl(app1, app2),
|
|
322
|
+
});
|
|
323
|
+
return result;
|
|
324
|
+
}
|
|
325
|
+
async function getDiffCodeImpl(app1, app2) {
|
|
326
|
+
const markdownLines = [''];
|
|
327
|
+
if (app1.name === app2.name) {
|
|
328
|
+
markdownLines.push('<p className="p-4 text-center">You are comparing the same app</p>');
|
|
329
|
+
const code = await compileMarkdownString(markdownLines.join('\n'));
|
|
330
|
+
return code;
|
|
331
|
+
}
|
|
332
|
+
const { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2);
|
|
333
|
+
const { stdout: diffOutput } = await execa('git', [
|
|
334
|
+
'diff',
|
|
335
|
+
'--no-index',
|
|
336
|
+
app1CopyPath,
|
|
337
|
+
app2CopyPath,
|
|
338
|
+
'--color=never',
|
|
339
|
+
'--color-moved-ws=allow-indentation-change',
|
|
340
|
+
'--no-prefix',
|
|
341
|
+
'--ignore-blank-lines',
|
|
342
|
+
'--ignore-space-change',
|
|
343
|
+
], { cwd: diffTmpDir }).catch((e) => e);
|
|
344
|
+
void fsExtra.remove(app1CopyPath);
|
|
345
|
+
void fsExtra.remove(app2CopyPath);
|
|
346
|
+
const parsed = parseGitDiff(diffOutput);
|
|
347
|
+
if (!parsed.files.length) {
|
|
348
|
+
markdownLines.push('<div className="m-5 inline-flex items-center justify-center bg-foreground px-1 py-0.5 font-mono text-sm uppercase text-background">No changes</div>');
|
|
349
|
+
}
|
|
350
|
+
const app1TestFiles = getAppTestFiles(app1);
|
|
351
|
+
const app2TestFiles = getAppTestFiles(app2);
|
|
352
|
+
for (const file of parsed.files) {
|
|
353
|
+
const pathToCopy = file.type === 'RenamedFile' ? file.pathBefore : file.path;
|
|
354
|
+
const relativePath = diffPathToRelative(pathToCopy);
|
|
355
|
+
if (app1TestFiles.includes(relativePath))
|
|
356
|
+
continue;
|
|
357
|
+
const filePathApp1 = path.join(app1.fullPath, relativePath);
|
|
358
|
+
const pathToApp2 = file.type === 'RenamedFile' ? file.pathAfter : file.path;
|
|
359
|
+
const relativePathApp2 = diffPathToRelative(pathToApp2);
|
|
360
|
+
if (app2TestFiles.includes(relativePathApp2))
|
|
361
|
+
continue;
|
|
362
|
+
const filePathApp2 = path.join(app2.fullPath, relativePathApp2);
|
|
363
|
+
switch (file.type) {
|
|
364
|
+
case 'ChangedFile': {
|
|
365
|
+
markdownLines.push(`
|
|
366
|
+
|
|
367
|
+
<Accordion title=${JSON.stringify(relativePath)} variant="changed">
|
|
368
|
+
|
|
369
|
+
${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\n')}
|
|
370
|
+
|
|
371
|
+
</Accordion>
|
|
372
|
+
|
|
373
|
+
`);
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
case 'DeletedFile': {
|
|
377
|
+
markdownLines.push(`
|
|
378
|
+
<Accordion title=${JSON.stringify(relativePath)} variant="deleted">
|
|
379
|
+
|
|
380
|
+
${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\n')}
|
|
381
|
+
|
|
382
|
+
</Accordion>
|
|
383
|
+
`);
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
case 'RenamedFile': {
|
|
387
|
+
const relativeBefore = diffPathToRelative(file.pathBefore);
|
|
388
|
+
const relativeAfter = diffPathToRelative(file.pathAfter);
|
|
389
|
+
const title = JSON.stringify(`${relativeBefore} ▶️ ${relativeAfter}`);
|
|
390
|
+
markdownLines.push(`
|
|
391
|
+
<Accordion title=${title} variant="renamed">
|
|
392
|
+
|
|
393
|
+
${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\n')}
|
|
394
|
+
|
|
395
|
+
</Accordion>
|
|
396
|
+
`);
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
case 'AddedFile': {
|
|
400
|
+
markdownLines.push(`
|
|
401
|
+
<Accordion title=${JSON.stringify(relativePath)} variant="added">
|
|
402
|
+
|
|
403
|
+
${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\n')}
|
|
404
|
+
|
|
405
|
+
</Accordion>
|
|
406
|
+
`);
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
default: {
|
|
410
|
+
console.error(file);
|
|
411
|
+
throw new Error(`Unknown file type: ${file}`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const code = await compileMarkdownString(markdownLines.join('\n'));
|
|
416
|
+
return code;
|
|
417
|
+
}
|
|
418
|
+
export async function getDiffOutputWithRelativePaths(app1, app2) {
|
|
419
|
+
const { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2);
|
|
420
|
+
const { stdout: diffOutput } = await execa('git', [
|
|
421
|
+
'diff',
|
|
422
|
+
'--no-index',
|
|
423
|
+
app1CopyPath,
|
|
424
|
+
app2CopyPath,
|
|
425
|
+
'--color=never',
|
|
426
|
+
'--color-moved-ws=allow-indentation-change',
|
|
427
|
+
'--no-prefix',
|
|
428
|
+
'--ignore-blank-lines',
|
|
429
|
+
'--ignore-space-change',
|
|
430
|
+
], { cwd: diffTmpDir }).catch((e) => e);
|
|
431
|
+
void fsExtra.remove(app1CopyPath);
|
|
432
|
+
void fsExtra.remove(app2CopyPath);
|
|
433
|
+
return diffOutput
|
|
434
|
+
.replaceAll(app1CopyPath.slice(1), '.')
|
|
435
|
+
.replaceAll(app2CopyPath.slice(1), '.');
|
|
436
|
+
}
|
|
437
|
+
//# sourceMappingURL=diff.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.server.js","sourceRoot":"","sources":["../../src/diff.server.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'os'\nimport path from 'path'\nimport { type CacheEntry } from '@epic-web/cachified'\nimport { execa } from 'execa'\nimport fsExtra from 'fs-extra'\nimport ignore from 'ignore'\nimport parseGitDiff, { type AnyFileChange } from 'parse-git-diff'\nimport { bundledLanguagesInfo } from 'shiki/langs'\nimport {\n\tgetForceFreshForDir,\n\tgetRelativePath,\n\tworkshopRoot,\n\tmodifiedTimes,\n\ttype App,\n} from './apps.server.js'\nimport { cachified, diffCodeCache, diffFilesCache } from './cache.server.js'\nimport { compileMarkdownString } from './compile-mdx.server.js'\nimport { modifiedMoreRecentlyThan } from './modified-time.server.js'\nimport { type Timings } from './timing.server.js'\n\nconst epicshopTempDir = path.join(os.tmpdir(), 'epicshop')\n\nconst isDeployed = ENV.EPICSHOP_DEPLOYED\n\nconst diffTmpDir = path.join(epicshopTempDir, 'diff')\n\nfunction diffPathToRelative(filePath: string) {\n\tlet normalizedPath = path.normalize(filePath.replace(/^(\"|')|(\"|')$/g, ''))\n\tif (\n\t\tnormalizedPath.startsWith('a\\\\') ||\n\t\tnormalizedPath.startsWith('b\\\\') ||\n\t\tnormalizedPath.startsWith('a/') ||\n\t\tnormalizedPath.startsWith('b/')\n\t) {\n\t\tnormalizedPath = normalizedPath.slice(2)\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tconst [workshopRootDirname, appId, id, ...relativePath] = normalizedPath\n\t\t.replace(\n\t\t\tprocess.platform === 'win32' || normalizedPath.startsWith(path.sep)\n\t\t\t\t? `${diffTmpDir}${path.sep}`\n\t\t\t\t: `${diffTmpDir.slice(1)}${path.sep}`,\n\t\t\t'',\n\t\t)\n\t\t.split(path.sep)\n\n\treturn relativePath.join(path.sep)\n}\n\nfunction getLanguage(ext: string) {\n\treturn (\n\t\tbundledLanguagesInfo.find((l) => l.id === ext || l.aliases?.includes(ext))\n\t\t\t?.id ?? 'text'\n\t)\n}\n\nfunction getFileCodeblocks(\n\tfile: ReturnType<typeof parseGitDiff>['files'][number],\n\tfilePathApp1: string,\n\tfilePathApp2: string,\n\ttype: string,\n) {\n\tif (!file.chunks.length) {\n\t\treturn [\n\t\t\t`<p className=\"m-0 p-4 border-b text-muted-foreground\">No changes</p>`,\n\t\t]\n\t}\n\tconst filepath = diffPathToRelative(\n\t\tfile.type === 'RenamedFile' ? file.pathAfter : file.path,\n\t)\n\tconst extension = path.extname(filepath).slice(1)\n\tconst lang = getLanguage(extension)\n\tconst pathToCopy = file.type === 'RenamedFile' ? file.pathBefore : file.path\n\tconst relativePath = diffPathToRelative(pathToCopy)\n\tconst markdownLines = []\n\tfor (const chunk of file.chunks) {\n\t\tconst removedLineNumbers = []\n\t\tconst addedLineNumbers = []\n\t\tconst lines = []\n\t\tlet toStartLine = 0\n\t\tlet startLine = 1\n\t\tif (chunk.type === 'BinaryFilesChunk') {\n\t\t\tlines.push(\n\t\t\t\ttype === 'AddedFile'\n\t\t\t\t\t? `Binary file added`\n\t\t\t\t\t: type === 'DeletedFile'\n\t\t\t\t\t\t? 'Binary file deleted'\n\t\t\t\t\t\t: 'Binary file changed',\n\t\t\t)\n\t\t} else {\n\t\t\tstartLine =\n\t\t\t\tchunk.type === 'Chunk'\n\t\t\t\t\t? chunk.fromFileRange.start\n\t\t\t\t\t: chunk.type === 'CombinedChunk'\n\t\t\t\t\t\t? chunk.fromFileRangeA.start\n\t\t\t\t\t\t: 1\n\t\t\ttoStartLine = chunk.toFileRange.start\n\t\t\tfor (\n\t\t\t\tlet lineNumber = 0;\n\t\t\t\tlineNumber < chunk.changes.length;\n\t\t\t\tlineNumber++\n\t\t\t) {\n\t\t\t\tconst change = chunk.changes[lineNumber]\n\t\t\t\tif (!change) continue\n\t\t\t\tlines.push(change.content)\n\t\t\t\tswitch (change.type) {\n\t\t\t\t\tcase 'AddedLine': {\n\t\t\t\t\t\taddedLineNumbers.push(startLine + lineNumber)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'DeletedLine': {\n\t\t\t\t\t\tremovedLineNumbers.push(startLine + lineNumber)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst params = [\n\t\t\t['filename', relativePath.replace(/\\\\/g, '\\\\\\\\')],\n\t\t\t['start', startLine.toString()],\n\t\t\tremovedLineNumbers.length\n\t\t\t\t? ['remove', removedLineNumbers.join(',')]\n\t\t\t\t: null,\n\t\t\taddedLineNumbers.length ? ['add', addedLineNumbers.join(',')] : null,\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.map(([key, value]) => `${key}=${value}`)\n\t\t\t.join(' ')\n\n\t\tconst launchEditorClassName =\n\t\t\t'border hover:bg-foreground/20 rounded px-2 py-0.5 font-mono text-xs font-semibold'\n\n\t\tfunction launchEditor(appNum: number, line: number) {\n\t\t\tif (isDeployed) {\n\t\t\t\tif (type === 'DeletedFile' && appNum === 2) return ''\n\t\t\t\tif (type === 'AddedFile' && appNum === 1) return ''\n\t\t\t}\n\n\t\t\tconst label =\n\t\t\t\t(type === 'AddedFile' && appNum === 1) ||\n\t\t\t\t(type === 'DeletedFile' && appNum === 2)\n\t\t\t\t\t? `CREATE in APP ${appNum}`\n\t\t\t\t\t: `OPEN in APP ${appNum}`\n\t\t\tconst file = JSON.stringify(appNum === 1 ? filePathApp1 : filePathApp2)\n\t\t\tconst fixedTitle = getRelativePath(file)\n\n\t\t\treturn `\n<LaunchEditor file=${file} line={${line}}>\n\t<span title=\"${fixedTitle}\" className=\"${launchEditorClassName}\">${label}</span>\n</LaunchEditor>`\n\t\t}\n\n\t\tmarkdownLines.push(`\n<div className=\"relative\">\n\n\\`\\`\\`${lang} ${params}\n${lines.join('\\n')}\n\\`\\`\\`\n\n<div className=\"flex gap-4 absolute top-1 right-3 items-center\">\n\t${launchEditor(1, startLine)}\n\t<div className=\"display-alt-down flex gap-2\">\n\t\t<LaunchEditor file=${JSON.stringify(\n\t\t\tfilePathApp1,\n\t\t)} syncTo={{file: ${JSON.stringify(filePathApp2)}}}>\n\t\t\t<span className=\"block ${launchEditorClassName}\">\n\t\t\t\t<Icon name=\"ArrowLeft\" title=\"Copy app 2 file to app 1\" />\n\t\t\t</span>\n\t\t</LaunchEditor>\n\t\t<LaunchEditor file=${JSON.stringify(\n\t\t\tfilePathApp2,\n\t\t)} syncTo={{file: ${JSON.stringify(filePathApp1)}}}>\n\t\t\t<span className=\"block ${launchEditorClassName}\">\n\t\t\t\t<Icon name=\"ArrowRight\" title=\"Copy app 1 file to app 2\" />\n\t\t\t</span>\n\t\t</LaunchEditor>\n\t</div>\n\t${launchEditor(2, toStartLine)}\n</div>\n\n</div>\n`)\n\t}\n\treturn markdownLines\n}\n\nconst DEFAULT_IGNORE_PATTERNS = [\n\t'**/README.*',\n\t'**/package-lock.json',\n\t'**/.DS_Store',\n\t'**/.vscode',\n\t'**/.idea',\n\t'**/.git',\n\t'**/*.db',\n\t'**/epicshop/**',\n]\n\nasync function copyUnignoredFiles(\n\tsrcDir: string,\n\tdestDir: string,\n\tignoreList: Array<string>,\n) {\n\tconst key = `COPY_${srcDir}__${destDir}__${ignoreList.join('_')}`\n\tawait cachified({\n\t\tkey,\n\t\tcache: diffCodeCache,\n\t\tforceFresh: getForceFreshForDir(diffCodeCache.get(key), srcDir),\n\t\tasync getFreshValue() {\n\t\t\t// @ts-ignore 🤷♂️ weird module stuff\n\t\t\tconst ig = ignore().add(ignoreList)\n\n\t\t\tawait fsExtra.remove(destDir)\n\t\t\tawait fsExtra.copy(srcDir, destDir, {\n\t\t\t\tfilter: async (file) => {\n\t\t\t\t\tif (file === srcDir) return true\n\t\t\t\t\treturn !ig.ignores(path.relative(srcDir, file))\n\t\t\t\t},\n\t\t\t})\n\t\t},\n\t})\n}\n\nasync function prepareForDiff(app1: App, app2: App) {\n\tconst id = Math.random().toString(36).slice(2)\n\tconst app1CopyPath = path.join(\n\t\tdiffTmpDir,\n\t\tpath.basename(workshopRoot),\n\t\tapp1.name,\n\t\tid,\n\t)\n\tconst app2CopyPath = path.join(\n\t\tdiffTmpDir,\n\t\tpath.basename(workshopRoot),\n\t\tapp2.name,\n\t\tid,\n\t)\n\t// if everything except the `name` property of the `package.json` is the same\n\t// the don't bother copying it\n\tconst comparePkgJson = (pkg1: any, pkg2: any) => {\n\t\tconst { name, ...rest1 } = pkg1\n\t\tconst { name: name2, ...rest2 } = pkg2\n\t\treturn JSON.stringify(rest1) === JSON.stringify(rest2)\n\t}\n\tconst app1PkgJson =\n\t\tapp1.dev.type === 'script'\n\t\t\t? await fsExtra\n\t\t\t\t\t.readJSON(path.join(app1.fullPath, 'package.json'))\n\t\t\t\t\t.catch(() => ({}))\n\t\t\t: {}\n\tconst app2PkgJson =\n\t\tapp1.dev.type === 'script'\n\t\t\t? await fsExtra\n\t\t\t\t\t.readJSON(path.join(app2.fullPath, 'package.json'))\n\t\t\t\t\t.catch(() => ({}))\n\t\t\t: {}\n\tconst pkgJsonIgnore: Array<string> = comparePkgJson(app1PkgJson, app2PkgJson)\n\t\t? ['package.json']\n\t\t: []\n\tconst workshopIgnore = [\n\t\t...(await getDiffIgnore(path.join(workshopRoot, '.gitignore'))),\n\t\t...(await getDiffIgnore(\n\t\t\tpath.join(workshopRoot, 'epicshop', '.diffignore'),\n\t\t)),\n\t]\n\n\tawait Promise.all([\n\t\tcopyUnignoredFiles(app1.fullPath, app1CopyPath, [\n\t\t\t...DEFAULT_IGNORE_PATTERNS,\n\t\t\t...pkgJsonIgnore,\n\t\t\t...workshopIgnore,\n\t\t\t...(await getDiffIgnore(path.join(app1.fullPath, '.gitignore'))),\n\t\t\t...(await getDiffIgnore(\n\t\t\t\tpath.join(app1.fullPath, 'epicshop', '.diffignore'),\n\t\t\t)),\n\t\t]),\n\t\tcopyUnignoredFiles(app2.fullPath, app2CopyPath, [\n\t\t\t...DEFAULT_IGNORE_PATTERNS,\n\t\t\t...pkgJsonIgnore,\n\t\t\t...workshopIgnore,\n\t\t\t...(await getDiffIgnore(path.join(app2.fullPath, '.gitignore'))),\n\t\t\t...(await getDiffIgnore(\n\t\t\t\tpath.join(app2.fullPath, 'epicshop', '.diffignore'),\n\t\t\t)),\n\t\t]),\n\t])\n\n\treturn { app1CopyPath, app2CopyPath }\n}\n\nasync function getDiffIgnore(filePath: string): Promise<Array<string>> {\n\treturn (await fsExtra.pathExists(filePath))\n\t\t? fsExtra.readFile(filePath, 'utf8').then((content) =>\n\t\t\t\tcontent\n\t\t\t\t\t.split('\\n')\n\t\t\t\t\t.map((line) => line.trim())\n\t\t\t\t\t.filter((line) => !line.startsWith('#'))\n\t\t\t\t\t.filter(Boolean),\n\t\t\t)\n\t\t: []\n}\n\nasync function getForceFreshForDiff(\n\tapp1: App,\n\tapp2: App,\n\tcacheEntry: CacheEntry | null | undefined,\n) {\n\t// don't know when the cache was created? force refresh\n\tconst cacheModified = cacheEntry?.metadata.createdTime\n\tif (!cacheModified) return true\n\n\t// app1 modified after cache? force refresh\n\tconst app1Modified = modifiedTimes.get(app1.fullPath) ?? 0\n\tif (app1Modified > cacheModified) return true\n\n\t// app2 modified after cache? force refresh\n\tconst app2Modified = modifiedTimes.get(app2.fullPath) ?? 0\n\tif (app2Modified > cacheModified) return true\n\n\t// ok, now let's actually check the modified times of all files in the\n\t// directories and as soon as we find a file that was modified more recently\n\t// then we know we need to force refresh\n\tconst modifiedMoreRecently = await modifiedMoreRecentlyThan(\n\t\tcacheModified,\n\t\tapp1.fullPath,\n\t\tapp2.fullPath,\n\t)\n\tif (modifiedMoreRecently) return true\n\n\treturn undefined\n}\n\nexport async function getDiffFiles(\n\tapp1: App,\n\tapp2: App,\n\t{\n\t\tforceFresh,\n\t\ttimings,\n\t\trequest,\n\t}: { forceFresh?: boolean; timings?: Timings; request?: Request } = {},\n) {\n\tconst key = `${app1.relativePath}__vs__${app2.relativePath}`\n\tconst cacheEntry = diffFilesCache.get(key)\n\tconst result = await cachified({\n\t\tkey,\n\t\tcache: diffFilesCache,\n\t\tforceFresh:\n\t\t\tforceFresh || (await getForceFreshForDiff(app1, app2, cacheEntry)),\n\t\ttimings,\n\t\trequest,\n\t\tgetFreshValue: () => getDiffFilesImpl(app1, app2),\n\t})\n\treturn result\n}\n\nfunction getAppTestFiles(app: App) {\n\treturn app.test.type === 'browser' ? app.test.testFiles : []\n}\n\nasync function getDiffFilesImpl(app1: App, app2: App) {\n\tif (app1.name === app2.name) {\n\t\treturn []\n\t}\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath)\n\tvoid fsExtra.remove(app2CopyPath)\n\n\tconst typesMap = {\n\t\tChangedFile: 'modified',\n\t\tAddedFile: 'added',\n\t\tDeletedFile: 'deleted',\n\t\tRenamedFile: 'renamed',\n\t}\n\n\tconst parsed = parseGitDiff(diffOutput, { noPrefix: true })\n\n\tconst testFiles = Array.from(\n\t\tnew Set([...getAppTestFiles(app1), ...getAppTestFiles(app2)]),\n\t)\n\n\tconst startLine = (file: AnyFileChange) => {\n\t\tconst chunk = file.type === 'ChangedFile' && file.chunks[0]\n\t\tif (chunk) {\n\t\t\treturn chunk.type === 'Chunk'\n\t\t\t\t? chunk.fromFileRange.start\n\t\t\t\t: chunk.type === 'CombinedChunk'\n\t\t\t\t\t? chunk.fromFileRangeA.start\n\t\t\t\t\t: 1\n\t\t}\n\t\treturn 1\n\t}\n\n\treturn parsed.files\n\t\t.map((file) => ({\n\t\t\t// prettier-ignore\n\n\t\t\tstatus: (typesMap[file.type] ?? 'unknown') as 'renamed' | 'modified' | 'deleted' | 'added' | 'unknown',\n\t\t\tpath: diffPathToRelative(\n\t\t\t\tfile.type === 'RenamedFile' ? file.pathBefore : file.path,\n\t\t\t),\n\t\t\tline: startLine(file),\n\t\t}))\n\t\t.filter((file) => !testFiles.includes(file.path))\n}\n\nexport async function getDiffCode(\n\tapp1: App,\n\tapp2: App,\n\t{\n\t\tforceFresh,\n\t\ttimings,\n\t\trequest,\n\t}: { forceFresh?: boolean; timings?: Timings; request?: Request } = {},\n) {\n\tconst key = `${app1.relativePath}__vs__${app2.relativePath}`\n\tconst cacheEntry = diffCodeCache.get(key)\n\tconst result = await cachified({\n\t\tkey,\n\t\tcache: diffCodeCache,\n\t\tforceFresh:\n\t\t\tforceFresh || (await getForceFreshForDiff(app1, app2, cacheEntry)),\n\t\ttimings,\n\t\trequest,\n\t\tgetFreshValue: () => getDiffCodeImpl(app1, app2),\n\t})\n\treturn result\n}\n\nasync function getDiffCodeImpl(app1: App, app2: App) {\n\tconst markdownLines = ['']\n\n\tif (app1.name === app2.name) {\n\t\tmarkdownLines.push(\n\t\t\t'<p className=\"p-4 text-center\">You are comparing the same app</p>',\n\t\t)\n\t\tconst code = await compileMarkdownString(markdownLines.join('\\n'))\n\t\treturn code\n\t}\n\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t\t'--color=never',\n\t\t\t'--color-moved-ws=allow-indentation-change',\n\t\t\t'--no-prefix',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath)\n\tvoid fsExtra.remove(app2CopyPath)\n\n\tconst parsed = parseGitDiff(diffOutput)\n\n\tif (!parsed.files.length) {\n\t\tmarkdownLines.push(\n\t\t\t'<div className=\"m-5 inline-flex items-center justify-center bg-foreground px-1 py-0.5 font-mono text-sm uppercase text-background\">No changes</div>',\n\t\t)\n\t}\n\n\tconst app1TestFiles = getAppTestFiles(app1)\n\tconst app2TestFiles = getAppTestFiles(app2)\n\n\tfor (const file of parsed.files) {\n\t\tconst pathToCopy = file.type === 'RenamedFile' ? file.pathBefore : file.path\n\t\tconst relativePath = diffPathToRelative(pathToCopy)\n\t\tif (app1TestFiles.includes(relativePath)) continue\n\t\tconst filePathApp1 = path.join(app1.fullPath, relativePath)\n\n\t\tconst pathToApp2 = file.type === 'RenamedFile' ? file.pathAfter : file.path\n\t\tconst relativePathApp2 = diffPathToRelative(pathToApp2)\n\t\tif (app2TestFiles.includes(relativePathApp2)) continue\n\t\tconst filePathApp2 = path.join(app2.fullPath, relativePathApp2)\n\n\t\tswitch (file.type) {\n\t\t\tcase 'ChangedFile': {\n\t\t\t\tmarkdownLines.push(`\n\n<Accordion title=${JSON.stringify(relativePath)} variant=\"changed\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'DeletedFile': {\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${JSON.stringify(relativePath)} variant=\"deleted\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'RenamedFile': {\n\t\t\t\tconst relativeBefore = diffPathToRelative(file.pathBefore)\n\t\t\t\tconst relativeAfter = diffPathToRelative(file.pathAfter)\n\t\t\t\tconst title = JSON.stringify(`${relativeBefore} ▶️ ${relativeAfter}`)\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${title} variant=\"renamed\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'AddedFile': {\n\t\t\t\tmarkdownLines.push(`\n<Accordion title=${JSON.stringify(relativePath)} variant=\"added\">\n\n${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join('\\n')}\n\n</Accordion>\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(file)\n\t\t\t\tthrow new Error(`Unknown file type: ${file}`)\n\t\t\t}\n\t\t}\n\t}\n\tconst code = await compileMarkdownString(markdownLines.join('\\n'))\n\treturn code\n}\n\nexport async function getDiffOutputWithRelativePaths(app1: App, app2: App) {\n\tconst { app1CopyPath, app2CopyPath } = await prepareForDiff(app1, app2)\n\n\tconst { stdout: diffOutput } = await execa(\n\t\t'git',\n\t\t[\n\t\t\t'diff',\n\t\t\t'--no-index',\n\t\t\tapp1CopyPath,\n\t\t\tapp2CopyPath,\n\t\t\t'--color=never',\n\t\t\t'--color-moved-ws=allow-indentation-change',\n\t\t\t'--no-prefix',\n\t\t\t'--ignore-blank-lines',\n\t\t\t'--ignore-space-change',\n\t\t],\n\t\t{ cwd: diffTmpDir },\n\t\t// --no-index implies --exit-code, so we need to use the error output\n\t).catch((e) => e as { stdout: string })\n\n\tvoid fsExtra.remove(app1CopyPath)\n\tvoid fsExtra.remove(app2CopyPath)\n\n\treturn diffOutput\n\t\t.replaceAll(app1CopyPath.slice(1), '.')\n\t\t.replaceAll(app2CopyPath.slice(1), '.')\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epic-web/workshop-utils",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.13.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"exports": {
|
|
14
14
|
"./package.json": "./package.json",
|
|
15
15
|
"./apps.server": "./src/apps.server.ts",
|
|
16
|
+
"./diff.server": "./src/diff.server.ts",
|
|
16
17
|
"./env.server": "./src/env.server.ts",
|
|
17
18
|
"./epic-api.server": "./src/epic-api.server.ts",
|
|
18
19
|
"./user.server": "./src/user.server.ts",
|
|
@@ -39,6 +40,12 @@
|
|
|
39
40
|
"default": "./dist/esm/apps.server.js"
|
|
40
41
|
}
|
|
41
42
|
},
|
|
43
|
+
"./diff.server": {
|
|
44
|
+
"import": {
|
|
45
|
+
"types": "./dist/esm/diff.server.d.ts",
|
|
46
|
+
"default": "./dist/esm/diff.server.js"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
42
49
|
"./env.server": {
|
|
43
50
|
"import": {
|
|
44
51
|
"types": "./dist/esm/env.server.d.ts",
|
|
@@ -171,16 +178,19 @@
|
|
|
171
178
|
"fkill": "^9.0.0",
|
|
172
179
|
"fs-extra": "^11.2.0",
|
|
173
180
|
"globby": "^14.0.2",
|
|
181
|
+
"ignore": "^5.3.2",
|
|
174
182
|
"lru-cache": "^11.0.1",
|
|
175
183
|
"md5-hex": "^5.0.0",
|
|
176
184
|
"mdast-util-mdx-jsx": "^3.1.3",
|
|
177
185
|
"mdx-bundler": "^10.0.3",
|
|
178
186
|
"p-queue": "^8.0.1",
|
|
187
|
+
"parse-git-diff": "^0.0.16",
|
|
179
188
|
"rehype": "^13.0.2",
|
|
180
189
|
"remark": "^15.0.1",
|
|
181
190
|
"remark-autolink-headings": "^7.0.1",
|
|
182
191
|
"remark-emoji": "^5.0.1",
|
|
183
192
|
"remark-gfm": "^4.0.0",
|
|
193
|
+
"shiki": "^1.22.0",
|
|
184
194
|
"unified": "^11.0.5",
|
|
185
195
|
"unist-util-remove-position": "^5.0.0",
|
|
186
196
|
"unist-util-visit": "^5.0.0",
|