Skip to content

Commit 5d4872b

Browse files
committed
Fix static course manifest structure for scaffolded apps
Updates CLI and standalone-ui to use the new hierarchical manifest structure that was introduced for the docs site but not propagated to scaffolded applications. Changes: - CLI now generates course-level skuilder.json for each course - CLI now generates root skuilder.json in public/ with course dependencies - standalone-ui updated to fetch root manifest and use new DataLayerProvider API The new structure has three levels: 1. Root /public/skuilder.json (lists course dependencies) 2. Course /static-courses/{id}/skuilder.json (points to manifest.json) 3. Course /static-courses/{id}/manifest.json (contains courseConfig and data) This matches the implementation in docs/.vitepress/theme/composables/useStaticDataLayer.ts and the updated StaticDataLayerProvider API from commits 4fb97b0, 0e2fb4b, 40aaf39. Fixes runtime failures in newly scaffolded static apps caused by API mismatch.
1 parent 837c1ba commit 5d4872b

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

packages/cli/src/utils/template.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,35 @@ export async function generateSkuilderConfig(
289289

290290
await fs.writeFile(configPath, JSON.stringify(skuilderConfig, null, 2));
291291

292+
// For static data layer, create root skuilder.json manifest
293+
if (config.dataLayerType === 'static' && outputPath && skuilderConfig.course) {
294+
const publicPath = path.join(outputPath, 'public');
295+
await fs.mkdir(publicPath, { recursive: true });
296+
297+
// Determine course IDs to include in dependencies
298+
const courseIds = config.importCourseIds && config.importCourseIds.length > 0
299+
? config.importCourseIds
300+
: [skuilderConfig.course];
301+
302+
// Create root skuilder.json with course dependencies
303+
const rootManifest = {
304+
name: `@skuilder/${config.projectName}`,
305+
version: '1.0.0',
306+
description: config.title,
307+
dependencies: Object.fromEntries(
308+
courseIds.map((courseId) => [
309+
`@skuilder/course-${courseId}`,
310+
`/static-courses/${courseId}/skuilder.json`,
311+
])
312+
),
313+
};
314+
315+
await fs.writeFile(
316+
path.join(publicPath, 'skuilder.json'),
317+
JSON.stringify(rootManifest, null, 2)
318+
);
319+
}
320+
292321
// For static data layer without imports, create empty course structure
293322
if (
294323
config.dataLayerType === 'static' &&
@@ -393,6 +422,22 @@ async function createEmptyCourseStructure(
393422

394423
await fs.writeFile(path.join(coursePath, 'manifest.json'), JSON.stringify(manifest, null, 2));
395424

425+
// Create course-level skuilder.json (points to manifest.json)
426+
const courseSkuilderJson = {
427+
name: `@skuilder/course-${courseId}`,
428+
version: '1.0.0',
429+
description: title,
430+
content: {
431+
type: 'static',
432+
manifest: './manifest.json',
433+
},
434+
};
435+
436+
await fs.writeFile(
437+
path.join(coursePath, 'skuilder.json'),
438+
JSON.stringify(courseSkuilderJson, null, 2)
439+
);
440+
396441
// Create empty tags index
397442
await fs.writeFile(
398443
path.join(coursePath, 'indices', 'tags.json'),

packages/standalone-ui/src/main.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,32 +42,25 @@ import config from '../skuilder.config.json';
4242
};
4343

4444
if (config.dataLayerType === 'static') {
45-
// Load manifest for static mode
46-
const courseId = config.course;
47-
if (!courseId) {
48-
throw new Error('Course ID required for static data layer');
49-
}
50-
45+
// Load root skuilder.json manifest for static mode
5146
try {
52-
const manifestResponse = await fetch(`/static-courses/${courseId}/manifest.json`);
53-
if (!manifestResponse.ok) {
47+
const rootManifestUrl = '/skuilder.json';
48+
const rootManifestResponse = await fetch(rootManifestUrl);
49+
if (!rootManifestResponse.ok) {
5450
throw new Error(
55-
`Failed to load manifest: ${manifestResponse.status} ${manifestResponse.statusText}`
51+
`Failed to load root manifest: ${rootManifestResponse.status} ${rootManifestResponse.statusText}`
5652
);
5753
}
58-
const manifest = await manifestResponse.json();
59-
console.log(`Loaded manifest for course ${courseId}`);
60-
console.log(JSON.stringify(manifest));
54+
const rootManifest = await rootManifestResponse.json();
55+
console.log('[DEBUG] Loaded root manifest:', rootManifest);
6156

6257
dataLayerOptions = {
63-
staticContentPath: '/static-courses',
64-
manifests: {
65-
[courseId]: manifest,
66-
},
58+
rootManifest,
59+
rootManifestUrl: new URL(rootManifestUrl, window.location.href).href,
6760
};
6861
} catch (error) {
69-
console.error('[DEBUG] Failed to load course manifest:', error);
70-
throw new Error(`Could not load course manifest for ${courseId}: ${error}`);
62+
console.error('[DEBUG] Failed to load root manifest:', error);
63+
throw new Error(`Could not load root skuilder.json manifest: ${error}`);
7164
}
7265
}
7366

0 commit comments

Comments
 (0)