@actuate-media/cli 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +69 -12
- package/CHANGELOG.md +58 -0
- package/dist/__tests__/db-init.test.d.ts +2 -0
- package/dist/__tests__/db-init.test.d.ts.map +1 -0
- package/dist/__tests__/db-init.test.js +127 -0
- package/dist/__tests__/db-init.test.js.map +1 -0
- package/dist/__tests__/db-sync.test.d.ts +2 -0
- package/dist/__tests__/db-sync.test.d.ts.map +1 -0
- package/dist/__tests__/db-sync.test.js +136 -0
- package/dist/__tests__/db-sync.test.js.map +1 -0
- package/dist/__tests__/deployment-diagnostics.test.js.map +1 -1
- package/dist/__tests__/init.test.js.map +1 -1
- package/dist/__tests__/schema-fragment.test.js +1 -1
- package/dist/__tests__/schema-fragment.test.js.map +1 -1
- package/dist/__tests__/seed.test.js.map +1 -1
- package/dist/commands/db-init.d.ts +19 -2
- package/dist/commands/db-init.d.ts.map +1 -1
- package/dist/commands/db-init.js +128 -306
- package/dist/commands/db-init.js.map +1 -1
- package/dist/commands/db-status.d.ts +1 -1
- package/dist/commands/db-status.d.ts.map +1 -1
- package/dist/commands/db-status.js +33 -33
- package/dist/commands/db-status.js.map +1 -1
- package/dist/commands/db-sync.d.ts +31 -0
- package/dist/commands/db-sync.d.ts.map +1 -0
- package/dist/commands/db-sync.js +195 -0
- package/dist/commands/db-sync.js.map +1 -0
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +48 -41
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/export.d.ts +1 -1
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +32 -32
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/generate.d.ts +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +8 -8
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/import.d.ts +1 -1
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +55 -58
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate.d.ts +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +18 -24
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/seed.d.ts +1 -1
- package/dist/commands/seed.d.ts.map +1 -1
- package/dist/commands/seed.js +156 -157
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/update-check.d.ts +1 -1
- package/dist/commands/update-check.d.ts.map +1 -1
- package/dist/commands/update-check.js +34 -27
- package/dist/commands/update-check.js.map +1 -1
- package/dist/commands/upgrade.d.ts +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +46 -34
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/deployment/diagnostics.d.ts.map +1 -1
- package/dist/deployment/diagnostics.js +7 -2
- package/dist/deployment/diagnostics.js.map +1 -1
- package/dist/index.js +17 -15
- package/dist/index.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +5 -5
- package/dist/utils/logger.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/db-init.test.ts +155 -0
- package/src/__tests__/db-sync.test.ts +167 -0
- package/src/__tests__/deployment-diagnostics.test.ts +68 -60
- package/src/__tests__/init.test.ts +17 -17
- package/src/__tests__/schema-fragment.test.ts +29 -25
- package/src/__tests__/seed.test.ts +25 -25
- package/src/commands/db-init.ts +146 -319
- package/src/commands/db-status.ts +70 -68
- package/src/commands/db-sync.ts +227 -0
- package/src/commands/doctor.ts +102 -88
- package/src/commands/export.ts +65 -75
- package/src/commands/generate.ts +14 -16
- package/src/commands/import.ts +125 -140
- package/src/commands/init.ts +14 -14
- package/src/commands/migrate.ts +29 -35
- package/src/commands/seed.ts +294 -300
- package/src/commands/update-check.ts +77 -72
- package/src/commands/upgrade.ts +100 -85
- package/src/deployment/diagnostics.ts +86 -72
- package/src/index.ts +32 -30
- package/src/utils/logger.ts +10 -10
|
@@ -1,65 +1,72 @@
|
|
|
1
|
-
import { Command } from
|
|
2
|
-
import { readFile } from
|
|
3
|
-
import { existsSync } from
|
|
4
|
-
import { resolve } from
|
|
5
|
-
import ora from
|
|
6
|
-
import { logger } from
|
|
7
|
-
|
|
8
|
-
const
|
|
1
|
+
import { Command } from 'commander'
|
|
2
|
+
import { readFile } from 'node:fs/promises'
|
|
3
|
+
import { existsSync } from 'node:fs'
|
|
4
|
+
import { resolve } from 'node:path'
|
|
5
|
+
import ora from 'ora'
|
|
6
|
+
import { logger } from '../utils/logger.js'
|
|
7
|
+
|
|
8
|
+
const UPDATE_SERVER_BASE = (
|
|
9
|
+
process.env.ACTUATE_UPDATE_SERVER_URL ?? 'https://updates.actuatecms.com'
|
|
10
|
+
).replace(/\/+$/, '')
|
|
11
|
+
const UPDATE_SERVER_URL = `${UPDATE_SERVER_BASE}/api/versions`
|
|
9
12
|
|
|
10
13
|
function compareVersions(a: string, b: string): number {
|
|
11
|
-
const pa = a
|
|
12
|
-
|
|
14
|
+
const pa = a
|
|
15
|
+
.replace(/^[^0-9]*/, '')
|
|
16
|
+
.split('.')
|
|
17
|
+
.map(Number)
|
|
18
|
+
const pb = b
|
|
19
|
+
.replace(/^[^0-9]*/, '')
|
|
20
|
+
.split('.')
|
|
21
|
+
.map(Number)
|
|
13
22
|
for (let i = 0; i < 3; i++) {
|
|
14
|
-
if ((pa[i] || 0) > (pb[i] || 0)) return 1
|
|
15
|
-
if ((pa[i] || 0) < (pb[i] || 0)) return -1
|
|
23
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return 1
|
|
24
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return -1
|
|
16
25
|
}
|
|
17
|
-
return 0
|
|
26
|
+
return 0
|
|
18
27
|
}
|
|
19
28
|
|
|
20
29
|
interface PackageVersions {
|
|
21
|
-
[pkg: string]: string
|
|
30
|
+
[pkg: string]: string
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
async function getLocalVersions(): Promise<PackageVersions> {
|
|
25
|
-
const pkgPath = resolve(process.cwd(),
|
|
34
|
+
const pkgPath = resolve(process.cwd(), 'package.json')
|
|
26
35
|
if (!existsSync(pkgPath)) {
|
|
27
|
-
throw new Error(
|
|
36
|
+
throw new Error('No package.json found in the current directory.')
|
|
28
37
|
}
|
|
29
38
|
|
|
30
|
-
const raw = await readFile(pkgPath,
|
|
31
|
-
const pkg = JSON.parse(raw)
|
|
32
|
-
const versions: PackageVersions = {}
|
|
39
|
+
const raw = await readFile(pkgPath, 'utf-8')
|
|
40
|
+
const pkg = JSON.parse(raw)
|
|
41
|
+
const versions: PackageVersions = {}
|
|
33
42
|
|
|
34
|
-
for (const section of [
|
|
35
|
-
const deps = pkg[section]
|
|
36
|
-
if (!deps) continue
|
|
43
|
+
for (const section of ['dependencies', 'devDependencies'] as const) {
|
|
44
|
+
const deps = pkg[section]
|
|
45
|
+
if (!deps) continue
|
|
37
46
|
for (const [name, version] of Object.entries(deps)) {
|
|
38
|
-
if (name.startsWith(
|
|
39
|
-
versions[name] = version.replace(/^[\^~]/,
|
|
47
|
+
if (name.startsWith('@actuate-media/') && typeof version === 'string') {
|
|
48
|
+
versions[name] = version.replace(/^[\^~]/, '').replace('workspace:', '')
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
return versions
|
|
53
|
+
return versions
|
|
45
54
|
}
|
|
46
55
|
|
|
47
|
-
async function fetchLatestVersions(
|
|
48
|
-
|
|
49
|
-
): Promise<PackageVersions> {
|
|
50
|
-
const versions: PackageVersions = {};
|
|
56
|
+
async function fetchLatestVersions(packages: string[]): Promise<PackageVersions> {
|
|
57
|
+
const versions: PackageVersions = {}
|
|
51
58
|
|
|
52
59
|
try {
|
|
53
|
-
const res = await fetch(UPDATE_SERVER_URL)
|
|
60
|
+
const res = await fetch(UPDATE_SERVER_URL)
|
|
54
61
|
if (res.ok) {
|
|
55
|
-
const data = await res.json()
|
|
62
|
+
const data = await res.json()
|
|
56
63
|
for (const pkg of packages) {
|
|
57
64
|
if (data[pkg]) {
|
|
58
|
-
versions[pkg] = data[pkg]
|
|
65
|
+
versions[pkg] = data[pkg]
|
|
59
66
|
}
|
|
60
67
|
}
|
|
61
68
|
if (Object.keys(versions).length === packages.length) {
|
|
62
|
-
return versions
|
|
69
|
+
return versions
|
|
63
70
|
}
|
|
64
71
|
}
|
|
65
72
|
} catch {
|
|
@@ -67,81 +74,79 @@ async function fetchLatestVersions(
|
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
for (const pkg of packages) {
|
|
70
|
-
if (versions[pkg]) continue
|
|
77
|
+
if (versions[pkg]) continue
|
|
71
78
|
try {
|
|
72
|
-
const npmUrl = `https://registry.npmjs.org/${pkg}/latest
|
|
73
|
-
const res = await fetch(npmUrl)
|
|
79
|
+
const npmUrl = `https://registry.npmjs.org/${pkg}/latest`
|
|
80
|
+
const res = await fetch(npmUrl)
|
|
74
81
|
if (res.ok) {
|
|
75
|
-
const data = await res.json()
|
|
76
|
-
versions[pkg] = data.version
|
|
82
|
+
const data = await res.json()
|
|
83
|
+
versions[pkg] = data.version
|
|
77
84
|
}
|
|
78
85
|
} catch {
|
|
79
86
|
// Skip packages we can't look up
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
89
|
|
|
83
|
-
return versions
|
|
90
|
+
return versions
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
async function runUpdateCheck(): Promise<void> {
|
|
87
|
-
const spinner = ora(
|
|
94
|
+
const spinner = ora('Checking for updates…').start()
|
|
88
95
|
|
|
89
96
|
try {
|
|
90
|
-
const local = await getLocalVersions()
|
|
91
|
-
const packages = Object.keys(local)
|
|
97
|
+
const local = await getLocalVersions()
|
|
98
|
+
const packages = Object.keys(local)
|
|
92
99
|
|
|
93
100
|
if (packages.length === 0) {
|
|
94
|
-
spinner.warn(
|
|
95
|
-
return
|
|
101
|
+
spinner.warn('No @actuate-media/* packages found in package.json.')
|
|
102
|
+
return
|
|
96
103
|
}
|
|
97
104
|
|
|
98
|
-
const latest = await fetchLatestVersions(packages)
|
|
99
|
-
spinner.stop()
|
|
105
|
+
const latest = await fetchLatestVersions(packages)
|
|
106
|
+
spinner.stop()
|
|
100
107
|
|
|
101
|
-
let hasUpdates = false
|
|
108
|
+
let hasUpdates = false
|
|
102
109
|
|
|
103
|
-
console.log(
|
|
104
|
-
|
|
110
|
+
console.log(
|
|
111
|
+
'\n ' + 'Package'.padEnd(30) + 'Current'.padEnd(14) + 'Latest'.padEnd(14) + 'Status',
|
|
112
|
+
)
|
|
113
|
+
console.log(' ' + '-'.repeat(68))
|
|
105
114
|
|
|
106
115
|
for (const pkg of packages) {
|
|
107
|
-
const current = local[pkg]
|
|
108
|
-
const remote = latest[pkg] ??
|
|
109
|
-
let status: string
|
|
116
|
+
const current = local[pkg]
|
|
117
|
+
const remote = latest[pkg] ?? 'unknown'
|
|
118
|
+
let status: string
|
|
110
119
|
|
|
111
|
-
if (remote ===
|
|
112
|
-
status =
|
|
120
|
+
if (remote === 'unknown') {
|
|
121
|
+
status = '?'
|
|
113
122
|
} else if (compareVersions(current!, remote) < 0) {
|
|
114
|
-
status =
|
|
115
|
-
hasUpdates = true
|
|
123
|
+
status = 'Update available'
|
|
124
|
+
hasUpdates = true
|
|
116
125
|
} else {
|
|
117
|
-
status =
|
|
126
|
+
status = 'Up to date'
|
|
118
127
|
}
|
|
119
128
|
|
|
120
|
-
console.log(
|
|
121
|
-
` ${pkg.padEnd(30)}${(current ?? '').padEnd(14)}${remote.padEnd(14)}${status}`,
|
|
122
|
-
);
|
|
129
|
+
console.log(` ${pkg.padEnd(30)}${(current ?? '').padEnd(14)}${remote.padEnd(14)}${status}`)
|
|
123
130
|
}
|
|
124
131
|
|
|
125
|
-
console.log()
|
|
132
|
+
console.log()
|
|
126
133
|
|
|
127
134
|
if (hasUpdates) {
|
|
128
|
-
logger.warn('Updates available! Run "actuate upgrade" to update.')
|
|
135
|
+
logger.warn('Updates available! Run "actuate upgrade" to update.')
|
|
129
136
|
} else {
|
|
130
|
-
logger.success(
|
|
137
|
+
logger.success('All packages are up to date!')
|
|
131
138
|
}
|
|
132
139
|
} catch (err) {
|
|
133
|
-
spinner.fail(
|
|
134
|
-
const message = err instanceof Error ? err.message : String(err)
|
|
135
|
-
logger.error(message)
|
|
136
|
-
process.exit(1)
|
|
140
|
+
spinner.fail('Update check failed.')
|
|
141
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
142
|
+
logger.error(message)
|
|
143
|
+
process.exit(1)
|
|
137
144
|
}
|
|
138
145
|
}
|
|
139
146
|
|
|
140
147
|
export function registerUpdateCheckCommand(program: Command): void {
|
|
141
148
|
program
|
|
142
|
-
.command(
|
|
143
|
-
.description(
|
|
144
|
-
|
|
145
|
-
)
|
|
146
|
-
.action(runUpdateCheck);
|
|
149
|
+
.command('update-check')
|
|
150
|
+
.description('Check for available Actuate CMS package updates')
|
|
151
|
+
.action(runUpdateCheck)
|
|
147
152
|
}
|
package/src/commands/upgrade.ts
CHANGED
|
@@ -1,173 +1,188 @@
|
|
|
1
|
-
import { Command } from
|
|
2
|
-
import { readFile, writeFile } from
|
|
3
|
-
import { existsSync } from
|
|
4
|
-
import { resolve } from
|
|
5
|
-
import { createInterface } from
|
|
6
|
-
import ora from
|
|
7
|
-
import { logger } from
|
|
8
|
-
|
|
9
|
-
const
|
|
1
|
+
import { Command } from 'commander'
|
|
2
|
+
import { readFile, writeFile } from 'node:fs/promises'
|
|
3
|
+
import { existsSync } from 'node:fs'
|
|
4
|
+
import { resolve } from 'node:path'
|
|
5
|
+
import { createInterface } from 'node:readline/promises'
|
|
6
|
+
import ora from 'ora'
|
|
7
|
+
import { logger } from '../utils/logger.js'
|
|
8
|
+
|
|
9
|
+
const UPDATE_SERVER_BASE = (
|
|
10
|
+
process.env.ACTUATE_UPDATE_SERVER_URL ?? 'https://updates.actuatecms.com'
|
|
11
|
+
).replace(/\/+$/, '')
|
|
12
|
+
const UPDATE_SERVER_URL = `${UPDATE_SERVER_BASE}/api/versions`
|
|
10
13
|
|
|
11
14
|
function compareVersions(a: string, b: string): number {
|
|
12
|
-
const pa = a
|
|
13
|
-
|
|
15
|
+
const pa = a
|
|
16
|
+
.replace(/^[^0-9]*/, '')
|
|
17
|
+
.split('.')
|
|
18
|
+
.map(Number)
|
|
19
|
+
const pb = b
|
|
20
|
+
.replace(/^[^0-9]*/, '')
|
|
21
|
+
.split('.')
|
|
22
|
+
.map(Number)
|
|
14
23
|
for (let i = 0; i < 3; i++) {
|
|
15
|
-
if ((pa[i] || 0) > (pb[i] || 0)) return 1
|
|
16
|
-
if ((pa[i] || 0) < (pb[i] || 0)) return -1
|
|
24
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return 1
|
|
25
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return -1
|
|
17
26
|
}
|
|
18
|
-
return 0
|
|
27
|
+
return 0
|
|
19
28
|
}
|
|
20
29
|
|
|
21
30
|
async function confirm(question: string): Promise<boolean> {
|
|
22
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout })
|
|
31
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout })
|
|
23
32
|
try {
|
|
24
|
-
const answer = await rl.question(`${question} (y/N) `)
|
|
25
|
-
return answer.trim().toLowerCase() ===
|
|
33
|
+
const answer = await rl.question(`${question} (y/N) `)
|
|
34
|
+
return answer.trim().toLowerCase() === 'y'
|
|
26
35
|
} finally {
|
|
27
|
-
rl.close()
|
|
36
|
+
rl.close()
|
|
28
37
|
}
|
|
29
38
|
}
|
|
30
39
|
|
|
31
|
-
async function fetchLatestVersions(
|
|
32
|
-
|
|
33
|
-
): Promise<Record<string, string>> {
|
|
34
|
-
const versions: Record<string, string> = {};
|
|
40
|
+
async function fetchLatestVersions(packages: string[]): Promise<Record<string, string>> {
|
|
41
|
+
const versions: Record<string, string> = {}
|
|
35
42
|
|
|
36
43
|
try {
|
|
37
|
-
const res = await fetch(UPDATE_SERVER_URL)
|
|
44
|
+
const res = await fetch(UPDATE_SERVER_URL)
|
|
38
45
|
if (res.ok) {
|
|
39
|
-
const data = await res.json()
|
|
46
|
+
const data = await res.json()
|
|
40
47
|
for (const pkg of packages) {
|
|
41
|
-
if (data[pkg]) versions[pkg] = data[pkg]
|
|
48
|
+
if (data[pkg]) versions[pkg] = data[pkg]
|
|
42
49
|
}
|
|
43
|
-
if (Object.keys(versions).length === packages.length) return versions
|
|
50
|
+
if (Object.keys(versions).length === packages.length) return versions
|
|
44
51
|
}
|
|
45
52
|
} catch {
|
|
46
53
|
// Fall through to npm registry
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
for (const pkg of packages) {
|
|
50
|
-
if (versions[pkg]) continue
|
|
57
|
+
if (versions[pkg]) continue
|
|
51
58
|
try {
|
|
52
|
-
const res = await fetch(`https://registry.npmjs.org/${pkg}/latest`)
|
|
59
|
+
const res = await fetch(`https://registry.npmjs.org/${pkg}/latest`)
|
|
53
60
|
if (res.ok) {
|
|
54
|
-
const data = await res.json()
|
|
55
|
-
versions[pkg] = data.version
|
|
61
|
+
const data = await res.json()
|
|
62
|
+
versions[pkg] = data.version
|
|
56
63
|
}
|
|
57
64
|
} catch {
|
|
58
65
|
// Skip
|
|
59
66
|
}
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
return versions
|
|
69
|
+
return versions
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
interface UpgradeOptions {
|
|
66
|
-
latest?: boolean
|
|
67
|
-
version?: string
|
|
68
|
-
dryRun?: boolean
|
|
73
|
+
latest?: boolean
|
|
74
|
+
version?: string
|
|
75
|
+
dryRun?: boolean
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
async function runUpgrade(options: UpgradeOptions): Promise<void> {
|
|
72
|
-
const pkgPath = resolve(process.cwd(),
|
|
79
|
+
const pkgPath = resolve(process.cwd(), 'package.json')
|
|
73
80
|
if (!existsSync(pkgPath)) {
|
|
74
|
-
logger.error(
|
|
75
|
-
process.exit(1)
|
|
81
|
+
logger.error('No package.json found in the current directory.')
|
|
82
|
+
process.exit(1)
|
|
76
83
|
}
|
|
77
84
|
|
|
78
|
-
const raw = await readFile(pkgPath,
|
|
79
|
-
const pkg = JSON.parse(raw)
|
|
85
|
+
const raw = await readFile(pkgPath, 'utf-8')
|
|
86
|
+
const pkg = JSON.parse(raw)
|
|
80
87
|
|
|
81
|
-
const actuatePackages: { name: string; current: string; section: string }[] = []
|
|
88
|
+
const actuatePackages: { name: string; current: string; section: string }[] = []
|
|
82
89
|
|
|
83
|
-
for (const section of [
|
|
84
|
-
const deps = pkg[section]
|
|
85
|
-
if (!deps) continue
|
|
90
|
+
for (const section of ['dependencies', 'devDependencies'] as const) {
|
|
91
|
+
const deps = pkg[section]
|
|
92
|
+
if (!deps) continue
|
|
86
93
|
for (const [name, version] of Object.entries(deps)) {
|
|
87
|
-
if (name.startsWith(
|
|
88
|
-
if (version.startsWith(
|
|
94
|
+
if (name.startsWith('@actuate-media/') && typeof version === 'string') {
|
|
95
|
+
if (version.startsWith('workspace:')) continue
|
|
89
96
|
actuatePackages.push({
|
|
90
97
|
name,
|
|
91
|
-
current: version.replace(/^[\^~]/,
|
|
98
|
+
current: version.replace(/^[\^~]/, ''),
|
|
92
99
|
section,
|
|
93
|
-
})
|
|
100
|
+
})
|
|
94
101
|
}
|
|
95
102
|
}
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
if (actuatePackages.length === 0) {
|
|
99
|
-
logger.warn(
|
|
100
|
-
|
|
106
|
+
logger.warn(
|
|
107
|
+
'No @actuate-media/* packages found in package.json (excluding workspace: references).',
|
|
108
|
+
)
|
|
109
|
+
return
|
|
101
110
|
}
|
|
102
111
|
|
|
103
|
-
const spinner = ora(
|
|
112
|
+
const spinner = ora('Resolving target versions…').start()
|
|
104
113
|
|
|
105
|
-
let targetVersions: Record<string, string
|
|
114
|
+
let targetVersions: Record<string, string>
|
|
106
115
|
|
|
107
116
|
if (options.version) {
|
|
108
|
-
targetVersions = {}
|
|
117
|
+
targetVersions = {}
|
|
109
118
|
for (const p of actuatePackages) {
|
|
110
|
-
targetVersions[p.name] = options.version
|
|
119
|
+
targetVersions[p.name] = options.version
|
|
111
120
|
}
|
|
112
|
-
spinner.succeed(`Target version: ${options.version}`)
|
|
121
|
+
spinner.succeed(`Target version: ${options.version}`)
|
|
113
122
|
} else {
|
|
114
|
-
targetVersions = await fetchLatestVersions(
|
|
115
|
-
|
|
116
|
-
);
|
|
117
|
-
spinner.succeed("Resolved latest versions.");
|
|
123
|
+
targetVersions = await fetchLatestVersions(actuatePackages.map((p) => p.name))
|
|
124
|
+
spinner.succeed('Resolved latest versions.')
|
|
118
125
|
}
|
|
119
126
|
|
|
120
|
-
const upgrades: { name: string; from: string; to: string; section: string }[] = []
|
|
127
|
+
const upgrades: { name: string; from: string; to: string; section: string }[] = []
|
|
121
128
|
|
|
122
129
|
for (const p of actuatePackages) {
|
|
123
|
-
const target = targetVersions[p.name]
|
|
124
|
-
if (!target) continue
|
|
130
|
+
const target = targetVersions[p.name]
|
|
131
|
+
if (!target) continue
|
|
125
132
|
if (compareVersions(p.current, target) < 0) {
|
|
126
|
-
upgrades.push({ name: p.name, from: p.current, to: target, section: p.section })
|
|
133
|
+
upgrades.push({ name: p.name, from: p.current, to: target, section: p.section })
|
|
127
134
|
}
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
if (upgrades.length === 0) {
|
|
131
|
-
logger.success(
|
|
132
|
-
return
|
|
138
|
+
logger.success('All @actuate-media/* packages are already up to date.')
|
|
139
|
+
return
|
|
133
140
|
}
|
|
134
141
|
|
|
135
|
-
console.log(
|
|
136
|
-
console.log(
|
|
137
|
-
console.log(
|
|
142
|
+
console.log('\n Proposed upgrades:\n')
|
|
143
|
+
console.log(' ' + 'Package'.padEnd(30) + 'From'.padEnd(14) + 'To')
|
|
144
|
+
console.log(' ' + '-'.repeat(54))
|
|
138
145
|
for (const u of upgrades) {
|
|
139
|
-
console.log(` ${u.name.padEnd(30)}${u.from.padEnd(14)}${u.to}`)
|
|
146
|
+
console.log(` ${u.name.padEnd(30)}${u.from.padEnd(14)}${u.to}`)
|
|
140
147
|
}
|
|
141
|
-
console.log()
|
|
148
|
+
console.log()
|
|
142
149
|
|
|
143
150
|
if (options.dryRun) {
|
|
144
|
-
logger.info(
|
|
145
|
-
return
|
|
151
|
+
logger.info('Dry run — no changes were made.')
|
|
152
|
+
return
|
|
146
153
|
}
|
|
147
154
|
|
|
148
|
-
const proceed = await confirm(
|
|
155
|
+
const proceed = await confirm('Apply these upgrades to package.json?')
|
|
149
156
|
if (!proceed) {
|
|
150
|
-
logger.warn(
|
|
151
|
-
return
|
|
157
|
+
logger.warn('Upgrade cancelled.')
|
|
158
|
+
return
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
for (const u of upgrades) {
|
|
155
|
-
const prefix = pkg[u.section][u.name]?.match(/^[\^~]/)?.[0] ??
|
|
156
|
-
pkg[u.section][u.name] = `${prefix}${u.to}
|
|
162
|
+
const prefix = pkg[u.section][u.name]?.match(/^[\^~]/)?.[0] ?? '^'
|
|
163
|
+
pkg[u.section][u.name] = `${prefix}${u.to}`
|
|
157
164
|
}
|
|
158
165
|
|
|
159
|
-
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) +
|
|
166
|
+
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8')
|
|
167
|
+
|
|
168
|
+
logger.success(`Updated ${upgrades.length} package(s) in package.json.`)
|
|
169
|
+
logger.info('Run "pnpm install" to apply the upgrade.')
|
|
160
170
|
|
|
161
|
-
|
|
162
|
-
|
|
171
|
+
// A cms-core bump can introduce new models/migrations. Bumping the version
|
|
172
|
+
// alone leaves the consumer's Prisma schema stale, so point them at db:sync.
|
|
173
|
+
if (upgrades.some((u) => u.name === '@actuate-media/cms-core')) {
|
|
174
|
+
logger.info(
|
|
175
|
+
'cms-core changed — after installing, run "actuate db:sync" then "npx prisma migrate deploy" to update your Prisma schema.',
|
|
176
|
+
)
|
|
177
|
+
}
|
|
163
178
|
}
|
|
164
179
|
|
|
165
180
|
export function registerUpgradeCommand(program: Command): void {
|
|
166
181
|
program
|
|
167
|
-
.command(
|
|
168
|
-
.description(
|
|
169
|
-
.option(
|
|
170
|
-
.option(
|
|
171
|
-
.option(
|
|
172
|
-
.action(runUpgrade)
|
|
182
|
+
.command('upgrade')
|
|
183
|
+
.description('Upgrade @actuate-media/* packages to the latest or a specific version')
|
|
184
|
+
.option('--latest', 'Upgrade to the latest version (default)', true)
|
|
185
|
+
.option('--version <ver>', 'Upgrade to a specific version')
|
|
186
|
+
.option('--dry-run', 'Show proposed changes without modifying files')
|
|
187
|
+
.action(runUpgrade)
|
|
173
188
|
}
|