Skip to content

Commit 782764a

Browse files
committed
updated-upgrade-script
1 parent ab5260a commit 782764a

4 files changed

Lines changed: 107 additions & 3 deletions

File tree

lib/upgrade.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,36 @@ function copyFileWithBackup(src, dest) {
8383
return { updated: true, backup: null };
8484
}
8585

86+
export function addMissingRuntimeDependencies(projectPkg, templatePkg) {
87+
const requiredDeps = templatePkg.dependencies || {};
88+
const existingDeps = projectPkg.dependencies || {};
89+
const existingDevDeps = projectPkg.devDependencies || {};
90+
const added = [];
91+
92+
for (const [name, version] of Object.entries(requiredDeps)) {
93+
if (existingDeps[name]) {
94+
continue;
95+
}
96+
97+
existingDeps[name] = existingDevDeps[name] || version;
98+
delete existingDevDeps[name];
99+
added.push(name);
100+
}
101+
102+
if (added.length > 0) {
103+
projectPkg.dependencies = Object.fromEntries(
104+
Object.entries(existingDeps).sort(([a], [b]) => a.localeCompare(b))
105+
);
106+
if (projectPkg.devDependencies) {
107+
projectPkg.devDependencies = Object.fromEntries(
108+
Object.entries(existingDevDeps).sort(([a], [b]) => a.localeCompare(b))
109+
);
110+
}
111+
}
112+
113+
return added;
114+
}
115+
86116
export async function upgrade(options = {}) {
87117
const cwd = process.cwd();
88118
const rcPath = path.join(cwd, '.coursecoderc.json');
@@ -109,6 +139,7 @@ export async function upgrade(options = {}) {
109139
// Get CLI version (this is the version we'll upgrade to)
110140
const cliPkg = JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf-8'));
111141
const targetVersion = cliPkg.version;
142+
const templatePkg = JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'template', 'package.json'), 'utf-8'));
112143

113144
console.log(`
114145
📦 CourseCode Upgrade
@@ -138,6 +169,7 @@ export async function upgrade(options = {}) {
138169
- framework/ (replace entirely)
139170
- schemas/ (replace entirely)
140171
- lib/manifest/ (replace entirely)
172+
- package.json (add missing runtime dependencies)
141173
- .coursecoderc.json (update version)`;
142174

143175
if (options.configs) {
@@ -150,7 +182,6 @@ export async function upgrade(options = {}) {
150182
151183
Would NOT touch:
152184
- course/ (your content)${!options.configs ? '\n - vite.config.js\n - eslint.config.js' : ''}
153-
- package.json
154185
- .env
155186
`;
156187
console.log(dryRunMsg);
@@ -231,13 +262,34 @@ export async function upgrade(options = {}) {
231262
rcConfig.upgradedFrom = currentVersion;
232263
fs.writeFileSync(rcPath, JSON.stringify(rcConfig, null, 2));
233264

265+
// Add any runtime dependencies introduced by the new framework while preserving
266+
// the project's existing version ranges.
267+
const pkgPath = path.join(cwd, 'package.json');
268+
let addedRuntimeDeps = [];
269+
if (fs.existsSync(pkgPath)) {
270+
const projectPkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
271+
addedRuntimeDeps = addMissingRuntimeDependencies(projectPkg, templatePkg);
272+
if (addedRuntimeDeps.length > 0) {
273+
fs.writeFileSync(pkgPath, JSON.stringify(projectPkg, null, 2) + '\n');
274+
}
275+
}
276+
234277
let successMsg = `
235278
✅ Upgrade complete!
236279
237280
${currentVersion}${targetVersion}
238281
239282
Your course/ directory was not modified.`;
240283

284+
if (addedRuntimeDeps.length > 0) {
285+
successMsg += `
286+
287+
Runtime dependencies added to package.json:
288+
- ${addedRuntimeDeps.join('\n - ')}
289+
290+
Run npm install to update node_modules and your lockfile.`;
291+
}
292+
241293
if (configUpdates.length > 0) {
242294
successMsg += `
243295

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "coursecode",
3-
"version": "0.1.43",
3+
"version": "0.1.44",
44
"description": "Multi-format course authoring framework with CLI tools (SCORM 2004, SCORM 1.2, cmi5, LTI 1.3)",
55
"type": "module",
66
"bin": {

template/vite.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ function scanDistFiles() {
190190
function scormPostBuild(isDev) {
191191
return {
192192
name: 'scorm-post-build',
193+
enforce: 'post',
193194
buildStart() {
194195
if (isDev) console.log('🔨 Building...');
195196
},
@@ -251,7 +252,7 @@ function scormPostBuild(isDev) {
251252
console.log('\n📦 Creating external hosting package archives...');
252253
await createExternalPackagesForClients({ rootDir: ROOT_DIR, config });
253254
}
254-
console.log('\n Package built successfully');
255+
console.log('\n Package archive created');
255256
} else {
256257
console.log('✅ Build complete\n');
257258
}

tests/lib/upgrade.test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { describe, it, expect } from 'vitest';
2+
import { addMissingRuntimeDependencies } from '../../lib/upgrade.js';
3+
4+
describe('upgrade package dependency migration', () => {
5+
it('adds missing runtime dependencies from the current template', () => {
6+
const projectPkg = {
7+
dependencies: {
8+
'marked': '^16.0.0'
9+
},
10+
devDependencies: {
11+
'vite': '~7.2.2'
12+
}
13+
};
14+
const templatePkg = {
15+
dependencies: {
16+
'@xapi/cmi5': '^1.4.0',
17+
'jose': '^6.2.2',
18+
'marked': '^17.0.6'
19+
}
20+
};
21+
22+
const added = addMissingRuntimeDependencies(projectPkg, templatePkg);
23+
24+
expect(added).toEqual(['@xapi/cmi5', 'jose']);
25+
expect(projectPkg.dependencies).toEqual({
26+
'@xapi/cmi5': '^1.4.0',
27+
'jose': '^6.2.2',
28+
'marked': '^16.0.0'
29+
});
30+
});
31+
32+
it('moves required runtime dependencies out of dev dependencies', () => {
33+
const projectPkg = {
34+
devDependencies: {
35+
'jose': '^6.1.0',
36+
'vite': '~7.2.2'
37+
}
38+
};
39+
const templatePkg = {
40+
dependencies: {
41+
'jose': '^6.2.2'
42+
}
43+
};
44+
45+
const added = addMissingRuntimeDependencies(projectPkg, templatePkg);
46+
47+
expect(added).toEqual(['jose']);
48+
expect(projectPkg.dependencies).toEqual({ 'jose': '^6.1.0' });
49+
expect(projectPkg.devDependencies).toEqual({ 'vite': '~7.2.2' });
50+
});
51+
});

0 commit comments

Comments
 (0)