Skip to content

Commit d0876c2

Browse files
committed
chore: bump version
1 parent 2386ff3 commit d0876c2

File tree

9 files changed

+218
-22
lines changed

9 files changed

+218
-22
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@icebreakers/monorepo': patch
3+
---
4+
5+
Add merge-on-upgrade for `pnpm-workspace.yaml` so missing defaults are filled without overwriting existing workspace settings.

apps/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"vite": "^7.2.6",
4545
"vite-plugin-vue-devtools": "^8.0.5",
4646
"vite-tsconfig-paths": "^5.1.4",
47-
"vue-tsc": "3.1.5",
47+
"vue-tsc": "3.1.6",
4848
"wrangler": "^4.53.0",
4949
"zod": "^4.1.13"
5050
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"@changesets/cli": "^2.29.8",
4545
"@commitlint/cli": "^20.2.0",
4646
"@icebreakers/commitlint-config": "^1.2.3",
47-
"@icebreakers/eslint-config": "^1.6.3",
47+
"@icebreakers/eslint-config": "^1.6.4",
4848
"@icebreakers/monorepo": "workspace:*",
4949
"@icebreakers/stylelint-config": "^1.2.3",
5050
"@types/fs-extra": "^11.0.4",

packages/monorepo/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@
9292
"pathe": "^2.0.3",
9393
"picocolors": "^1.1.1",
9494
"semver": "^7.7.3",
95-
"simple-git": "^3.30.0"
95+
"simple-git": "^3.30.0",
96+
"yaml": "^2.8.2"
9697
},
9798
"devDependencies": {
9899
"@types/klaw": "^3.0.7",

packages/monorepo/src/commands/upgrade/index.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import fs from 'fs-extra'
66
import klaw from 'klaw'
77
import path from 'pathe'
88
import set from 'set-value'
9+
import YAML from 'yaml'
910
import { assetsDir } from '../../constants'
1011
import { resolveCommandConfig } from '../../core/config'
1112
import { GitClient } from '../../core/git'
@@ -14,6 +15,7 @@ import { escapeStringRegexp, isIgnorableFsError, isMatch, toWorkspaceGitignorePa
1415
import { evaluateWriteIntent, flushPendingOverwrites, scheduleOverwrite } from './overwrite'
1516
import { setPkgJson } from './pkg-json'
1617
import { getAssetTargets } from './targets'
18+
import { mergeWorkspaceManifest, normalizeWorkspaceManifest } from './workspace'
1719

1820
export { setPkgJson }
1921

@@ -110,6 +112,32 @@ export async function upgradeMonorepo(opts: CliOpts) {
110112
continue
111113
}
112114

115+
if (relPath === 'pnpm-workspace.yaml') {
116+
const sourceManifest = normalizeWorkspaceManifest(
117+
YAML.parse(await fs.readFile(file.path, 'utf8')),
118+
)
119+
const exists = await fs.pathExists(targetPath)
120+
const targetManifest = exists
121+
? normalizeWorkspaceManifest(YAML.parse(await fs.readFile(targetPath, 'utf8')))
122+
: normalizeWorkspaceManifest({})
123+
const mergedManifest = exists
124+
? mergeWorkspaceManifest(sourceManifest, targetManifest)
125+
: sourceManifest
126+
const data = YAML.stringify(mergedManifest)
127+
const intent = await evaluateWriteIntent(targetPath, { skipOverwrite, source: data })
128+
const action = async () => {
129+
await fs.outputFile(targetPath, data, 'utf8')
130+
logger.success(targetPath)
131+
}
132+
await scheduleOverwrite(intent, {
133+
relPath,
134+
targetPath,
135+
action,
136+
pending: pendingOverwrites,
137+
})
138+
continue
139+
}
140+
113141
if (relPath === '.changeset/config.json' && repoName) {
114142
const changesetJson = await fs.readJson(file.path)
115143
set(changesetJson, 'changelog.1.repo', repoName)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import type { WorkspaceManifest } from '@pnpm/workspace.read-manifest'
2+
3+
export type WorkspaceManifestLike = Partial<WorkspaceManifest> & Record<string, unknown>
4+
5+
function isPlainObject(value: unknown): value is Record<string, unknown> {
6+
return typeof value === 'object' && value !== null && !Array.isArray(value)
7+
}
8+
9+
export function normalizeWorkspaceManifest(manifest: unknown): WorkspaceManifestLike {
10+
if (isPlainObject(manifest)) {
11+
return { ...manifest }
12+
}
13+
return {}
14+
}
15+
16+
function mergeUniqueArray<T>(target: T[], source: T[]) {
17+
const result = [...target]
18+
for (const item of source) {
19+
if (!result.includes(item)) {
20+
result.push(item)
21+
}
22+
}
23+
return result
24+
}
25+
26+
/**
27+
* Merge pnpm workspace manifests by filling missing fields only.
28+
* Existing values take precedence; arrays are deduped while keeping target order.
29+
*/
30+
export function mergeWorkspaceManifest(source: WorkspaceManifestLike, target: WorkspaceManifestLike): WorkspaceManifestLike {
31+
const normalizedSource = normalizeWorkspaceManifest(source)
32+
const normalizedTarget = normalizeWorkspaceManifest(target)
33+
const result: WorkspaceManifestLike = { ...normalizedTarget }
34+
35+
for (const [key, value] of Object.entries(normalizedSource)) {
36+
const current = (normalizedTarget as Record<string, unknown>)[key]
37+
if (current === undefined) {
38+
(result as Record<string, unknown>)[key] = value
39+
continue
40+
}
41+
42+
if (Array.isArray(current) && Array.isArray(value)) {
43+
(result as Record<string, unknown>)[key] = mergeUniqueArray(current, value)
44+
continue
45+
}
46+
47+
if (isPlainObject(current) && isPlainObject(value)) {
48+
(result as Record<string, unknown>)[key] = mergeWorkspaceManifest(
49+
value as WorkspaceManifestLike,
50+
current as WorkspaceManifestLike,
51+
)
52+
continue
53+
}
54+
55+
(result as Record<string, unknown>)[key] = current
56+
}
57+
58+
return result
59+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { WorkspaceManifest } from '@pnpm/workspace.read-manifest'
2+
import { describe, expect, it } from 'vitest'
3+
import { mergeWorkspaceManifest, normalizeWorkspaceManifest } from '@/commands/upgrade/workspace'
4+
5+
describe('mergeWorkspaceManifest', () => {
6+
it('adds missing workspace config without overriding existing values', () => {
7+
const source: WorkspaceManifest = normalizeWorkspaceManifest({
8+
packages: ['apps/*', 'packages/*', '!**/test/**'],
9+
onlyBuiltDependencies: ['esbuild', 'sharp'],
10+
catalogs: {
11+
default: {
12+
typescript: '5.5.0',
13+
vitest: '2.0.0',
14+
},
15+
},
16+
})
17+
const target: WorkspaceManifest = normalizeWorkspaceManifest({
18+
packages: ['apps/*'],
19+
onlyBuiltDependencies: ['sharp'],
20+
catalogs: {
21+
default: {
22+
typescript: '5.4.0',
23+
},
24+
custom: {
25+
eslint: '9.0.0',
26+
},
27+
},
28+
})
29+
30+
const merged = mergeWorkspaceManifest(source, target)
31+
32+
expect(merged.packages).toEqual(['apps/*', 'packages/*', '!**/test/**'])
33+
expect(merged.onlyBuiltDependencies).toEqual(['sharp', 'esbuild'])
34+
expect(merged.catalogs).toEqual({
35+
default: {
36+
typescript: '5.4.0',
37+
vitest: '2.0.0',
38+
},
39+
custom: {
40+
eslint: '9.0.0',
41+
},
42+
})
43+
})
44+
45+
it('keeps target shapes when source types differ', () => {
46+
const merged = mergeWorkspaceManifest(
47+
normalizeWorkspaceManifest({ packages: ['apps/*'], hoist: true }),
48+
normalizeWorkspaceManifest({ packages: 'string-value', hoist: false }),
49+
)
50+
51+
expect(merged.packages).toBe('string-value')
52+
expect(merged.hoist).toBe(false)
53+
})
54+
})

packages/vue-lib-template/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@
5656
"vite-plugin-dts": "^4.5.4",
5757
"vue": "^3.5.25",
5858
"vue-router": "^4.6.3",
59-
"vue-tsc": "^3.1.5"
59+
"vue-tsc": "^3.1.6"
6060
}
6161
}

0 commit comments

Comments
 (0)