Skip to content

Commit 680882f

Browse files
committed
fix(cli): merge conflicts
1 parent 6af331f commit 680882f

3 files changed

Lines changed: 16 additions & 368 deletions

File tree

packages/workshop-cli/src/commands/admin/launch-readiness.ts

Lines changed: 0 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,6 @@ type ContentCheckFile = {
6464
relativePath: string
6565
}
6666

67-
<<<<<<< Updated upstream
68-
<<<<<<< Updated upstream
69-
=======
70-
=======
71-
>>>>>>> Stashed changes
72-
type ProductModuleType = 'workshop' | 'tutorial'
73-
7467
function stripEpicAiSlugSuffix(value: string) {
7568
// EpicAI embeds sometimes include a `~...` suffix in the slug segment.
7669
return value.replace(/~[^ ]*$/, '')
@@ -79,15 +72,6 @@ function stripEpicAiSlugSuffix(value: string) {
7972
function isProductLessonPathSegment(segment: string | undefined) {
8073
return segment === 'workshops' || segment === 'tutorials'
8174
}
82-
83-
function getProductModulePathSegment(moduleType: ProductModuleType) {
84-
return moduleType === 'tutorial' ? 'tutorials' : 'workshops'
85-
}
86-
87-
<<<<<<< Updated upstream
88-
>>>>>>> Stashed changes
89-
=======
90-
>>>>>>> Stashed changes
9175
function normalizeHost(host: string) {
9276
return host.toLowerCase().replace(/^www\./, '')
9377
}
@@ -138,29 +122,6 @@ function parseEpicLessonSlugFromEmbedUrl(urlString: string): string | null {
138122
}
139123
}
140124

141-
<<<<<<< Updated upstream
142-
=======
143-
function formatProductLessonUrl({
144-
productHost,
145-
productSlug,
146-
moduleType,
147-
lessonSlug,
148-
sectionSlug,
149-
}: {
150-
productHost: string
151-
productSlug: string
152-
moduleType: ProductModuleType
153-
lessonSlug: string
154-
sectionSlug: string | null
155-
}) {
156-
const productPath = getProductModulePathSegment(moduleType)
157-
// The product site will typically redirect to a section-specific path when needed.
158-
return sectionSlug
159-
? `https://${productHost}/${productPath}/${productSlug}/${sectionSlug}/${lessonSlug}`
160-
: `https://${productHost}/${productPath}/${productSlug}/${lessonSlug}`
161-
}
162-
163-
>>>>>>> Stashed changes
164125
function formatIssue(issue: Issue, workshopRoot: string) {
165126
const icon = issue.level === 'error' ? chalk.red('❌') : chalk.yellow('⚠️ ')
166127
const filePart = issue.file
@@ -336,127 +297,6 @@ async function buildExpectedFiles({
336297
return { files, contentFiles, issues }
337298
}
338299

339-
<<<<<<< Updated upstream
340-
=======
341-
async function fetchRemoteWorkshopLessonSlugs({
342-
productHost,
343-
workshopSlug,
344-
}: {
345-
productHost: string
346-
workshopSlug: string
347-
}): Promise<
348-
| {
349-
status: 'success'
350-
lessons: Array<{ slug: string; sectionSlug: string | null }>
351-
moduleType: ProductModuleType
352-
}
353-
| { status: 'error'; message: string }
354-
> {
355-
const url = `https://${productHost}/api/workshops/${encodeURIComponent(workshopSlug)}`
356-
357-
const fetchOnce = async (accessToken?: string) => {
358-
const timeout = AbortSignal.timeout(15_000)
359-
const headers: Record<string, string> = {}
360-
if (accessToken) headers.authorization = `Bearer ${accessToken}`
361-
return fetch(url, { headers, signal: timeout })
362-
}
363-
364-
let response: Response | null = null
365-
try {
366-
response = await fetchOnce()
367-
} catch (error) {
368-
return {
369-
status: 'error',
370-
message: `Failed to fetch product workshop data: ${getErrorMessage(error)}`,
371-
}
372-
}
373-
374-
if (response.status === 401 || response.status === 403) {
375-
const authInfo = await getAuthInfo({ productHost }).catch(() => null)
376-
const accessToken = authInfo?.tokenSet?.access_token
377-
if (accessToken) {
378-
try {
379-
response = await fetchOnce(accessToken)
380-
} catch (error) {
381-
return {
382-
status: 'error',
383-
message: `Failed to fetch product workshop data (after auth): ${getErrorMessage(
384-
error,
385-
)}`,
386-
}
387-
}
388-
}
389-
}
390-
391-
if (!response.ok) {
392-
const body = await response.text().catch(() => '')
393-
const hint =
394-
response.status === 401 || response.status === 403
395-
? ` (try: npx epicshop auth login ${productHost.replace(/^www\./, '')})`
396-
: response.status === 404
397-
? ` (check epicshop.product.host + epicshop.product.slug)`
398-
: ''
399-
return {
400-
status: 'error',
401-
message: `Product API request failed: ${response.status} ${response.statusText}${hint}${
402-
body ? `\n${body}` : ''
403-
}`,
404-
}
405-
}
406-
407-
let data: any
408-
try {
409-
data = await response.json()
410-
} catch (error) {
411-
return {
412-
status: 'error',
413-
message: `Product API response was not valid JSON: ${getErrorMessage(error)}`,
414-
}
415-
}
416-
417-
const resources = data?.resources
418-
const moduleType: ProductModuleType =
419-
data?.moduleType === 'tutorial' ? 'tutorial' : 'workshop'
420-
if (!Array.isArray(resources)) {
421-
return {
422-
status: 'error',
423-
message: `Product API response did not include an array "resources" field`,
424-
}
425-
}
426-
427-
const lessons: Array<{ slug: string; sectionSlug: string | null }> = []
428-
for (const resource of resources) {
429-
if (!resource || typeof resource !== 'object') continue
430-
const r = resource as Record<string, unknown>
431-
432-
if (r._type === 'lesson') {
433-
const slug = r.slug
434-
if (typeof slug === 'string') lessons.push({ slug, sectionSlug: null })
435-
continue
436-
}
437-
438-
if (r._type === 'section') {
439-
const sectionSlug =
440-
typeof r.slug === 'string' && r.slug.trim().length > 0
441-
? r.slug.trim()
442-
: null
443-
const sectionLessons = r.lessons
444-
if (!Array.isArray(sectionLessons)) continue
445-
for (const lesson of sectionLessons) {
446-
if (!lesson || typeof lesson !== 'object') continue
447-
const l = lesson as Record<string, unknown>
448-
const slug = l.slug
449-
if (typeof slug === 'string') {
450-
lessons.push({ slug, sectionSlug })
451-
}
452-
}
453-
}
454-
}
455-
456-
return { status: 'success', lessons, moduleType }
457-
}
458-
459-
>>>>>>> Stashed changes
460300
async function checkMinContentLength({
461301
fullPath,
462302
minChars,

0 commit comments

Comments
 (0)