@epic-web/workshop-utils 6.47.6 → 6.47.7
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 → apps.server.d.ts} +1 -2
- package/dist/{esm/apps.server.js → apps.server.js} +11 -12
- package/dist/{esm/cache.server.d.ts → cache.server.d.ts} +1 -2
- package/dist/{esm/cache.server.js → cache.server.js} +5 -6
- package/dist/{esm/compile-mdx.server.d.ts → compile-mdx.server.d.ts} +2 -3
- package/dist/{esm/compile-mdx.server.js → compile-mdx.server.js} +3 -4
- package/dist/{esm/config.server.d.ts → config.server.d.ts} +0 -1
- package/dist/{esm/config.server.js → config.server.js} +2 -3
- package/dist/{esm/data-storage.server.d.ts → data-storage.server.d.ts} +0 -1
- package/dist/{esm/data-storage.server.js → data-storage.server.js} +0 -1
- package/dist/{esm/db.server.d.ts → db.server.d.ts} +1 -2
- package/dist/{esm/db.server.js → db.server.js} +3 -4
- package/dist/{esm/diff.server.d.ts → diff.server.d.ts} +2 -3
- package/dist/{esm/diff.server.js → diff.server.js} +5 -6
- package/dist/{esm/env.server.d.ts → env.server.d.ts} +0 -1
- package/dist/{esm/env.server.js → env.server.js} +1 -2
- package/dist/{esm/epic-api.server.d.ts → epic-api.server.d.ts} +1 -2
- package/dist/{esm/epic-api.server.js → epic-api.server.js} +7 -8
- package/dist/{esm/git.server.d.ts → git.server.d.ts} +1 -2
- package/dist/{esm/git.server.js → git.server.js} +8 -9
- package/dist/{esm/iframe-sync.d.ts → iframe-sync.d.ts} +0 -1
- package/dist/{esm/iframe-sync.js → iframe-sync.js} +0 -1
- package/dist/init-env.d.ts +2 -0
- package/dist/init-env.js +5 -0
- package/dist/{esm/launch-editor.server.d.ts → launch-editor.server.d.ts} +0 -1
- package/dist/{esm/launch-editor.server.js → launch-editor.server.js} +1 -2
- package/dist/{esm/logger.d.ts → logger.d.ts} +0 -1
- package/dist/{esm/logger.js → logger.js} +0 -1
- package/dist/{esm/modified-time.server.d.ts → modified-time.server.d.ts} +1 -2
- package/dist/{esm/modified-time.server.js → modified-time.server.js} +2 -3
- package/dist/{esm/notifications.server.d.ts → notifications.server.d.ts} +0 -1
- package/dist/{esm/notifications.server.js → notifications.server.js} +4 -5
- package/dist/{esm/playwright.server.d.ts → playwright.server.d.ts} +1 -2
- package/dist/{esm/playwright.server.js → playwright.server.js} +2 -3
- package/dist/{esm/process-manager.server.d.ts → process-manager.server.d.ts} +2 -3
- package/dist/{esm/process-manager.server.js → process-manager.server.js} +4 -5
- package/dist/{esm/request-context.server.d.ts → request-context.server.d.ts} +1 -2
- package/dist/{esm/request-context.server.js → request-context.server.js} +1 -2
- package/dist/{esm/test.d.ts → test.d.ts} +0 -1
- package/dist/{esm/test.js → test.js} +0 -1
- package/dist/{esm/timing.server.d.ts → timing.server.d.ts} +1 -2
- package/dist/{esm/timing.server.js → timing.server.js} +1 -2
- package/dist/{esm/user.server.d.ts → user.server.d.ts} +0 -1
- package/dist/{esm/user.server.js → user.server.js} +2 -3
- package/dist/{esm/utils.d.ts → utils.d.ts} +1 -2
- package/dist/{esm/utils.js → utils.js} +1 -2
- package/dist/utils.server.d.ts +7 -0
- package/dist/{esm/utils.server.js → utils.server.js} +4 -15
- package/dist/{esm/workshops.server.d.ts → workshops.server.d.ts} +0 -1
- package/dist/{esm/workshops.server.js → workshops.server.js} +1 -2
- package/package.json +56 -109
- package/dist/esm/apps.server.d.ts.map +0 -1
- package/dist/esm/apps.server.js.map +0 -1
- package/dist/esm/cache.server.d.ts.map +0 -1
- package/dist/esm/cache.server.js.map +0 -1
- package/dist/esm/compile-mdx.server.d.ts.map +0 -1
- package/dist/esm/compile-mdx.server.js.map +0 -1
- package/dist/esm/config.server.d.ts.map +0 -1
- package/dist/esm/config.server.js.map +0 -1
- package/dist/esm/config.test.d.ts +0 -2
- package/dist/esm/config.test.d.ts.map +0 -1
- package/dist/esm/config.test.js +0 -77
- package/dist/esm/config.test.js.map +0 -1
- package/dist/esm/data-storage.server.d.ts.map +0 -1
- package/dist/esm/data-storage.server.js.map +0 -1
- package/dist/esm/data-storage.test.d.ts +0 -2
- package/dist/esm/data-storage.test.d.ts.map +0 -1
- package/dist/esm/data-storage.test.js +0 -339
- package/dist/esm/data-storage.test.js.map +0 -1
- package/dist/esm/db.server.d.ts.map +0 -1
- package/dist/esm/db.server.js.map +0 -1
- package/dist/esm/diff.server.d.ts.map +0 -1
- package/dist/esm/diff.server.js.map +0 -1
- package/dist/esm/env.server.d.ts.map +0 -1
- package/dist/esm/env.server.js.map +0 -1
- package/dist/esm/epic-api.server.d.ts.map +0 -1
- package/dist/esm/epic-api.server.js.map +0 -1
- package/dist/esm/git.server.d.ts.map +0 -1
- package/dist/esm/git.server.js.map +0 -1
- package/dist/esm/iframe-sync.d.ts.map +0 -1
- package/dist/esm/iframe-sync.js.map +0 -1
- package/dist/esm/init-env.d.ts +0 -3
- package/dist/esm/init-env.d.ts.map +0 -1
- package/dist/esm/init-env.js +0 -6
- package/dist/esm/init-env.js.map +0 -1
- package/dist/esm/launch-editor.server.d.ts.map +0 -1
- package/dist/esm/launch-editor.server.js.map +0 -1
- package/dist/esm/logger.d.ts.map +0 -1
- package/dist/esm/logger.js.map +0 -1
- package/dist/esm/modified-time.server.d.ts.map +0 -1
- package/dist/esm/modified-time.server.js.map +0 -1
- package/dist/esm/notifications.server.d.ts.map +0 -1
- package/dist/esm/notifications.server.js.map +0 -1
- package/dist/esm/package.json +0 -3
- package/dist/esm/playwright.server.d.ts.map +0 -1
- package/dist/esm/playwright.server.js.map +0 -1
- package/dist/esm/process-manager.server.d.ts.map +0 -1
- package/dist/esm/process-manager.server.js.map +0 -1
- package/dist/esm/request-context.server.d.ts.map +0 -1
- package/dist/esm/request-context.server.js.map +0 -1
- package/dist/esm/test.d.ts.map +0 -1
- package/dist/esm/test.js.map +0 -1
- package/dist/esm/timing.server.d.ts.map +0 -1
- package/dist/esm/timing.server.js.map +0 -1
- package/dist/esm/user.server.d.ts.map +0 -1
- package/dist/esm/user.server.js.map +0 -1
- package/dist/esm/utils.d.ts.map +0 -1
- package/dist/esm/utils.js.map +0 -1
- package/dist/esm/utils.server.d.ts +0 -9
- package/dist/esm/utils.server.d.ts.map +0 -1
- package/dist/esm/utils.server.js.map +0 -1
- package/dist/esm/utils.test.d.ts +0 -2
- package/dist/esm/utils.test.d.ts.map +0 -1
- package/dist/esm/utils.test.js +0 -139
- package/dist/esm/utils.test.js.map +0 -1
- package/dist/esm/workshops.server.d.ts.map +0 -1
- package/dist/esm/workshops.server.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"epic-api.server.js","sourceRoot":"","sources":["../../src/epic-api.server.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from '@epic-web/invariant'\nimport * as cookie from 'cookie'\n\nimport md5 from 'md5-hex'\nimport { z } from 'zod'\nimport {\n\tgetExerciseApp,\n\tgetExercises,\n\tgetWorkshopFinished,\n\tgetWorkshopInstructions,\n} from './apps.server.js'\nimport { cachified, epicApiCache } from './cache.server.js'\nimport { getWorkshopConfig } from './config.server.js'\nimport { getAuthInfo, setAuthInfo } from './db.server.js'\nimport { getEnv } from './init-env.js'\nimport { logger } from './logger.js'\nimport { type Timings } from './timing.server.js'\nimport { getErrorMessage } from './utils.js'\n\n// Module-level logger for epic-api operations\nconst log = logger('epic:api')\n\nconst Transcript = z\n\t.string()\n\t.nullable()\n\t.optional()\n\t.transform((s) => s ?? 'Transcripts not available')\nconst EpicVideoInfoSchema = z.object({\n\ttitle: z.string().nullable().optional(),\n\ttranscript: Transcript,\n\tmuxPlaybackId: z.string(),\n})\n\nconst EpicVideoRegionRestrictedErrorSchema = z.object({\n\trequestCountry: z.string(),\n\trestrictedCountry: z.string(),\n\tisRegionRestricted: z.literal(true),\n})\n\nconst CachedEpicVideoInfoSchema = z\n\t.object({\n\t\ttitle: z.string().nullable().optional(),\n\t\ttranscript: Transcript,\n\t\tmuxPlaybackId: z.string(),\n\t\tstatus: z.literal('success'),\n\t\tstatusCode: z.number(),\n\t\tstatusText: z.string(),\n\t})\n\t.or(\n\t\tz.object({\n\t\t\tstatus: z.literal('error'),\n\t\t\tstatusCode: z.number(),\n\t\t\tstatusText: z.string(),\n\t\t\ttype: z.literal('unknown'),\n\t\t}),\n\t)\n\t.or(\n\t\tz.object({\n\t\t\tstatus: z.literal('error'),\n\t\t\tstatusCode: z.number(),\n\t\t\tstatusText: z.string(),\n\t\t\ttype: z.literal('region-restricted'),\n\t\t\trequestCountry: z.string(),\n\t\t\trestrictedCountry: z.string(),\n\t\t}),\n\t)\n\t.or(z.null())\n\nexport type EpicVideoInfos = Record<\n\tstring,\n\tAwaited<ReturnType<typeof getEpicVideoInfo>>\n>\n\nconst videoInfoLog = log.logger('video-info')\n\nexport async function getEpicVideoInfos(\n\tepicWebUrls?: Array<string> | null,\n\t{ request, timings }: { request?: Request; timings?: Timings } = {},\n) {\n\tif (!epicWebUrls) {\n\t\tvideoInfoLog.warn('no epic web URLs provided, returning empty object')\n\t\treturn {}\n\t}\n\n\tconst authInfo = await getAuthInfo()\n\tif (getEnv().EPICSHOP_DEPLOYED) return {}\n\n\tvideoInfoLog(`fetching epic video infos for ${epicWebUrls.length} URLs`)\n\tconst epicVideoInfos: EpicVideoInfos = {}\n\tfor (const epicVideoEmbed of epicWebUrls) {\n\t\tconst epicVideoInfo = await getEpicVideoInfo({\n\t\t\tepicVideoEmbed,\n\t\t\taccessToken: authInfo?.tokenSet.access_token,\n\t\t\trequest,\n\t\t\ttimings,\n\t\t})\n\t\tif (epicVideoInfo) {\n\t\t\tepicVideoInfos[epicVideoEmbed] = epicVideoInfo\n\t\t}\n\t}\n\tvideoInfoLog(\n\t\t`successfully fetched ${Object.keys(epicVideoInfos).length} epic video infos`,\n\t)\n\treturn epicVideoInfos\n}\n\nasync function getEpicVideoInfo({\n\tepicVideoEmbed,\n\taccessToken,\n\trequest,\n\ttimings,\n}: {\n\tepicVideoEmbed: string\n\taccessToken?: string\n\trequest?: Request\n\ttimings?: Timings\n}) {\n\tconst tokenPortion = accessToken ? md5(accessToken) : 'unauthenticated'\n\tconst key = `epic-video-info:${tokenPortion}:${epicVideoEmbed}`\n\n\tvideoInfoLog(`fetching video info for URL: ${epicVideoEmbed}`)\n\treturn cachified({\n\t\tkey,\n\t\trequest,\n\t\tcache: epicApiCache,\n\t\ttimings,\n\t\tttl: 1000 * 60 * 60,\n\t\tswr: 1000 * 60 * 60 * 24 * 365 * 10,\n\t\tofflineFallbackValue: null,\n\t\tcheckValue: CachedEpicVideoInfoSchema,\n\t\tasync getFreshValue(\n\t\t\tcontext,\n\t\t): Promise<z.infer<typeof CachedEpicVideoInfoSchema>> {\n\t\t\tconst epicUrl = new URL(epicVideoEmbed)\n\t\t\tif (\n\t\t\t\tepicUrl.host !== 'www.epicweb.dev' &&\n\t\t\t\tepicUrl.host !== 'www.epicreact.dev' &&\n\t\t\t\tepicUrl.host !== 'www.epicai.pro'\n\t\t\t) {\n\t\t\t\tvideoInfoLog.error(`unsupported host for video URL: ${epicUrl.host}`)\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\t// this may be temporary until the /tutorials/ endpoint supports /api\n\t\t\tif (epicUrl.pathname.startsWith('/tutorials/')) {\n\t\t\t\tepicUrl.pathname = epicUrl.pathname.replace(\n\t\t\t\t\t/^\\/tutorials\\//,\n\t\t\t\t\t'/workshops/',\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// special case for epicai.pro videos\n\t\t\tconst apiUrl =\n\t\t\t\tepicUrl.host === 'www.epicai.pro'\n\t\t\t\t\t? getEpicAIVideoAPIUrl(epicVideoEmbed)\n\t\t\t\t\t: `https://${epicUrl.host}/api${epicUrl.pathname}`\n\n\t\t\tvideoInfoLog(`making API request to: ${apiUrl}`)\n\t\t\tconst infoResponse = await fetch(\n\t\t\t\tapiUrl,\n\t\t\t\taccessToken\n\t\t\t\t\t? { headers: { authorization: `Bearer ${accessToken}` } }\n\t\t\t\t\t: undefined,\n\t\t\t)\n\t\t\tconst { status, statusText } = infoResponse\n\t\t\tvideoInfoLog(`API response: ${status} ${statusText}`)\n\n\t\t\tif (infoResponse.status >= 200 && infoResponse.status < 300) {\n\t\t\t\tlet rawInfo = await infoResponse.json()\n\t\t\t\t// another special case for epicai.pro videos\n\t\t\t\tif (epicUrl.host === 'www.epicai.pro') {\n\t\t\t\t\trawInfo = preprocessEpicAIVideoAPIResult(rawInfo)\n\t\t\t\t}\n\t\t\t\tconst infoResult = EpicVideoInfoSchema.safeParse(rawInfo)\n\t\t\t\tif (infoResult.success) {\n\t\t\t\t\tvideoInfoLog(`successfully parsed video info for ${epicVideoEmbed}`)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: 'success',\n\t\t\t\t\t\tstatusCode: status,\n\t\t\t\t\t\tstatusText,\n\t\t\t\t\t\t...infoResult.data,\n\t\t\t\t\t} as const\n\t\t\t\t} else {\n\t\t\t\t\t// don't cache errors for long...\n\t\t\t\t\tcontext.metadata.ttl = 1000 * 2\n\t\t\t\t\tcontext.metadata.swr = 0\n\t\t\t\t\tconst restrictedResult =\n\t\t\t\t\t\tEpicVideoRegionRestrictedErrorSchema.safeParse(rawInfo)\n\t\t\t\t\tif (restrictedResult.success) {\n\t\t\t\t\t\tvideoInfoLog.warn(`video is region restricted: ${epicVideoEmbed}`)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstatus: 'error',\n\t\t\t\t\t\t\tstatusCode: status,\n\t\t\t\t\t\t\tstatusText,\n\t\t\t\t\t\t\ttype: 'region-restricted',\n\t\t\t\t\t\t\t...restrictedResult.data,\n\t\t\t\t\t\t} as const\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvideoInfoLog.error(\n\t\t\t\t\t\t\t`API response parsing failed for ${epicVideoEmbed}`,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\turl: epicUrl.pathname,\n\t\t\t\t\t\t\t\trawInfo,\n\t\t\t\t\t\t\t\tparseError: infoResult.error,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstatus: 'error',\n\t\t\t\t\t\t\tstatusCode: 500,\n\t\t\t\t\t\t\tstatusText: 'API Data Type Mismatch',\n\t\t\t\t\t\t\ttype: 'unknown',\n\t\t\t\t\t\t} as const\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// don't cache errors for long...\n\t\t\t\tcontext.metadata.ttl = 1000 * 2\n\t\t\t\tcontext.metadata.swr = 0\n\t\t\t\tvideoInfoLog.error(`video API request failed for ${epicVideoEmbed}`, {\n\t\t\t\t\tstatus,\n\t\t\t\t\tstatusText,\n\t\t\t\t\turl: apiUrl,\n\t\t\t\t})\n\t\t\t\treturn {\n\t\t\t\t\tstatus: 'error',\n\t\t\t\t\tstatusCode: status,\n\t\t\t\t\tstatusText,\n\t\t\t\t\ttype: 'unknown',\n\t\t\t\t} as const\n\t\t\t}\n\t\t},\n\t}).catch((e) => {\n\t\tvideoInfoLog.error(\n\t\t\t`failed to fetch epic video info for ${epicVideoEmbed}:`,\n\t\t\te,\n\t\t)\n\t\tthrow e\n\t})\n}\n\nfunction getEpicAIVideoAPIUrl(epicVideoEmbed: string) {\n\tconst epicUrl = new URL(epicVideoEmbed)\n\tconst pathSegments = epicUrl.pathname.split('/').filter(Boolean)\n\n\tif (epicUrl.pathname.endsWith('/solution')) {\n\t\t// slug is right before 'solution'\n\t\tconst slug = pathSegments.at(-2)\n\t\tinvariant(slug, 'Expected slug before /solution in pathname')\n\t\treturn `https://www.epicai.pro/api/lessons/${slug}/solution`\n\t} else if (epicUrl.pathname.includes('/workshops')) {\n\t\tconst slug = pathSegments.at(-1)\n\t\tinvariant(slug, 'Expected slug at end of /workshops pathname')\n\t\treturn `https://www.epicai.pro/api/lessons?slugOrId=${slug}`\n\t} else {\n\t\tconst slug = pathSegments.at(-1)\n\t\tinvariant(slug, 'Expected slug at end of pathname')\n\t\treturn `https://www.epicai.pro/api/posts?slugOrId=${slug}`\n\t}\n}\n\nfunction preprocessEpicAIVideoAPIResult(result: any) {\n\tconst PostVideoResourceSchema = z.object({\n\t\tresource: z.object({\n\t\t\ttype: z.literal('videoResource'),\n\t\t\tfields: EpicVideoInfoSchema,\n\t\t}),\n\t})\n\tconst PostSchema = z.object({\n\t\tfields: z.object({ title: z.string() }),\n\t\tresources: z.array(z.any()).nullable(),\n\t})\n\tconst post = PostSchema.safeParse(result)\n\tif (!post.success) return null\n\tfor (const resource of post.data.resources ?? []) {\n\t\tconst videoResource = PostVideoResourceSchema.safeParse(resource)\n\n\t\tif (videoResource.success) {\n\t\t\treturn {\n\t\t\t\t...videoResource.data.resource.fields,\n\t\t\t\ttitle: post.data.fields.title,\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null\n}\n\nasync function getEpicProgress({\n\ttimings,\n\trequest,\n\tforceFresh,\n}: { timings?: Timings; request?: Request; forceFresh?: boolean } = {}) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return []\n\n\tconst authInfo = await getAuthInfo()\n\tconst {\n\t\tproduct: { host },\n\t} = getWorkshopConfig()\n\tif (!authInfo) return []\n\n\tconst tokenPart = md5(authInfo.tokenSet.access_token)\n\tconst EpicProgressSchema = z.array(\n\t\tz.object({\n\t\t\tlessonId: z.string(),\n\t\t\tcompletedAt: z.string().nullable(),\n\t\t}),\n\t)\n\n\tlog(`fetching progress from EpicWeb host: ${host}`)\n\treturn cachified({\n\t\tkey: `epic-progress:${host}:${tokenPart}`,\n\t\tcache: epicApiCache,\n\t\trequest,\n\t\ttimings,\n\t\tforceFresh,\n\t\tttl: 1000 * 2,\n\t\tswr: 1000 * 60 * 60 * 24 * 365 * 10,\n\t\tofflineFallbackValue: [],\n\t\tcheckValue: EpicProgressSchema,\n\t\tasync getFreshValue(context): Promise<z.infer<typeof EpicProgressSchema>> {\n\t\t\tconst progressUrl = `https://${host}/api/progress`\n\t\t\tlog(`making progress API request to: ${progressUrl}`)\n\n\t\t\tconst response = await fetch(progressUrl, {\n\t\t\t\theaders: {\n\t\t\t\t\tauthorization: `Bearer ${authInfo.tokenSet.access_token}`,\n\t\t\t\t},\n\t\t\t}).catch((e) => new Response(getErrorMessage(e), { status: 500 }))\n\n\t\t\tlog(`progress API response: ${response.status} ${response.statusText}`)\n\n\t\t\tif (response.status < 200 || response.status >= 300) {\n\t\t\t\tlog.error(\n\t\t\t\t\t`failed to fetch progress from EpicWeb: ${response.status} ${response.statusText}`,\n\t\t\t\t)\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Failed to fetch progress from EpicWeb: ${response.status} ${response.statusText}`,\n\t\t\t\t)\n\t\t\t\t// don't cache errors for long...\n\t\t\t\tcontext.metadata.ttl = 1000 * 2\n\t\t\t\tcontext.metadata.swr = 0\n\t\t\t\treturn []\n\t\t\t}\n\n\t\t\tconst progressData = await response.json()\n\t\t\tconst parsedProgress = EpicProgressSchema.parse(progressData)\n\t\t\tlog(`successfully fetched ${parsedProgress.length} progress entries`)\n\t\t\treturn parsedProgress\n\t\t},\n\t})\n}\n\nexport type Progress = Awaited<ReturnType<typeof getProgress>>[number]\nexport async function getProgress({\n\ttimings,\n\trequest,\n}: {\n\ttimings?: Timings\n\trequest?: Request\n} = {}) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return []\n\n\tconst authInfo = await getAuthInfo()\n\tif (!authInfo) return []\n\n\tconst {\n\t\tproduct: { slug, host },\n\t} = getWorkshopConfig()\n\tif (!slug) return []\n\n\tlog(`aggregating progress data for workshop: ${slug}`)\n\tconst [\n\t\tworkshopData,\n\t\tepicProgress,\n\t\tworkshopInstructions,\n\t\tworkshopFinished,\n\t\texercises,\n\t] = await Promise.all([\n\t\tgetWorkshopData(slug, { request, timings }),\n\t\tgetEpicProgress({ request, timings }),\n\t\tgetWorkshopInstructions({ request }),\n\t\tgetWorkshopFinished({ request }),\n\t\tgetExercises({ request, timings }),\n\t])\n\n\ttype ProgressInfo = {\n\t\tepicLessonUrl: string\n\t\tepicLessonSlug: string\n\t\tepicCompletedAt: string | null\n\t}\n\tconst progress: Array<\n\t\tProgressInfo &\n\t\t\t(ReturnType<typeof getProgressForLesson> | { type: 'unknown' })\n\t> = []\n\n\tfor (const resource of workshopData.resources ?? []) {\n\t\tconst lessons = resource._type === 'section' ? resource.lessons : [resource]\n\t\tfor (const lesson of lessons) {\n\t\t\tconst epicLessonSlug = lesson.slug\n\t\t\tconst lessonProgress = epicProgress.find(\n\t\t\t\t({ lessonId }) => lessonId === lesson._id,\n\t\t\t)\n\t\t\tconst epicCompletedAt = lessonProgress ? lessonProgress.completedAt : null\n\t\t\tconst progressForLesson = getProgressForLesson(epicLessonSlug, {\n\t\t\t\tworkshopInstructions,\n\t\t\t\tworkshopFinished,\n\t\t\t\texercises,\n\t\t\t})\n\t\t\tconst epicLessonUrl = `https://${host}/workshops/${slug}/${epicLessonSlug}`\n\t\t\tif (progressForLesson) {\n\t\t\t\tprogress.push({\n\t\t\t\t\t...progressForLesson,\n\t\t\t\t\tepicLessonUrl,\n\t\t\t\t\tepicLessonSlug,\n\t\t\t\t\tepicCompletedAt,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tprogress.push({\n\t\t\t\t\ttype: 'unknown',\n\t\t\t\t\tepicLessonUrl,\n\t\t\t\t\tepicLessonSlug,\n\t\t\t\t\tepicCompletedAt,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\tlog(`processed ${progress.length} progress entries for workshop: ${slug}`)\n\treturn progress\n}\n\nfunction getProgressForLesson(\n\tepicLessonSlug: string,\n\t{\n\t\tworkshopInstructions,\n\t\tworkshopFinished,\n\t\texercises,\n\t}: {\n\t\tworkshopInstructions: Awaited<ReturnType<typeof getWorkshopInstructions>>\n\t\tworkshopFinished: Awaited<ReturnType<typeof getWorkshopFinished>>\n\t\texercises: Awaited<ReturnType<typeof getExercises>>\n\t},\n) {\n\tconst hasEmbed = (embed?: Array<string>) =>\n\t\tembed?.some((e) => e.split('/').at(-1) === epicLessonSlug)\n\tif (\n\t\tworkshopInstructions.compiled.status === 'success' &&\n\t\thasEmbed(workshopInstructions.compiled.epicVideoEmbeds)\n\t) {\n\t\treturn { type: 'workshop-instructions' } as const\n\t}\n\tif (\n\t\tworkshopFinished.compiled.status === 'success' &&\n\t\thasEmbed(workshopFinished.compiled.epicVideoEmbeds)\n\t) {\n\t\treturn { type: 'workshop-finished' } as const\n\t}\n\tfor (const exercise of exercises) {\n\t\tif (hasEmbed(exercise.instructionsEpicVideoEmbeds)) {\n\t\t\treturn {\n\t\t\t\ttype: 'instructions',\n\t\t\t\texerciseNumber: exercise.exerciseNumber,\n\t\t\t} as const\n\t\t}\n\t\tif (hasEmbed(exercise.finishedEpicVideoEmbeds)) {\n\t\t\treturn {\n\t\t\t\ttype: 'finished',\n\t\t\t\texerciseNumber: exercise.exerciseNumber,\n\t\t\t} as const\n\t\t}\n\t\tfor (const step of exercise.steps.filter(Boolean)) {\n\t\t\tif (hasEmbed(step.problem?.epicVideoEmbeds)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'step',\n\t\t\t\t\texerciseNumber: exercise.exerciseNumber,\n\t\t\t\t\tstepNumber: step.stepNumber,\n\t\t\t\t} as const\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function updateProgress(\n\t{ lessonSlug, complete }: { lessonSlug: string; complete?: boolean },\n\t{\n\t\ttimings,\n\t\trequest,\n\t}: {\n\t\ttimings?: Timings\n\t\trequest?: Request\n\t} = {},\n) {\n\tif (getEnv().EPICSHOP_DEPLOYED) {\n\t\treturn {\n\t\t\tstatus: 'error',\n\t\t\terror: 'cannot update progress when deployed',\n\t\t} as const\n\t}\n\n\tconst authInfo = await getAuthInfo()\n\tif (!authInfo) {\n\t\treturn { status: 'error', error: 'not authenticated' } as const\n\t}\n\n\tconst {\n\t\tproduct: { host },\n\t} = getWorkshopConfig()\n\n\tconst progressUrl = `https://${host}/api/progress`\n\tconst payload = complete ? { lessonSlug } : { lessonSlug, remove: true }\n\n\tlog(`updating progress for lesson: ${lessonSlug} (complete: ${complete})`)\n\tlog(\n\t\t`making POST request to: ${progressUrl} with payload: ${JSON.stringify(payload)}`,\n\t)\n\n\tconst response = await fetch(progressUrl, {\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\tauthorization: `Bearer ${authInfo.tokenSet.access_token}`,\n\t\t\t'content-type': 'application/json',\n\t\t},\n\t\tbody: JSON.stringify(payload),\n\t}).catch((e) => new Response(getErrorMessage(e), { status: 500 }))\n\n\tlog(`progress update response: ${response.status} ${response.statusText}`)\n\n\t// force the progress to be fresh whether or not we're successful\n\tawait getEpicProgress({ forceFresh: true, request, timings })\n\n\tif (response.status < 200 || response.status >= 300) {\n\t\tlog(`progress update failed: ${response.status} ${response.statusText}`)\n\t\treturn {\n\t\t\tstatus: 'error',\n\t\t\terror: `${response.status} ${response.statusText}`,\n\t\t} as const\n\t}\n\n\tlog(`progress update successful for lesson: ${lessonSlug}`)\n\treturn { status: 'success' } as const\n}\n\nconst ModuleSchema = z.object({\n\tresources: z\n\t\t.array(\n\t\t\tz.union([\n\t\t\t\tz.object({\n\t\t\t\t\t_type: z.literal('lesson'),\n\t\t\t\t\t_id: z.string(),\n\t\t\t\t\tslug: z.string(),\n\t\t\t\t}),\n\t\t\t\tz.object({\n\t\t\t\t\t_type: z.literal('section'),\n\t\t\t\t\tlessons: z.array(z.object({ _id: z.string(), slug: z.string() })),\n\t\t\t\t}),\n\t\t\t]),\n\t\t)\n\t\t.nullable(),\n})\n\nexport async function getWorkshopData(\n\tslug: string,\n\t{\n\t\ttimings,\n\t\trequest,\n\t\tforceFresh,\n\t}: {\n\t\ttimings?: Timings\n\t\trequest?: Request\n\t\tforceFresh?: boolean\n\t} = {},\n) {\n\tif (getEnv().EPICSHOP_DEPLOYED) return { resources: [] }\n\n\tconst authInfo = await getAuthInfo()\n\t// auth is not required, but we only use it for progress which is only needed\n\t// if you're authenticated anyway.\n\tif (!authInfo) return { resources: [] }\n\n\tconst {\n\t\tproduct: { host },\n\t} = getWorkshopConfig()\n\n\tlog(`fetching workshop data for slug: ${slug} from host: ${host}`)\n\treturn cachified({\n\t\tkey: `epic-workshop-data:${host}:${slug}`,\n\t\tttl: 1000 * 60 * 5,\n\t\tswr: 1000 * 60 * 60 * 24 * 365 * 10,\n\t\tcache: epicApiCache,\n\t\trequest,\n\t\tforceFresh,\n\t\ttimings,\n\t\tofflineFallbackValue: { resources: [] },\n\t\tcheckValue: ModuleSchema,\n\t\tasync getFreshValue(): Promise<z.infer<typeof ModuleSchema>> {\n\t\t\tconst workshopUrl = `https://${host}/api/workshops/${encodeURIComponent(slug)}`\n\t\t\tlog(`making workshop data request to: ${workshopUrl}`)\n\n\t\t\tconst response = await fetch(workshopUrl).catch(\n\t\t\t\t(e) => new Response(getErrorMessage(e), { status: 500 }),\n\t\t\t)\n\n\t\t\tlog(`workshop data response: ${response.status} ${response.statusText}`)\n\n\t\t\tif (response.status < 200 || response.status >= 300) {\n\t\t\t\tlog.error(\n\t\t\t\t\t`failed to fetch workshop data from EpicWeb for ${slug}: ${response.status} ${response.statusText}`,\n\t\t\t\t)\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Failed to fetch workshop data from EpicWeb for ${slug}: ${response.status} ${response.statusText}`,\n\t\t\t\t)\n\t\t\t\treturn { resources: [] }\n\t\t\t}\n\n\t\t\tconst jsonResponse = await response.json()\n\t\t\tconst parsedData = ModuleSchema.parse(jsonResponse)\n\t\t\tlog(\n\t\t\t\t`successfully fetched workshop data for ${slug} with ${parsedData.resources?.length ?? 0} resources`,\n\t\t\t)\n\t\t\treturn parsedData\n\t\t},\n\t})\n}\n\nexport async function userHasAccessToExerciseStep({\n\texerciseNumber,\n\tstepNumber,\n\ttimings,\n\trequest,\n\tforceFresh,\n}: {\n\texerciseNumber: number\n\tstepNumber: number\n\trequest?: Request\n\ttimings?: Timings\n\tforceFresh?: boolean\n}) {\n\tconst hasAccessToWorkshop = await userHasAccessToWorkshop({\n\t\trequest,\n\t\ttimings,\n\t\tforceFresh,\n\t})\n\tif (hasAccessToWorkshop) return true\n\n\tif (getEnv().EPICSHOP_DEPLOYED) return false\n\n\t// if they have access to the solution then they have access to the exercise step\n\tconst exerciseApp = await getExerciseApp(\n\t\t{ exerciseNumber, stepNumber, type: 'solution' },\n\t\t{ request, timings },\n\t)\n\tif (!exerciseApp) return false\n\n\tconst [firstVideoEmbed] = exerciseApp.epicVideoEmbeds ?? []\n\tif (!firstVideoEmbed) return true\n\n\tconst authInfo = await getAuthInfo()\n\tif (!authInfo) return false\n\n\tconst videoInfo = await getEpicVideoInfo({\n\t\taccessToken: authInfo.tokenSet.access_token,\n\t\tepicVideoEmbed: firstVideoEmbed,\n\t\trequest,\n\t\ttimings,\n\t})\n\n\treturn videoInfo?.status === 'success'\n}\n\nfunction tryGetWorkshopProduct(): { host?: string; slug?: string } {\n\ttry {\n\t\tconst config = getWorkshopConfig()\n\t\treturn { host: config.product.host, slug: config.product.slug }\n\t} catch {\n\t\treturn {}\n\t}\n}\n\nexport async function userHasAccessToWorkshop({\n\ttimings,\n\trequest,\n\tforceFresh,\n\tproductHost,\n\tworkshopSlug,\n}: {\n\trequest?: Request\n\ttimings?: Timings\n\tforceFresh?: boolean\n\tproductHost?: string\n\tworkshopSlug?: string\n} = {}) {\n\tconst configProduct = tryGetWorkshopProduct()\n\tconst host = productHost ?? configProduct.host\n\tconst slug = workshopSlug ?? configProduct.slug\n\tif (!slug) return true\n\n\tif (getEnv().EPICSHOP_DEPLOYED) {\n\t\tconst cookieHeader = request?.headers.get('Cookie')\n\t\tif (!cookieHeader) return false\n\t\tconst cookies = cookie.parse(cookieHeader)\n\t\treturn cookies.skill?.split(',').includes(slug) ?? false\n\t}\n\n\tconst authInfo = await getAuthInfo({ productHost: host })\n\tif (!authInfo) return false\n\n\treturn cachified({\n\t\tkey: `user-has-access-to-workshop:${host}:${slug}`,\n\t\tcache: epicApiCache,\n\t\trequest,\n\t\tforceFresh,\n\t\ttimings,\n\t\tttl: 1000 * 5,\n\t\tofflineFallbackValue: false,\n\t\tcheckValue: z.boolean(),\n\t\tasync getFreshValue(context) {\n\t\t\tconst accessUrl = `https://${host}/api/workshops/${encodeURIComponent(slug)}/access`\n\t\t\tlog(`checking workshop access via API: ${accessUrl}`)\n\n\t\t\tconst response = await fetch(accessUrl, {\n\t\t\t\theaders: {\n\t\t\t\t\tauthorization: `Bearer ${authInfo.tokenSet.access_token}`,\n\t\t\t\t},\n\t\t\t}).catch((e) => new Response(getErrorMessage(e), { status: 500 }))\n\n\t\t\tlog(\n\t\t\t\t`workshop access API response: ${response.status} ${response.statusText}`,\n\t\t\t)\n\n\t\t\tconst hasAccess = response.ok ? (await response.json()) === true : false\n\t\t\tlog(`workshop access result for ${slug}: ${hasAccess}`)\n\n\t\t\tif (hasAccess) {\n\t\t\t\tcontext.metadata.ttl = 1000 * 60 * 5\n\t\t\t\tcontext.metadata.swr = 1000 * 60 * 60 * 24 * 365 * 10\n\t\t\t}\n\n\t\t\treturn hasAccess\n\t\t},\n\t}).catch((e) => {\n\t\tconsole.error('Failed to check workshop access', e)\n\t\treturn false\n\t})\n}\n\nconst UserInfoSchema = z\n\t.object({\n\t\tid: z.string(),\n\t\tname: z.string().nullable(),\n\t\temail: z.string().email(),\n\t\timage: z.string().nullable(),\n\t\tdiscordProfile: z\n\t\t\t.object({\n\t\t\t\tnick: z.string().nullable().optional(),\n\t\t\t\tuser: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tid: z.string(),\n\t\t\t\t\t\tusername: z.string(),\n\t\t\t\t\t\tavatar: z.string().nullable().optional(),\n\t\t\t\t\t\tglobal_name: z.string().nullable().optional(),\n\t\t\t\t\t})\n\t\t\t\t\t.optional(),\n\t\t\t})\n\t\t\t.nullable()\n\t\t\t.optional(),\n\t})\n\t.transform((data) => {\n\t\treturn {\n\t\t\t...data,\n\t\t\timageUrlSmall:\n\t\t\t\tresizeImageUrl(data.image, { size: 64 }) ??\n\t\t\t\tresolveDiscordAvatar(data.discordProfile?.user, {\n\t\t\t\t\tsize: 64,\n\t\t\t\t}) ??\n\t\t\t\tresolveGravatarUrl(data.email, { size: 64 }),\n\t\t\timageUrlLarge:\n\t\t\t\tresizeImageUrl(data.image, { size: 512 }) ??\n\t\t\t\tresolveDiscordAvatar(data.discordProfile?.user, {\n\t\t\t\t\tsize: 512,\n\t\t\t\t}) ??\n\t\t\t\tresolveGravatarUrl(data.email, { size: 512 }),\n\t\t}\n\t})\n\nfunction resizeImageUrl(url: string | null, { size }: { size: number }) {\n\tif (!url) return null\n\tconst urlObj = new URL(url)\n\turlObj.searchParams.set('size', size.toString())\n\treturn urlObj.toString()\n}\n\nfunction resolveGravatarUrl(\n\temail: string | undefined,\n\t{ size }: { size: number },\n) {\n\tif (!email) return null\n\n\tconst hash = md5(email.toLowerCase())\n\tconst gravatarOptions = new URLSearchParams({\n\t\tsize: size.toString(),\n\t\tdefault: 'identicon',\n\t})\n\treturn `https://www.gravatar.com/avatar/${hash}?${gravatarOptions.toString()}`\n}\n\nfunction resolveDiscordAvatar(\n\tuser: { avatar?: string | null; id: string } | undefined,\n\t{ size }: { size: 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 },\n) {\n\tif (!user) return null\n\n\tconst { avatar, id: userId } = user\n\tif (!avatar) return null\n\tconst isGif = avatar.startsWith('a_')\n\tconst url = new URL(\n\t\t`/avatars/${userId}/${avatar}.${isGif ? 'gif' : 'png'}`,\n\t\t'https://cdn.discordapp.com',\n\t)\n\turl.searchParams.set('size', size.toString())\n\treturn url.toString()\n}\n\nexport type UserInfo = z.infer<typeof UserInfoSchema>\n\nconst userinfoLog = log.logger('userinfo')\nexport async function getUserInfo({\n\ttimings,\n\trequest,\n\tforceFresh,\n}: {\n\ttimings?: Timings\n\trequest?: Request\n\tforceFresh?: boolean\n} = {}) {\n\tconst authInfo = await getAuthInfo()\n\tif (!authInfo) return null\n\n\tconst { tokenSet } = authInfo\n\tconst {\n\t\tproduct: { host },\n\t} = getWorkshopConfig()\n\n\tconst accessToken = tokenSet.access_token\n\tconst url = `https://${host}/oauth/userinfo`\n\n\tuserinfoLog(`calling cachified to get user info from: ${url}`)\n\tconst userInfo = await cachified({\n\t\tkey: `${url}:${md5(accessToken)}`,\n\t\tcache: epicApiCache,\n\t\trequest,\n\t\tforceFresh,\n\t\ttimings,\n\t\tttl: 1000 * 30,\n\t\tswr: 1000 * 60 * 60 * 24 * 365 * 10,\n\t\tofflineFallbackValue: null,\n\t\tcheckValue: UserInfoSchema,\n\t\tasync getFreshValue(): Promise<UserInfo> {\n\t\t\tuserinfoLog(`getting fresh value for user info from: ${url}`)\n\n\t\t\tconst response = await fetch(url, {\n\t\t\t\theaders: { authorization: `Bearer ${accessToken}` },\n\t\t\t}).catch((e) => new Response(getErrorMessage(e), { status: 500 }))\n\n\t\t\tuserinfoLog(\n\t\t\t\t`user info API response: ${response.status} ${response.statusText}`,\n\t\t\t)\n\n\t\t\tif (!response.ok) {\n\t\t\t\tuserinfoLog(\n\t\t\t\t\t`user info API request failed: ${response.status} ${response.statusText}`,\n\t\t\t\t)\n\t\t\t\tif (\n\t\t\t\t\tresponse.headers.get('content-type')?.includes('application/json')\n\t\t\t\t) {\n\t\t\t\t\tconst data = await response.json()\n\t\t\t\t\tthrow new Error(`Failed to fetch user info: ${JSON.stringify(data)}`)\n\t\t\t\t} else {\n\t\t\t\t\tconst text = await response.text()\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Failed to fetch user info: ${text || response.statusText}`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst data = await response.json()\n\t\t\tconst parsedUserInfo = UserInfoSchema.parse(data)\n\t\t\tuserinfoLog(\n\t\t\t\t`successfully fetched user info for user: ${parsedUserInfo.id} (${parsedUserInfo.email})`,\n\t\t\t)\n\t\t\treturn parsedUserInfo\n\t\t},\n\t}).catch((e) => {\n\t\tuserinfoLog.error(`failed to get user info:`, e)\n\t\treturn null\n\t})\n\n\t// we used to md5 hash the email to get the id\n\t// if the id doesn't match what we have on file, update it\n\t// you can probably safely remove this in January 2025\n\tif (userInfo && authInfo.id !== userInfo.id) {\n\t\tawait setAuthInfo({\n\t\t\t...authInfo,\n\t\t\tid: userInfo.id,\n\t\t})\n\t}\n\n\treturn userInfo\n}\n\nexport async function warmCache() {\n\tawait Promise.all([getUserInfo(), getProgress()])\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git.server.d.ts","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAiFtB,wBAAsB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEpC;AAED,wBAAsB,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAc1C;AAED,wBAAsB,eAAe;;;;;;;;;GAmDpC;AAED,wBAAsB,aAAa;;;;UAelC;AAED,wBAAsB,2BAA2B,2BAehD;AAED,wBAAsB,uBAAuB,qBAiB5C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git.server.js","sourceRoot":"","sources":["../../src/git.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { execa, execaCommand } from 'execa'\nimport { getWorkshopRoot } from './apps.server.js'\nimport { cachified, checkForUpdatesCache } from './cache.server.js'\nimport { getWorkshopConfig } from './config.server.js'\nimport { getEnv } from './env.server.js'\nimport { logger } from './logger.js'\nimport { getErrorMessage } from './utils.js'\nimport { checkConnection } from './utils.server.js'\n\nconst gitLog = logger('epic:git')\n\nfunction dirHasTrackedFiles(cwd: string, dirPath: string) {\n\treturn execa('git', ['ls-files', dirPath], { cwd }).then(\n\t\t(s) => s.stdout.trim().length > 0,\n\t\t() => true,\n\t)\n}\n\nfunction isDirectory(dirPath: string) {\n\treturn fs.stat(dirPath).then(\n\t\t(s) => s.isDirectory(),\n\t\t() => false,\n\t)\n}\n\nasync function cleanupEmptyExerciseDirectories(cwd: string) {\n\tconsole.log('🧹 Cleaning up empty exercise directories...')\n\ttry {\n\t\tconst exercisesDirPath = path.join(cwd, 'exercises')\n\t\tconst exercisesDirs = (await fs.readdir(exercisesDirPath)).sort()\n\t\tfor (const exerciseDir of exercisesDirs) {\n\t\t\tconst exerciseDirPath = path.join(exercisesDirPath, exerciseDir)\n\t\t\tif (!(await isDirectory(exerciseDirPath))) continue\n\n\t\t\tif (!(await dirHasTrackedFiles(cwd, exerciseDirPath))) {\n\t\t\t\tgitLog.info(`Deleting empty exercise directory: ${exerciseDirPath}`)\n\t\t\t\tawait fs.rm(exerciseDirPath, { recursive: true, force: true })\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst stepDirs = (await fs.readdir(exerciseDirPath)).sort()\n\t\t\tfor (const stepDir of stepDirs) {\n\t\t\t\tconst stepDirPath = path.join(exerciseDirPath, stepDir)\n\t\t\t\tif (!(await isDirectory(stepDirPath))) continue\n\n\t\t\t\tif (!(await dirHasTrackedFiles(cwd, stepDirPath))) {\n\t\t\t\t\tgitLog.info(`Deleting empty step directory: ${stepDirPath}`)\n\t\t\t\t\tawait fs.rm(stepDirPath, { recursive: true, force: true })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconsole.warn(\n\t\t\t'⚠️ Warning: Failed to cleanup empty directories:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t}\n}\n\nasync function getDiffUrl(commitBefore: string, commitAfter: string) {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout: remoteUrl } = await execaCommand(\n\t\t\t'git config --get remote.origin.url',\n\t\t\t{ cwd },\n\t\t)\n\t\tconst [, username, repoName] =\n\t\t\tremoteUrl.match(/(?:[^/]+\\/|:)([^/]+)\\/([^.]+)\\.git/) ?? []\n\t\tconst diffUrl = `https://github.com/${username}/${repoName}/compare/${commitBefore}...${commitAfter}`\n\t\treturn diffUrl\n\t} catch (error) {\n\t\tconsole.error('Failed to get repository info:', getErrorMessage(error))\n\t\treturn null\n\t}\n}\n\nexport async function checkForUpdates() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn { updatesAvailable: false, message: 'The app is deployed' } as const\n\t}\n\n\tconst cwd = getWorkshopRoot()\n\tconst online = await checkConnection()\n\tif (!online) {\n\t\treturn { updatesAvailable: false, message: 'You are offline' } as const\n\t}\n\n\tconst isInRepo = await execaCommand('git rev-parse --is-inside-work-tree', {\n\t\tcwd,\n\t}).then(\n\t\t() => true,\n\t\t() => false,\n\t)\n\tif (!isInRepo) {\n\t\treturn { updatesAvailable: false, message: 'Not in a git repo' } as const\n\t}\n\n\tconst { stdout: remote } = await execaCommand('git remote', { cwd })\n\tif (!remote) {\n\t\treturn { updatesAvailable: false, message: 'Cannot find remote' } as const\n\t}\n\n\tlet localCommit, remoteCommit\n\ttry {\n\t\tconst currentBranch = (\n\t\t\tawait execaCommand('git rev-parse --abbrev-ref HEAD', { cwd })\n\t\t).stdout.trim()\n\n\t\tlocalCommit = (\n\t\t\tawait execaCommand('git rev-parse --short HEAD', { cwd })\n\t\t).stdout.trim()\n\n\t\tawait execaCommand('git fetch --all', { cwd })\n\n\t\tremoteCommit = (\n\t\t\tawait execaCommand(`git rev-parse --short origin/${currentBranch}`, {\n\t\t\t\tcwd,\n\t\t\t})\n\t\t).stdout.trim()\n\n\t\tconst { stdout } = await execa(\n\t\t\t'git',\n\t\t\t['rev-list', '--count', '--left-right', 'HEAD...@{upstream}'],\n\t\t\t{ cwd },\n\t\t)\n\t\tconst [, behind = 0] = stdout.trim().split(/\\s+/).map(Number)\n\t\tconst updatesAvailable = behind > 0\n\n\t\treturn {\n\t\t\tupdatesAvailable,\n\t\t\tlocalCommit,\n\t\t\tremoteCommit,\n\t\t\tdiffLink: await getDiffUrl(localCommit, remoteCommit),\n\t\t\tmessage: null,\n\t\t} as const\n\t} catch (error) {\n\t\tconsole.error('Unable to check for updates', getErrorMessage(error))\n\t\treturn {\n\t\t\tupdatesAvailable: false,\n\t\t\tlocalCommit,\n\t\t\tremoteCommit,\n\t\t\tdiffLink:\n\t\t\t\tlocalCommit && remoteCommit\n\t\t\t\t\t? await getDiffUrl(localCommit, remoteCommit)\n\t\t\t\t\t: null,\n\t\t} as const\n\t}\n}\n\nexport async function checkForUpdatesCached() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn { updatesAvailable: false } as const\n\t}\n\n\tconst key = 'checkForUpdates'\n\treturn cachified({\n\t\tttl: 1000 * 60,\n\t\tswr: 1000 * 60 * 60 * 24,\n\t\tkey,\n\t\tgetFreshValue: checkForUpdates,\n\t\tcache: checkForUpdatesCache,\n\t})\n}\n\nexport async function updateLocalRepo() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\treturn {\n\t\t\tstatus: 'error',\n\t\t\tmessage: 'Updates are not available in deployed environments.',\n\t\t} as const\n\t}\n\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst updates = await checkForUpdates()\n\t\tif (!updates.updatesAvailable) {\n\t\t\treturn {\n\t\t\t\tstatus: 'success',\n\t\t\t\tmessage: updates.message ?? 'No updates available.',\n\t\t\t} as const\n\t\t}\n\n\t\tconst uncommittedChanges =\n\t\t\t(await execaCommand('git status --porcelain', { cwd })).stdout.trim()\n\t\t\t\t.length > 0\n\n\t\tif (uncommittedChanges) {\n\t\t\tconsole.log('👜 Stashing uncommitted changes...')\n\t\t\tawait execaCommand('git stash --include-untracked', { cwd })\n\t\t}\n\n\t\tconsole.log('⬇️ Pulling latest changes...')\n\t\tawait execaCommand('git pull origin HEAD', { cwd })\n\n\t\tif (uncommittedChanges) {\n\t\t\tconsole.log('👜 re-applying stashed changes...')\n\t\t\tawait execaCommand('git stash pop', { cwd })\n\t\t}\n\n\t\tconsole.log('📦 Re-installing dependencies...')\n\t\tawait execaCommand('npm install', { cwd, stdio: 'inherit' })\n\n\t\tawait cleanupEmptyExerciseDirectories(cwd)\n\n\t\tconst postUpdateScript = getWorkshopConfig().scripts?.postupdate\n\t\tif (postUpdateScript) {\n\t\t\tconsole.log('🏃 Running post update script...')\n\t\t\tawait execaCommand(postUpdateScript, { cwd, stdio: 'inherit' })\n\t\t}\n\n\t\treturn { status: 'success', message: 'Updated successfully.' } as const\n\t} catch (error) {\n\t\treturn { status: 'error', message: getErrorMessage(error) } as const\n\t}\n}\n\nexport async function getCommitInfo() {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout: hash } = await execaCommand('git rev-parse HEAD', { cwd })\n\t\tconst { stdout: message } = await execaCommand('git log -1 --pretty=%B', {\n\t\t\tcwd,\n\t\t})\n\t\tconst { stdout: date } = await execaCommand('git log -1 --format=%cI', {\n\t\t\tcwd,\n\t\t})\n\t\treturn { hash: hash.trim(), message: message.trim(), date: date.trim() }\n\t} catch (error) {\n\t\tconsole.error('Failed to get commit info:', getErrorMessage(error))\n\t\treturn null\n\t}\n}\n\nexport async function getLatestWorkshopAppVersion() {\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout } = await execaCommand(\n\t\t\t'npm view @epic-web/workshop-app version',\n\t\t\t{ cwd },\n\t\t)\n\t\treturn stdout.trim()\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t'Failed to get latest workshop app version:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t\treturn null\n\t}\n}\n\nexport async function checkForExerciseChanges() {\n\tconst ENV = getEnv()\n\tif (ENV.EPICSHOP_DEPLOYED) return false\n\n\tconst cwd = getWorkshopRoot()\n\ttry {\n\t\tconst { stdout } = await execaCommand('git status --porcelain exercises/', {\n\t\t\tcwd,\n\t\t})\n\t\treturn stdout.trim().length > 0\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t'Failed to check for exercise changes:',\n\t\t\tgetErrorMessage(error),\n\t\t)\n\t\treturn false\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"iframe-sync.d.ts","sourceRoot":"","sources":["../../src/iframe-sync.tsx"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,QAGjD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"iframe-sync.js","sourceRoot":"","sources":["../../src/iframe-sync.tsx"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,MAAe;IACjD,WAAW;IACX,OAAO,IAAI,CAAA;AACZ,CAAC","sourcesContent":["export function EpicShopIFrameSync(_props: unknown) {\n\t// no-op...\n\treturn null\n}\n"]}
|
package/dist/esm/init-env.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"init-env.d.ts","sourceRoot":"","sources":["../../src/init-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAK9C,OAAO,EAAE,MAAM,EAAE,CAAA"}
|
package/dist/esm/init-env.js
DELETED
package/dist/esm/init-env.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"init-env.js","sourceRoot":"","sources":["../../src/init-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,IAAI,EAAE,CAAA;AACZ,MAAM,GAAG,GAAG,MAAM,EAAE,CACnB;AAAC,MAAc,CAAC,GAAG,GAAG,GAAG,CAAA;AAC1B,OAAO,EAAE,MAAM,EAAE,CAAA","sourcesContent":["import { init, getEnv } from './env.server.js'\n\nawait init()\nconst ENV = getEnv()\n;(global as any).ENV = ENV\nexport { getEnv }\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"launch-editor.server.d.ts","sourceRoot":"","sources":["../../src/launch-editor.server.ts"],"names":[],"mappings":"AAwRA,MAAM,MAAM,MAAM,GACf;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AACvC,wBAAsB,YAAY,CACjC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAC3B,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAU,GACnB,OAAO,CAAC,MAAM,CAAC,CAiLjB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"launch-editor.server.js","sourceRoot":"","sources":["../../src/launch-editor.server.ts"],"names":[],"mappings":"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","sourcesContent":["// copied (and barely modified) from create-react-app:\n// https://github.com/facebook/create-react-app/blob/d960b9e38c062584ff6cfb1a70e1512509a966e7/packages/react-dev-utils/launchEditor.js\n\nimport child_process from 'child_process'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport fsExtra from 'fs-extra'\nimport shellQuote from 'shell-quote'\nimport { getRelativePath } from './apps.server.js'\n\nfunction readablePath(filePath: string = '') {\n\tconst relative = getRelativePath(filePath)\n\tconst name = path.basename(relative)\n\tconst dir = path.dirname(relative)\n\treturn `'${name}' from:\\n'${dir}'`\n}\n\nfunction isTerminalEditor(editor: string) {\n\tswitch (editor) {\n\t\tcase 'vim':\n\t\tcase 'emacs':\n\t\tcase 'nano':\n\t\t\treturn true\n\t}\n\treturn false\n}\n\n// Map from full process name to binary that starts the process\n// We can't just re-use full process name, because it will spawn a new instance\n// of the app every time\nconst COMMON_EDITORS_OSX = {\n\t'/Applications/Atom.app/Contents/MacOS/Atom': 'atom',\n\t'/Applications/Atom Beta.app/Contents/MacOS/Atom Beta':\n\t\t'/Applications/Atom Beta.app/Contents/MacOS/Atom Beta',\n\t'/Applications/Brackets.app/Contents/MacOS/Brackets': 'brackets',\n\t'/Applications/Sublime Text.app/Contents/MacOS/Sublime Text':\n\t\t'/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl',\n\t'/Applications/Sublime Text Dev.app/Contents/MacOS/Sublime Text':\n\t\t'/Applications/Sublime Text Dev.app/Contents/SharedSupport/bin/subl',\n\t'/Applications/Sublime Text 2.app/Contents/MacOS/Sublime Text 2':\n\t\t'/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl',\n\t'/Applications/Cursor.app/Contents/MacOS/Cursor': 'cursor',\n\t'/Applications/Visual Studio Code.app/Contents/MacOS/Electron': 'code',\n\t'/Applications/Visual Studio Code - Insiders.app/Contents/MacOS/Electron':\n\t\t'code-insiders',\n\t'/Applications/VSCodium.app/Contents/MacOS/Electron': 'vscodium',\n\t'/Applications/AppCode.app/Contents/MacOS/appcode':\n\t\t'/Applications/AppCode.app/Contents/MacOS/appcode',\n\t'/Applications/CLion.app/Contents/MacOS/clion':\n\t\t'/Applications/CLion.app/Contents/MacOS/clion',\n\t'/Applications/IntelliJ IDEA.app/Contents/MacOS/idea':\n\t\t'/Applications/IntelliJ IDEA.app/Contents/MacOS/idea',\n\t'/Applications/PhpStorm.app/Contents/MacOS/phpstorm':\n\t\t'/Applications/PhpStorm.app/Contents/MacOS/phpstorm',\n\t'/Applications/PyCharm.app/Contents/MacOS/pycharm':\n\t\t'/Applications/PyCharm.app/Contents/MacOS/pycharm',\n\t'/Applications/PyCharm CE.app/Contents/MacOS/pycharm':\n\t\t'/Applications/PyCharm CE.app/Contents/MacOS/pycharm',\n\t'/Applications/RubyMine.app/Contents/MacOS/rubymine':\n\t\t'/Applications/RubyMine.app/Contents/MacOS/rubymine',\n\t'/Applications/WebStorm.app/Contents/MacOS/webstorm':\n\t\t'/Applications/WebStorm.app/Contents/MacOS/webstorm',\n\t'/Applications/MacVim.app/Contents/MacOS/MacVim': 'mvim',\n\t'/Applications/GoLand.app/Contents/MacOS/goland':\n\t\t'/Applications/GoLand.app/Contents/MacOS/goland',\n\t'/Applications/Rider.app/Contents/MacOS/rider':\n\t\t'/Applications/Rider.app/Contents/MacOS/rider',\n\t'/Applications/Zed/Zed.app/Contents/MacOS/zed': 'zed',\n} as const\n\nconst COMMON_EDITORS_LINUX = {\n\tatom: 'atom',\n\tBrackets: 'brackets',\n\tcursor: 'cursor',\n\tcode: 'code',\n\t'code-insiders': 'code-insiders',\n\tvscodium: 'vscodium',\n\temacs: 'emacs',\n\tgvim: 'gvim',\n\t'idea.sh': 'idea',\n\t'phpstorm.sh': 'phpstorm',\n\t'pycharm.sh': 'pycharm',\n\t'rubymine.sh': 'rubymine',\n\tsublime_text: 'sublime_text',\n\tvim: 'vim',\n\t'webstorm.sh': 'webstorm',\n\t'goland.sh': 'goland',\n\t'rider.sh': 'rider',\n\tzed: 'zed',\n}\n\nconst COMMON_EDITORS_WIN = [\n\t'Brackets.exe',\n\t'Cursor.exe',\n\t'Code.exe',\n\t'Code - Insiders.exe',\n\t'VSCodium.exe',\n\t'atom.exe',\n\t'sublime_text.exe',\n\t'notepad++.exe',\n\t'clion.exe',\n\t'clion64.exe',\n\t'idea.exe',\n\t'idea64.exe',\n\t'phpstorm.exe',\n\t'phpstorm64.exe',\n\t'pycharm.exe',\n\t'pycharm64.exe',\n\t'rubymine.exe',\n\t'rubymine64.exe',\n\t'webstorm.exe',\n\t'webstorm64.exe',\n\t'goland.exe',\n\t'goland64.exe',\n\t'rider.exe',\n\t'rider64.exe',\n\t'zed.exe',\n]\n\n// Transpiled version of: /^([A-Za-z]:[/\\\\])?[\\p{L}0-9/.\\-_\\\\]+$/u\n// Non-transpiled version requires support for Unicode property regex. Allows\n// alphanumeric characters, periods, dashes, slashes, and underscores.\nconst WINDOWS_FILE_NAME_WHITELIST =\n\t/^([A-Za-z]:[/\\\\])?(?:[\\x2D-9A-Z\\\\_a-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05D0-\\u05EA\\u05EF-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086A\\u08A0-\\u08B4\\u08B6-\\u08BD\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u09FC\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1878\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1C90-\\u1CBA\\u1CBD-\\u1CBF\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312F\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FEF\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7B9\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA8FE\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB65\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF2D-\\uDF40\\uDF42-\\uDF49\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF]|\\uD801[\\uDC00-\\uDC9D\\uDCB0-\\uDCD3\\uDCD8-\\uDCFB\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDCE0-\\uDCF2\\uDCF4\\uDCF5\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE35\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48\\uDC80-\\uDCB2\\uDCC0-\\uDCF2\\uDD00-\\uDD23\\uDF00-\\uDF1C\\uDF27\\uDF30-\\uDF45]|\\uD804[\\uDC03-\\uDC37\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD44\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDDDC\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDE80-\\uDE86\\uDE88\\uDE8A-\\uDE8D\\uDE8F-\\uDE9D\\uDE9F-\\uDEA8\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF50\\uDF5D-\\uDF61]|\\uD805[\\uDC00-\\uDC34\\uDC47-\\uDC4A\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDDD8-\\uDDDB\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA\\uDF00-\\uDF1A]|\\uD806[\\uDC00-\\uDC2B\\uDCA0-\\uDCDF\\uDCFF\\uDE00\\uDE0B-\\uDE32\\uDE3A\\uDE50\\uDE5C-\\uDE83\\uDE86-\\uDE89\\uDE9D\\uDEC0-\\uDEF8]|\\uD807[\\uDC00-\\uDC08\\uDC0A-\\uDC2E\\uDC40\\uDC72-\\uDC8F\\uDD00-\\uDD06\\uDD08\\uDD09\\uDD0B-\\uDD30\\uDD46\\uDD60-\\uDD65\\uDD67\\uDD68\\uDD6A-\\uDD89\\uDD98\\uDEE0-\\uDEF2]|\\uD808[\\uDC00-\\uDF99]|\\uD809[\\uDC80-\\uDD43]|[\\uD80C\\uD81C-\\uD820\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD811[\\uDC00-\\uDE46]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDE40-\\uDE7F\\uDF00-\\uDF44\\uDF50\\uDF93-\\uDF9F\\uDFE0\\uDFE1]|\\uD821[\\uDC00-\\uDFF1]|\\uD822[\\uDC00-\\uDEF2]|\\uD82C[\\uDC00-\\uDD1E\\uDD70-\\uDEFB]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD83A[\\uDC00-\\uDCC4\\uDD00-\\uDD43]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDED6\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF34\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D])+$/\n\nfunction addWorkspaceToArgumentsIfExists(\n\targs: Array<string>,\n\tworkspace: string | null,\n) {\n\tif (workspace) {\n\t\targs.unshift(workspace)\n\t}\n\treturn args\n}\n\nfunction getArgumentsForLineNumber(\n\teditor: string,\n\tfileName: string,\n\tlineNumber: number,\n\tcolNumber: number | undefined,\n\tworkspace: string | null,\n) {\n\tconst editorBasename = path.basename(editor).replace(/\\.(exe|cmd|bat)$/i, '')\n\tswitch (editorBasename) {\n\t\tcase 'atom':\n\t\tcase 'Atom':\n\t\tcase 'Atom Beta':\n\t\tcase 'subl':\n\t\tcase 'sublime':\n\t\tcase 'sublime_text':\n\t\t\treturn [`${fileName}:${lineNumber}:${colNumber}`]\n\t\tcase 'wstorm':\n\t\tcase 'charm':\n\t\t\treturn [`${fileName}:${lineNumber}`]\n\t\tcase 'notepad++':\n\t\t\treturn [`-n${lineNumber}`, `-c${colNumber}`, fileName]\n\t\tcase 'vim':\n\t\tcase 'mvim':\n\t\tcase 'joe':\n\t\tcase 'gvim':\n\t\t\treturn [`+${lineNumber}`, fileName]\n\t\tcase 'emacs':\n\t\tcase 'emacsclient':\n\t\t\treturn [`+${lineNumber}:${colNumber}`, fileName]\n\t\tcase 'rmate':\n\t\tcase 'mate':\n\t\tcase 'mine':\n\t\t\treturn ['--line', lineNumber, fileName]\n\t\tcase 'cursor':\n\t\tcase 'code':\n\t\tcase 'Code':\n\t\tcase 'code-insiders':\n\t\tcase 'Code - Insiders':\n\t\tcase 'vscodium':\n\t\tcase 'VSCodium':\n\t\t\treturn addWorkspaceToArgumentsIfExists(\n\t\t\t\t['-g', `${fileName}:${lineNumber}:${colNumber}`],\n\t\t\t\tworkspace,\n\t\t\t)\n\t\tcase 'appcode':\n\t\tcase 'clion':\n\t\tcase 'clion64':\n\t\tcase 'idea':\n\t\tcase 'idea64':\n\t\tcase 'phpstorm':\n\t\tcase 'phpstorm64':\n\t\tcase 'pycharm':\n\t\tcase 'pycharm64':\n\t\tcase 'rubymine':\n\t\tcase 'rubymine64':\n\t\tcase 'webstorm':\n\t\tcase 'webstorm64':\n\t\tcase 'goland':\n\t\tcase 'goland64':\n\t\tcase 'rider':\n\t\tcase 'rider64':\n\t\t\treturn addWorkspaceToArgumentsIfExists(\n\t\t\t\t['--line', lineNumber.toString(), fileName],\n\t\t\t\tworkspace,\n\t\t\t)\n\t}\n\n\t// For all others, drop the lineNumber until we have\n\t// a mapping above, since providing the lineNumber incorrectly\n\t// can result in errors or confusing behavior.\n\treturn [fileName]\n}\n\nfunction guessEditor(): Array<string | null> {\n\t// Explicit config always wins\n\tif (process.env.EPICSHOP_EDITOR) {\n\t\treturn shellQuote.parse(process.env.EPICSHOP_EDITOR).map((a) => String(a))\n\t}\n\n\t// We can find out which editor is currently running by:\n\t// `ps x` on macOS and Linux\n\t// `Get-Process` on Windows\n\ttry {\n\t\tif (process.platform === 'darwin') {\n\t\t\tconst output = child_process.execSync('ps x').toString()\n\t\t\tconst processNames = Object.keys(COMMON_EDITORS_OSX) as Array<\n\t\t\t\tkeyof typeof COMMON_EDITORS_OSX\n\t\t\t>\n\t\t\tfor (let i = 0; i < processNames.length; i++) {\n\t\t\t\tconst processName = processNames[i]\n\t\t\t\tif (processName && output.includes(processName)) {\n\t\t\t\t\tconst editor = COMMON_EDITORS_OSX[processName]\n\t\t\t\t\treturn [editor]\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (process.platform === 'win32') {\n\t\t\t// Some processes need elevated rights to get its executable path.\n\t\t\t// Just filter them out upfront. This also saves 10-20ms on the command.\n\t\t\tconst output = child_process\n\t\t\t\t.execSync(\n\t\t\t\t\t'wmic process where \"executablepath is not null\" get executablepath',\n\t\t\t\t)\n\t\t\t\t.toString()\n\t\t\tconst runningProcesses = output.split('\\r\\n')\n\t\t\tfor (let i = 0; i < runningProcesses.length; i++) {\n\t\t\t\tconst processPath = runningProcesses[i]?.trim()\n\t\t\t\tif (!processPath) continue\n\t\t\t\tconst processName = path.basename(processPath)\n\t\t\t\tif (COMMON_EDITORS_WIN.includes(processName)) {\n\t\t\t\t\treturn [processPath]\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (process.platform === 'linux') {\n\t\t\t// --no-heading No header line\n\t\t\t// x List all processes owned by you\n\t\t\t// -o comm Need only names column\n\t\t\tconst output = child_process\n\t\t\t\t.execSync('ps x --no-heading -o comm --sort=comm')\n\t\t\t\t.toString()\n\t\t\tconst processNames = Object.keys(COMMON_EDITORS_LINUX)\n\t\t\tfor (let i = 0; i < processNames.length; i++) {\n\t\t\t\tconst processName = processNames[i]\n\t\t\t\tif (!processName) continue\n\t\t\t\tif (output.includes(processName)) {\n\t\t\t\t\t// @ts-expect-error 🤷♂️ it's fine\n\t\t\t\t\treturn [COMMON_EDITORS_LINUX[processName]]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ignore...\n\t}\n\n\t// Last resort, use old skool env vars\n\tif (process.env.VISUAL) {\n\t\treturn [process.env.VISUAL]\n\t} else if (process.env.EDITOR) {\n\t\treturn [process.env.EDITOR]\n\t}\n\n\treturn [null]\n}\n\nlet _childProcess: ReturnType<typeof child_process.spawn> | null = null\nexport type Result =\n\t| { status: 'success' }\n\t| { status: 'error'; message: string }\nexport async function launchEditor(\n\tpathList: string[] | string,\n\tlineNumber: number = 1,\n\tcolNumber: number = 1,\n): Promise<Result> {\n\t// Sanitize lineNumber to prevent malicious use on win32\n\t// via: https://github.com/nodejs/node/blob/c3bb4b1aa5e907d489619fb43d233c3336bfc03d/lib/child_process.js#L333\n\t// and it should be a positive integer\n\tif (lineNumber && !(Number.isInteger(lineNumber) && lineNumber > 0)) {\n\t\treturn { status: 'error', message: 'lineNumber must be a positive integer' }\n\t}\n\n\t// colNumber is optional, but should be a positive integer too\n\t// default is 1\n\tif (colNumber && !(Number.isInteger(colNumber) && colNumber > 0)) {\n\t\tcolNumber = 1\n\t}\n\n\tconst editorInfo = guessEditor()\n\tconst editor = editorInfo[0]\n\tlet args = editorInfo.slice(1).filter(Boolean)\n\n\tif (!editor) {\n\t\treturn { status: 'error', message: 'No editor found' }\n\t}\n\n\tif (editor.toLowerCase() === 'none') {\n\t\treturn { status: 'error', message: 'Editor set to \"none\"' }\n\t}\n\n\tif (typeof pathList === 'string') {\n\t\tpathList = [pathList]\n\t}\n\n\ttype accumulator = {\n\t\tfileList: string[]\n\t\terrorsList: string[]\n\t}\n\n\tconst initArgs: accumulator = { fileList: [], errorsList: [] }\n\n\tconst { fileList, errorsList } = pathList.reduce(\n\t\t(acc: accumulator, fileName: string) => {\n\t\t\tif (\n\t\t\t\tprocess.platform === 'linux' &&\n\t\t\t\tfileName.startsWith('/mnt/') &&\n\t\t\t\t/Microsoft/i.test(os.release())\n\t\t\t) {\n\t\t\t\t// Assume WSL / \"Bash on Ubuntu on Windows\" is being used, and\n\t\t\t\t// that the file exists on the Windows file system.\n\t\t\t\t// `os.release()` is \"4.4.0-43-Microsoft\" in the current release\n\t\t\t\t// build of WSL, see: https://github.com/Microsoft/BashOnWindows/issues/423#issuecomment-221627364\n\t\t\t\t// When a Windows editor is specified, interop functionality can\n\t\t\t\t// handle the path translation, but only if a relative path is used.\n\t\t\t\tfileName = path.relative('', fileName)\n\t\t\t}\n\n\t\t\tconst fileExists = fs.existsSync(fileName)\n\t\t\t// cmd.exe on Windows is vulnerable to RCE attacks given a file name of the\n\t\t\t// form \"C:\\Users\\myusername\\Downloads\\& curl 172.21.93.52\". Use a whitelist\n\t\t\t// to validate user-provided file names. This doesn't cover the entire range\n\t\t\t// of valid file names but should cover almost all of them in practice.\n\t\t\t// if the file exists, then we're good.\n\t\t\tif (\n\t\t\t\t!fileExists &&\n\t\t\t\tprocess.platform === 'win32' &&\n\t\t\t\t!WINDOWS_FILE_NAME_WHITELIST.test(fileName)\n\t\t\t) {\n\t\t\t\tacc.errorsList.push(fileName)\n\t\t\t} else {\n\t\t\t\tif (!fileExists) {\n\t\t\t\t\tfsExtra.ensureDirSync(path.dirname(fileName))\n\t\t\t\t\tfsExtra.writeFileSync(fileName, '', 'utf8')\n\t\t\t\t}\n\n\t\t\t\tacc.fileList.push(fileName.trim())\n\t\t\t}\n\t\t\treturn acc\n\t\t},\n\t\tinitArgs,\n\t)\n\n\t// TODO: figure out how to send error messages as JSX from here...\n\tfunction getErrorMessage() {\n\t\tlet message: string\n\t\tif (errorsList.length) {\n\t\t\tconst readableName =\n\t\t\t\terrorsList.length === 1 ? readablePath(errorsList[0]) : 'some files'\n\t\t\tmessage = `Could not open ${readableName} in the editor.\\n\\nWhen running on Windows, file names are checked against a whitelist to protect against remote code execution attacks.\\nFile names may consist only of alphanumeric characters (all languages), periods, dashes, slashes, and underscores. Maybe you have your files in a folder that includes a space in the pathname? Rename the folder to remove the space and try again.`\n\t\t} else {\n\t\t\tmessage = 'pathList must contain at least one valid file path'\n\t\t}\n\t\treturn {\n\t\t\tstatus: 'error',\n\t\t\tmessage,\n\t\t} as Result\n\t}\n\n\tconst workspace = null\n\tif (lineNumber && fileList.length === 1) {\n\t\tconst fileName = fileList[0]\n\t\tif (!fileName) {\n\t\t\treturn getErrorMessage()\n\t\t}\n\t\targs = args.concat(\n\t\t\tgetArgumentsForLineNumber(\n\t\t\t\teditor,\n\t\t\t\tfileName,\n\t\t\t\tlineNumber,\n\t\t\t\tcolNumber,\n\t\t\t\tworkspace,\n\t\t\t)\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.map(String),\n\t\t)\n\t} else {\n\t\tconst argList = fileList.filter(Boolean)\n\t\tif (!argList.length) {\n\t\t\treturn getErrorMessage()\n\t\t}\n\t\targs.push(...argList)\n\t}\n\n\tif (_childProcess && isTerminalEditor(editor)) {\n\t\t// There's an existing editor process already and it's attached\n\t\t// to the terminal, so go kill it. Otherwise two separate editor\n\t\t// instances attach to the stdin/stdout which gets confusing.\n\t\t_childProcess.kill('SIGKILL')\n\t}\n\n\treturn new Promise((res) => {\n\t\tif (process.platform === 'win32') {\n\t\t\t// On Windows, launch the editor in a shell because spawn can only\n\t\t\t// launch .exe files.\n\t\t\t_childProcess = child_process.spawn(\n\t\t\t\t'cmd.exe',\n\t\t\t\t['/C', editor].concat(args).filter(Boolean),\n\t\t\t\t{ stdio: ['inherit', 'inherit', 'pipe'] },\n\t\t\t)\n\t\t} else {\n\t\t\t_childProcess = child_process.spawn(editor, args, {\n\t\t\t\tstdio: ['inherit', 'inherit', 'pipe'],\n\t\t\t})\n\t\t}\n\t\t_childProcess.stderr?.on('data', (data: string | Uint8Array) => {\n\t\t\tconst message = String(data)\n\t\t\t// Filter out the specific error message for environment variable issues\n\t\t\tif (!message.includes('Node.js environment variables are disabled')) {\n\t\t\t\tprocess.stderr.write(data) // Only write non-filtered messages to stderr\n\t\t\t}\n\t\t})\n\t\t_childProcess.on('exit', async (errorCode) => {\n\t\t\t_childProcess = null\n\n\t\t\tif (errorCode) {\n\t\t\t\tconst readableName =\n\t\t\t\t\tfileList.length === 1 ? readablePath(fileList[0]) : 'some files'\n\t\t\t\treturn res({\n\t\t\t\t\tstatus: 'error',\n\t\t\t\t\tmessage: `Could not open ${readableName} in the editor.\\n\\nThe editor process exited with an error code (${errorCode}).`,\n\t\t\t\t})\n\t\t\t} else if (errorsList.length) {\n\t\t\t\t// show error message even when the editor was opened successfully,\n\t\t\t\t// if some file path was not valid in windows\n\t\t\t\treturn res(getErrorMessage())\n\t\t\t} else {\n\t\t\t\treturn res({ status: 'success' })\n\t\t\t}\n\t\t})\n\n\t\t_childProcess.on('error', async (error: Error & { code?: string }) => {\n\t\t\tif (error.code === 'EBADF') {\n\t\t\t\treturn res({\n\t\t\t\t\tstatus: 'error',\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'Unable to launch editor. This commonly happens when running in a containerized or server environment without terminal access.',\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn res({ status: 'error', message: error.message })\n\t\t})\n\t})\n}\n"]}
|
package/dist/esm/logger.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAEtD,KAAK,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAA;AAClC,KAAK,MAAM,GAAG,OAAO,EAAE,CAAA;AACvB,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;AAEvD,UAAU,MAAO,SAAQ,WAAW,EAAE,WAAW;IAChD,KAAK,EAAE,WAAW,CAAA;IAClB,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,WAAW,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,MAAM,CAAA;CACrB;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAyBzC"}
|
package/dist/esm/logger.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAoB,MAAM,WAAW,CAAA;AActD,MAAM,UAAU,MAAM,CAAC,EAAU;IAChC,MAAM,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAExB,MAAM,gBAAgB,GAAG,CACxB,MAAqB,EACrB,UAAe,EACf,GAAG,MAAc,EAChB,EAAE;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO;YAAE,OAAM;QACjC,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;QAC3E,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAA;IACxD,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAW,CAAA;IAE5D,QAAQ,CAAC,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAClD,QAAQ,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACjD,QAAQ,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACjD,QAAQ,CAAC,SAAS,GAAG,EAAE,CAAA;IACvB,QAAQ,CAAC,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,KAAK,EAAE,CAAC,CAAA;IAC7D,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE;QAC1C,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO;KACtB,CAAC,CAAA;IAEF,OAAO,QAAQ,CAAA;AAChB,CAAC","sourcesContent":["import { debuglog, type DebugLogger } from 'node:util'\n\ntype Msg = string | (() => string)\ntype Params = unknown[]\ntype LogFunction = (msg: Msg, ...param: Params) => void\n\ninterface Logger extends LogFunction, DebugLogger {\n\terror: LogFunction\n\twarn: LogFunction\n\tinfo: LogFunction\n\tnamespace: string\n\tlogger: typeof logger\n}\n\nexport function logger(ns: string): Logger {\n\tconst log = debuglog(ns)\n\n\tconst prefixedLoggerFn = (\n\t\tprefix: string | null,\n\t\tstringOrFn: Msg,\n\t\t...params: Params\n\t) => {\n\t\tif (!debuglog(ns).enabled) return\n\t\tconst string = typeof stringOrFn === 'function' ? stringOrFn() : stringOrFn\n\t\tlog(prefix ? `${prefix} ${string}` : string, ...params)\n\t}\n\n\tconst loggerFn = prefixedLoggerFn.bind(null, null) as Logger\n\n\tloggerFn.error = prefixedLoggerFn.bind(null, '🚨')\n\tloggerFn.warn = prefixedLoggerFn.bind(null, '⚠️')\n\tloggerFn.info = prefixedLoggerFn.bind(null, 'ℹ️')\n\tloggerFn.namespace = ns\n\tloggerFn.logger = (subNs: string) => logger(`${ns}:${subNs}`)\n\tObject.defineProperty(loggerFn, 'enabled', {\n\t\tget: () => log.enabled,\n\t})\n\n\treturn loggerFn\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"modified-time.server.d.ts","sourceRoot":"","sources":["../../src/modified-time.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAQtB,iBAAe,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,EAAE,UAAkB,EAAE,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GACnD,OAAO,CAAC,MAAM,CAAC,CASjB;AA2CD,wBAAsB,wBAAwB,CAC7C,IAAI,EAAE,MAAM,EACZ,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,oBAStB;AAeD,iBAAe,wBAAwB,CACtC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,mBAK9C;AAED,OAAO,EAAE,wBAAwB,IAAI,kBAAkB,EAAE,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"modified-time.server.js","sourceRoot":"","sources":["../../src/modified-time.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isGitIgnored } from 'globby'\nimport PQueue from 'p-queue'\nimport { cachified, dirModifiedTimeCache } from './cache.server.js'\n\nasync function getDirModifiedTime(\n\tdir: string,\n\t{ forceFresh = false }: { forceFresh?: boolean } = {},\n): Promise<number> {\n\tconst result = await cachified({\n\t\tkey: dir,\n\t\tcache: dirModifiedTimeCache,\n\t\tttl: 200,\n\t\tforceFresh,\n\t\tgetFreshValue: () => getDirModifiedTimeImpl(dir),\n\t})\n\treturn result\n}\n\nasync function getDirModifiedTimeImpl(dir: string): Promise<number> {\n\tconst isIgnored = await isGitIgnored({ cwd: dir }).catch(() => () => false)\n\tconst files = await fs.promises\n\t\t.readdir(dir, { withFileTypes: true })\n\t\t.catch(() => [])\n\n\tconst modifiedTimes: Array<number> = []\n\n\tfor (const file of files) {\n\t\t// Skip ignored files\n\t\tif (isIgnored(path.join(dir, file.name))) continue\n\n\t\tconst filePath = path.join(dir, file.name)\n\n\t\tif (file.isDirectory()) {\n\t\t\tmodifiedTimes.push(await getDirModifiedTime(filePath))\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tconst { mtimeMs } = await fs.promises.stat(filePath)\n\t\t\t\tmodifiedTimes.push(mtimeMs)\n\t\t\t} catch {\n\t\t\t\t// ignore errors (e.g., file access permissions, file has been moved or deleted)\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\tconst { mtimeMs } = await fs.promises.stat(dir)\n\t\tmodifiedTimes.push(mtimeMs)\n\t} catch {\n\t\t// ignore errors (e.g., file access permissions, file has been moved or deleted)\n\t}\n\n\treturn Math.max(-1, ...modifiedTimes)\n}\n\n// this will return true as soon as one of the directories has been found to\n// have been modified more recently than the given time\n// TODO: this could be improved by not waiting for entire directories to be\n// scanned and instead stopping the scan as soon as we find a file that was\n// modified more recently than the given time\nexport async function modifiedMoreRecentlyThan(\n\ttime: number,\n\t...dirs: Array<string>\n) {\n\tconst modifiedTimePromises = dirs.map((dir) => getDirModifiedTime(dir))\n\tconst allFinishedPromise = Promise.all(modifiedTimePromises)\n\tconst firstMoreRecentPromise = modifiedTimePromises.map((p) =>\n\t\tp.then((t) => (t > time ? true : allFinishedPromise.then(() => false))),\n\t)\n\tconst firstMoreRecent = await Promise.race(firstMoreRecentPromise)\n\treturn firstMoreRecent\n}\n\nlet _queue: PQueue | null = null\nfunction getQueue() {\n\tif (_queue) return _queue\n\n\t_queue = new PQueue({\n\t\tconcurrency: 10,\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 queuedGetDirModifiedTime(\n\t...args: Parameters<typeof getDirModifiedTime>\n) {\n\tconst queue = getQueue()\n\tconst result = await queue.add(() => getDirModifiedTime(...args))\n\treturn result || -1\n}\n\nexport { queuedGetDirModifiedTime as getDirModifiedTime }\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.server.d.ts","sourceRoot":"","sources":["../../src/notifications.server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBtB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAsB7D,wBAAsB,uBAAuB;;;;;;;;;;;KAgC5C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.server.js","sourceRoot":"","sources":["../../src/notifications.server.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { getEnv } from './init-env.js'\n\nimport json5 from 'json5'\nimport { z } from 'zod'\nimport { cachified, notificationsCache } from './cache.server.js'\nimport { getWorkshopConfig } from './config.server.js'\nimport { getMutedNotifications } from './db.server.js'\n\nconst NotificationSchema = z.object({\n\tid: z.string(),\n\ttitle: z.string(),\n\tmessage: z.string(),\n\tlink: z.string().optional(),\n\ttype: z.enum(['info', 'warning', 'danger']),\n\tproducts: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\thost: z.string(),\n\t\t\t\tslug: z.string().optional(),\n\t\t\t}),\n\t\t)\n\t\t.optional(),\n\texpiresAt: z\n\t\t.string()\n\t\t.nullable()\n\t\t.transform((val) => (val ? new Date(val) : null)),\n})\n\nexport type Notification = z.infer<typeof NotificationSchema>\n\nasync function getRemoteNotifications() {\n\treturn cachified({\n\t\tkey: 'notifications',\n\t\tcache: notificationsCache,\n\t\tttl: 1000 * 60 * 60 * 6,\n\t\tswr: 1000 * 60 * 60 * 24,\n\t\tofflineFallbackValue: [],\n\t\tasync getFreshValue() {\n\t\t\tconst URL =\n\t\t\t\t'https://gist.github.com/kentcdodds/c3aaa5141f591cdbb0e6bfcacd361f39'\n\t\t\tconst filename = 'notifications.json5'\n\t\t\tconst response = await fetch(`${URL}/raw/${filename}`)\n\t\t\tconst text = await response.text()\n\t\t\tconst json = json5.parse(text)\n\n\t\t\treturn NotificationSchema.array().parse(json)\n\t\t},\n\t}).catch(() => [])\n}\n\nexport async function getUnmutedNotifications() {\n\tif (getEnv().EPICSHOP_DEPLOYED) return []\n\n\tconst remoteNotifications = await getRemoteNotifications()\n\n\tconst config = getWorkshopConfig()\n\n\tconst notificationsToShow = remoteNotifications\n\t\t.filter((n) => {\n\t\t\tif (n.expiresAt && n.expiresAt < new Date()) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\t.filter((n) => {\n\t\t\tif (!n.products) return true\n\t\t\treturn n.products.some((p) => {\n\t\t\t\treturn (\n\t\t\t\t\tp.host === config.product.host &&\n\t\t\t\t\t(p.slug ? p.slug === config.product.slug : true)\n\t\t\t\t)\n\t\t\t})\n\t\t})\n\t\t.concat(config.notifications)\n\n\tconst muted = await getMutedNotifications()\n\n\tconst visibleNotifications = notificationsToShow.filter(\n\t\t(n) => !muted.includes(n.id),\n\t)\n\n\treturn visibleNotifications\n}\n"]}
|
package/dist/esm/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.server.d.ts","sourceRoot":"","sources":["../../src/playwright.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAOtB,wBAAsB,qBAAqB;;;KAe1C;AAuBD,wBAAgB,mBAAmB,SA6DlC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.server.js","sourceRoot":"","sources":["../../src/playwright.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport { expect, test } from '@playwright/test'\nimport crossSpawn from 'cross-spawn'\nimport z from 'zod'\nimport { getApps, isSolutionApp } from './apps.server.js'\n\nexport async function getInBrowserTestPages() {\n\tconst apps = (await getApps())\n\t\t.filter(isSolutionApp)\n\t\t.filter((a) => a.test.type === 'browser')\n\tconst pages = apps.map((app) => {\n\t\tif (app.test.type !== 'browser') return null\n\t\tconst { pathname } = app.test\n\t\treturn app.test.testFiles.map((testFile) => {\n\t\t\treturn {\n\t\t\t\tpath: `${pathname}${testFile}`,\n\t\t\t\ttestFile,\n\t\t\t}\n\t\t})\n\t})\n\treturn pages.filter(Boolean).flat()\n}\n\nconst sleep = (time: number) =>\n\tnew Promise((resolve) => setTimeout(resolve, time))\n\nasync function waitFor<ReturnValue>(\n\tcb: () => ReturnValue | Promise<ReturnValue> | undefined | null,\n\t{ timeout = 1000, interval = 30 } = {},\n) {\n\tconst timeEnd = Date.now() + timeout\n\tlet lastError: unknown | null = null\n\twhile (Date.now() < timeEnd) {\n\t\ttry {\n\t\t\tconst result = await cb()\n\t\t\tif (result) return result\n\t\t} catch (error) {\n\t\t\tlastError = error\n\t\t}\n\t\tawait sleep(interval)\n\t}\n\tthrow lastError || new Error(`waitFor timed out after ${timeout}ms`)\n}\n\nexport function setupInBrowserTests() {\n\t// doing this because playwright needs the tests to be registered synchoronously\n\tconst code = `import('@epic-web/workshop-utils/playwright.server').then(({ getInBrowserTestPages }) => getInBrowserTestPages().then(r => console.log(JSON.stringify(r)))).catch(e => {console.error(e);throw e;})`\n\tconst result = crossSpawn.sync('node', ['--eval', code], {\n\t\tencoding: 'utf-8',\n\t})\n\tif (result.status !== 0) {\n\t\tconsole.error(result.output.join('\\n'))\n\t\tthrow new Error(\n\t\t\t`Failed to get in-browser test pages. Status: ${result.status}.`,\n\t\t)\n\t}\n\tconst testPages = z\n\t\t.array(z.object({ path: z.string() }))\n\t\t.parse(JSON.parse(result.stdout))\n\n\ttest.describe.parallel('in-browser tests', () => {\n\t\tfor (const testPage of testPages) {\n\t\t\ttest(testPage.path, async ({ page }) => {\n\t\t\t\tconst errors: Array<string> = []\n\t\t\t\tconst logs: Array<string> = []\n\t\t\t\tconst infos: Array<string> = []\n\t\t\t\tpage.on('console', (message) => {\n\t\t\t\t\tswitch (message.type()) {\n\t\t\t\t\t\tcase 'error': {\n\t\t\t\t\t\t\terrors.push(message.text())\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'log': {\n\t\t\t\t\t\t\tlogs.push(message.text())\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'info': {\n\t\t\t\t\t\t\tinfos.push(message.text())\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tawait page.goto(testPage.path)\n\t\t\t\tawait page.waitForLoadState()\n\t\t\t\tawait waitFor(\n\t\t\t\t\t() => infos.find((info) => info.includes('status: pending')),\n\t\t\t\t\t{ timeout: 10_000 },\n\t\t\t\t)\n\t\t\t\tconst result = await Promise.race([\n\t\t\t\t\twaitFor(() => logs.find((log) => log.includes('status: pass')), {\n\t\t\t\t\t\ttimeout: 10_000,\n\t\t\t\t\t}),\n\t\t\t\t\twaitFor(() => (errors.length > 0 ? errors : null), {\n\t\t\t\t\t\ttimeout: 10_000,\n\t\t\t\t\t}).then((errors) => {\n\t\t\t\t\t\tthrow errors\n\t\t\t\t\t}),\n\t\t\t\t])\n\t\t\t\texpect(result).toContain('status: pass')\n\t\t\t})\n\t\t}\n\t})\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"process-manager.server.d.ts","sourceRoot":"","sources":["../../src/process-manager.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAIxD,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAG7C,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAc3C,KAAK,eAAe,GAAG,GAAG,CACzB,MAAM,EACN;IACC,KAAK,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;IAC9B,OAAO,EAAE,YAAY,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;CACZ,CACD,CAAA;AAED,KAAK,mBAAmB,GAAG,GAAG,CAC7B,MAAM,EACN;IACC,KAAK,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;IAC9B,OAAO,EAAE,YAAY,CAAA;CACrB,CACD,CAAA;AAED,KAAK,UAAU,GAAG;IACjB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,KAAK,gBAAgB,GAAG;IACvB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAA;IAC5B,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB,CAAA;AAED,KAAK,gBAAgB,GAAG,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;AACrD,OAAO,CAAC,MAAM,CAAC;IACd,IAAI,uCAAuC,EAAE,UAAU,CACrD,OAAO,cAAc,CACrB,EACD,wCAAwC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,EAC3E,2CAA2C,EAAE,UAAU,CACtD,OAAO,cAAc,CACrB,CAAA;CACF;AAoDD,QAAA,MAAM,MAAM,mIAWF,CAAA;AA4BV,wBAAsB,SAAS,CAAC,GAAG,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;GAgEvC;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,GAAG;;;GAkDzC;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,GAAG;;;;;;UAwBvC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYvE;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,oBAYvD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,WAUlD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,gCAExD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,WAE1D;AAED,wBAAgB,YAAY;;;;EAE3B;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAStE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAqEhE;AAED,wBAAgB,oBAAoB,SASnC;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,iBAwB7C;AAID,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,iBAInD;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,iBAWnE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"process-manager.server.js","sourceRoot":"","sources":["../../src/process-manager.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport { spawn, type ChildProcess } from 'child_process'\nimport net from 'node:net'\nimport { remember } from '@epic-web/remember'\nimport chalk from 'chalk'\nimport closeWithGrace from 'close-with-grace'\nimport findProcessDefault from 'find-process'\nimport fkill from 'fkill'\nimport { type App } from './apps.server.js'\nimport { getWorkshopUrl } from './config.server.js'\nimport { getEnv } from './env.server.js'\nimport { getErrorMessage } from './utils.js'\n\n// https://github.com/yibn2008/find-process/issues/85\nconst findProcess = ('default' in findProcessDefault\n\t? findProcessDefault.default\n\t: findProcessDefault) as unknown as typeof findProcessDefault\n\nconst isDeployed =\n\tprocess.env.EPICSHOP_DEPLOYED === 'true' ||\n\tprocess.env.EPICSHOP_DEPLOYED === '1'\n\ntype DevProcessesMap = Map<\n\tstring,\n\t{\n\t\tcolor: (typeof colors)[number]\n\t\tprocess: ChildProcess\n\t\tport: number\n\t}\n>\n\ntype SidecarProcessesMap = Map<\n\tstring,\n\t{\n\t\tcolor: (typeof colors)[number]\n\t\tprocess: ChildProcess\n\t}\n>\n\ntype OutputLine = {\n\ttype: 'stdout' | 'stderr'\n\tcontent: string\n\ttimestamp: number\n}\n\ntype TestProcessEntry = {\n\tprocess: ChildProcess | null\n\toutput: Array<OutputLine>\n\texitCode?: number | null\n}\n\ntype TestProcessesMap = Map<string, TestProcessEntry>\ndeclare global {\n\tvar __process_dev_close_with_grace_return__: ReturnType<\n\t\t\ttypeof closeWithGrace\n\t\t>,\n\t\t__process_test_close_with_grace_return__: ReturnType<typeof closeWithGrace>,\n\t\t__process_sidecar_close_with_grace_return__: ReturnType<\n\t\t\ttypeof closeWithGrace\n\t\t>\n}\n\nconst devProcesses = remember('dev_processes', getDevProcessesMap)\nconst testProcesses = remember('test_processes', getTestProcessesMap)\nconst sidecarProcesses = remember('sidecar_processes', getSidecarProcessesMap)\n\nfunction getDevProcessesMap() {\n\tconst procs: DevProcessesMap = new Map()\n\n\tglobal.__process_dev_close_with_grace_return__?.uninstall()\n\n\tglobal.__process_dev_close_with_grace_return__ = closeWithGrace(async () => {\n\t\tfor (const [name, proc] of procs.entries()) {\n\t\t\tconsole.log('closing', name)\n\t\t\tproc.process.kill()\n\t\t}\n\t})\n\treturn procs\n}\n\nfunction getTestProcessesMap() {\n\tconst procs: TestProcessesMap = new Map()\n\n\tglobal.__process_test_close_with_grace_return__?.uninstall()\n\n\tglobal.__process_test_close_with_grace_return__ = closeWithGrace(async () => {\n\t\tfor (const [id, proc] of procs.entries()) {\n\t\t\tif (proc.process) {\n\t\t\t\tconsole.log('closing', id)\n\t\t\t\tproc.process.kill()\n\t\t\t}\n\t\t}\n\t})\n\treturn procs\n}\n\nfunction getSidecarProcessesMap() {\n\tconst procs: SidecarProcessesMap = new Map()\n\n\tglobal.__process_sidecar_close_with_grace_return__?.uninstall()\n\n\tglobal.__process_sidecar_close_with_grace_return__ = closeWithGrace(\n\t\tasync () => {\n\t\t\tfor (const [name, proc] of procs.entries()) {\n\t\t\t\tconsole.log('closing sidecar', name)\n\t\t\t\tproc.process.kill()\n\t\t\t}\n\t\t},\n\t)\n\treturn procs\n}\n\nconst colors = [\n\t'blue',\n\t'green',\n\t'yellow',\n\t'red',\n\t'magenta',\n\t'redBright',\n\t'greenBright',\n\t'yellowBright',\n\t'blueBright',\n\t'magentaBright',\n] as const\n\nfunction getNextAvailableColor(): (typeof colors)[number] {\n\tconst usedColors = new Set<(typeof colors)[number]>()\n\n\t// Collect colors used by dev processes\n\tfor (const proc of devProcesses.values()) {\n\t\tusedColors.add(proc.color)\n\t}\n\n\t// Collect colors used by sidecar processes\n\tfor (const proc of sidecarProcesses.values()) {\n\t\tusedColors.add(proc.color)\n\t}\n\n\t// Find available colors\n\tconst availableColors = colors.filter((color) => !usedColors.has(color))\n\n\tif (availableColors.length === 0) {\n\t\t// If all colors are used, cycle through them based on total process count\n\t\tconst totalProcesses = devProcesses.size + sidecarProcesses.size\n\t\treturn colors[totalProcesses % colors.length] ?? 'blue'\n\t}\n\n\t// Use the first available color\n\treturn availableColors[0] ?? 'blue'\n}\n\nexport async function runAppDev(app: App) {\n\tif (isDeployed) throw new Error('cannot run apps in deployed mode')\n\tconst key = app.name\n\t// if the app is already running, don't start it again\n\tif (devProcesses.has(key)) {\n\t\treturn { status: 'process-running', running: true } as const\n\t}\n\n\tif (app.dev.type !== 'script') {\n\t\treturn { status: 'error', error: 'no-server' } as const\n\t}\n\n\tconst { portNumber } = app.dev\n\tif (!(await isPortAvailable(portNumber))) {\n\t\treturn { status: 'port-unavailable', running: false, portNumber } as const\n\t}\n\tconst color = getNextAvailableColor()\n\tconst appProcess = spawn('npm', ['run', 'dev', '--silent'], {\n\t\tcwd: app.fullPath,\n\t\tshell: true,\n\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t// TODO: support specifying the env\n\t\t\tNODE_ENV: 'development',\n\t\t\t// TODO: support specifying the port\n\t\t\tPORT: String(portNumber),\n\t\t\tAPP_SERVER_PORT: String(portNumber),\n\t\t\t// let it pick a random port...\n\t\t\tREMIX_DEV_SERVER_WS_PORT: '',\n\t\t},\n\t})\n\tconst prefix = chalk[color](\n\t\t`[${app.name.replace(/^exercises\\./, '')}:${portNumber}]`,\n\t)\n\tfunction handleStdOutData(data: Buffer) {\n\t\tconsole.log(\n\t\t\tdata\n\t\t\t\t.toString('utf-8')\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `${prefix} ${line}`)\n\t\t\t\t.join('\\n'),\n\t\t)\n\t}\n\tappProcess.stdout.on('data', handleStdOutData)\n\tfunction handleStdErrData(data: Buffer) {\n\t\tconsole.error(\n\t\t\tdata\n\t\t\t\t.toString('utf-8')\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `${prefix} ${line}`)\n\t\t\t\t.join('\\n'),\n\t\t)\n\t}\n\tappProcess.stderr.on('data', handleStdErrData)\n\tdevProcesses.set(key, { color, process: appProcess, port: portNumber })\n\tappProcess.on('exit', (code) => {\n\t\tappProcess.stdout.off('data', handleStdOutData)\n\t\tappProcess.stderr.off('data', handleStdErrData)\n\t\tconsole.log(`${prefix} exited (${code})`)\n\t\tdevProcesses.delete(key)\n\t})\n\n\treturn { status: 'process-started', running: true } as const\n}\n\nexport async function runAppTests(app: App) {\n\tif (isDeployed) throw new Error('cannot run tests in deployed mode')\n\tconst key = app.name\n\n\tif (app.test.type !== 'script') {\n\t\treturn { status: 'error', error: 'no-test' } as const\n\t}\n\n\tconst testProcess = spawn('npm', ['run', 'test', '--silent'], {\n\t\tcwd: app.fullPath,\n\t\tshell: true,\n\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t// TODO: support specifying the env\n\t\t\tNODE_ENV: 'development',\n\t\t\t// TODO: support specifying the port\n\t\t\tPORT: app.dev.type === 'script' ? String(app.dev.portNumber) : undefined,\n\t\t\tAPP_SERVER_PORT:\n\t\t\t\tapp.dev.type === 'script' ? String(app.dev.portNumber) : undefined,\n\t\t\t// let it pick a random port...\n\t\t\tREMIX_DEV_SERVER_WS_PORT: '',\n\t\t},\n\t})\n\tconst output: Array<OutputLine> = []\n\tconst entry: TestProcessEntry = { process: testProcess, output }\n\tfunction handleStdOutData(data: Buffer) {\n\t\toutput.push({\n\t\t\ttype: 'stdout',\n\t\t\tcontent: data.toString('utf-8'),\n\t\t\ttimestamp: Date.now(),\n\t\t})\n\t}\n\ttestProcess.stdout.on('data', handleStdOutData)\n\tfunction handleStdErrData(data: Buffer) {\n\t\toutput.push({\n\t\t\ttype: 'stderr',\n\t\t\tcontent: data.toString('utf-8'),\n\t\t\ttimestamp: Date.now(),\n\t\t})\n\t}\n\ttestProcess.stderr.on('data', handleStdErrData)\n\ttestProcess.on('exit', (code) => {\n\t\ttestProcess.stdout.off('data', handleStdOutData)\n\t\ttestProcess.stderr.off('data', handleStdErrData)\n\t\tentry.process = null\n\t\tentry.exitCode = code\n\t})\n\ttestProcesses.set(key, entry)\n\treturn testProcess\n}\n\nexport async function waitOnApp(app: App) {\n\tif (app.dev.type === 'script') {\n\t\tconst startTime = Date.now()\n\n\t\tconst retryInterval = 100\n\t\tconst timeout = 20_000\n\t\tlet lastError: unknown\n\t\twhile (Date.now() - startTime < timeout) {\n\t\t\ttry {\n\t\t\t\tconst url = getWorkshopUrl(app.dev.portNumber)\n\t\t\t\tawait fetch(url, {\n\t\t\t\t\tmethod: 'HEAD',\n\t\t\t\t\theaders: { Accept: '*/*' },\n\t\t\t\t})\n\t\t\t\treturn { status: 'success' } as const\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, retryInterval))\n\t\t\t}\n\t\t}\n\n\t\treturn { status: 'error', error: getErrorMessage(lastError) } as const\n\t}\n\treturn null\n}\n\nexport function isPortAvailable(port: number | string): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst server = net.createServer()\n\t\tserver.unref()\n\t\tserver.on('error', () => resolve(false))\n\n\t\tserver.listen(Number(port), () => {\n\t\t\tserver.close(() => {\n\t\t\t\tresolve(true)\n\t\t\t})\n\t\t})\n\t})\n}\n\nexport async function isAppRunning(app: { name: string }) {\n\ttry {\n\t\tconst devProcess = devProcesses.get(app.name)\n\t\tif (!devProcess?.process.pid) return false\n\t\t// @ts-ignore - find-process is not typed correctly\n\t\t// https://github.com/yibn2008/find-process/issues/85\n\t\tconst found = await findProcess('pid', devProcess.process.pid)\n\t\treturn found.length > 0\n\t} catch (error: unknown) {\n\t\tconsole.error('Error checking if app is running:', getErrorMessage(error))\n\t\treturn false\n\t}\n}\n\nexport function isTestRunning(app: { name: string }) {\n\ttry {\n\t\tconst testProcess = testProcesses.get(app.name)\n\t\tif (!testProcess) return false\n\t\tif (testProcess.process === null) return false\n\t\ttestProcess.process.kill(0)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\nexport function getTestProcessEntry(app: { name: string }) {\n\treturn testProcesses.get(app.name)\n}\n\nexport function clearTestProcessEntry(app: { name: string }) {\n\treturn testProcesses.delete(app.name)\n}\n\nexport function getProcesses() {\n\treturn { devProcesses, testProcesses, sidecarProcesses }\n}\n\nexport function startSidecarProcesses(processes: Record<string, string>) {\n\tif (isDeployed) {\n\t\tconsole.log('Sidecar processes are not supported in deployed mode')\n\t\treturn\n\t}\n\n\tfor (const [name, command] of Object.entries(processes)) {\n\t\tstartSidecarProcess(name, command)\n\t}\n}\n\nexport function startSidecarProcess(name: string, command: string) {\n\tif (isDeployed)\n\t\tthrow new Error('cannot run sidecar processes in deployed mode')\n\n\t// if the process is already running, don't start it again\n\tif (sidecarProcesses.has(name)) {\n\t\tconsole.log(`Sidecar process ${name} is already running`)\n\t\treturn\n\t}\n\n\tconst color = getNextAvailableColor()\n\n\t// Spawn the command using shell to handle complex commands properly\n\tconst workshopRoot = getEnv().EPICSHOP_CONTEXT_CWD\n\tconst sidecarProcess = spawn(command, [], {\n\t\tshell: true,\n\t\tcwd: workshopRoot,\n\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\tNODE_ENV: 'development',\n\t\t},\n\t})\n\n\tconst prefix = chalk[color](`[${name}]`)\n\n\tfunction handleStdOutData(data: Buffer) {\n\t\tconsole.log(\n\t\t\tdata\n\t\t\t\t.toString('utf-8')\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `${prefix} ${line}`)\n\t\t\t\t.join('\\n'),\n\t\t)\n\t}\n\tsidecarProcess.stdout?.on('data', handleStdOutData)\n\n\tfunction handleStdErrData(data: Buffer) {\n\t\tconsole.error(\n\t\t\tdata\n\t\t\t\t.toString('utf-8')\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `${prefix} ${line}`)\n\t\t\t\t.join('\\n'),\n\t\t)\n\t}\n\tsidecarProcess.stderr?.on('data', handleStdErrData)\n\n\tsidecarProcesses.set(name, { color, process: sidecarProcess })\n\n\tsidecarProcess.on('exit', (code: number | null, signal: string | null) => {\n\t\tsidecarProcess.stdout?.off('data', handleStdOutData)\n\t\tsidecarProcess.stderr?.off('data', handleStdErrData)\n\t\tif (code === 0) {\n\t\t\tconsole.log(`${prefix} exited successfully`)\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`${prefix} exited with code ${code}${signal ? ` (signal: ${signal})` : ''}`,\n\t\t\t)\n\t\t}\n\t\tsidecarProcesses.delete(name)\n\t})\n\n\tsidecarProcess.on('error', (error) => {\n\t\tconsole.error(`${prefix} failed to start: ${error.message}`)\n\t\tsidecarProcesses.delete(name)\n\t})\n\n\tconsole.log(`${prefix} started`)\n}\n\nexport function stopSidecarProcesses() {\n\tif (isDeployed)\n\t\tthrow new Error('cannot stop sidecar processes in deployed mode')\n\n\tfor (const [name, proc] of sidecarProcesses.entries()) {\n\t\tconsole.log(`Stopping sidecar process: ${name}`)\n\t\tproc.process.kill()\n\t}\n\tsidecarProcesses.clear()\n}\n\nexport async function closeProcess(key: string) {\n\tif (isDeployed) throw new Error('cannot close processes in deployed mode')\n\tconst proc = devProcesses.get(key)\n\tif (proc) {\n\t\tconst exitedPromise = new Promise((resolve) =>\n\t\t\tproc.process.on('exit', resolve),\n\t\t)\n\t\tif (process.platform === 'win32') {\n\t\t\tconst { execa } = await import('execa')\n\t\t\ttry {\n\t\t\t\tawait execa('taskkill', ['/pid', String(proc.process.pid), '/f', '/t'])\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`Failed to taskkill process ${proc.process.pid}:`, err)\n\t\t\t}\n\t\t} else {\n\t\t\tproc.process.kill()\n\t\t}\n\t\tawait Promise.race([\n\t\t\tnew Promise((resolve) => setTimeout(resolve, 500)),\n\t\t\texitedPromise,\n\t\t])\n\t\tawait stopPort(proc.port) // just in case 🤷♂️\n\t\tdevProcesses.delete(key)\n\t}\n}\n\nconst sleep = (t: number) => new Promise((resolve) => setTimeout(resolve, t))\n\nexport async function stopPort(port: string | number) {\n\tif (isDeployed) throw new Error('cannot stop ports in deployed mode')\n\tawait fkill(`:${port}`, { force: true, silent: true })\n\tawait waitForPortToBeAvailable(port)\n}\n\nexport async function waitForPortToBeAvailable(port: string | number) {\n\t// wait for the port to become available again\n\tconst timeout = Date.now() + 10_000\n\tlet portAvailable = false\n\tdo {\n\t\tportAvailable = await isPortAvailable(port)\n\t\tawait sleep(100)\n\t} while (!portAvailable && Date.now() < timeout)\n\tif (!portAvailable) {\n\t\tconsole.error('Timed out waiting for the port to become available')\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.server.d.ts","sourceRoot":"","sources":["../../src/request-context.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGpD,MAAM,MAAM,mBAAmB,GAAG;IAEjC,mBAAmB,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB,CAAA;AAID,eAAO,MAAM,cAAc,wCAG1B,CAAA;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EAC3E,EAAE,EAAE,CAAC,EACL,GAAG,CAAC,EAAE,MAAM,GACV,CAAC,CAWH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.server.js","sourceRoot":"","sources":["../../src/request-context.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAS7C,qGAAqG;AACrG,2CAA2C;AAC3C,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CACrC,gBAAgB,EAChB,GAAG,EAAE,CAAC,IAAI,iBAAiB,EAAuB,CAClD,CAAA;AAED,MAAM,UAAU,iBAAiB,CAChC,EAAK,EACL,GAAY;IAEZ,MAAM,UAAU,GAAG,GAAG,IAAI,EAAE,CAAC,IAAI,CAAA;IACjC,OAAO,UAAU,GAAG,IAAW;QAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAA;QACvC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC,UAAU,CAAC,CAAA;QACzB,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QAC3B,IAAI,KAAK;YAAE,KAAK,CAAC,UAAU,CAAC,GAAG,OAAO,CAAA;QACtC,OAAO,OAAO,CAAA;IACf,CAAM,CAAA;AACP,CAAC","sourcesContent":["import './init-env.js'\n\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { remember } from '@epic-web/remember'\n\nexport type RequestContextStore = {\n\t// Add more keys for other per-request caches as needed\n\tgetExercisesPromise?: Promise<any>\n\tgetAppsPromise?: Promise<any>\n\t[key: string]: unknown\n}\n\n// this is important to make it global so even if somehow we have two versions of the workshop-utils,\n// they will share the same request context\nexport const requestContext = remember(\n\t'requestContext',\n\t() => new AsyncLocalStorage<RequestContextStore>(),\n)\n\nexport function requestStorageify<T extends (...args: any[]) => Promise<any>>(\n\tfn: T,\n\tkey?: string,\n): T {\n\tconst storageKey = key ?? fn.name\n\treturn function (...args: any[]) {\n\t\tconst store = requestContext.getStore()\n\t\tif (store?.[storageKey]) {\n\t\t\treturn store[storageKey]\n\t\t}\n\t\tconst promise = fn(...args)\n\t\tif (store) store[storageKey] = promise\n\t\treturn promise\n\t} as T\n}\n"]}
|
package/dist/esm/test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,sBAAsB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAA;AAC9D,OAAO,EAIN,KAAK,YAAY,EACjB,MAAM,gBAAgB,CAAA;AAiBvB,OAAO,QAAQ,gBAAgB,CAAC;IAC/B,UAAU,aAAa,CAAC,CAAC,GAAG,GAAG,CAC9B,SAAQ,QAAQ,CAAC,sBAAsB,CACtC,UAAU,CAAC,OAAO,MAAM,CAAC,gBAAgB,CAAC,EAC1C,CAAC,CACD;KAAG;CACL;AAOD,eAAO,MAAM,MAAM,EAAkB,YAAY,CAAA;AACjD,OAAO,EAAE,GAAG,EAAE,CAAA;AAWd,wBAAsB,QAAQ,CAAC,WAAW,EACzC,KAAK,EACF,MAAM,GACN,CAAC,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,CAAC,EAC1E,GAAG,EAAE,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,GACrD,OAAO,CAAC,WAAW,CAAC,CAmCtB"}
|
package/dist/esm/test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as dtl from '@testing-library/dom'\nimport * as matchers from '@testing-library/jest-dom/matchers'\nimport {\n\tJestAsymmetricMatchers,\n\tJestChaiExpect,\n\tJestExtend,\n\ttype ExpectStatic,\n} from '@vitest/expect'\nimport * as chai from 'chai'\nimport chaiDOM from 'chai-dom'\n\n// allows using expect.extend instead of chai.use to extend plugins\nchai.use(JestExtend)\n// adds all jest matchers to expect\nchai.use(JestChaiExpect)\n// adds asymmetric matchers like stringContaining, objectContaining\nchai.use(JestAsymmetricMatchers)\n\nchai.use(chaiDOM)\n\n// @ts-expect-error weird typescript nonsense\n// I *think* vitest is using the extend API wrong or something 🤷♂️\n// this works though so...\n;(chai.expect as ExpectStatic).extend(chai.expect, matchers)\ndeclare module '@vitest/expect' {\n\tinterface JestAssertion<T = any>\n\t\textends matchers.TestingLibraryMatchers<\n\t\t\tReturnType<typeof expect.stringContaining>,\n\t\t\tT\n\t\t> {}\n}\n\n// in the browser logging out the element is not necessary\ndtl.configure({\n\tgetElementError: (message) => new Error(message ?? 'Unknown error'),\n})\n\nexport const expect = chai.expect as ExpectStatic\nexport { dtl }\n\nfunction isError(maybeError: any): maybeError is Error {\n\treturn (\n\t\tmaybeError &&\n\t\ttypeof maybeError === 'object' &&\n\t\t'message' in maybeError &&\n\t\ttypeof maybeError.message === 'string'\n\t)\n}\n\nexport async function testStep<ReturnValue>(\n\ttitle:\n\t\t| string\n\t\t| ((result: { type: 'fail'; error: Error } | { type: 'pass' }) => string),\n\tget: (() => ReturnValue) | (() => Promise<ReturnValue>),\n): Promise<ReturnValue> {\n\ttry {\n\t\tconst result = await get()\n\t\tconst titleString =\n\t\t\ttypeof title === 'function' ? title({ type: 'pass' }) : title\n\t\tif (window.parent === window) {\n\t\t\tconsole.log(`✅ ${titleString}`)\n\t\t} else {\n\t\t\twindow.parent.postMessage(\n\t\t\t\t{\n\t\t\t\t\ttype: 'epicshop:test-step-update',\n\t\t\t\t\tstatus: 'pass',\n\t\t\t\t\ttitle: titleString,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t\t'*',\n\t\t\t)\n\t\t}\n\t\treturn result\n\t} catch (caughtError: unknown) {\n\t\tconst error = isError(caughtError)\n\t\t\t? caughtError\n\t\t\t: new Error(\n\t\t\t\t\ttypeof caughtError === 'string' ? caughtError : 'Unknown error',\n\t\t\t\t\t{ cause: caughtError },\n\t\t\t\t)\n\t\tconst titleString =\n\t\t\ttypeof title === 'function' ? title({ type: 'fail', error }) : title\n\t\tif (window.parent === window) {\n\t\t\tconsole.error(`❌ ${titleString}`)\n\t\t\tconsole.error(error.message)\n\t\t}\n\t\terror.message = `${titleString}${error.message ? `\\n\\n${error.message}` : ''}`\n\t\tthrow error\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timing.server.d.ts","sourceRoot":"","sources":["../../src/timing.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzD,MAAM,MAAM,OAAO,GAAG,MAAM,CAC3B,MAAM,EACN,KAAK,CACJ;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,CACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/B;IAAE,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CACjC,CACD,CACD,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,WAWtD;AAgBD,wBAAsB,IAAI,CAAC,UAAU,EACpC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,EAClE,EACC,IAAI,EACJ,IAAI,EACJ,OAAO,GACP,EAAE;IACF,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB,GACC,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,UAuBpD;AAaD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,UAIxE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAC5C,OAAO,CAAC,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,MAAM,GAChB,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CA6BnC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timing.server.js","sourceRoot":"","sources":["../../src/timing.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport { type CreateReporter } from '@epic-web/cachified'\n\nexport type Timings = Record<\n\tstring,\n\tArray<\n\t\t{ desc?: string } & (\n\t\t\t| { time: number; start?: never }\n\t\t\t| { time?: never; start: number }\n\t\t)\n\t>\n>\n\nexport function makeTimings(type: string, desc?: string) {\n\tconst timings: Timings = {\n\t\t[type]: [{ desc, start: performance.now() }],\n\t}\n\tObject.defineProperty(timings, 'toString', {\n\t\tvalue() {\n\t\t\treturn getServerTimeHeader(timings)\n\t\t},\n\t\tenumerable: false,\n\t})\n\treturn timings\n}\n\nfunction createTimer(type: string, desc?: string) {\n\tconst start = performance.now()\n\treturn {\n\t\tend(timings: Timings) {\n\t\t\tlet timingType = timings[type]\n\n\t\t\tif (!timingType) {\n\t\t\t\ttimingType = timings[type] = []\n\t\t\t}\n\t\t\ttimingType.push({ desc, time: performance.now() - start })\n\t\t},\n\t}\n}\n\nexport async function time<ReturnType>(\n\tfn: Promise<ReturnType> | (() => ReturnType | Promise<ReturnType>),\n\t{\n\t\ttype,\n\t\tdesc,\n\t\ttimings,\n\t}: {\n\t\ttype: string\n\t\tdesc?: string\n\t\ttimings?: Timings\n\t},\n): Promise<ReturnType> {\n\tconst timer = createTimer(type, desc)\n\tconst promise = typeof fn === 'function' ? fn() : fn\n\tif (!timings) return promise\n\n\tconst result = await promise\n\n\ttimer.end(timings)\n\treturn result\n}\n\nexport function getServerTimeHeader(timings?: Timings) {\n\tif (!timings) return ''\n\treturn Object.entries(timings)\n\t\t.map(([key, timingInfos]) => {\n\t\t\tconst dur = timingInfos\n\t\t\t\t.reduce((acc, timingInfo) => {\n\t\t\t\t\tconst time = timingInfo.time ?? performance.now() - timingInfo.start\n\t\t\t\t\treturn acc + time\n\t\t\t\t}, 0)\n\t\t\t\t.toFixed(1)\n\t\t\tconst desc = timingInfos\n\t\t\t\t.map((t) => t.desc)\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(' & ')\n\t\t\treturn [\n\t\t\t\tsanitizeHeaderValue(key).replaceAll(/(:| |@|=|;|,|\\/|\\\\|\\{|\\})/g, '_'),\n\t\t\t\tdesc ? `desc=${sanitizeHeaderValue(desc)}` : null,\n\t\t\t\t`dur=${dur}`,\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(';')\n\t\t})\n\t\t.join(',')\n}\n\nfunction sanitizeHeaderValue(value: string): string {\n\t// Replace non-ASCII characters with ASCII equivalents\n\t// This ensures HTTP header compliance\n\treturn value\n\t\t.replace(/['']/g, \"'\") // Replace smart quotes with regular apostrophe\n\t\t.replace(/[\"\"]/g, '\"') // Replace smart quotes with regular quotes\n\t\t.replace(/[–—]/g, '-') // Replace em/en dashes with hyphen\n\t\t.replace(/[…]/g, '...') // Replace ellipsis with three dots\n\t\t.replace(/[^\\x20-\\x7E]/g, '') // Remove any remaining non-printable ASCII characters\n}\n\nexport function combineServerTimings(headers1: Headers, headers2: Headers) {\n\tconst newHeaders = new Headers(headers1)\n\tnewHeaders.append('Server-Timing', headers2.get('Server-Timing') ?? '')\n\treturn newHeaders.get('Server-Timing') ?? ''\n}\n\nexport function cachifiedTimingReporter<Value>(\n\ttimings?: Timings,\n\ttimingKey?: string,\n): undefined | CreateReporter<Value> {\n\tif (!timings) return\n\n\treturn ({ key }) => {\n\t\ttimingKey = timingKey ?? key\n\t\tconst cacheRetrievalTimer = createTimer(\n\t\t\t`cache:${timingKey}`,\n\t\t\t`${timingKey} cache retrieval`,\n\t\t)\n\t\tlet getFreshValueTimer: ReturnType<typeof createTimer> | undefined\n\t\treturn (event) => {\n\t\t\tswitch (event.name) {\n\t\t\t\tcase 'getFreshValueStart':\n\t\t\t\t\tgetFreshValueTimer = createTimer(\n\t\t\t\t\t\t`getFreshValue:${timingKey}`,\n\t\t\t\t\t\t`request forced to wait for a fresh ${timingKey} value`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'getFreshValueSuccess':\n\t\t\t\t\tgetFreshValueTimer?.end(timings)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'done':\n\t\t\t\t\tcacheRetrievalTimer.end(timings)\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"user.server.d.ts","sourceRoot":"","sources":["../../src/user.server.ts"],"names":[],"mappings":"AAOA,wBAAsB,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE;;;;;;;;;;;;GAiChE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,UAE1D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"user.server.js","sourceRoot":"","sources":["../../src/user.server.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEzD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAE,OAAO,EAAwB;IAChE,IAAI,MAAM,EAAE,CAAC,iBAAiB,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAClD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAA;QAEpD,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC1B,OAAO;gBACN,EAAE,EAAE,WAAW,CAAC,QAAQ;gBACxB,IAAI,EAAE,iBAAiB;aACd,CAAA;QACX,CAAC;aAAM,CAAC;YACP,MAAM,KAAK,GAAG,IAAI,EAAE,CAAA;YACpB,OAAO;gBACN,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,iBAAiB;aACd,CAAA;QACX,CAAC;IACF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IAEpC,IAAI,QAAQ,EAAE,EAAE,EAAE,CAAC;QAClB,OAAO;YACN,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,IAAI,EAAE,aAAa;SACV,CAAA;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IACpC,OAAO;QACN,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,aAAa;KACV,CAAA;AACX,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IAC1D,OAAO,YAAY,QAAQ,kCAAkC,CAAA;AAC9D,CAAC","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { getEnv } from './init-env.js'\n\nimport { randomUUID as cuid } from 'crypto'\nimport * as cookie from 'cookie'\nimport { getAuthInfo, getClientId } from './db.server.js'\n\nexport async function getUserId({ request }: { request: Request }) {\n\tif (getEnv().EPICSHOP_DEPLOYED) {\n\t\tconst cookieHeader = request.headers.get('cookie')\n\t\tconst cookieValue = cookie.parse(cookieHeader ?? '')\n\n\t\tif (cookieValue.clientId) {\n\t\t\treturn {\n\t\t\t\tid: cookieValue.clientId,\n\t\t\t\ttype: 'cookie.clientId',\n\t\t\t} as const\n\t\t} else {\n\t\t\tconst newId = cuid()\n\t\t\treturn {\n\t\t\t\tid: newId,\n\t\t\t\ttype: 'cookie.randomId',\n\t\t\t} as const\n\t\t}\n\t}\n\n\tconst authInfo = await getAuthInfo()\n\n\tif (authInfo?.id) {\n\t\treturn {\n\t\t\tid: authInfo.id,\n\t\t\ttype: 'db.authInfo',\n\t\t} as const\n\t}\n\n\tconst clientId = await getClientId()\n\treturn {\n\t\tid: clientId,\n\t\ttype: 'db.clientId',\n\t} as const\n}\n\nexport function getSetClientIdCookieHeader(clientId: string) {\n\treturn `clientId=${clientId}; Path=/; HttpOnly; SameSite=Lax`\n}\n"]}
|
package/dist/esm/utils.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAGtB,OAAO,QAAQ,MAAM,OAAO,CAAA;AAK5B,eAAO,MAAM,KAAK,iBAKhB,CAAA;AAEF,wBAAgB,eAAe,CAC9B,KAAK,EAAE,OAAO,EACd,eAAe,SAAkB,GAC/B,MAAM,CAYR;AAED,wBAAgB,uBAAuB,CAAC,EACvC,UAAU,EACV,UAAU,GACV,EAAE;IACF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;;;EAaA"}
|
package/dist/esm/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,QAAQ,MAAM,OAAO,CAAA;AAC5B,OAAO,kBAAkB,MAAM,8BAA8B,CAAA;AAC7D,OAAO,cAAc,MAAM,0BAA0B,CAAA;AACrD,OAAO,SAAS,MAAM,qBAAqB,CAAA;AAE3C,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IAC3C,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IACnC,OAAO,QAAQ,CAAA;AAChB,CAAC,CAAC,CAAA;AAEF,MAAM,UAAU,eAAe,CAC9B,KAAc,EACd,eAAe,GAAG,eAAe;IAEjC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IACC,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,SAAS,IAAI,KAAK;QAClB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAChC,CAAC;QACF,OAAO,KAAK,CAAC,OAAO,CAAA;IACrB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;IAC7D,OAAO,eAAe,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EACvC,UAAU,EACV,UAAU,GAIV;IACA,IAAI,UAAU,EAAE,CAAC;QAChB,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QAC1C,UAAU,GAAG,GAAG,UAAU,YAAY,CAAA;IACvC,CAAC;SAAM,IAAI,UAAU,EAAE,CAAC;QACvB,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAA;QACzD,UAAU,GAAG,GAAG,UAAU,YAAY,CAAA;IACvC,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACd,sJAAsJ,CACtJ,CAAA;IACF,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAA;AAClC,CAAC","sourcesContent":["import './init-env.js'\n\nimport { remember } from '@epic-web/remember'\nimport dayjsLib from 'dayjs'\nimport relativeTimePlugin from 'dayjs/plugin/relativeTime.js'\nimport timeZonePlugin from 'dayjs/plugin/timezone.js'\nimport utcPlugin from 'dayjs/plugin/utc.js'\n\nexport const dayjs = remember('dayjs', () => {\n\tdayjsLib.extend(utcPlugin)\n\tdayjsLib.extend(timeZonePlugin)\n\tdayjsLib.extend(relativeTimePlugin)\n\treturn dayjsLib\n})\n\nexport function getErrorMessage(\n\terror: unknown,\n\tfallbackMessage = 'Unknown Error',\n): string {\n\tif (typeof error === 'string') return error\n\tif (\n\t\terror &&\n\t\ttypeof error === 'object' &&\n\t\t'message' in error &&\n\t\ttypeof error.message === 'string'\n\t) {\n\t\treturn error.message\n\t}\n\tconsole.error('Unable to get error message for error', error)\n\treturn fallbackMessage\n}\n\nexport function handleGitHubRepoAndRoot({\n\tgithubRepo,\n\tgithubRoot,\n}: {\n\tgithubRepo?: string\n\tgithubRoot?: string\n}) {\n\tif (githubRepo) {\n\t\tgithubRepo = githubRepo.replace(/\\/$/, '')\n\t\tgithubRoot = `${githubRepo}/tree/main`\n\t} else if (githubRoot) {\n\t\tgithubRepo = githubRoot.replace(/\\/(blob|tree)\\/.*$/, '')\n\t\tgithubRoot = `${githubRepo}/tree/main`\n\t} else {\n\t\tthrow new Error(\n\t\t\t`Either githubRepo or githubRoot is required. Please ensure your epicshop package.json config includes either githubRepo or githubRoot configuration.`,\n\t\t)\n\t}\n\treturn { githubRepo, githubRoot }\n}\n"]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import './init-env.js';
|
|
2
|
-
import dayjsLib from 'dayjs';
|
|
3
|
-
import { type Timings } from './timing.server.js';
|
|
4
|
-
export declare const dayjs: typeof dayjsLib;
|
|
5
|
-
export declare function checkConnection({ request, timings, }?: {
|
|
6
|
-
request?: Request;
|
|
7
|
-
timings?: Timings;
|
|
8
|
-
}): Promise<boolean>;
|
|
9
|
-
//# sourceMappingURL=utils.server.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.server.d.ts","sourceRoot":"","sources":["../../src/utils.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAGtB,OAAO,QAAQ,MAAM,OAAO,CAAA;AAM5B,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAEjD,eAAO,MAAM,KAAK,iBAKhB,CAAA;AAkDF,wBAAsB,eAAe,CAAC,EACrC,OAAO,EACP,OAAO,GACP,GAAE;IACF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;CACZ,oBAwBL"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.server.js","sourceRoot":"","sources":["../../src/utils.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport { remember } from '@epic-web/remember'\nimport dayjsLib from 'dayjs'\nimport relativeTimePlugin from 'dayjs/plugin/relativeTime.js'\nimport timeZonePlugin from 'dayjs/plugin/timezone.js'\nimport utcPlugin from 'dayjs/plugin/utc.js'\nimport { cachified, connectionCache } from './cache.server.js'\nimport { logger } from './logger.js'\nimport { type Timings } from './timing.server.js'\n\nexport const dayjs = remember('dayjs', () => {\n\tdayjsLib.extend(utcPlugin)\n\tdayjsLib.extend(timeZonePlugin)\n\tdayjsLib.extend(relativeTimePlugin)\n\treturn dayjsLib\n})\n\nconst connectionLog = logger('epic:connection')\n\nasync function probeOnce(\n\turl: string,\n\texpectedOk: (status: number) => boolean = (s) => s >= 200 && s < 300,\n\tinit?: RequestInit,\n): Promise<boolean> {\n\tconst signal = AbortSignal.timeout(10_000)\n\tconst start = Date.now()\n\tconnectionLog(`probing ${url}`)\n\tconst res = await fetch(url, {\n\t\tmethod: 'HEAD',\n\t\tcache: 'no-store',\n\t\tsignal,\n\t\t...init,\n\t})\n\tconnectionLog(\n\t\t`probe to ${url} returned ${res.status} in ${Date.now() - start}ms`,\n\t)\n\treturn expectedOk(res.status)\n}\n\nasync function raceConnectivity(): Promise<boolean> {\n\t// we have multiple just in case some VPN blocks one or another\n\tconst candidates: Array<Promise<boolean>> = [\n\t\tprobeOnce('https://connected.kentcdodds.workers.dev'),\n\n\t\t// Non-CF options (different providers / networks):\n\t\tprobeOnce('https://www.gstatic.com/generate_204', (s) => s === 204),\n\t\tprobeOnce(\n\t\t\t'http://www.msftconnecttest.com/connecttest.txt',\n\t\t\t(s) => s === 200,\n\t\t),\n\t]\n\n\t// Use Promise.any to succeed on first truthy result; treat rejections/non-2xx as false\n\tconst wrapped = candidates.map((p) =>\n\t\tp.then((ok) => (ok ? true : Promise.reject(new Error('not ok')))),\n\t)\n\n\ttry {\n\t\tawait Promise.any(wrapped)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\nexport async function checkConnection({\n\trequest,\n\ttimings,\n}: {\n\trequest?: Request\n\ttimings?: Timings\n} = {}) {\n\tconnectionLog('calling cachified to check connection')\n\tconst isOnline = await cachified({\n\t\tcache: connectionCache,\n\t\trequest,\n\t\ttimings,\n\t\tkey: 'connected',\n\t\tttl: 1000 * 10,\n\t\tasync getFreshValue(context) {\n\t\t\tconnectionLog('getting fresh connection value')\n\t\t\tconst isOnline = await raceConnectivity()\n\t\t\tif (isOnline) {\n\t\t\t\tcontext.metadata.ttl = 1000 * 60\n\t\t\t\tcontext.metadata.swr = 1000 * 60 * 30\n\t\t\t\treturn true\n\t\t\t} else {\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\t})\n\tconnectionLog(\n\t\t`connection check says we are ${isOnline ? 'online' : 'offline'}`,\n\t)\n\treturn isOnline\n}\n"]}
|
package/dist/esm/utils.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../src/utils.test.ts"],"names":[],"mappings":""}
|