@epic-web/workshop-utils 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/apps.server.d.ts +7 -1
- package/dist/esm/apps.server.d.ts.map +1 -1
- package/dist/esm/apps.server.js +17 -7
- package/dist/esm/apps.server.js.map +1 -1
- package/dist/esm/cache.server.d.ts.map +1 -1
- package/dist/esm/cache.server.js +2 -3
- package/dist/esm/cache.server.js.map +1 -1
- package/dist/esm/codefile-mdx.server.d.ts.map +1 -1
- package/dist/esm/codefile-mdx.server.js +10 -11
- package/dist/esm/codefile-mdx.server.js.map +1 -1
- package/dist/esm/compile-mdx.server.d.ts.map +1 -1
- package/dist/esm/compile-mdx.server.js +6 -7
- package/dist/esm/compile-mdx.server.js.map +1 -1
- package/dist/esm/db.server.js +1 -1
- package/dist/esm/db.server.js.map +1 -1
- package/dist/esm/iframe-sync.d.ts.map +1 -1
- package/dist/esm/iframe-sync.js +0 -4
- package/dist/esm/iframe-sync.js.map +1 -1
- package/dist/esm/playwright.server.d.ts.map +1 -1
- package/dist/esm/playwright.server.js +9 -10
- package/dist/esm/playwright.server.js.map +1 -1
- package/dist/esm/process-manager.server.d.ts.map +1 -1
- package/dist/esm/process-manager.server.js +10 -10
- package/dist/esm/process-manager.server.js.map +1 -1
- package/dist/esm/test.d.ts.map +1 -1
- package/dist/esm/test.js +1 -2
- package/dist/esm/test.js.map +1 -1
- package/dist/esm/timing.server.d.ts.map +1 -1
- package/dist/esm/timing.server.js +2 -4
- package/dist/esm/timing.server.js.map +1 -1
- package/dist/esm/utils.server.d.ts.map +1 -1
- package/dist/esm/utils.server.js +0 -1
- package/dist/esm/utils.server.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.server.js","sourceRoot":"","sources":["../../src/cache.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,KAAK,CAAC,MAAM,qBAAqB,CAAA;AACxC,OAAO,EACN,eAAe,GAGf,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,OAAO,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,GAAG,MAAM,SAAS,CAAA;AAQzB,OAAO,EAAE,uBAAuB,EAAgB,MAAM,oBAAoB,CAAA;AAE1E,MAAM,CAAC,MAAM,gBAAgB,GAC5B,kBAAkB,CAAc,kBAAkB,CAAC,CAAA;AACpD,MAAM,CAAC,MAAM,eAAe,GAAG,kBAAkB,CAAa,iBAAiB,CAAC,CAAA;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG,kBAAkB,CAAa,iBAAiB,CAAC,CAAA;AAChF,MAAM,CAAC,MAAM,kBAAkB,GAC9B,kBAAkB,CAAgB,oBAAoB,CAAC,CAAA;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,kBAAkB,CAAM,WAAW,CAAC,CAAA;AAC7D,MAAM,CAAC,MAAM,aAAa,GAAG,kBAAkB,CAAS,eAAe,CAAC,CAAA;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAS,gBAAgB,CAAC,CAAA;AAC1E,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CACtD,uBAAuB,CACvB,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAElD,oBAAoB,CAAC,CAAA;AACvB,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAS,mBAAmB,CAAC,CAAA;AAEhF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;AAE9D,MAAM,CAAC,MAAM,OAAO,GAAmB;IACtC,IAAI,EAAE,kBAAkB;IACxB,KAAK,CAAC,GAAG,CAAC,GAAG;QACZ,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"cache.server.js","sourceRoot":"","sources":["../../src/cache.server.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'os'\nimport path from 'path'\nimport * as C from '@epic-web/cachified'\nimport {\n\tverboseReporter,\n\ttype CacheEntry,\n\ttype Cache as CachifiedCache,\n} from '@epic-web/cachified'\nimport { remember } from '@epic-web/remember'\nimport fsExtra from 'fs-extra'\nimport { LRUCache } from 'lru-cache'\nimport md5 from 'md5-hex'\nimport {\n\ttype App,\n\ttype ExampleApp,\n\ttype PlaygroundApp,\n\ttype ProblemApp,\n\ttype SolutionApp,\n} from './apps.server.js'\nimport { cachifiedTimingReporter, type Timings } from './timing.server.js'\n\nexport const solutionAppCache =\n\tmakeSingletonCache<SolutionApp>('SolutionAppCache')\nexport const problemAppCache = makeSingletonCache<ProblemApp>('ProblemAppCache')\nexport const exampleAppCache = makeSingletonCache<ExampleApp>('ExampleAppCache')\nexport const playgroundAppCache =\n\tmakeSingletonCache<PlaygroundApp>('PlaygroundAppCache')\nexport const appsCache = makeSingletonCache<App>('AppsCache')\nexport const diffCodeCache = makeSingletonCache<string>('DiffCodeCache')\nexport const diffFilesCache = makeSingletonCache<string>('DiffFilesCache')\nexport const compiledMarkdownCache = makeSingletonCache<string>(\n\t'CompiledMarkdownCache',\n)\nexport type CachedEmbeddedFilesList = Record<string, string[]>\nexport const embeddedFilesCache = makeSingletonCache<\n\tCachedEmbeddedFilesList | undefined\n>('EmbeddedFilesCache')\nexport const compiledCodeCache = makeSingletonCache<string>('CompiledCodeCache')\n\nconst cacheDir = path.join(os.homedir(), '.epicshop', 'cache')\n\nexport const fsCache: CachifiedCache = {\n\tname: 'Filesystem cache',\n\tasync get(key) {\n\t\ttry {\n\t\t\tconst filePath = path.join(cacheDir, md5(key))\n\n\t\t\tconst data = await fsExtra.readJSON(filePath)\n\t\t\treturn data\n\t\t} catch (error: unknown) {\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\t'code' in error &&\n\t\t\t\terror.code === 'ENOENT'\n\t\t\t) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t},\n\tasync set(key, entry) {\n\t\tconst filePath = path.join(cacheDir, md5(key))\n\t\tawait fsExtra.ensureDir(path.dirname(filePath))\n\t\tawait fsExtra.writeJSON(filePath, entry)\n\t},\n\tasync delete(key) {\n\t\tconst filePath = path.join(cacheDir, md5(key))\n\t\tawait fsExtra.remove(filePath)\n\t},\n}\n\nexport async function deleteCache() {\n\tif (process.env.EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (await fsExtra.exists(cacheDir)) {\n\t\t\tawait fsExtra.remove(cacheDir)\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(`Error deleting the cache in ${cacheDir}`, error)\n\t}\n}\n\nexport function makeSingletonCache<CacheEntryType>(name: string) {\n\treturn remember(name, () => {\n\t\tconst lruInstance = new LRUCache<string, CacheEntry<CacheEntryType>>({\n\t\t\tmax: 1000,\n\t\t})\n\n\t\tconst lru = {\n\t\t\tname,\n\t\t\tset: (key, value) => {\n\t\t\t\tconst ttl = C.totalTtl(value.metadata)\n\t\t\t\tlruInstance.set(key, value, {\n\t\t\t\t\tttl: ttl === Infinity ? undefined : ttl,\n\t\t\t\t\tstart: value.metadata.createdTime,\n\t\t\t\t})\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tget: (key) => lruInstance.get(key),\n\t\t\tdelete: (key) => lruInstance.delete(key),\n\t\t} satisfies C.Cache<CacheEntryType>\n\n\t\treturn lru\n\t})\n}\n\nexport async function cachified<Value>({\n\trequest,\n\ttimings,\n\tkey,\n\t// TODO: figure out what this was for before...\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\ttimingKey = key.length > 18 ? `${key.slice(0, 7)}...${key.slice(-8)}` : key,\n\t...options\n}: Omit<C.CachifiedOptions<Value>, 'forceFresh'> & {\n\trequest?: Request\n\ttimings?: Timings\n\tforceFresh?: boolean | string\n\ttimingKey?: string\n}): Promise<Value> {\n\treturn C.cachified(\n\t\t{\n\t\t\t...options,\n\t\t\tkey,\n\t\t\tforceFresh: await shouldForceFresh({\n\t\t\t\tforceFresh: options.forceFresh,\n\t\t\t\trequest,\n\t\t\t\tkey,\n\t\t\t}),\n\t\t},\n\t\tC.mergeReporters(\n\t\t\tcachifiedTimingReporter(timings),\n\t\t\tprocess.env.EPICSHOP_DEBUG_CACHE ? verboseReporter() : undefined,\n\t\t),\n\t)\n}\n\nexport async function shouldForceFresh({\n\tforceFresh,\n\trequest,\n\tkey,\n}: {\n\tforceFresh?: boolean | string\n\trequest?: Request\n\tkey?: string\n}) {\n\tif (typeof forceFresh === 'boolean') return forceFresh\n\tif (typeof forceFresh === 'string' && key) {\n\t\treturn forceFresh.split(',').includes(key)\n\t}\n\n\tif (!request) return false\n\tconst fresh = new URL(request.url).searchParams.get('fresh')\n\tif (typeof fresh !== 'string') return false\n\tif (fresh === '') return true\n\tif (!key) return false\n\n\treturn fresh.split(',').includes(key)\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codefile-mdx.server.d.ts","sourceRoot":"","sources":["../../src/codefile-mdx.server.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"codefile-mdx.server.d.ts","sourceRoot":"","sources":["../../src/codefile-mdx.server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,IAAI,SAAS,EAAiC,MAAM,OAAO,CAAA;AAuB7E,MAAM,MAAM,YAAY,GAAG;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAC9C,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CACxC,CAAA;AA8LD,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,UA4IA,SAAS,mBAczD"}
|
|
@@ -9,14 +9,14 @@ const APP_TYPES = ['problem', 'solution', 'playground'];
|
|
|
9
9
|
const safePath = (s) => s.replace(/\\/g, '/');
|
|
10
10
|
const REG_EXP = /^(?:\d+(?:-\d+)?,)*\d+(?:-\d+)?$/;
|
|
11
11
|
const isValidRangeFormat = (value) => value ? REG_EXP.test(value) : true;
|
|
12
|
-
const transformRange = (value) => value?.split(',').map(range => {
|
|
12
|
+
const transformRange = (value) => value?.split(',').map((range) => {
|
|
13
13
|
const [start, end] = range.split('-').map(Number);
|
|
14
14
|
return [start, end ?? start];
|
|
15
15
|
});
|
|
16
16
|
const isRangeBounded = (range, ctx, lines) => {
|
|
17
17
|
if (!lines || !Array.isArray(range))
|
|
18
18
|
return;
|
|
19
|
-
if (range.flat().some(r => r < 1 || r > lines)) {
|
|
19
|
+
if (range.flat().some((r) => r < 1 || r > lines)) {
|
|
20
20
|
ctx.addIssue({
|
|
21
21
|
code: z.ZodIssueCode.custom,
|
|
22
22
|
message: `Range must be between 1 and ${lines}`,
|
|
@@ -42,7 +42,7 @@ async function getFileContent(filePath) {
|
|
|
42
42
|
fileContentCache.set(filePath, fileContent);
|
|
43
43
|
return fileContent;
|
|
44
44
|
}
|
|
45
|
-
catch
|
|
45
|
+
catch {
|
|
46
46
|
console.warn(`@epic-web/workshop-app - invalid CodeFile.\nCould not read file: ${filePath}\n`);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -52,8 +52,8 @@ async function validateProps(props, appDir) {
|
|
|
52
52
|
const BooleanSchema = z
|
|
53
53
|
.nullable(z.string())
|
|
54
54
|
.optional()
|
|
55
|
-
.refine(v => ['true', 'false', null, undefined].includes(v), 'optional boolean key can be "true", "false", null or undefined')
|
|
56
|
-
.transform(v => v === null || Boolean(v));
|
|
55
|
+
.refine((v) => ['true', 'false', null, undefined].includes(v), 'optional boolean key can be "true", "false", null or undefined')
|
|
56
|
+
.transform((v) => v === null || Boolean(v));
|
|
57
57
|
const RangeSchema = z
|
|
58
58
|
.string()
|
|
59
59
|
.optional()
|
|
@@ -85,13 +85,13 @@ async function validateProps(props, appDir) {
|
|
|
85
85
|
content,
|
|
86
86
|
};
|
|
87
87
|
}),
|
|
88
|
-
range: RangeSchema.refine(range => {
|
|
88
|
+
range: RangeSchema.refine((range) => {
|
|
89
89
|
const isValid = isRangesNonOverlapping(range);
|
|
90
90
|
// we use this value in highlight refine
|
|
91
91
|
validRange = isValid ? range : undefined;
|
|
92
92
|
return isValid;
|
|
93
93
|
}, 'Ranges must not overlap'),
|
|
94
|
-
highlight: RangeSchema.refine(highlight => {
|
|
94
|
+
highlight: RangeSchema.refine((highlight) => {
|
|
95
95
|
if (!Array.isArray(highlight) || !Array.isArray(validRange)) {
|
|
96
96
|
return z.NEVER;
|
|
97
97
|
}
|
|
@@ -104,8 +104,8 @@ async function validateProps(props, appDir) {
|
|
|
104
104
|
buttons: z
|
|
105
105
|
.string()
|
|
106
106
|
.optional()
|
|
107
|
-
.transform(str =>
|
|
108
|
-
.refine(arr => arr.every(item => APP_TYPES.includes(item)), {
|
|
107
|
+
.transform((str) => str ? str.split(',') : [])
|
|
108
|
+
.refine((arr) => arr.every((item) => APP_TYPES.includes(item)), {
|
|
109
109
|
message: `Buttons can only be any of ${APP_TYPES.join(',')}`,
|
|
110
110
|
}),
|
|
111
111
|
})
|
|
@@ -133,7 +133,7 @@ ${content}
|
|
|
133
133
|
<CodeFileNotification variant="error" file="${filename}" line="${startLine}" type="${appType}">
|
|
134
134
|
<callout-danger class="notification">
|
|
135
135
|
<div className="title">CodeFile Error: invalid input</div>
|
|
136
|
-
${errors.map(error => `<div>${error}</div>`).join('')}
|
|
136
|
+
${errors.map((error) => `<div>${error}</div>`).join('')}
|
|
137
137
|
${await codeFence()}
|
|
138
138
|
</callout-danger>
|
|
139
139
|
</CodeFileNotification>`;
|
|
@@ -197,7 +197,6 @@ export function remarkCodeFile(data) {
|
|
|
197
197
|
const meta = [`filename=${filePath}`];
|
|
198
198
|
// nonumbers nocopy ....
|
|
199
199
|
Object.entries(result.data).forEach(([key, val]) => typeof val === 'boolean' && val && meta.push(`${key}=true`));
|
|
200
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
201
200
|
if (result.data.buttons) {
|
|
202
201
|
meta.push(`buttons=${result.data.buttons.join(',')}`);
|
|
203
202
|
meta.push(`type=${appType}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codefile-mdx.server.js","sourceRoot":"","sources":["../../src/codefile-mdx.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,GAAG,MAAM,SAAS,CAAA;AAMzB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAgB,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAaxB,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAU,CAAA;AAkBhE,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AAErD,MAAM,OAAO,GAAG,kCAAkC,CAAA;AAElD,MAAM,kBAAkB,GAAG,CAAC,KAAyB,EAAE,EAAE,CACxD,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAEnC,MAAM,cAAc,GAAG,CAAC,KAAyB,EAAE,EAAE,CACpD,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;IAC7B,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACjD,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,KAAK,CAAqB,CAAA;AACjD,CAAC,CAAC,CAAA;AAEH,MAAM,cAAc,GAAG,CACtB,KAAiB,EACjB,GAAoB,EACpB,KAAa,EACZ,EAAE;IACH,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAM;IAC3C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,QAAQ,CAAC;YACZ,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;YAC3B,OAAO,EAAE,+BAA+B,KAAK,EAAE;SAC/C,CAAC,CAAA;IACH,CAAC;AACF,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,KAAiB,EAAE,EAAE,CAC5C,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;IACnB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC,CAAC,IAAI,CAAA;AAER,MAAM,sBAAsB,GAAG,CAAC,KAAiB,EAAE,EAAE;IACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACtC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;AACxE,CAAC,CAAA;AAED,IAAI,gBAAgB,GAAmB,IAAI,GAAG,EAAE,CAAA;AAChD,KAAK,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,OAAO,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IACD,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC7D,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACvC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;QAC3C,OAAO,WAAW,CAAA;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CACX,oEAAoE,QAAQ,IAAI,CAChF,CAAA;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,KAAoB,EAAE,MAAc;IAChE,IAAI,UAAsB,CAAA;IAC1B,IAAI,UAAU,GAAG,CAAC,CAAA;IAElB,MAAM,aAAa,GAAG,CAAC;SACrB,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACpB,QAAQ,EAAE;SACV,MAAM,CACN,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EACnD,gEAAgE,CAChE;SACA,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IAE1C,MAAM,WAAW,GAAG,CAAC;SACnB,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,MAAM,CAAC,kBAAkB,EAAE,sBAAsB,CAAC;SAClD,SAAS,CAAC,cAAc,CAAC;SACzB,WAAW,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;SAC/D,MAAM,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAA;IAE3D,MAAM,WAAW,GAAG,CAAC;SACnB,MAAM,CAAC;QACP,IAAI,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACxC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAA;YAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,GAAG,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;oBAC3B,OAAO,EAAE,qBAAqB;oBAC9B,KAAK,EAAE,IAAI;iBACX,CAAC,CAAA;gBACF,OAAO,CAAC,CAAC,KAAK,CAAA;YACf,CAAC;YACD,UAAU,GAAG,OAAO,CAAC,MAAM,CAAA;YAC3B,mEAAmE;YACnE,OAAO;gBACN,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBAC5B,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;gBACxB,OAAO;aACP,CAAA;QACF,CAAC,CAAC;QACH,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YACjC,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;YAC7C,wCAAwC;YACxC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;YACxC,OAAO,OAAO,CAAA;QACf,CAAC,EAAE,yBAAyB,CAAC;QAC7B,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;YACzC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7D,OAAO,CAAC,CAAC,KAAK,CAAA;YACf,CAAC;YACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CACzC,UAAU,EAAE,IAAI,CACf,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CACpD,CACD,CAAA;QACF,CAAC,EAAE,8CAA8C,CAAC;aAChD,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,SAA0B,CAAC;aACjD,QAAQ,EAAE;QACZ,QAAQ,EAAE,aAAa;QACvB,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aACtE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;YAC3D,OAAO,EAAE,8BAA8B,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;SAC5D,CAAC;KACH,CAAC;SACD,MAAM,EAAE,CAAA;IAEV,OAAO,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;AACzC,CAAC;AAED,KAAK,UAAU,uBAAuB,CACrC,IAAuB,EACvB,MAAgB,EAChB,OAAe,EACf,OAAe;IAEf,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAA;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAA;IAEvC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;QAC5B,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;YAChD,MAAM,OAAO,GAAG,UAAU,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACpE,IAAI,OAAO,EAAE,CAAC;gBACb,OAAO;qBACU,QAAQ,UAAU,SAAS;EAC9C,OAAO;OACF,CAAC,IAAI,EAAE,CAAA;YACX,CAAC;QACF,CAAC;QACD,OAAO,EAAE,CAAA;IACV,CAAC,CAAA;IAED,MAAM,SAAS,GAAG;8CAC2B,QAAQ,WAAW,SAAS,WAAW,OAAO;;;MAGtF,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;EACvD,MAAM,SAAS,EAAE;;wBAEK,CAAA;IAEvB,OAAO,UAAU,CAAC,SAAS,CAAC,CAAA;AAC7B,CAAC;AAED,wDAAwD;AACxD,SAAS,WAAW,CAAC,MAAc;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC5E,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QAClB,OAAO,MAAM,CAAA;IACd,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,MAAM,GAAG,EAAE,IAAI,CAAC,CAAA;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AACjC,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC9B,MAAM,SAAS,GAAG,eAAe,EAAE,CAAA;IACnC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACpE,cAAc,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACtC,OAAO,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAkB;IAChD,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAA;IAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;IAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC1C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC7B,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,OAAO,CAAA,CAAC,kBAAkB;IAE9B,KAAK,UAAU,mBAAmB,CAAC,EAClC,IAAI,EACJ,MAAM,GACI;QACV,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACX,+DAA+D,CAC/D,CAAA;YACD,OAAM;QACP,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC3C,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CACX,2EAA2E,CAC3E,CAAA;YACD,OAAM;QACP,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,UAA+B,CAAA;QACvD,MAAM,KAAK,GAAkB,EAAE,CAAA;QAC/B,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;QACpB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACjD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAC5D,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAChE,CAAA;YACD,MAAM,YAAY,GAAG,MAAM,uBAAuB,CACjD,IAAI,EACJ,MAAM,EACN,OAAO,EACP,OAAO,CACP,CAAA;YACD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,YAAY,CAAC,CAAA;YAEjD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,eAAe,EAAE;gBACvC,KAAK,EAAE,IAAI;gBACX,IAAI,EAAE,KAAK,CAAC,IAAc;gBAC1B,IAAI,EAAE,EAAE;gBACR,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;aACpC,CAAC,CAAA;YACF,OAAM;QACP,CAAC;QAED,MAAM,EACL,IAAI,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACrC,SAAS,EACT,KAAK,GACL,GAAG,MAAM,CAAC,IAAI,CAAA;QACf,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;QACpD,MAAM,IAAI,GAAG,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAA;QAErC,wBAAwB;QACxB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAClC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CACd,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,CAC5D,CAAA;QAED,uEAAuE;QACvE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACrD,IAAI,CAAC,IAAI,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAA;YAC5B,IAAI,CAAC,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAA;YACjC,iEAAiE;YACjE,sCAAsC;YACtC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC7B,CAAC;QAED,IAAI,SAAS,EAAE,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,SAAS,SAAS,EAAE,CAAC,CAAA;QAChC,CAAC;QAED,MAAM,YAAY,GAAG,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QAClE,MAAM,aAAa,GAAG,EAAE,CAAA;QACxB,MAAM,QAAQ,GAAG,EAAE,CAAA;QACnB,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,YAAY,EAAE,CAAC;YACzC,MAAM,YAAY,GAAG,WAAW,CAC/B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACpD,CAAA;YACD,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAChC,MAAM,SAAS,GAAG;QACb,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACzD,YAAY;OACP,CAAA;YACJ,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAA;QACxC,CAAC;QAED;;;;;WAKG;QACH,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;QACzD,MAAM,WAAW,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAChD,MAAM,OAAO,GAAiB;YAC7B,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,WAAW;SACjB,CAAA;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAE5D,IACC,UAAU;YACV,yEAAyE;YACzE,gEAAgE;YAChE,CAAC,CAAC,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,KAAK,WAAW,CAAC;gBAC1D,CAAC,CAAC,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,EACzD,CAAC;YACF,iDAAiD;YACjD,OAAO,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,IAAI,CAAA;YACvD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,CAAA;YAChD,OAAO,CAAC,IAAI,GAAG,SAAS,CAAA;YACxB,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;YACxC,MAAM,OAAO,GAAG;gDAC6B,WAAW,WAAW,SAAS,WAAW,OAAO;iBAChF,IAAI,CAAC,aAAa,kBAAkB,WAAW;;;gBAGhD,QAAQ;;wBAEA,CAAA;YACrB,QAAQ,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;QACzC,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAE5C,gDAAgD;QAChD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,KAAK,UAAU,mBAAmB,CAAC,IAAe;QACxD,MAAM,SAAS,GAAe,EAAE,CAAA;QAChC,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,UAAU,EAAW,CAAA;QACvE,KAAK,CAA2B,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACvE,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QACjC,CAAC,CAAuC,CAAC,CAAA;QAEzC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,mBAAmB,CAAC,KAAK,CAAC,CAAA;QACjC,CAAC;QAED,UAAU;QACV,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAA;IAC7B,CAAC,CAAA;AACF,CAAC","sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport { createProcessor } from '@mdx-js/mdx'\nimport md5 from 'md5-hex'\nimport { type RootContent, type Root as MdastRoot, type Parent } from 'mdast'\nimport {\n\ttype MdxJsxAttribute,\n\ttype MdxJsxFlowElement,\n} from 'mdast-util-mdx-jsx'\nimport { removePosition } from 'unist-util-remove-position'\nimport { type Visitor, visit } from 'unist-util-visit'\nimport * as z from 'zod'\n\ntype CodeFile = {\n\tnode: MdxJsxFlowElement\n\tparent: Parent | null | undefined\n}\n\ntype RangeArray = [number, number][] | undefined\n\ntype CodeFileProps = Record<string, unknown>\n\ntype PathContentMap = Map<string, string[]>\n\nconst APP_TYPES = ['problem', 'solution', 'playground'] as const\ntype AppTypes = typeof APP_TYPES\n\nexport type EmbeddedFile = {\n\terror?: boolean\n\tfile: string\n\thash: string\n\tline?: number\n\twarning?: string\n}\n\nexport type CodeFileData = {\n\tmdxFile: string\n\tcacheLocation: string\n\tcachedEmbeddedFiles: Map<string, EmbeddedFile>\n\tembeddedFiles: Map<string, EmbeddedFile>\n}\n\nconst safePath = (s: string) => s.replace(/\\\\/g, '/')\n\nconst REG_EXP = /^(?:\\d+(?:-\\d+)?,)*\\d+(?:-\\d+)?$/\n\nconst isValidRangeFormat = (value: string | undefined) =>\n\tvalue ? REG_EXP.test(value) : true\n\nconst transformRange = (value: string | undefined) =>\n\tvalue?.split(',').map(range => {\n\t\tconst [start, end] = range.split('-').map(Number)\n\t\treturn [start, end ?? start] as [number, number]\n\t})\n\nconst isRangeBounded = (\n\trange: RangeArray,\n\tctx: z.RefinementCtx,\n\tlines: number,\n) => {\n\tif (!lines || !Array.isArray(range)) return\n\tif (range.flat().some(r => r < 1 || r > lines)) {\n\t\tctx.addIssue({\n\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\tmessage: `Range must be between 1 and ${lines}`,\n\t\t})\n\t}\n}\n\nconst isRangeInOrder = (range: RangeArray) =>\n\tArray.isArray(range)\n\t\t? range.every(([a, b]) => !isNaN(Number(a)) && !isNaN(Number(b)) && b >= a)\n\t\t: true\n\nconst isRangesNonOverlapping = (range: RangeArray) => {\n\tif (!Array.isArray(range)) return true\n\treturn range.every(([a], i) => i === 0 || (range[i - 1]?.[1] ?? 0) < a)\n}\n\nlet fileContentCache: PathContentMap = new Map()\nasync function getFileContent(filePath: string) {\n\tif (fileContentCache.has(filePath)) {\n\t\treturn fileContentCache.get(filePath)\n\t}\n\ttry {\n\t\tconst content = await fs.promises.readFile(filePath, 'utf-8')\n\t\tconst fileContent = content.split('\\n')\n\t\tfileContentCache.set(filePath, fileContent)\n\t\treturn fileContent\n\t} catch (error) {\n\t\tconsole.warn(\n\t\t\t`@epic-web/workshop-app - invalid CodeFile.\\nCould not read file: ${filePath}\\n`,\n\t\t)\n\t}\n}\n\nasync function validateProps(props: CodeFileProps, appDir: string) {\n\tlet validRange: RangeArray\n\tlet linesCount = 0\n\n\tconst BooleanSchema = z\n\t\t.nullable(z.string())\n\t\t.optional()\n\t\t.refine(\n\t\t\tv => ['true', 'false', null, undefined].includes(v),\n\t\t\t'optional boolean key can be \"true\", \"false\", null or undefined',\n\t\t)\n\t\t.transform(v => v === null || Boolean(v))\n\n\tconst RangeSchema = z\n\t\t.string()\n\t\t.optional()\n\t\t.refine(isValidRangeFormat, 'Invalid range format')\n\t\t.transform(transformRange)\n\t\t.superRefine((val, ctx) => isRangeBounded(val, ctx, linesCount))\n\t\t.refine(isRangeInOrder, 'Range must be in order low-high')\n\n\tconst inputSchema = z\n\t\t.object({\n\t\t\tfile: z\n\t\t\t\t.string()\n\t\t\t\t.nonempty()\n\t\t\t\t.transform(async (file, ctx) => {\n\t\t\t\t\tconst fullPath = path.join(appDir, file)\n\t\t\t\t\tconst content = await getFileContent(fullPath)\n\t\t\t\t\tif (!content) {\n\t\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\t\t\t\t\tmessage: `Could not read file`,\n\t\t\t\t\t\t\tfatal: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn z.NEVER\n\t\t\t\t\t}\n\t\t\t\t\tlinesCount = content.length\n\t\t\t\t\t// @mdx-js/mdx parser can NOT handle relative path with backslashes\n\t\t\t\t\treturn {\n\t\t\t\t\t\tfullPath: safePath(fullPath),\n\t\t\t\t\t\tfilePath: safePath(file),\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\trange: RangeSchema.refine(range => {\n\t\t\t\tconst isValid = isRangesNonOverlapping(range)\n\t\t\t\t// we use this value in highlight refine\n\t\t\t\tvalidRange = isValid ? range : undefined\n\t\t\t\treturn isValid\n\t\t\t}, 'Ranges must not overlap'),\n\t\t\thighlight: RangeSchema.refine(highlight => {\n\t\t\t\tif (!Array.isArray(highlight) || !Array.isArray(validRange)) {\n\t\t\t\t\treturn z.NEVER\n\t\t\t\t}\n\t\t\t\treturn highlight.every(([hStart, hEnd]) =>\n\t\t\t\t\tvalidRange?.some(\n\t\t\t\t\t\t([rStart, rEnd]) => hStart >= rStart && hEnd <= rEnd,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}, 'Highlight range must be within defined range')\n\t\t\t\t.transform(() => props.highlight as Array<string>)\n\t\t\t\t.optional(),\n\t\t\tnonumber: BooleanSchema,\n\t\t\tnocopy: BooleanSchema,\n\t\t\tbuttons: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.transform(str => (str ? (str.split(',') as unknown as AppTypes) : []))\n\t\t\t\t.refine(arr => arr.every(item => APP_TYPES.includes(item)), {\n\t\t\t\t\tmessage: `Buttons can only be any of ${APP_TYPES.join(',')}`,\n\t\t\t\t}),\n\t\t})\n\t\t.strict()\n\n\treturn inputSchema.safeParseAsync(props)\n}\n\nasync function createErrorNotification(\n\tnode: MdxJsxFlowElement,\n\terrors: string[],\n\tmdxFile: string,\n\tappType: string,\n) {\n\tconst filename = path.basename(mdxFile)\n\tconst startLine = node.position?.start.line\n\tconst endLine = node.position?.end.line\n\n\tconst codeFence = async () => {\n\t\tif (startLine && endLine) {\n\t\t\tconst contentStr = await getFileContent(mdxFile)\n\t\t\tconst content = contentStr?.slice(startLine - 1, endLine).join('\\n')\n\t\t\tif (content) {\n\t\t\t\treturn `\n\\`\\`\\`tsx filename=${filename} start=${startLine} nocopy\n${content}\n\\`\\`\\``.trim()\n\t\t\t}\n\t\t}\n\t\treturn ''\n\t}\n\n\tconst mdxSource = `\n<CodeFileNotification variant=\"error\" file=\"${filename}\" line=\"${startLine}\" type=\"${appType}\">\n <callout-danger class=\"notification\">\n <div className=\"title\">CodeFile Error: invalid input</div>\n ${errors.map(error => `<div>${error}</div>`).join('')}\n${await codeFence()}\n </callout-danger>\n</CodeFileNotification>`\n\n\treturn mdxToMdast(mdxSource)\n}\n\n// based on https://github.com/sindresorhus/strip-indent\nfunction stripIndent(string: string) {\n\tconst match = string.match(/^[ \\t]*(?=\\S)/gm)\n\tconst indent = match?.reduce((r, a) => Math.min(r, a.length), Infinity) ?? 0\n\tif (indent === 0) {\n\t\treturn string\n\t}\n\tconst regex = new RegExp(`^[ \\\\t]{${indent}}`, 'gm')\n\treturn string.replace(regex, '')\n}\n\nfunction mdxToMdast(mdx: string) {\n\tconst processor = createProcessor()\n\tconst mdast = processor.parse(mdx.trim()) as MdastRoot | RootContent\n\tremovePosition(mdast, { force: true })\n\treturn mdast.type === 'root' ? mdast.children : [mdast]\n}\n\nexport function remarkCodeFile(data: CodeFileData) {\n\tfileContentCache = new Map()\n\tconst mdxFile = data.mdxFile\n\tconst appDir = path.dirname(mdxFile)\n\tconst appType = mdxFile.includes('problem')\n\t\t? 'problem'\n\t\t: mdxFile.includes('solution')\n\t\t\t? 'solution'\n\t\t\t: 'other' // not in exercise\n\n\tasync function replaceCodeFileNode({\n\t\tnode,\n\t\tparent,\n\t}: CodeFile): Promise<void> {\n\t\tif (!parent) {\n\t\t\tconsole.warn(\n\t\t\t\t'Unexpected error: replaceCodeFileNode called without a Parent',\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tconst index = parent.children.indexOf(node)\n\t\tif (index === -1) {\n\t\t\tconsole.warn(\n\t\t\t\t'Unexpected error: replaceCodeFileNode could not find node index in Parent',\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tconst attributes = node.attributes as MdxJsxAttribute[]\n\t\tconst props: CodeFileProps = {}\n\t\tfor (const { name, value } of attributes) {\n\t\t\tprops[name] = value\n\t\t}\n\n\t\tconst result = await validateProps(props, appDir)\n\t\tif (!result.success) {\n\t\t\tconst errors = result.error.issues.map(({ message, path }) =>\n\t\t\t\tpath[0] ? `${message}: ${path[0]}=\"${props[path[0]]}\"` : message,\n\t\t\t)\n\t\t\tconst notification = await createErrorNotification(\n\t\t\t\tnode,\n\t\t\t\terrors,\n\t\t\t\tmdxFile,\n\t\t\t\tappType,\n\t\t\t)\n\t\t\tparent.children.splice(index, 1, ...notification)\n\n\t\t\tdata.embeddedFiles.set('invalid input', {\n\t\t\t\terror: true,\n\t\t\t\tfile: props.file as string,\n\t\t\t\thash: '',\n\t\t\t\tline: node.position?.start.line ?? 1,\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tconst {\n\t\t\tfile: { content, filePath, fullPath },\n\t\t\thighlight,\n\t\t\trange,\n\t\t} = result.data\n\t\tconst language = path.extname(filePath).substring(1)\n\t\tconst meta = [`filename=${filePath}`]\n\n\t\t// nonumbers nocopy ....\n\t\tObject.entries(result.data).forEach(\n\t\t\t([key, val]) =>\n\t\t\t\ttypeof val === 'boolean' && val && meta.push(`${key}=true`),\n\t\t)\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\tif (result.data.buttons) {\n\t\t\tmeta.push(`buttons=${result.data.buttons.join(',')}`)\n\t\t\tmeta.push(`type=${appType}`)\n\t\t\tmeta.push(`fullpath=${fullPath}`)\n\t\t\t// Avoid the headache of finding the separator on the client side\n\t\t\t// path.sep is always / on client side\n\t\t\tmeta.push(`sep=${path.sep}`)\n\t\t}\n\n\t\tif (highlight?.length) {\n\t\t\tmeta.push(`lines=${highlight}`)\n\t\t}\n\n\t\tconst fileSections = range?.length ? range : [[1, content.length]]\n\t\tconst rangesContent = []\n\t\tconst preNodes = []\n\t\tfor (const [start, end] of fileSections) {\n\t\t\tconst rangeContent = stripIndent(\n\t\t\t\tcontent.slice(start ? start - 1 : 0, end).join('\\n'),\n\t\t\t)\n\t\t\trangesContent.push(rangeContent)\n\t\t\tconst mdxSource = `\n\\`\\`\\`${language} ${meta.concat(`start=${start}`).join(' ')}\n${rangeContent}\n\\`\\`\\``\n\t\t\tpreNodes.push(...mdxToMdast(mdxSource))\n\t\t}\n\n\t\t/**\n\t\t * Show a warning above the file content if the range we show changed in the\n\t\t * embedded file and the range in <CodeFile range=\"a-b\"> did not change.\n\t\t * The warning will be removed automatically after the <CodeFile> range changes\n\t\t * or by canceling it from the UI.\n\t\t */\n\t\tconst embeddedKey = md5(fullPath + JSON.stringify(range))\n\t\tconst contentHash = md5(rangesContent.join(','))\n\t\tconst newData: EmbeddedFile = {\n\t\t\tfile: fullPath,\n\t\t\thash: contentHash,\n\t\t}\n\t\tconst cachedData = data.cachedEmbeddedFiles.get(embeddedKey)\n\n\t\tif (\n\t\t\tcachedData &&\n\t\t\t// If a warning existed previously and its hash matched the current hash,\n\t\t\t// then the changes were reverted and the warning will be remove\n\t\t\t((cachedData.warning && cachedData.warning !== contentHash) ??\n\t\t\t\t(!cachedData.warning && cachedData.hash !== contentHash))\n\t\t) {\n\t\t\t// keep previously saved warning or previous hash\n\t\t\tnewData.warning = cachedData.warning ?? cachedData.hash\n\t\t\tconst startLine = node.position?.start.line ?? 1\n\t\t\tnewData.line = startLine\n\t\t\tconst mdxFilename = path.basename(mdxFile)\n\t\t\tconst filename = path.basename(filePath)\n\t\t\tconst warning = `\n<CodeFileNotification variant=\"warning\" file=\"${mdxFilename}\" line=\"${startLine}\" type=\"${appType}\"\ncacheLocation=\"${data.cacheLocation}\" embeddedKey=\"${embeddedKey}\">\n <callout-warning class=\"notification\">\n <div className=\"title\">CodeFile Warning:</div>\n <div>file ${filename} content was changed, review 'range' and 'highlight' inputs</div>\n </callout-warning>\n</CodeFileNotification>`\n\t\t\tpreNodes.unshift(...mdxToMdast(warning))\n\t\t}\n\t\tdata.embeddedFiles.set(embeddedKey, newData)\n\n\t\t// replace <CodeFile> with embedded file content\n\t\tparent.children.splice(index, 1, ...preNodes)\n\t}\n\n\treturn async function codeFileTransformer(tree: MdastRoot) {\n\t\tconst codeFiles: CodeFile[] = []\n\t\tconst filter = { type: 'mdxJsxFlowElement', name: 'CodeFile' } as const\n\t\tvisit<MdastRoot, typeof filter>(tree, filter, ((node, _index, parent) => {\n\t\t\tcodeFiles.push({ node, parent })\n\t\t}) as Visitor<MdxJsxFlowElement, Parent>)\n\n\t\tfor (const props of codeFiles) {\n\t\t\tawait replaceCodeFileNode(props)\n\t\t}\n\n\t\t// cleanup\n\t\tfileContentCache = new Map()\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"codefile-mdx.server.js","sourceRoot":"","sources":["../../src/codefile-mdx.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,GAAG,MAAM,SAAS,CAAA;AAMzB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,KAAK,EAAgB,MAAM,kBAAkB,CAAA;AACtD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAaxB,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAU,CAAA;AAkBhE,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AAErD,MAAM,OAAO,GAAG,kCAAkC,CAAA;AAElD,MAAM,kBAAkB,GAAG,CAAC,KAAyB,EAAE,EAAE,CACxD,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAEnC,MAAM,cAAc,GAAG,CAAC,KAAyB,EAAE,EAAE,CACpD,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;IAC/B,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACjD,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,KAAK,CAAqB,CAAA;AACjD,CAAC,CAAC,CAAA;AAEH,MAAM,cAAc,GAAG,CACtB,KAAiB,EACjB,GAAoB,EACpB,KAAa,EACZ,EAAE;IACH,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAM;IAC3C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;QAClD,GAAG,CAAC,QAAQ,CAAC;YACZ,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;YAC3B,OAAO,EAAE,+BAA+B,KAAK,EAAE;SAC/C,CAAC,CAAA;IACH,CAAC;AACF,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,KAAiB,EAAE,EAAE,CAC5C,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;IACnB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC,CAAC,IAAI,CAAA;AAER,MAAM,sBAAsB,GAAG,CAAC,KAAiB,EAAE,EAAE;IACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACtC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;AACxE,CAAC,CAAA;AAED,IAAI,gBAAgB,GAAmB,IAAI,GAAG,EAAE,CAAA;AAChD,KAAK,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,OAAO,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACtC,CAAC;IACD,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC7D,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACvC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;QAC3C,OAAO,WAAW,CAAA;IACnB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,CAAC,IAAI,CACX,oEAAoE,QAAQ,IAAI,CAChF,CAAA;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,KAAoB,EAAE,MAAc;IAChE,IAAI,UAAsB,CAAA;IAC1B,IAAI,UAAU,GAAG,CAAC,CAAA;IAElB,MAAM,aAAa,GAAG,CAAC;SACrB,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACpB,QAAQ,EAAE;SACV,MAAM,CACN,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EACrD,gEAAgE,CAChE;SACA,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IAE5C,MAAM,WAAW,GAAG,CAAC;SACnB,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,MAAM,CAAC,kBAAkB,EAAE,sBAAsB,CAAC;SAClD,SAAS,CAAC,cAAc,CAAC;SACzB,WAAW,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;SAC/D,MAAM,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAA;IAE3D,MAAM,WAAW,GAAG,CAAC;SACnB,MAAM,CAAC;QACP,IAAI,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACxC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAA;YAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,GAAG,CAAC,QAAQ,CAAC;oBACZ,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;oBAC3B,OAAO,EAAE,qBAAqB;oBAC9B,KAAK,EAAE,IAAI;iBACX,CAAC,CAAA;gBACF,OAAO,CAAC,CAAC,KAAK,CAAA;YACf,CAAC;YACD,UAAU,GAAG,OAAO,CAAC,MAAM,CAAA;YAC3B,mEAAmE;YACnE,OAAO;gBACN,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBAC5B,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;gBACxB,OAAO;aACP,CAAA;QACF,CAAC,CAAC;QACH,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACnC,MAAM,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;YAC7C,wCAAwC;YACxC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;YACxC,OAAO,OAAO,CAAA;QACf,CAAC,EAAE,yBAAyB,CAAC;QAC7B,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;YAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7D,OAAO,CAAC,CAAC,KAAK,CAAA;YACf,CAAC;YACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CACzC,UAAU,EAAE,IAAI,CACf,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,CACpD,CACD,CAAA;QACF,CAAC,EAAE,8CAA8C,CAAC;aAChD,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,SAA0B,CAAC;aACjD,QAAQ,EAAE;QACZ,QAAQ,EAAE,aAAa;QACvB,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAClB,GAAG,CAAC,CAAC,CAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC,CAAC,CAAC,EAAE,CAClD;aACA,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;YAC/D,OAAO,EAAE,8BAA8B,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;SAC5D,CAAC;KACH,CAAC;SACD,MAAM,EAAE,CAAA;IAEV,OAAO,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;AACzC,CAAC;AAED,KAAK,UAAU,uBAAuB,CACrC,IAAuB,EACvB,MAAgB,EAChB,OAAe,EACf,OAAe;IAEf,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAA;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAA;IAEvC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;QAC5B,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;YAChD,MAAM,OAAO,GAAG,UAAU,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACpE,IAAI,OAAO,EAAE,CAAC;gBACb,OAAO;qBACU,QAAQ,UAAU,SAAS;EAC9C,OAAO;OACF,CAAC,IAAI,EAAE,CAAA;YACX,CAAC;QACF,CAAC;QACD,OAAO,EAAE,CAAA;IACV,CAAC,CAAA;IAED,MAAM,SAAS,GAAG;8CAC2B,QAAQ,WAAW,SAAS,WAAW,OAAO;;;MAGtF,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;EACzD,MAAM,SAAS,EAAE;;wBAEK,CAAA;IAEvB,OAAO,UAAU,CAAC,SAAS,CAAC,CAAA;AAC7B,CAAC;AAED,wDAAwD;AACxD,SAAS,WAAW,CAAC,MAAc;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC5E,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QAClB,OAAO,MAAM,CAAA;IACd,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,MAAM,GAAG,EAAE,IAAI,CAAC,CAAA;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AACjC,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC9B,MAAM,SAAS,GAAG,eAAe,EAAE,CAAA;IACnC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACpE,cAAc,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACtC,OAAO,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAkB;IAChD,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAA;IAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;IAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC1C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC7B,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,OAAO,CAAA,CAAC,kBAAkB;IAE9B,KAAK,UAAU,mBAAmB,CAAC,EAClC,IAAI,EACJ,MAAM,GACI;QACV,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACX,+DAA+D,CAC/D,CAAA;YACD,OAAM;QACP,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC3C,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CACX,2EAA2E,CAC3E,CAAA;YACD,OAAM;QACP,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,UAA+B,CAAA;QACvD,MAAM,KAAK,GAAkB,EAAE,CAAA;QAC/B,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;QACpB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACjD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAC5D,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAChE,CAAA;YACD,MAAM,YAAY,GAAG,MAAM,uBAAuB,CACjD,IAAI,EACJ,MAAM,EACN,OAAO,EACP,OAAO,CACP,CAAA;YACD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,YAAY,CAAC,CAAA;YAEjD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,eAAe,EAAE;gBACvC,KAAK,EAAE,IAAI;gBACX,IAAI,EAAE,KAAK,CAAC,IAAc;gBAC1B,IAAI,EAAE,EAAE;gBACR,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;aACpC,CAAC,CAAA;YACF,OAAM;QACP,CAAC;QAED,MAAM,EACL,IAAI,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EACrC,SAAS,EACT,KAAK,GACL,GAAG,MAAM,CAAC,IAAI,CAAA;QACf,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;QACpD,MAAM,IAAI,GAAG,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAA;QAErC,wBAAwB;QACxB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAClC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CACd,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,CAC5D,CAAA;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACrD,IAAI,CAAC,IAAI,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAA;YAC5B,IAAI,CAAC,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAA;YACjC,iEAAiE;YACjE,sCAAsC;YACtC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC7B,CAAC;QAED,IAAI,SAAS,EAAE,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,SAAS,SAAS,EAAE,CAAC,CAAA;QAChC,CAAC;QAED,MAAM,YAAY,GAAG,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QAClE,MAAM,aAAa,GAAG,EAAE,CAAA;QACxB,MAAM,QAAQ,GAAG,EAAE,CAAA;QACnB,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,YAAY,EAAE,CAAC;YACzC,MAAM,YAAY,GAAG,WAAW,CAC/B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACpD,CAAA;YACD,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAChC,MAAM,SAAS,GAAG;QACb,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACzD,YAAY;OACP,CAAA;YACJ,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAA;QACxC,CAAC;QAED;;;;;WAKG;QACH,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;QACzD,MAAM,WAAW,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAChD,MAAM,OAAO,GAAiB;YAC7B,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,WAAW;SACjB,CAAA;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAE5D,IACC,UAAU;YACV,yEAAyE;YACzE,gEAAgE;YAChE,CAAC,CAAC,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,KAAK,WAAW,CAAC;gBAC1D,CAAC,CAAC,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,EACzD,CAAC;YACF,iDAAiD;YACjD,OAAO,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,IAAI,CAAA;YACvD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,CAAA;YAChD,OAAO,CAAC,IAAI,GAAG,SAAS,CAAA;YACxB,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;YACxC,MAAM,OAAO,GAAG;gDAC6B,WAAW,WAAW,SAAS,WAAW,OAAO;iBAChF,IAAI,CAAC,aAAa,kBAAkB,WAAW;;;gBAGhD,QAAQ;;wBAEA,CAAA;YACrB,QAAQ,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;QACzC,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAE5C,gDAAgD;QAChD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,KAAK,UAAU,mBAAmB,CAAC,IAAe;QACxD,MAAM,SAAS,GAAe,EAAE,CAAA;QAChC,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,UAAU,EAAW,CAAA;QACvE,KAAK,CAA2B,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACvE,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QACjC,CAAC,CAAuC,CAAC,CAAA;QAEzC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,mBAAmB,CAAC,KAAK,CAAC,CAAA;QACjC,CAAC;QAED,UAAU;QACV,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAA;IAC7B,CAAC,CAAA;AACF,CAAC","sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport { createProcessor } from '@mdx-js/mdx'\nimport md5 from 'md5-hex'\nimport { type Root as MdastRoot, type Parent, type RootContent } from 'mdast'\nimport {\n\ttype MdxJsxAttribute,\n\ttype MdxJsxFlowElement,\n} from 'mdast-util-mdx-jsx'\nimport { removePosition } from 'unist-util-remove-position'\nimport { visit, type Visitor } from 'unist-util-visit'\nimport * as z from 'zod'\n\ntype CodeFile = {\n\tnode: MdxJsxFlowElement\n\tparent: Parent | null | undefined\n}\n\ntype RangeArray = [number, number][] | undefined\n\ntype CodeFileProps = Record<string, unknown>\n\ntype PathContentMap = Map<string, string[]>\n\nconst APP_TYPES = ['problem', 'solution', 'playground'] as const\ntype AppTypes = typeof APP_TYPES\n\nexport type EmbeddedFile = {\n\terror?: boolean\n\tfile: string\n\thash: string\n\tline?: number\n\twarning?: string\n}\n\nexport type CodeFileData = {\n\tmdxFile: string\n\tcacheLocation: string\n\tcachedEmbeddedFiles: Map<string, EmbeddedFile>\n\tembeddedFiles: Map<string, EmbeddedFile>\n}\n\nconst safePath = (s: string) => s.replace(/\\\\/g, '/')\n\nconst REG_EXP = /^(?:\\d+(?:-\\d+)?,)*\\d+(?:-\\d+)?$/\n\nconst isValidRangeFormat = (value: string | undefined) =>\n\tvalue ? REG_EXP.test(value) : true\n\nconst transformRange = (value: string | undefined) =>\n\tvalue?.split(',').map((range) => {\n\t\tconst [start, end] = range.split('-').map(Number)\n\t\treturn [start, end ?? start] as [number, number]\n\t})\n\nconst isRangeBounded = (\n\trange: RangeArray,\n\tctx: z.RefinementCtx,\n\tlines: number,\n) => {\n\tif (!lines || !Array.isArray(range)) return\n\tif (range.flat().some((r) => r < 1 || r > lines)) {\n\t\tctx.addIssue({\n\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\tmessage: `Range must be between 1 and ${lines}`,\n\t\t})\n\t}\n}\n\nconst isRangeInOrder = (range: RangeArray) =>\n\tArray.isArray(range)\n\t\t? range.every(([a, b]) => !isNaN(Number(a)) && !isNaN(Number(b)) && b >= a)\n\t\t: true\n\nconst isRangesNonOverlapping = (range: RangeArray) => {\n\tif (!Array.isArray(range)) return true\n\treturn range.every(([a], i) => i === 0 || (range[i - 1]?.[1] ?? 0) < a)\n}\n\nlet fileContentCache: PathContentMap = new Map()\nasync function getFileContent(filePath: string) {\n\tif (fileContentCache.has(filePath)) {\n\t\treturn fileContentCache.get(filePath)\n\t}\n\ttry {\n\t\tconst content = await fs.promises.readFile(filePath, 'utf-8')\n\t\tconst fileContent = content.split('\\n')\n\t\tfileContentCache.set(filePath, fileContent)\n\t\treturn fileContent\n\t} catch {\n\t\tconsole.warn(\n\t\t\t`@epic-web/workshop-app - invalid CodeFile.\\nCould not read file: ${filePath}\\n`,\n\t\t)\n\t}\n}\n\nasync function validateProps(props: CodeFileProps, appDir: string) {\n\tlet validRange: RangeArray\n\tlet linesCount = 0\n\n\tconst BooleanSchema = z\n\t\t.nullable(z.string())\n\t\t.optional()\n\t\t.refine(\n\t\t\t(v) => ['true', 'false', null, undefined].includes(v),\n\t\t\t'optional boolean key can be \"true\", \"false\", null or undefined',\n\t\t)\n\t\t.transform((v) => v === null || Boolean(v))\n\n\tconst RangeSchema = z\n\t\t.string()\n\t\t.optional()\n\t\t.refine(isValidRangeFormat, 'Invalid range format')\n\t\t.transform(transformRange)\n\t\t.superRefine((val, ctx) => isRangeBounded(val, ctx, linesCount))\n\t\t.refine(isRangeInOrder, 'Range must be in order low-high')\n\n\tconst inputSchema = z\n\t\t.object({\n\t\t\tfile: z\n\t\t\t\t.string()\n\t\t\t\t.nonempty()\n\t\t\t\t.transform(async (file, ctx) => {\n\t\t\t\t\tconst fullPath = path.join(appDir, file)\n\t\t\t\t\tconst content = await getFileContent(fullPath)\n\t\t\t\t\tif (!content) {\n\t\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\t\t\t\t\tmessage: `Could not read file`,\n\t\t\t\t\t\t\tfatal: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t\treturn z.NEVER\n\t\t\t\t\t}\n\t\t\t\t\tlinesCount = content.length\n\t\t\t\t\t// @mdx-js/mdx parser can NOT handle relative path with backslashes\n\t\t\t\t\treturn {\n\t\t\t\t\t\tfullPath: safePath(fullPath),\n\t\t\t\t\t\tfilePath: safePath(file),\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\trange: RangeSchema.refine((range) => {\n\t\t\t\tconst isValid = isRangesNonOverlapping(range)\n\t\t\t\t// we use this value in highlight refine\n\t\t\t\tvalidRange = isValid ? range : undefined\n\t\t\t\treturn isValid\n\t\t\t}, 'Ranges must not overlap'),\n\t\t\thighlight: RangeSchema.refine((highlight) => {\n\t\t\t\tif (!Array.isArray(highlight) || !Array.isArray(validRange)) {\n\t\t\t\t\treturn z.NEVER\n\t\t\t\t}\n\t\t\t\treturn highlight.every(([hStart, hEnd]) =>\n\t\t\t\t\tvalidRange?.some(\n\t\t\t\t\t\t([rStart, rEnd]) => hStart >= rStart && hEnd <= rEnd,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}, 'Highlight range must be within defined range')\n\t\t\t\t.transform(() => props.highlight as Array<string>)\n\t\t\t\t.optional(),\n\t\t\tnonumber: BooleanSchema,\n\t\t\tnocopy: BooleanSchema,\n\t\t\tbuttons: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.transform((str) =>\n\t\t\t\t\tstr ? (str.split(',') as unknown as AppTypes) : [],\n\t\t\t\t)\n\t\t\t\t.refine((arr) => arr.every((item) => APP_TYPES.includes(item)), {\n\t\t\t\t\tmessage: `Buttons can only be any of ${APP_TYPES.join(',')}`,\n\t\t\t\t}),\n\t\t})\n\t\t.strict()\n\n\treturn inputSchema.safeParseAsync(props)\n}\n\nasync function createErrorNotification(\n\tnode: MdxJsxFlowElement,\n\terrors: string[],\n\tmdxFile: string,\n\tappType: string,\n) {\n\tconst filename = path.basename(mdxFile)\n\tconst startLine = node.position?.start.line\n\tconst endLine = node.position?.end.line\n\n\tconst codeFence = async () => {\n\t\tif (startLine && endLine) {\n\t\t\tconst contentStr = await getFileContent(mdxFile)\n\t\t\tconst content = contentStr?.slice(startLine - 1, endLine).join('\\n')\n\t\t\tif (content) {\n\t\t\t\treturn `\n\\`\\`\\`tsx filename=${filename} start=${startLine} nocopy\n${content}\n\\`\\`\\``.trim()\n\t\t\t}\n\t\t}\n\t\treturn ''\n\t}\n\n\tconst mdxSource = `\n<CodeFileNotification variant=\"error\" file=\"${filename}\" line=\"${startLine}\" type=\"${appType}\">\n <callout-danger class=\"notification\">\n <div className=\"title\">CodeFile Error: invalid input</div>\n ${errors.map((error) => `<div>${error}</div>`).join('')}\n${await codeFence()}\n </callout-danger>\n</CodeFileNotification>`\n\n\treturn mdxToMdast(mdxSource)\n}\n\n// based on https://github.com/sindresorhus/strip-indent\nfunction stripIndent(string: string) {\n\tconst match = string.match(/^[ \\t]*(?=\\S)/gm)\n\tconst indent = match?.reduce((r, a) => Math.min(r, a.length), Infinity) ?? 0\n\tif (indent === 0) {\n\t\treturn string\n\t}\n\tconst regex = new RegExp(`^[ \\\\t]{${indent}}`, 'gm')\n\treturn string.replace(regex, '')\n}\n\nfunction mdxToMdast(mdx: string) {\n\tconst processor = createProcessor()\n\tconst mdast = processor.parse(mdx.trim()) as MdastRoot | RootContent\n\tremovePosition(mdast, { force: true })\n\treturn mdast.type === 'root' ? mdast.children : [mdast]\n}\n\nexport function remarkCodeFile(data: CodeFileData) {\n\tfileContentCache = new Map()\n\tconst mdxFile = data.mdxFile\n\tconst appDir = path.dirname(mdxFile)\n\tconst appType = mdxFile.includes('problem')\n\t\t? 'problem'\n\t\t: mdxFile.includes('solution')\n\t\t\t? 'solution'\n\t\t\t: 'other' // not in exercise\n\n\tasync function replaceCodeFileNode({\n\t\tnode,\n\t\tparent,\n\t}: CodeFile): Promise<void> {\n\t\tif (!parent) {\n\t\t\tconsole.warn(\n\t\t\t\t'Unexpected error: replaceCodeFileNode called without a Parent',\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tconst index = parent.children.indexOf(node)\n\t\tif (index === -1) {\n\t\t\tconsole.warn(\n\t\t\t\t'Unexpected error: replaceCodeFileNode could not find node index in Parent',\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tconst attributes = node.attributes as MdxJsxAttribute[]\n\t\tconst props: CodeFileProps = {}\n\t\tfor (const { name, value } of attributes) {\n\t\t\tprops[name] = value\n\t\t}\n\n\t\tconst result = await validateProps(props, appDir)\n\t\tif (!result.success) {\n\t\t\tconst errors = result.error.issues.map(({ message, path }) =>\n\t\t\t\tpath[0] ? `${message}: ${path[0]}=\"${props[path[0]]}\"` : message,\n\t\t\t)\n\t\t\tconst notification = await createErrorNotification(\n\t\t\t\tnode,\n\t\t\t\terrors,\n\t\t\t\tmdxFile,\n\t\t\t\tappType,\n\t\t\t)\n\t\t\tparent.children.splice(index, 1, ...notification)\n\n\t\t\tdata.embeddedFiles.set('invalid input', {\n\t\t\t\terror: true,\n\t\t\t\tfile: props.file as string,\n\t\t\t\thash: '',\n\t\t\t\tline: node.position?.start.line ?? 1,\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tconst {\n\t\t\tfile: { content, filePath, fullPath },\n\t\t\thighlight,\n\t\t\trange,\n\t\t} = result.data\n\t\tconst language = path.extname(filePath).substring(1)\n\t\tconst meta = [`filename=${filePath}`]\n\n\t\t// nonumbers nocopy ....\n\t\tObject.entries(result.data).forEach(\n\t\t\t([key, val]) =>\n\t\t\t\ttypeof val === 'boolean' && val && meta.push(`${key}=true`),\n\t\t)\n\n\t\tif (result.data.buttons) {\n\t\t\tmeta.push(`buttons=${result.data.buttons.join(',')}`)\n\t\t\tmeta.push(`type=${appType}`)\n\t\t\tmeta.push(`fullpath=${fullPath}`)\n\t\t\t// Avoid the headache of finding the separator on the client side\n\t\t\t// path.sep is always / on client side\n\t\t\tmeta.push(`sep=${path.sep}`)\n\t\t}\n\n\t\tif (highlight?.length) {\n\t\t\tmeta.push(`lines=${highlight}`)\n\t\t}\n\n\t\tconst fileSections = range?.length ? range : [[1, content.length]]\n\t\tconst rangesContent = []\n\t\tconst preNodes = []\n\t\tfor (const [start, end] of fileSections) {\n\t\t\tconst rangeContent = stripIndent(\n\t\t\t\tcontent.slice(start ? start - 1 : 0, end).join('\\n'),\n\t\t\t)\n\t\t\trangesContent.push(rangeContent)\n\t\t\tconst mdxSource = `\n\\`\\`\\`${language} ${meta.concat(`start=${start}`).join(' ')}\n${rangeContent}\n\\`\\`\\``\n\t\t\tpreNodes.push(...mdxToMdast(mdxSource))\n\t\t}\n\n\t\t/**\n\t\t * Show a warning above the file content if the range we show changed in the\n\t\t * embedded file and the range in <CodeFile range=\"a-b\"> did not change.\n\t\t * The warning will be removed automatically after the <CodeFile> range changes\n\t\t * or by canceling it from the UI.\n\t\t */\n\t\tconst embeddedKey = md5(fullPath + JSON.stringify(range))\n\t\tconst contentHash = md5(rangesContent.join(','))\n\t\tconst newData: EmbeddedFile = {\n\t\t\tfile: fullPath,\n\t\t\thash: contentHash,\n\t\t}\n\t\tconst cachedData = data.cachedEmbeddedFiles.get(embeddedKey)\n\n\t\tif (\n\t\t\tcachedData &&\n\t\t\t// If a warning existed previously and its hash matched the current hash,\n\t\t\t// then the changes were reverted and the warning will be remove\n\t\t\t((cachedData.warning && cachedData.warning !== contentHash) ??\n\t\t\t\t(!cachedData.warning && cachedData.hash !== contentHash))\n\t\t) {\n\t\t\t// keep previously saved warning or previous hash\n\t\t\tnewData.warning = cachedData.warning ?? cachedData.hash\n\t\t\tconst startLine = node.position?.start.line ?? 1\n\t\t\tnewData.line = startLine\n\t\t\tconst mdxFilename = path.basename(mdxFile)\n\t\t\tconst filename = path.basename(filePath)\n\t\t\tconst warning = `\n<CodeFileNotification variant=\"warning\" file=\"${mdxFilename}\" line=\"${startLine}\" type=\"${appType}\"\ncacheLocation=\"${data.cacheLocation}\" embeddedKey=\"${embeddedKey}\">\n <callout-warning class=\"notification\">\n <div className=\"title\">CodeFile Warning:</div>\n <div>file ${filename} content was changed, review 'range' and 'highlight' inputs</div>\n </callout-warning>\n</CodeFileNotification>`\n\t\t\tpreNodes.unshift(...mdxToMdast(warning))\n\t\t}\n\t\tdata.embeddedFiles.set(embeddedKey, newData)\n\n\t\t// replace <CodeFile> with embedded file content\n\t\tparent.children.splice(index, 1, ...preNodes)\n\t}\n\n\treturn async function codeFileTransformer(tree: MdastRoot) {\n\t\tconst codeFiles: CodeFile[] = []\n\t\tconst filter = { type: 'mdxJsxFlowElement', name: 'CodeFile' } as const\n\t\tvisit<MdastRoot, typeof filter>(tree, filter, ((node, _index, parent) => {\n\t\t\tcodeFiles.push({ node, parent })\n\t\t}) as Visitor<MdxJsxFlowElement, Parent>)\n\n\t\tfor (const props of codeFiles) {\n\t\t\tawait replaceCodeFileNode(props)\n\t\t}\n\n\t\t// cleanup\n\t\tfileContentCache = new Map()\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile-mdx.server.d.ts","sourceRoot":"","sources":["../../src/compile-mdx.server.ts"],"names":[],"mappings":"AAkHA,wBAAsB,UAAU,CAC/B,IAAI,EAAE,MAAM,EACZ,EAAE,OAAO,EAAE,UAAU,EAAE,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GACvE,OAAO,CAAC;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAC9B,CAAC,CA8HD;AAED,wBAAsB,qBAAqB,CAAC,cAAc,EAAE,MAAM,mBAuCjE;
|
|
1
|
+
{"version":3,"file":"compile-mdx.server.d.ts","sourceRoot":"","sources":["../../src/compile-mdx.server.ts"],"names":[],"mappings":"AAkHA,wBAAsB,UAAU,CAC/B,IAAI,EAAE,MAAM,EACZ,EAAE,OAAO,EAAE,UAAU,EAAE,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GACvE,OAAO,CAAC;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAC9B,CAAC,CA8HD;AAED,wBAAsB,qBAAqB,CAAC,cAAc,EAAE,MAAM,mBAuCjE;AAmFD,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,oBAQpD"}
|
|
@@ -124,11 +124,11 @@ export async function compileMdx(file, { request, forceFresh } = {}) {
|
|
|
124
124
|
[remarkAutolinkHeadings, { behavior: 'wrap' }],
|
|
125
125
|
gfm,
|
|
126
126
|
() => (tree) => {
|
|
127
|
-
visit(tree, 'heading', node => {
|
|
127
|
+
visit(tree, 'heading', (node) => {
|
|
128
128
|
if (title)
|
|
129
129
|
return;
|
|
130
130
|
if (node.depth === 1) {
|
|
131
|
-
visit(node, 'text', textNode => {
|
|
131
|
+
visit(node, 'text', (textNode) => {
|
|
132
132
|
title = textNode.value.trim();
|
|
133
133
|
});
|
|
134
134
|
}
|
|
@@ -136,10 +136,10 @@ export async function compileMdx(file, { request, forceFresh } = {}) {
|
|
|
136
136
|
title = title ? title.replace(/^\d+\. /, '').trim() : null;
|
|
137
137
|
},
|
|
138
138
|
() => (tree) => {
|
|
139
|
-
visit(tree, 'mdxJsxFlowElement', jsxEl => {
|
|
139
|
+
visit(tree, 'mdxJsxFlowElement', (jsxEl) => {
|
|
140
140
|
if (jsxEl.name !== 'EpicVideo')
|
|
141
141
|
return;
|
|
142
|
-
const urlAttr = jsxEl.attributes.find(a => a.type === 'mdxJsxAttribute' && a.name === 'url');
|
|
142
|
+
const urlAttr = jsxEl.attributes.find((a) => a.type === 'mdxJsxAttribute' && a.name === 'url');
|
|
143
143
|
if (!urlAttr)
|
|
144
144
|
return;
|
|
145
145
|
let url = urlAttr.value;
|
|
@@ -237,9 +237,8 @@ async function updateEmbeddedFilesCache({ mdxFile, embeddedFiles, }) {
|
|
|
237
237
|
// make sure we get clean list before updating it
|
|
238
238
|
if (cachedList) {
|
|
239
239
|
for (const [key, value] of Object.entries(cachedList)) {
|
|
240
|
-
cachedList[key] = value.filter(item => item !== mdxFile);
|
|
240
|
+
cachedList[key] = value.filter((item) => item !== mdxFile);
|
|
241
241
|
if (cachedList[key]?.length === 0) {
|
|
242
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
243
242
|
delete cachedList[key];
|
|
244
243
|
}
|
|
245
244
|
}
|
|
@@ -284,7 +283,7 @@ async function getEmbeddedFilesCache() {
|
|
|
284
283
|
return JSON.parse(await fs.promises.readFile(embeddedFilesLocation, 'utf-8'));
|
|
285
284
|
}
|
|
286
285
|
}
|
|
287
|
-
catch
|
|
286
|
+
catch {
|
|
288
287
|
console.error(`Unable to read 'embeddedFiles.json' from: `, cacheDir);
|
|
289
288
|
}
|
|
290
289
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile-mdx.server.js","sourceRoot":"","sources":["../../src/compile-mdx.server.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { cachified, type CacheEntry } from '@epic-web/cachified'\nimport { remember } from '@epic-web/remember'\nimport { remarkCodeBlocksShiki } from '@kentcdodds/md-temp'\nimport fsExtra from 'fs-extra'\nimport { type Element, type Root as HastRoot } from 'hast'\nimport md5 from 'md5-hex'\nimport { type Root as MdastRoot } from 'mdast'\nimport { bundleMDX } from 'mdx-bundler'\nimport PQueue from 'p-queue'\nimport remarkAutolinkHeadings from 'remark-autolink-headings'\nimport emoji from 'remark-emoji'\nimport gfm from 'remark-gfm'\nimport { type PluggableList } from 'unified'\nimport { visit } from 'unist-util-visit'\nimport {\n\ttype CachedEmbeddedFilesList,\n\tcompiledMarkdownCache,\n\tembeddedFilesCache,\n\tshouldForceFresh,\n} from './cache.server.js'\nimport {\n\tremarkCodeFile,\n\ttype CodeFileData,\n\ttype EmbeddedFile,\n} from './codefile-mdx.server.js'\n\nconst cacheDir = path.join(\n\tprocess.env.EPICSHOP_CONTEXT_CWD ?? process.cwd(),\n\t'./node_modules/.cache/compile-mdx',\n)\n\nfunction trimCodeBlocks() {\n\treturn async function transformer(tree: HastRoot) {\n\t\tvisit(tree, 'element', (preNode: Element) => {\n\t\t\tif (preNode.tagName !== 'pre' || !preNode.children.length) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst codeNode = preNode.children[0]\n\t\t\tif (\n\t\t\t\t!codeNode ||\n\t\t\t\tcodeNode.type !== 'element' ||\n\t\t\t\tcodeNode.tagName !== 'code'\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst [codeStringNode] = codeNode.children\n\t\t\tif (!codeStringNode) return\n\n\t\t\tif (codeStringNode.type !== 'text') {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`trimCodeBlocks: Unexpected: codeStringNode type is not \"text\": ${codeStringNode.type}`,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcodeStringNode.value = codeStringNode.value.trimEnd()\n\t\t})\n\t}\n}\n\nfunction removePreContainerDivs() {\n\treturn async function preContainerDivsTransformer(tree: HastRoot) {\n\t\tvisit(\n\t\t\ttree,\n\t\t\t{ type: 'element', tagName: 'pre' },\n\t\t\tfunction visitor(node, index, parent) {\n\t\t\t\tif (parent?.type !== 'element') return\n\t\t\t\tif (parent.tagName !== 'div') return\n\t\t\t\tif (parent.children.length !== 1 && index === 0) return\n\t\t\t\tObject.assign(parent, node)\n\t\t\t},\n\t\t)\n\t}\n}\n\nconst rehypePlugins = [\n\ttrimCodeBlocks,\n\tremarkCodeBlocksShiki,\n\tremovePreContainerDivs,\n] satisfies PluggableList\n\nfunction checkFileExists(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\nconst verboseLog =\n\tprocess.env.EPICSHOP_VERBOSE_LOG === 'true' ? console.log : () => {}\n\n/**\n * @param embeddedFiles {string[]} - list of embedded files\n * @param lastCompiledTime {number} - timestamp indicating the last time mdx file was compiled\n * @returns true if all embedded file mtimeMs are older then the file compiled time,\n * false if we need update\n */\nfunction validateEmbeddedFiles(\n\tembeddedFiles: IterableIterator<EmbeddedFile>,\n\tlastCompiledTime: number,\n): Promise<boolean> {\n\tif (process.env.NODE_ENV !== 'development') return Promise.resolve(true)\n\treturn Promise.all(\n\t\tArray.from(embeddedFiles).map(async ({ file }) => {\n\t\t\tconst stat = await fs.promises.stat(file).catch(() => ({ mtimeMs: 0 }))\n\t\t\treturn lastCompiledTime > stat.mtimeMs || Promise.reject()\n\t\t}),\n\t).then(\n\t\t() => true,\n\t\t() => false,\n\t)\n}\n\nexport async function compileMdx(\n\tfile: string,\n\t{ request, forceFresh }: { request?: Request; forceFresh?: boolean } = {},\n): Promise<{\n\tcode: string\n\ttitle: string | null\n\tepicVideoEmbeds: Array<string>\n}> {\n\tif (!(await checkFileExists(file))) {\n\t\tthrow new Error(`File does not exist: ${file}`)\n\t}\n\n\tlet cachedEmbeddedFiles = new Map<string, EmbeddedFile>()\n\n\tconst stat = await fs.promises.stat(file)\n\tconst cacheLocation = path.join(cacheDir, `${md5(file)}.json`)\n\n\tconst requireFresh = await shouldForceFresh({\n\t\tforceFresh,\n\t\trequest,\n\t\tkey: cacheLocation,\n\t})\n\tif (!requireFresh && (await checkFileExists(cacheLocation))) {\n\t\tconst cached = JSON.parse(\n\t\t\tawait fs.promises.readFile(cacheLocation, 'utf-8'),\n\t\t) as any\n\n\t\tcachedEmbeddedFiles = new Map(\n\t\t\tObject.entries(cached.value.embeddedFiles ?? {}),\n\t\t)\n\n\t\tconst compiledTime = cached.value.compiledTime ?? 0\n\t\tconst warningCancled =\n\t\t\tprocess.env.NODE_ENV === 'development'\n\t\t\t\t? cached?.value?.warningCancled ?? false\n\t\t\t\t: false\n\t\tif (\n\t\t\tcompiledTime > stat.mtimeMs &&\n\t\t\t!warningCancled &&\n\t\t\t(await validateEmbeddedFiles(cachedEmbeddedFiles.values(), compiledTime))\n\t\t) {\n\t\t\treturn cached.value\n\t\t}\n\t}\n\tlet title: string | null = null\n\tconst epicVideoEmbeds: Array<string> = []\n\tconst codeFileData = {\n\t\tmdxFile: file,\n\t\tcacheLocation,\n\t\tcachedEmbeddedFiles,\n\t\tembeddedFiles: new Map<string, EmbeddedFile>(),\n\t}\n\n\ttry {\n\t\tverboseLog(`Compiling ${file}`)\n\t\tconst bundleResult = await queuedBundleMDX({\n\t\t\tfile,\n\t\t\tcwd: path.dirname(file),\n\t\t\tesbuildOptions(options) {\n\t\t\t\toptions.define = {\n\t\t\t\t\t'process.env.NODE_ENV': JSON.stringify(\n\t\t\t\t\t\tprocess.env.NODE_ENV ?? 'production',\n\t\t\t\t\t),\n\t\t\t\t\t...options.define,\n\t\t\t\t}\n\t\t\t\treturn options\n\t\t\t},\n\t\t\tmdxOptions(options) {\n\t\t\t\toptions.remarkPlugins = [\n\t\t\t\t\t...(options.remarkPlugins ?? []),\n\t\t\t\t\t[remarkAutolinkHeadings, { behavior: 'wrap' }],\n\t\t\t\t\tgfm,\n\t\t\t\t\t() => (tree: MdastRoot) => {\n\t\t\t\t\t\tvisit(tree, 'heading', node => {\n\t\t\t\t\t\t\tif (title) return\n\t\t\t\t\t\t\tif (node.depth === 1) {\n\t\t\t\t\t\t\t\tvisit(node, 'text', textNode => {\n\t\t\t\t\t\t\t\t\ttitle = textNode.value.trim()\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\ttitle = title ? title.replace(/^\\d+\\. /, '').trim() : null\n\t\t\t\t\t},\n\t\t\t\t\t() => (tree: MdastRoot) => {\n\t\t\t\t\t\tvisit(tree, 'mdxJsxFlowElement', jsxEl => {\n\t\t\t\t\t\t\tif (jsxEl.name !== 'EpicVideo') return\n\t\t\t\t\t\t\tconst urlAttr = jsxEl.attributes.find(\n\t\t\t\t\t\t\t\ta => a.type === 'mdxJsxAttribute' && a.name === 'url',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tif (!urlAttr) return\n\t\t\t\t\t\t\tlet url = urlAttr.value\n\t\t\t\t\t\t\tif (typeof url !== 'string') return\n\t\t\t\t\t\t\tif (url.endsWith('/')) url = url.slice(0, -1)\n\t\t\t\t\t\t\tepicVideoEmbeds.push(url)\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t\t() => remarkCodeFile(codeFileData),\n\t\t\t\t\temoji,\n\t\t\t\t]\n\t\t\t\toptions.rehypePlugins = [\n\t\t\t\t\t...(options.rehypePlugins ?? []),\n\t\t\t\t\t...rehypePlugins,\n\t\t\t\t]\n\t\t\t\toptions.mdxExtensions = ['.mdx', '.md']\n\t\t\t\toptions.format = 'mdx'\n\t\t\t\toptions.development = false\n\t\t\t\treturn options\n\t\t\t},\n\t\t})\n\t\tif (!bundleResult) throw new Error(`Timeout for file: ${file}`)\n\n\t\tconst result = { code: bundleResult.code, title, epicVideoEmbeds }\n\t\tawait fsExtra.ensureDir(cacheDir)\n\t\tawait fs.promises.writeFile(\n\t\t\tcacheLocation,\n\t\t\tJSON.stringify({\n\t\t\t\tvalue: {\n\t\t\t\t\t...result,\n\t\t\t\t\tcompiledTime: Date.now(),\n\t\t\t\t\tembeddedFiles: codeFileData.embeddedFiles.size\n\t\t\t\t\t\t? Object.fromEntries(codeFileData.embeddedFiles)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t\tawait updateEmbeddedFilesCache(codeFileData)\n\t\treturn result\n\t} catch (error: unknown) {\n\t\tconsole.error(`Compilation error for file: `, file, error)\n\t\tthrow error\n\t} finally {\n\t\tverboseLog(`Successfully compiled ${file}`)\n\t}\n}\n\nexport async function compileMarkdownString(markdownString: string) {\n\treturn cachified({\n\t\tkey: markdownString,\n\t\tcache: compiledMarkdownCache,\n\t\tttl: 1000 * 60 * 60 * 24,\n\t\tgetFreshValue: async () => {\n\t\t\ttry {\n\t\t\t\tverboseLog(`Compiling string`, markdownString)\n\t\t\t\tconst result = await queuedBundleMDX({\n\t\t\t\t\tsource: markdownString,\n\t\t\t\t\tesbuildOptions(options) {\n\t\t\t\t\t\toptions.define = {\n\t\t\t\t\t\t\t'process.env.NODE_ENV': JSON.stringify(\n\t\t\t\t\t\t\t\tprocess.env.NODE_ENV ?? 'production',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t...options.define,\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn options\n\t\t\t\t\t},\n\t\t\t\t\tmdxOptions(options) {\n\t\t\t\t\t\toptions.rehypePlugins = [\n\t\t\t\t\t\t\t...(options.rehypePlugins ?? []),\n\t\t\t\t\t\t\t...rehypePlugins,\n\t\t\t\t\t\t]\n\t\t\t\t\t\toptions.development = false\n\t\t\t\t\t\treturn options\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tif (!result) throw new Error(`Timed out compiling markdown string`)\n\n\t\t\t\treturn result.code\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconsole.error(`Compilation error for code: `, markdownString, error)\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\tverboseLog(`Successfully compiled string`, markdownString)\n\t\t\t}\n\t\t},\n\t})\n}\n\nconst modifiedEmbeddedFilesTime = remember(\n\t'modified_embedded_files_time',\n\t() => new Map<string, number>(),\n)\n\nconst EMBEDDED_FILES_CACHE_KEY = 'embeddedFilesCache'\n\nasync function updateEmbeddedFilesCache({\n\tmdxFile,\n\tembeddedFiles,\n}: CodeFileData) {\n\tif (mdxFile.includes('playground')) return\n\tlet cachedList = await getEmbeddedFilesCache()\n\tconst hash = cachedList ? md5(JSON.stringify(cachedList)) : null\n\n\t// make sure we get clean list before updating it\n\tif (cachedList) {\n\t\tfor (const [key, value] of Object.entries(cachedList)) {\n\t\t\tcachedList[key] = value.filter(item => item !== mdxFile)\n\t\t\tif (cachedList[key]?.length === 0) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete cachedList[key]\n\t\t\t}\n\t\t}\n\t}\n\n\tif (embeddedFiles.size) {\n\t\tif (!cachedList) {\n\t\t\tcachedList = {}\n\t\t}\n\t\tconst files = Array.from(\n\t\t\tnew Set(Array.from(embeddedFiles.values()).map(({ file }) => file)),\n\t\t).sort()\n\t\tfor (const file of files) {\n\t\t\tcachedList[file] = [...(cachedList[file] ?? []), mdxFile]\n\t\t}\n\t}\n\n\tif (cachedList && hash !== md5(JSON.stringify(cachedList))) {\n\t\tawait fsExtra.ensureDir(cacheDir)\n\t\tconst embeddedFilesLocation = path.join(cacheDir, 'embeddedFiles.json')\n\t\tmodifiedEmbeddedFilesTime.set(EMBEDDED_FILES_CACHE_KEY, Date.now())\n\t\tawait fs.promises.writeFile(\n\t\t\tembeddedFilesLocation,\n\t\t\tJSON.stringify({ ...cachedList }),\n\t\t)\n\t}\n}\n\nasync function getEmbeddedFilesCache() {\n\tconst key = EMBEDDED_FILES_CACHE_KEY\n\n\tfunction getForceFresh(cacheEntry: CacheEntry | null | undefined) {\n\t\tif (!cacheEntry) return true\n\t\tconst latestModifiedTime = modifiedEmbeddedFilesTime.get(key)\n\t\tif (!latestModifiedTime) return undefined\n\t\treturn latestModifiedTime > cacheEntry.metadata.createdTime\n\t\t\t? true\n\t\t\t: undefined\n\t}\n\n\treturn cachified({\n\t\tkey,\n\t\tcache: embeddedFilesCache,\n\t\tttl: 1000 * 60 * 60 * 24,\n\t\tforceFresh: getForceFresh(embeddedFilesCache.get(key)),\n\t\tgetFreshValue: async () => {\n\t\t\ttry {\n\t\t\t\tconst embeddedFilesLocation = path.join(cacheDir, 'embeddedFiles.json')\n\t\t\t\tif (await checkFileExists(embeddedFilesLocation)) {\n\t\t\t\t\treturn JSON.parse(\n\t\t\t\t\t\tawait fs.promises.readFile(embeddedFilesLocation, 'utf-8'),\n\t\t\t\t\t) as CachedEmbeddedFilesList\n\t\t\t\t}\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconsole.error(`Unable to read 'embeddedFiles.json' from: `, cacheDir)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t})\n}\n\nexport async function isEmbeddedFile(filePath: string) {\n\tif (process.env.NODE_ENV !== 'development') return false\n\tconst embeddedFilesList = await getEmbeddedFilesCache()\n\tif (embeddedFilesList) {\n\t\tconst embeddedFiles = Object.keys(embeddedFilesList)\n\t\treturn embeddedFiles.includes(filePath.replace(/\\\\/g, '/'))\n\t}\n\treturn false\n}\n\nlet _queue: PQueue | null = null\nasync function getQueue() {\n\tif (_queue) return _queue\n\n\t_queue = new PQueue({\n\t\tconcurrency: 1,\n\t\tthrowOnTimeout: true,\n\t\ttimeout: 1000 * 60,\n\t})\n\treturn _queue\n}\n\n// We have to use a queue because we can't run more than one of these at a time\n// or we'll hit an out of memory error because esbuild uses a lot of memory...\nasync function queuedBundleMDX(...args: Parameters<typeof bundleMDX>) {\n\tconst queue = await getQueue()\n\tconst result = await queue.add(() => bundleMDX(...args))\n\treturn result\n}\n\n// TODO: Fix these\n/*\neslint\n\t\"@typescript-eslint/no-unsafe-assignment\": \"off\",\n\t\"@typescript-eslint/no-unsafe-member-access\": \"off\",\n\t\"@typescript-eslint/no-unnecessary-condition\": \"off\",\n\t\"@typescript-eslint/no-unsafe-argument\": \"off\",\n*/\n"]}
|
|
1
|
+
{"version":3,"file":"compile-mdx.server.js","sourceRoot":"","sources":["../../src/compile-mdx.server.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { cachified, type CacheEntry } from '@epic-web/cachified'\nimport { remember } from '@epic-web/remember'\nimport { remarkCodeBlocksShiki } from '@kentcdodds/md-temp'\nimport fsExtra from 'fs-extra'\nimport { type Element, type Root as HastRoot } from 'hast'\nimport md5 from 'md5-hex'\nimport { type Root as MdastRoot } from 'mdast'\nimport { bundleMDX } from 'mdx-bundler'\nimport PQueue from 'p-queue'\nimport remarkAutolinkHeadings from 'remark-autolink-headings'\nimport emoji from 'remark-emoji'\nimport gfm from 'remark-gfm'\nimport { type PluggableList } from 'unified'\nimport { visit } from 'unist-util-visit'\nimport {\n\tcompiledMarkdownCache,\n\tembeddedFilesCache,\n\tshouldForceFresh,\n\ttype CachedEmbeddedFilesList,\n} from './cache.server.js'\nimport {\n\tremarkCodeFile,\n\ttype CodeFileData,\n\ttype EmbeddedFile,\n} from './codefile-mdx.server.js'\n\nconst cacheDir = path.join(\n\tprocess.env.EPICSHOP_CONTEXT_CWD ?? process.cwd(),\n\t'./node_modules/.cache/compile-mdx',\n)\n\nfunction trimCodeBlocks() {\n\treturn async function transformer(tree: HastRoot) {\n\t\tvisit(tree, 'element', (preNode: Element) => {\n\t\t\tif (preNode.tagName !== 'pre' || !preNode.children.length) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst codeNode = preNode.children[0]\n\t\t\tif (\n\t\t\t\t!codeNode ||\n\t\t\t\tcodeNode.type !== 'element' ||\n\t\t\t\tcodeNode.tagName !== 'code'\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst [codeStringNode] = codeNode.children\n\t\t\tif (!codeStringNode) return\n\n\t\t\tif (codeStringNode.type !== 'text') {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`trimCodeBlocks: Unexpected: codeStringNode type is not \"text\": ${codeStringNode.type}`,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcodeStringNode.value = codeStringNode.value.trimEnd()\n\t\t})\n\t}\n}\n\nfunction removePreContainerDivs() {\n\treturn async function preContainerDivsTransformer(tree: HastRoot) {\n\t\tvisit(\n\t\t\ttree,\n\t\t\t{ type: 'element', tagName: 'pre' },\n\t\t\tfunction visitor(node, index, parent) {\n\t\t\t\tif (parent?.type !== 'element') return\n\t\t\t\tif (parent.tagName !== 'div') return\n\t\t\t\tif (parent.children.length !== 1 && index === 0) return\n\t\t\t\tObject.assign(parent, node)\n\t\t\t},\n\t\t)\n\t}\n}\n\nconst rehypePlugins = [\n\ttrimCodeBlocks,\n\tremarkCodeBlocksShiki,\n\tremovePreContainerDivs,\n] satisfies PluggableList\n\nfunction checkFileExists(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\nconst verboseLog =\n\tprocess.env.EPICSHOP_VERBOSE_LOG === 'true' ? console.log : () => {}\n\n/**\n * @param embeddedFiles {string[]} - list of embedded files\n * @param lastCompiledTime {number} - timestamp indicating the last time mdx file was compiled\n * @returns true if all embedded file mtimeMs are older then the file compiled time,\n * false if we need update\n */\nfunction validateEmbeddedFiles(\n\tembeddedFiles: IterableIterator<EmbeddedFile>,\n\tlastCompiledTime: number,\n): Promise<boolean> {\n\tif (process.env.NODE_ENV !== 'development') return Promise.resolve(true)\n\treturn Promise.all(\n\t\tArray.from(embeddedFiles).map(async ({ file }) => {\n\t\t\tconst stat = await fs.promises.stat(file).catch(() => ({ mtimeMs: 0 }))\n\t\t\treturn lastCompiledTime > stat.mtimeMs || Promise.reject()\n\t\t}),\n\t).then(\n\t\t() => true,\n\t\t() => false,\n\t)\n}\n\nexport async function compileMdx(\n\tfile: string,\n\t{ request, forceFresh }: { request?: Request; forceFresh?: boolean } = {},\n): Promise<{\n\tcode: string\n\ttitle: string | null\n\tepicVideoEmbeds: Array<string>\n}> {\n\tif (!(await checkFileExists(file))) {\n\t\tthrow new Error(`File does not exist: ${file}`)\n\t}\n\n\tlet cachedEmbeddedFiles = new Map<string, EmbeddedFile>()\n\n\tconst stat = await fs.promises.stat(file)\n\tconst cacheLocation = path.join(cacheDir, `${md5(file)}.json`)\n\n\tconst requireFresh = await shouldForceFresh({\n\t\tforceFresh,\n\t\trequest,\n\t\tkey: cacheLocation,\n\t})\n\tif (!requireFresh && (await checkFileExists(cacheLocation))) {\n\t\tconst cached = JSON.parse(\n\t\t\tawait fs.promises.readFile(cacheLocation, 'utf-8'),\n\t\t) as any\n\n\t\tcachedEmbeddedFiles = new Map(\n\t\t\tObject.entries(cached.value.embeddedFiles ?? {}),\n\t\t)\n\n\t\tconst compiledTime = cached.value.compiledTime ?? 0\n\t\tconst warningCancled =\n\t\t\tprocess.env.NODE_ENV === 'development'\n\t\t\t\t? cached?.value?.warningCancled ?? false\n\t\t\t\t: false\n\t\tif (\n\t\t\tcompiledTime > stat.mtimeMs &&\n\t\t\t!warningCancled &&\n\t\t\t(await validateEmbeddedFiles(cachedEmbeddedFiles.values(), compiledTime))\n\t\t) {\n\t\t\treturn cached.value\n\t\t}\n\t}\n\tlet title: string | null = null\n\tconst epicVideoEmbeds: Array<string> = []\n\tconst codeFileData = {\n\t\tmdxFile: file,\n\t\tcacheLocation,\n\t\tcachedEmbeddedFiles,\n\t\tembeddedFiles: new Map<string, EmbeddedFile>(),\n\t}\n\n\ttry {\n\t\tverboseLog(`Compiling ${file}`)\n\t\tconst bundleResult = await queuedBundleMDX({\n\t\t\tfile,\n\t\t\tcwd: path.dirname(file),\n\t\t\tesbuildOptions(options) {\n\t\t\t\toptions.define = {\n\t\t\t\t\t'process.env.NODE_ENV': JSON.stringify(\n\t\t\t\t\t\tprocess.env.NODE_ENV ?? 'production',\n\t\t\t\t\t),\n\t\t\t\t\t...options.define,\n\t\t\t\t}\n\t\t\t\treturn options\n\t\t\t},\n\t\t\tmdxOptions(options) {\n\t\t\t\toptions.remarkPlugins = [\n\t\t\t\t\t...(options.remarkPlugins ?? []),\n\t\t\t\t\t[remarkAutolinkHeadings, { behavior: 'wrap' }],\n\t\t\t\t\tgfm,\n\t\t\t\t\t() => (tree: MdastRoot) => {\n\t\t\t\t\t\tvisit(tree, 'heading', (node) => {\n\t\t\t\t\t\t\tif (title) return\n\t\t\t\t\t\t\tif (node.depth === 1) {\n\t\t\t\t\t\t\t\tvisit(node, 'text', (textNode) => {\n\t\t\t\t\t\t\t\t\ttitle = textNode.value.trim()\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\ttitle = title ? title.replace(/^\\d+\\. /, '').trim() : null\n\t\t\t\t\t},\n\t\t\t\t\t() => (tree: MdastRoot) => {\n\t\t\t\t\t\tvisit(tree, 'mdxJsxFlowElement', (jsxEl) => {\n\t\t\t\t\t\t\tif (jsxEl.name !== 'EpicVideo') return\n\t\t\t\t\t\t\tconst urlAttr = jsxEl.attributes.find(\n\t\t\t\t\t\t\t\t(a) => a.type === 'mdxJsxAttribute' && a.name === 'url',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tif (!urlAttr) return\n\t\t\t\t\t\t\tlet url = urlAttr.value\n\t\t\t\t\t\t\tif (typeof url !== 'string') return\n\t\t\t\t\t\t\tif (url.endsWith('/')) url = url.slice(0, -1)\n\t\t\t\t\t\t\tepicVideoEmbeds.push(url)\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t\t() => remarkCodeFile(codeFileData),\n\t\t\t\t\temoji,\n\t\t\t\t]\n\t\t\t\toptions.rehypePlugins = [\n\t\t\t\t\t...(options.rehypePlugins ?? []),\n\t\t\t\t\t...rehypePlugins,\n\t\t\t\t]\n\t\t\t\toptions.mdxExtensions = ['.mdx', '.md']\n\t\t\t\toptions.format = 'mdx'\n\t\t\t\toptions.development = false\n\t\t\t\treturn options\n\t\t\t},\n\t\t})\n\t\tif (!bundleResult) throw new Error(`Timeout for file: ${file}`)\n\n\t\tconst result = { code: bundleResult.code, title, epicVideoEmbeds }\n\t\tawait fsExtra.ensureDir(cacheDir)\n\t\tawait fs.promises.writeFile(\n\t\t\tcacheLocation,\n\t\t\tJSON.stringify({\n\t\t\t\tvalue: {\n\t\t\t\t\t...result,\n\t\t\t\t\tcompiledTime: Date.now(),\n\t\t\t\t\tembeddedFiles: codeFileData.embeddedFiles.size\n\t\t\t\t\t\t? Object.fromEntries(codeFileData.embeddedFiles)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t\tawait updateEmbeddedFilesCache(codeFileData)\n\t\treturn result\n\t} catch (error: unknown) {\n\t\tconsole.error(`Compilation error for file: `, file, error)\n\t\tthrow error\n\t} finally {\n\t\tverboseLog(`Successfully compiled ${file}`)\n\t}\n}\n\nexport async function compileMarkdownString(markdownString: string) {\n\treturn cachified({\n\t\tkey: markdownString,\n\t\tcache: compiledMarkdownCache,\n\t\tttl: 1000 * 60 * 60 * 24,\n\t\tgetFreshValue: async () => {\n\t\t\ttry {\n\t\t\t\tverboseLog(`Compiling string`, markdownString)\n\t\t\t\tconst result = await queuedBundleMDX({\n\t\t\t\t\tsource: markdownString,\n\t\t\t\t\tesbuildOptions(options) {\n\t\t\t\t\t\toptions.define = {\n\t\t\t\t\t\t\t'process.env.NODE_ENV': JSON.stringify(\n\t\t\t\t\t\t\t\tprocess.env.NODE_ENV ?? 'production',\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t...options.define,\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn options\n\t\t\t\t\t},\n\t\t\t\t\tmdxOptions(options) {\n\t\t\t\t\t\toptions.rehypePlugins = [\n\t\t\t\t\t\t\t...(options.rehypePlugins ?? []),\n\t\t\t\t\t\t\t...rehypePlugins,\n\t\t\t\t\t\t]\n\t\t\t\t\t\toptions.development = false\n\t\t\t\t\t\treturn options\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tif (!result) throw new Error(`Timed out compiling markdown string`)\n\n\t\t\t\treturn result.code\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconsole.error(`Compilation error for code: `, markdownString, error)\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\tverboseLog(`Successfully compiled string`, markdownString)\n\t\t\t}\n\t\t},\n\t})\n}\n\nconst modifiedEmbeddedFilesTime = remember(\n\t'modified_embedded_files_time',\n\t() => new Map<string, number>(),\n)\n\nconst EMBEDDED_FILES_CACHE_KEY = 'embeddedFilesCache'\n\nasync function updateEmbeddedFilesCache({\n\tmdxFile,\n\tembeddedFiles,\n}: CodeFileData) {\n\tif (mdxFile.includes('playground')) return\n\tlet cachedList = await getEmbeddedFilesCache()\n\tconst hash = cachedList ? md5(JSON.stringify(cachedList)) : null\n\n\t// make sure we get clean list before updating it\n\tif (cachedList) {\n\t\tfor (const [key, value] of Object.entries(cachedList)) {\n\t\t\tcachedList[key] = value.filter((item) => item !== mdxFile)\n\t\t\tif (cachedList[key]?.length === 0) {\n\t\t\t\tdelete cachedList[key]\n\t\t\t}\n\t\t}\n\t}\n\n\tif (embeddedFiles.size) {\n\t\tif (!cachedList) {\n\t\t\tcachedList = {}\n\t\t}\n\t\tconst files = Array.from(\n\t\t\tnew Set(Array.from(embeddedFiles.values()).map(({ file }) => file)),\n\t\t).sort()\n\t\tfor (const file of files) {\n\t\t\tcachedList[file] = [...(cachedList[file] ?? []), mdxFile]\n\t\t}\n\t}\n\n\tif (cachedList && hash !== md5(JSON.stringify(cachedList))) {\n\t\tawait fsExtra.ensureDir(cacheDir)\n\t\tconst embeddedFilesLocation = path.join(cacheDir, 'embeddedFiles.json')\n\t\tmodifiedEmbeddedFilesTime.set(EMBEDDED_FILES_CACHE_KEY, Date.now())\n\t\tawait fs.promises.writeFile(\n\t\t\tembeddedFilesLocation,\n\t\t\tJSON.stringify({ ...cachedList }),\n\t\t)\n\t}\n}\n\nasync function getEmbeddedFilesCache() {\n\tconst key = EMBEDDED_FILES_CACHE_KEY\n\n\tfunction getForceFresh(cacheEntry: CacheEntry | null | undefined) {\n\t\tif (!cacheEntry) return true\n\t\tconst latestModifiedTime = modifiedEmbeddedFilesTime.get(key)\n\t\tif (!latestModifiedTime) return undefined\n\t\treturn latestModifiedTime > cacheEntry.metadata.createdTime\n\t\t\t? true\n\t\t\t: undefined\n\t}\n\n\treturn cachified({\n\t\tkey,\n\t\tcache: embeddedFilesCache,\n\t\tttl: 1000 * 60 * 60 * 24,\n\t\tforceFresh: getForceFresh(embeddedFilesCache.get(key)),\n\t\tgetFreshValue: async () => {\n\t\t\ttry {\n\t\t\t\tconst embeddedFilesLocation = path.join(cacheDir, 'embeddedFiles.json')\n\t\t\t\tif (await checkFileExists(embeddedFilesLocation)) {\n\t\t\t\t\treturn JSON.parse(\n\t\t\t\t\t\tawait fs.promises.readFile(embeddedFilesLocation, 'utf-8'),\n\t\t\t\t\t) as CachedEmbeddedFilesList\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tconsole.error(`Unable to read 'embeddedFiles.json' from: `, cacheDir)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t})\n}\n\nexport async function isEmbeddedFile(filePath: string) {\n\tif (process.env.NODE_ENV !== 'development') return false\n\tconst embeddedFilesList = await getEmbeddedFilesCache()\n\tif (embeddedFilesList) {\n\t\tconst embeddedFiles = Object.keys(embeddedFilesList)\n\t\treturn embeddedFiles.includes(filePath.replace(/\\\\/g, '/'))\n\t}\n\treturn false\n}\n\nlet _queue: PQueue | null = null\nasync function getQueue() {\n\tif (_queue) return _queue\n\n\t_queue = new PQueue({\n\t\tconcurrency: 1,\n\t\tthrowOnTimeout: true,\n\t\ttimeout: 1000 * 60,\n\t})\n\treturn _queue\n}\n\n// We have to use a queue because we can't run more than one of these at a time\n// or we'll hit an out of memory error because esbuild uses a lot of memory...\nasync function queuedBundleMDX(...args: Parameters<typeof bundleMDX>) {\n\tconst queue = await getQueue()\n\tconst result = await queue.add(() => bundleMDX(...args))\n\treturn result\n}\n\n// TODO: Fix these\n/*\neslint\n\t\"@typescript-eslint/no-unsafe-assignment\": \"off\",\n\t\"@typescript-eslint/no-unsafe-member-access\": \"off\",\n\t\"@typescript-eslint/no-unnecessary-condition\": \"off\",\n\t\"@typescript-eslint/no-unsafe-argument\": \"off\",\n*/\n"]}
|
package/dist/esm/db.server.js
CHANGED
|
@@ -50,7 +50,7 @@ const AuthInfoSchema = z
|
|
|
50
50
|
email: z.string(),
|
|
51
51
|
name: z.string().nullable().optional(),
|
|
52
52
|
})
|
|
53
|
-
.transform(d => ({ ...d, id: md5(d.email) }));
|
|
53
|
+
.transform((d) => ({ ...d, id: md5(d.email) }));
|
|
54
54
|
const DataSchema = z.object({
|
|
55
55
|
onboarding: z
|
|
56
56
|
.object({ finishedTourVideo: z.boolean() })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.server.js","sourceRoot":"","sources":["../../src/db.server.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'os'\nimport path from 'path'\nimport { redirect } from '@remix-run/node'\nimport fsExtra from 'fs-extra'\nimport md5 from 'md5-hex'\nimport { z } from 'zod'\n\nexport const DiscordMemberSchema = z.object({\n\tavatarURL: z.string().nullable().optional(),\n\tdisplayName: z.string(),\n\tid: z.string(),\n})\n\nconst TokenSetSchema = z.object({\n\taccess_token: z.string(),\n\ttoken_type: z.string(),\n\tscope: z.string(),\n})\nexport const PlayerPreferencesSchema = z\n\t.object({\n\t\tvolumeRate: z.number().optional(),\n\t\tplaybackRate: z.number().optional(),\n\t\tautoplay: z.boolean().optional(),\n\t\tsubtitle: z\n\t\t\t.object({\n\t\t\t\tid: z.string().nullable().default(null),\n\t\t\t\tmode: z\n\t\t\t\t\t.literal('disabled')\n\t\t\t\t\t.or(z.literal('hidden'))\n\t\t\t\t\t.or(z.literal('showing'))\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.default('disabled'),\n\t\t\t})\n\t\t\t.optional()\n\t\t\t.default({}),\n\t\tmuted: z.boolean().optional(),\n\t\ttheater: z.boolean().optional(),\n\t\tdefaultView: z.string().optional(),\n\t\tactiveSidebarTab: z.number().optional(),\n\t})\n\t.optional()\n\t.default({})\n\nconst PresencePreferencesSchema = z\n\t.object({\n\t\toptOut: z.boolean(),\n\t})\n\t.optional()\n\t.default({ optOut: false })\n\nconst AuthInfoSchema = z\n\t.object({\n\t\ttokenSet: TokenSetSchema,\n\t\temail: z.string(),\n\t\tname: z.string().nullable().optional(),\n\t})\n\t.transform(d => ({ ...d, id: md5(d.email) }))\n\nconst DataSchema = z.object({\n\tonboarding: z\n\t\t.object({ finishedTourVideo: z.boolean() })\n\t\t.optional()\n\t\t.default({ finishedTourVideo: false }),\n\tpreferences: z\n\t\t.object({\n\t\t\tplayer: PlayerPreferencesSchema,\n\t\t\tpresence: PresencePreferencesSchema,\n\t\t})\n\t\t.optional()\n\t\t.default({}),\n\tauthInfo: AuthInfoSchema.optional(),\n\tdiscordMember: DiscordMemberSchema.optional(),\n})\n\nconst appDir = path.join(os.homedir(), '.epicshop')\nconst dbPath = path.join(appDir, 'data.json')\n\nexport async function deleteDb() {\n\tif (process.env.EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (await fsExtra.exists(dbPath)) {\n\t\t\tawait fsExtra.remove(dbPath)\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(`Error deleting the database in ${dbPath}`, error)\n\t}\n}\n\nasync function readDb() {\n\tif (process.env.EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (await fsExtra.exists(dbPath)) {\n\t\t\tconst db = DataSchema.parse(await fsExtra.readJSON(dbPath))\n\t\t\treturn db\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t`Error reading the database in ${dbPath}, moving it to a .bkp file to avoid parsing errors in the future`,\n\t\t\terror,\n\t\t)\n\t\tvoid fsExtra.move(dbPath, `${dbPath}.bkp`).catch(() => {})\n\t}\n\treturn null\n}\n\nexport async function getAuthInfo() {\n\tconst data = await readDb()\n\treturn data?.authInfo ?? null\n}\n\nexport async function getUserInfo() {\n\tconst db = await readDb()\n\tif (!db?.authInfo) return null\n\n\treturn {\n\t\tid: db.authInfo.id,\n\t\tname: db.discordMember?.displayName ?? db.authInfo.name ?? null,\n\t\temail: db.authInfo.email,\n\t\tavatarUrl:\n\t\t\tdb.discordMember?.avatarURL ??\n\t\t\tgetGravatar({ email: db.authInfo.email, size: 288 }),\n\t}\n}\n\nfunction getGravatar({ email, size }: { email: string; size: number }) {\n\tconst gravatarOptions = new URLSearchParams({\n\t\tsize: size.toString(),\n\t\tdefault: 'identicon',\n\t})\n\tconst gravatarUrl = `https://www.gravatar.com/avatar/${md5(\n\t\temail,\n\t)}?${gravatarOptions.toString()}`\n\treturn gravatarUrl\n}\n\nexport async function requireAuthInfo({\n\trequest,\n\tredirectTo,\n}: {\n\trequest: Request\n\tredirectTo?: string | null\n}) {\n\tconst authInfo = await getAuthInfo()\n\tif (!authInfo) {\n\t\tconst requestUrl = new URL(request.url)\n\t\tredirectTo =\n\t\t\tredirectTo === null\n\t\t\t\t? null\n\t\t\t\t: redirectTo ?? `${requestUrl.pathname}${requestUrl.search}`\n\t\tconst loginParams = redirectTo ? new URLSearchParams({ redirectTo }) : null\n\t\tconst loginRedirect = ['/login', loginParams?.toString()]\n\t\t\t.filter(Boolean)\n\t\t\t.join('?')\n\t\tthrow redirect(loginRedirect)\n\t}\n\treturn authInfo\n}\n\nexport async function setAuthInfo({\n\ttokenSet,\n\temail = 'unknown@example.com',\n\tname,\n}: {\n\ttokenSet: Partial<z.infer<typeof TokenSetSchema>>\n\temail?: string\n\tname?: string\n}) {\n\tconst data = await readDb()\n\tconst authInfo = AuthInfoSchema.parse({ tokenSet, email, name })\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, { ...data, authInfo })\n\treturn authInfo\n}\n\nexport async function getPreferences() {\n\tconst data = await readDb()\n\treturn data?.preferences ?? null\n}\n\nexport async function setPlayerPreferences(\n\tplayerPreferences: z.input<typeof PlayerPreferencesSchema>,\n) {\n\tconst data = await readDb()\n\tconst updatedData = {\n\t\t...data,\n\t\tpreferences: { ...data?.preferences, player: playerPreferences },\n\t}\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, updatedData)\n\treturn updatedData.preferences.player\n}\n\nexport async function setPresencePreferences(\n\tpresnecePreferences: z.input<typeof PresencePreferencesSchema>,\n) {\n\tconst data = await readDb()\n\tconst updatedData = {\n\t\t...data,\n\t\tpreferences: { ...data?.preferences, presence: presnecePreferences },\n\t}\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, updatedData)\n\treturn updatedData.preferences.presence\n}\n\nexport async function getDiscordMember() {\n\tconst data = await readDb()\n\treturn data?.discordMember ?? null\n}\n\nexport async function setDiscordMember(\n\tdiscordMember: z.infer<typeof DiscordMemberSchema>,\n) {\n\tconst data = await readDb()\n\tconst updatedData = {\n\t\t...data,\n\t\tdiscordMember,\n\t}\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, updatedData)\n\treturn updatedData.discordMember\n}\n\nexport async function deleteDiscordInfo() {\n\tconst data = await readDb()\n\tdelete data?.discordMember\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, data)\n}\n\nexport async function readOnboardingData() {\n\tconst data = await readDb()\n\treturn data?.onboarding ?? null\n}\n\nexport async function updateOnboardingData(onboardingData: {\n\tfinishedTourVideo: boolean\n}) {\n\tconst data = await readDb()\n\tconst updatedData = {\n\t\t...data,\n\t\tonboarding: { ...data?.onboarding, ...onboardingData },\n\t}\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, updatedData)\n\treturn updatedData.onboarding\n}\n"]}
|
|
1
|
+
{"version":3,"file":"db.server.js","sourceRoot":"","sources":["../../src/db.server.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'os'\nimport path from 'path'\nimport { redirect } from '@remix-run/node'\nimport fsExtra from 'fs-extra'\nimport md5 from 'md5-hex'\nimport { z } from 'zod'\n\nexport const DiscordMemberSchema = z.object({\n\tavatarURL: z.string().nullable().optional(),\n\tdisplayName: z.string(),\n\tid: z.string(),\n})\n\nconst TokenSetSchema = z.object({\n\taccess_token: z.string(),\n\ttoken_type: z.string(),\n\tscope: z.string(),\n})\nexport const PlayerPreferencesSchema = z\n\t.object({\n\t\tvolumeRate: z.number().optional(),\n\t\tplaybackRate: z.number().optional(),\n\t\tautoplay: z.boolean().optional(),\n\t\tsubtitle: z\n\t\t\t.object({\n\t\t\t\tid: z.string().nullable().default(null),\n\t\t\t\tmode: z\n\t\t\t\t\t.literal('disabled')\n\t\t\t\t\t.or(z.literal('hidden'))\n\t\t\t\t\t.or(z.literal('showing'))\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.default('disabled'),\n\t\t\t})\n\t\t\t.optional()\n\t\t\t.default({}),\n\t\tmuted: z.boolean().optional(),\n\t\ttheater: z.boolean().optional(),\n\t\tdefaultView: z.string().optional(),\n\t\tactiveSidebarTab: z.number().optional(),\n\t})\n\t.optional()\n\t.default({})\n\nconst PresencePreferencesSchema = z\n\t.object({\n\t\toptOut: z.boolean(),\n\t})\n\t.optional()\n\t.default({ optOut: false })\n\nconst AuthInfoSchema = z\n\t.object({\n\t\ttokenSet: TokenSetSchema,\n\t\temail: z.string(),\n\t\tname: z.string().nullable().optional(),\n\t})\n\t.transform((d) => ({ ...d, id: md5(d.email) }))\n\nconst DataSchema = z.object({\n\tonboarding: z\n\t\t.object({ finishedTourVideo: z.boolean() })\n\t\t.optional()\n\t\t.default({ finishedTourVideo: false }),\n\tpreferences: z\n\t\t.object({\n\t\t\tplayer: PlayerPreferencesSchema,\n\t\t\tpresence: PresencePreferencesSchema,\n\t\t})\n\t\t.optional()\n\t\t.default({}),\n\tauthInfo: AuthInfoSchema.optional(),\n\tdiscordMember: DiscordMemberSchema.optional(),\n})\n\nconst appDir = path.join(os.homedir(), '.epicshop')\nconst dbPath = path.join(appDir, 'data.json')\n\nexport async function deleteDb() {\n\tif (process.env.EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (await fsExtra.exists(dbPath)) {\n\t\t\tawait fsExtra.remove(dbPath)\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(`Error deleting the database in ${dbPath}`, error)\n\t}\n}\n\nasync function readDb() {\n\tif (process.env.EPICSHOP_DEPLOYED) return null\n\n\ttry {\n\t\tif (await fsExtra.exists(dbPath)) {\n\t\t\tconst db = DataSchema.parse(await fsExtra.readJSON(dbPath))\n\t\t\treturn db\n\t\t}\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t`Error reading the database in ${dbPath}, moving it to a .bkp file to avoid parsing errors in the future`,\n\t\t\terror,\n\t\t)\n\t\tvoid fsExtra.move(dbPath, `${dbPath}.bkp`).catch(() => {})\n\t}\n\treturn null\n}\n\nexport async function getAuthInfo() {\n\tconst data = await readDb()\n\treturn data?.authInfo ?? null\n}\n\nexport async function getUserInfo() {\n\tconst db = await readDb()\n\tif (!db?.authInfo) return null\n\n\treturn {\n\t\tid: db.authInfo.id,\n\t\tname: db.discordMember?.displayName ?? db.authInfo.name ?? null,\n\t\temail: db.authInfo.email,\n\t\tavatarUrl:\n\t\t\tdb.discordMember?.avatarURL ??\n\t\t\tgetGravatar({ email: db.authInfo.email, size: 288 }),\n\t}\n}\n\nfunction getGravatar({ email, size }: { email: string; size: number }) {\n\tconst gravatarOptions = new URLSearchParams({\n\t\tsize: size.toString(),\n\t\tdefault: 'identicon',\n\t})\n\tconst gravatarUrl = `https://www.gravatar.com/avatar/${md5(\n\t\temail,\n\t)}?${gravatarOptions.toString()}`\n\treturn gravatarUrl\n}\n\nexport async function requireAuthInfo({\n\trequest,\n\tredirectTo,\n}: {\n\trequest: Request\n\tredirectTo?: string | null\n}) {\n\tconst authInfo = await getAuthInfo()\n\tif (!authInfo) {\n\t\tconst requestUrl = new URL(request.url)\n\t\tredirectTo =\n\t\t\tredirectTo === null\n\t\t\t\t? null\n\t\t\t\t: redirectTo ?? `${requestUrl.pathname}${requestUrl.search}`\n\t\tconst loginParams = redirectTo ? new URLSearchParams({ redirectTo }) : null\n\t\tconst loginRedirect = ['/login', loginParams?.toString()]\n\t\t\t.filter(Boolean)\n\t\t\t.join('?')\n\t\tthrow redirect(loginRedirect)\n\t}\n\treturn authInfo\n}\n\nexport async function setAuthInfo({\n\ttokenSet,\n\temail = 'unknown@example.com',\n\tname,\n}: {\n\ttokenSet: Partial<z.infer<typeof TokenSetSchema>>\n\temail?: string\n\tname?: string\n}) {\n\tconst data = await readDb()\n\tconst authInfo = AuthInfoSchema.parse({ tokenSet, email, name })\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, { ...data, authInfo })\n\treturn authInfo\n}\n\nexport async function getPreferences() {\n\tconst data = await readDb()\n\treturn data?.preferences ?? null\n}\n\nexport async function setPlayerPreferences(\n\tplayerPreferences: z.input<typeof PlayerPreferencesSchema>,\n) {\n\tconst data = await readDb()\n\tconst updatedData = {\n\t\t...data,\n\t\tpreferences: { ...data?.preferences, player: playerPreferences },\n\t}\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, updatedData)\n\treturn updatedData.preferences.player\n}\n\nexport async function setPresencePreferences(\n\tpresnecePreferences: z.input<typeof PresencePreferencesSchema>,\n) {\n\tconst data = await readDb()\n\tconst updatedData = {\n\t\t...data,\n\t\tpreferences: { ...data?.preferences, presence: presnecePreferences },\n\t}\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, updatedData)\n\treturn updatedData.preferences.presence\n}\n\nexport async function getDiscordMember() {\n\tconst data = await readDb()\n\treturn data?.discordMember ?? null\n}\n\nexport async function setDiscordMember(\n\tdiscordMember: z.infer<typeof DiscordMemberSchema>,\n) {\n\tconst data = await readDb()\n\tconst updatedData = {\n\t\t...data,\n\t\tdiscordMember,\n\t}\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, updatedData)\n\treturn updatedData.discordMember\n}\n\nexport async function deleteDiscordInfo() {\n\tconst data = await readDb()\n\tdelete data?.discordMember\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, data)\n}\n\nexport async function readOnboardingData() {\n\tconst data = await readDb()\n\treturn data?.onboarding ?? null\n}\n\nexport async function updateOnboardingData(onboardingData: {\n\tfinishedTourVideo: boolean\n}) {\n\tconst data = await readDb()\n\tconst updatedData = {\n\t\t...data,\n\t\tonboarding: { ...data?.onboarding, ...onboardingData },\n\t}\n\tawait fsExtra.ensureDir(appDir)\n\tawait fsExtra.writeJSON(dbPath, updatedData)\n\treturn updatedData.onboarding\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iframe-sync.d.ts","sourceRoot":"","sources":["../../src/iframe-sync.tsx"],"names":[],"mappings":"AAwBA,KAAK,eAAe,GAAG;IACtB,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;IACpE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAA;CACzE,CAAA;AAgCD,wBAAgB,kBAAkB,CAAC,SAAS,SAAS,eAAe,EAAE,EACrE,KAAK,EACL,QAAQ,GACR,EAAE;IACF,KAAK,EAAE,SAAS,CAAA;IAChB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;CACvC,
|
|
1
|
+
{"version":3,"file":"iframe-sync.d.ts","sourceRoot":"","sources":["../../src/iframe-sync.tsx"],"names":[],"mappings":"AAwBA,KAAK,eAAe,GAAG;IACtB,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;IACpE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAA;CACzE,CAAA;AAgCD,wBAAgB,kBAAkB,CAAC,SAAS,SAAS,eAAe,EAAE,EACrE,KAAK,EACL,QAAQ,GACR,EAAE;IACF,KAAK,EAAE,SAAS,CAAA;IAChB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;CACvC,OAiDA"}
|
package/dist/esm/iframe-sync.js
CHANGED
|
@@ -59,7 +59,6 @@ export function EpicShopIFrameSync({ React, navigate, }) {
|
|
|
59
59
|
if (window.parent === window)
|
|
60
60
|
return;
|
|
61
61
|
// @ts-expect-error - this is fine 🔥
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
63
62
|
window.__epicshop__?.onHydrated?.();
|
|
64
63
|
const methods = [
|
|
65
64
|
'pushState',
|
|
@@ -71,7 +70,6 @@ export function EpicShopIFrameSync({ React, navigate, }) {
|
|
|
71
70
|
for (const method of methods) {
|
|
72
71
|
// @ts-expect-error - this is fine 🔥
|
|
73
72
|
window.history[method] = new Proxy(window.history[method], {
|
|
74
|
-
// eslint-disable-next-line no-loop-func
|
|
75
73
|
apply(target, thisArg, argArray) {
|
|
76
74
|
window.parent.postMessage({ type: 'epicshop:history-call', method, args: argArray }, '*');
|
|
77
75
|
// @ts-expect-error - this is fine too 🙃
|
|
@@ -83,10 +81,8 @@ export function EpicShopIFrameSync({ React, navigate, }) {
|
|
|
83
81
|
// listen for messages from parent
|
|
84
82
|
React.useEffect(() => {
|
|
85
83
|
function handleMessage(event) {
|
|
86
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
87
84
|
const { type, params } = event.data;
|
|
88
85
|
if (type === 'epicshop:navigate-call') {
|
|
89
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
90
86
|
navigate(...params);
|
|
91
87
|
}
|
|
92
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iframe-sync.js","sourceRoot":"","sources":["../../src/iframe-sync.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,IAAI,WAAW,GAAG,KAAK,CAAA;AAOvB,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BzC,CAAA;AAED,MAAM,UAAU,kBAAkB,CAAoC,EACrE,KAAK,EACL,QAAQ,GAIR;IACA,0BAA0B;IAC1B,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,IAAI,WAAW;YAAE,OAAM;QACvB,WAAW,GAAG,IAAI,CAAA;QAClB,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;YAAE,OAAM;QAEpC,qCAAqC;
|
|
1
|
+
{"version":3,"file":"iframe-sync.js","sourceRoot":"","sources":["../../src/iframe-sync.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,IAAI,WAAW,GAAG,KAAK,CAAA;AAOvB,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BzC,CAAA;AAED,MAAM,UAAU,kBAAkB,CAAoC,EACrE,KAAK,EACL,QAAQ,GAIR;IACA,0BAA0B;IAC1B,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,IAAI,WAAW;YAAE,OAAM;QACvB,WAAW,GAAG,IAAI,CAAA;QAClB,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;YAAE,OAAM;QAEpC,qCAAqC;QAErC,MAAM,CAAC,YAAY,EAAE,UAAU,EAAE,EAAE,CAAA;QAEnC,MAAM,OAAO,GAAG;YACf,WAAW;YACX,cAAc;YACd,IAAI;YACJ,SAAS;YACT,MAAM;SACG,CAAA;QACV,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,qCAAqC;YACrC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBAC1D,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ;oBAC9B,MAAM,CAAC,MAAM,CAAC,WAAW,CACxB,EAAE,IAAI,EAAE,uBAAuB,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EACzD,GAAG,CACH,CAAA;oBACD,yCAAyC;oBACzC,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;gBACvC,CAAC;aACD,CAAC,CAAA;QACH,CAAC;IACF,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,kCAAkC;IAClC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,SAAS,aAAa,CAAC,KAAmB;YACzC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAA;YACnC,IAAI,IAAI,KAAK,wBAAwB,EAAE,CAAC;gBACvC,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAA;YACpB,CAAC;QACF,CAAC;QACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QACjD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAClE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,OAAO,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE;QACpC,IAAI,EAAE,QAAQ;QACd,uBAAuB,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE;KACrD,CAAC,CAAA;AACH,CAAC","sourcesContent":["/*\nThis file is kinda weird. EpicShop actually bundles react and react router to\navoid getting version clashes, but this component is used in the \"host\"\napplication. Anything we use in this file will be this file's version of that\ndependency, which in the case of bundled dependencies would be different from\nthe host app's version. We want to avoid shipping two versions of React and\nreact-router to the client. So we need to accept React and navigate as props\nrather than just using those things directly.\n\nTo reduce the annoyance, we'll have the host applications have a file like this:\n\n// Ignore this file please\nimport { EpicShopIFrameSync } from '@epic-web/workshop-utils/iframe-sync'\nimport { useNavigate } from '@remix-run/react'\nimport * as React from 'react'\n\nexport function EpicShop() {\n\tconst navigate = useNavigate()\n\treturn <EpicShopIFrameSync React={React} navigate={navigate} />\n}\n\n */\nlet effectSetup = false\n\ntype CustomReactType = {\n\tuseEffect: (cb: () => (() => void) | void, deps: Array<any>) => void\n\tcreateElement: (type: string, props: any, ...children: Array<any>) => any\n}\n\nconst iframeSyncScript = /* javascript */ `\nif (window.parent !== window) {\n\twindow.__epicshop__ = window.__epicshop__ || {};\n\twindow.parent.postMessage(\n\t\t{ type: 'epicshop:loaded', url: window.location.href },\n\t\t'*'\n\t);\n\tfunction handleMessage(event) {\n\t\tconst { type, params } = event.data\n\t\tif (type === 'epicshop:navigate-call') {\n\t\t\tconst [distanceOrUrl, options] = params\n\t\t\tif (typeof distanceOrUrl === 'number') {\n\t\t\t\twindow.history.go(distanceOrUrl)\n\t\t\t} else {\n\t\t\t\tif (options?.replace) {\n\t\t\t\t\twindow.location.replace(distanceOrUrl)\n\t\t\t\t} else {\n\t\t\t\t\twindow.location.assign(distanceOrUrl)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\twindow.addEventListener('message', handleMessage)\n\twindow.__epicshop__.onHydrated = function() {\n\t\twindow.removeEventListener('message', handleMessage)\n\t};\n}\n`\n\nexport function EpicShopIFrameSync<ReactType extends CustomReactType>({\n\tReact,\n\tnavigate,\n}: {\n\tReact: ReactType\n\tnavigate: (...args: Array<any>) => void\n}) {\n\t// communicate with parent\n\tReact.useEffect(() => {\n\t\tif (effectSetup) return\n\t\teffectSetup = true\n\t\tif (window.parent === window) return\n\n\t\t// @ts-expect-error - this is fine 🔥\n\n\t\twindow.__epicshop__?.onHydrated?.()\n\n\t\tconst methods = [\n\t\t\t'pushState',\n\t\t\t'replaceState',\n\t\t\t'go',\n\t\t\t'forward',\n\t\t\t'back',\n\t\t] as const\n\t\tfor (const method of methods) {\n\t\t\t// @ts-expect-error - this is fine 🔥\n\t\t\twindow.history[method] = new Proxy(window.history[method], {\n\t\t\t\tapply(target, thisArg, argArray) {\n\t\t\t\t\twindow.parent.postMessage(\n\t\t\t\t\t\t{ type: 'epicshop:history-call', method, args: argArray },\n\t\t\t\t\t\t'*',\n\t\t\t\t\t)\n\t\t\t\t\t// @ts-expect-error - this is fine too 🙃\n\t\t\t\t\treturn target.apply(thisArg, argArray)\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}, [])\n\n\t// listen for messages from parent\n\tReact.useEffect(() => {\n\t\tfunction handleMessage(event: MessageEvent) {\n\t\t\tconst { type, params } = event.data\n\t\t\tif (type === 'epicshop:navigate-call') {\n\t\t\t\tnavigate(...params)\n\t\t\t}\n\t\t}\n\t\twindow.addEventListener('message', handleMessage)\n\t\treturn () => window.removeEventListener('message', handleMessage)\n\t}, [navigate])\n\n\treturn React.createElement('script', {\n\t\ttype: 'module',\n\t\tdangerouslySetInnerHTML: { __html: iframeSyncScript },\n\t})\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.server.d.ts","sourceRoot":"","sources":["../../src/playwright.server.ts"],"names":[],"mappings":"AAKA,wBAAsB,qBAAqB;;;KAe1C;AAuBD,wBAAgB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"playwright.server.d.ts","sourceRoot":"","sources":["../../src/playwright.server.ts"],"names":[],"mappings":"AAKA,wBAAsB,qBAAqB;;;KAe1C;AAuBD,wBAAgB,mBAAmB,SA2DlC"}
|