@uniweb/build 0.6.16 → 0.6.17
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/package.json +3 -3
- package/src/i18n/index.js +11 -6
- package/src/i18n/sync.js +37 -1
- package/src/site/content-collector.js +14 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/build",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.17",
|
|
4
4
|
"description": "Build tooling for the Uniweb Component Web Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"sharp": "^0.33.2"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
|
-
"@uniweb/runtime": "0.5.21",
|
|
54
53
|
"@uniweb/schemas": "0.2.1",
|
|
55
|
-
"@uniweb/content-reader": "1.1.2"
|
|
54
|
+
"@uniweb/content-reader": "1.1.2",
|
|
55
|
+
"@uniweb/runtime": "0.5.21"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
package/src/i18n/index.js
CHANGED
|
@@ -176,7 +176,8 @@ export async function extractManifest(siteRoot, options = {}) {
|
|
|
176
176
|
const {
|
|
177
177
|
localesDir = DEFAULTS.localesDir,
|
|
178
178
|
siteContentPath = join(siteRoot, 'dist', 'site-content.json'),
|
|
179
|
-
verbose = false
|
|
179
|
+
verbose = false,
|
|
180
|
+
dryRun = false
|
|
180
181
|
} = options
|
|
181
182
|
|
|
182
183
|
// Load site content
|
|
@@ -203,8 +204,10 @@ export async function extractManifest(siteRoot, options = {}) {
|
|
|
203
204
|
// Generate sync report
|
|
204
205
|
const report = syncManifests(previousManifest, manifest)
|
|
205
206
|
|
|
206
|
-
// Write new manifest
|
|
207
|
-
|
|
207
|
+
// Write new manifest (skip in dry-run mode)
|
|
208
|
+
if (!dryRun) {
|
|
209
|
+
await writeFile(manifestPath, JSON.stringify(manifest, null, 2))
|
|
210
|
+
}
|
|
208
211
|
|
|
209
212
|
if (verbose) {
|
|
210
213
|
console.log(formatSyncReport(report))
|
|
@@ -222,7 +225,7 @@ export async function extractManifest(siteRoot, options = {}) {
|
|
|
222
225
|
* @returns {Promise<Object>} { manifest, report }
|
|
223
226
|
*/
|
|
224
227
|
export async function extractCollectionManifest(siteRoot, options = {}) {
|
|
225
|
-
const { localesDir = DEFAULTS.localesDir } = options
|
|
228
|
+
const { localesDir = DEFAULTS.localesDir, dryRun = false } = options
|
|
226
229
|
|
|
227
230
|
// Extract translatable content from collections
|
|
228
231
|
const manifest = await extractCollectionContent(siteRoot)
|
|
@@ -249,8 +252,10 @@ export async function extractCollectionManifest(siteRoot, options = {}) {
|
|
|
249
252
|
// Generate sync report
|
|
250
253
|
const report = syncManifests(previousManifest, manifest)
|
|
251
254
|
|
|
252
|
-
// Write new manifest
|
|
253
|
-
|
|
255
|
+
// Write new manifest (skip in dry-run mode)
|
|
256
|
+
if (!dryRun) {
|
|
257
|
+
await writeFile(manifestPath, JSON.stringify(manifest, null, 2))
|
|
258
|
+
}
|
|
254
259
|
|
|
255
260
|
return { manifest, report }
|
|
256
261
|
}
|
package/src/i18n/sync.js
CHANGED
|
@@ -143,6 +143,15 @@ export function formatSyncReport(report) {
|
|
|
143
143
|
|
|
144
144
|
if (report.moved.length > 0) {
|
|
145
145
|
lines.push(` ↻ ${report.moved.length} strings moved (contexts updated)`)
|
|
146
|
+
for (const item of report.moved.slice(0, 5)) {
|
|
147
|
+
const preview = truncate(item.source, 40)
|
|
148
|
+
const oldCtx = formatContext(item.previousContexts?.[0])
|
|
149
|
+
const newCtx = formatContext(item.currentContexts?.[0])
|
|
150
|
+
lines.push(` - "${preview}" ${oldCtx} → ${newCtx}`)
|
|
151
|
+
}
|
|
152
|
+
if (report.moved.length > 5) {
|
|
153
|
+
lines.push(` ... and ${report.moved.length - 5} more`)
|
|
154
|
+
}
|
|
146
155
|
}
|
|
147
156
|
|
|
148
157
|
if (report.changed.length > 0) {
|
|
@@ -150,7 +159,7 @@ export function formatSyncReport(report) {
|
|
|
150
159
|
for (const item of report.changed.slice(0, 5)) {
|
|
151
160
|
const prevPreview = truncate(item.previousSource, 30)
|
|
152
161
|
const currPreview = truncate(item.source, 30)
|
|
153
|
-
lines.push(` -
|
|
162
|
+
lines.push(` - "${prevPreview}" → "${currPreview}"`)
|
|
154
163
|
}
|
|
155
164
|
if (report.changed.length > 5) {
|
|
156
165
|
lines.push(` ... and ${report.changed.length - 5} more`)
|
|
@@ -159,15 +168,42 @@ export function formatSyncReport(report) {
|
|
|
159
168
|
|
|
160
169
|
if (report.added.length > 0) {
|
|
161
170
|
lines.push(` + ${report.added.length} new strings`)
|
|
171
|
+
for (const item of report.added.slice(0, 5)) {
|
|
172
|
+
const preview = truncate(item.source, 40)
|
|
173
|
+
const ctx = formatContext(item.contexts?.[0])
|
|
174
|
+
lines.push(` - "${preview}" ${ctx}`)
|
|
175
|
+
}
|
|
176
|
+
if (report.added.length > 5) {
|
|
177
|
+
lines.push(` ... and ${report.added.length - 5} more`)
|
|
178
|
+
}
|
|
162
179
|
}
|
|
163
180
|
|
|
164
181
|
if (report.removed.length > 0) {
|
|
165
182
|
lines.push(` - ${report.removed.length} strings removed`)
|
|
183
|
+
for (const item of report.removed.slice(0, 5)) {
|
|
184
|
+
const preview = truncate(item.source, 40)
|
|
185
|
+
const ctx = formatContext(item.contexts?.[0])
|
|
186
|
+
lines.push(` - "${preview}" ${ctx}`)
|
|
187
|
+
}
|
|
188
|
+
if (report.removed.length > 5) {
|
|
189
|
+
lines.push(` ... and ${report.removed.length - 5} more`)
|
|
190
|
+
}
|
|
166
191
|
}
|
|
167
192
|
|
|
168
193
|
return lines.join('\n')
|
|
169
194
|
}
|
|
170
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Format a context object for display
|
|
198
|
+
*/
|
|
199
|
+
function formatContext(context) {
|
|
200
|
+
if (!context) return ''
|
|
201
|
+
const location = context.page || context.collection || ''
|
|
202
|
+
const section = context.section || context.item || ''
|
|
203
|
+
if (!location && !section) return ''
|
|
204
|
+
return `(${location}:${section})`
|
|
205
|
+
}
|
|
206
|
+
|
|
171
207
|
/**
|
|
172
208
|
* Truncate string for display
|
|
173
209
|
*/
|
|
@@ -203,10 +203,12 @@ function isIgnoredFolder(name) {
|
|
|
203
203
|
/**
|
|
204
204
|
* Read folder configuration, determining content mode from config file presence.
|
|
205
205
|
*
|
|
206
|
-
* - folder.yml present →
|
|
207
|
-
* - page.yml present →
|
|
206
|
+
* - folder.yml present → folder mode (md files are child pages)
|
|
207
|
+
* - page.yml present → page mode (md files are sections of this page)
|
|
208
208
|
* - Neither → inherit mode from parent
|
|
209
209
|
*
|
|
210
|
+
* Internal mode values: 'pages' (folder mode), 'sections' (page mode)
|
|
211
|
+
*
|
|
210
212
|
* @param {string} dirPath - Directory path
|
|
211
213
|
* @param {string} inheritedMode - Mode inherited from parent ('sections' or 'pages')
|
|
212
214
|
* @returns {Promise<{config: Object, mode: string, source: string}>}
|
|
@@ -220,7 +222,7 @@ async function readFolderConfig(dirPath, inheritedMode) {
|
|
|
220
222
|
if (Object.keys(pageYml).length > 0) {
|
|
221
223
|
return { config: pageYml, mode: 'sections', source: 'page.yml' }
|
|
222
224
|
}
|
|
223
|
-
// Check for empty folder.yml (presence signals
|
|
225
|
+
// Check for empty folder.yml (presence signals folder mode even if empty)
|
|
224
226
|
if (existsSync(join(dirPath, 'folder.yml'))) {
|
|
225
227
|
return { config: {}, mode: 'pages', source: 'folder.yml' }
|
|
226
228
|
}
|
|
@@ -289,7 +291,7 @@ function applyNonStrictOrder(items, orderArray) {
|
|
|
289
291
|
}
|
|
290
292
|
|
|
291
293
|
/**
|
|
292
|
-
* Process a markdown file as a standalone page (
|
|
294
|
+
* Process a markdown file as a standalone page (folder mode).
|
|
293
295
|
* Creates a page with a single section from the markdown content.
|
|
294
296
|
*
|
|
295
297
|
* @param {string} filePath - Path to markdown file
|
|
@@ -818,7 +820,7 @@ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig
|
|
|
818
820
|
const folderNames = orderedFolders.map(f => f.name)
|
|
819
821
|
const detectedVersions = detectVersions(folderNames)
|
|
820
822
|
|
|
821
|
-
// If versioned section, handle version folders specially (always
|
|
823
|
+
// If versioned section, handle version folders specially (always page mode)
|
|
822
824
|
if (detectedVersions && !versionContext) {
|
|
823
825
|
const parentConfig = await readYamlFile(join(dirPath, 'page.yml'))
|
|
824
826
|
const versionMeta = buildVersionMetadata(detectedVersions, parentConfig)
|
|
@@ -880,7 +882,7 @@ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig
|
|
|
880
882
|
// Apply non-strict order to md-file-pages
|
|
881
883
|
const orderedMdPages = applyNonStrictOrder(mdPageItems, orderConfig?.order)
|
|
882
884
|
|
|
883
|
-
// In
|
|
885
|
+
// In folder mode, only promote an index if explicitly set via index: in folder.yml
|
|
884
886
|
// The container page itself owns the parent route — don't auto-promote children
|
|
885
887
|
const indexName = orderConfig?.index || null
|
|
886
888
|
|
|
@@ -906,7 +908,7 @@ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig
|
|
|
906
908
|
const isIndex = entry === indexName
|
|
907
909
|
|
|
908
910
|
if (dirMode === 'sections') {
|
|
909
|
-
// Subdirectory overrides to
|
|
911
|
+
// Subdirectory overrides to page mode — process normally
|
|
910
912
|
const result = await processPage(entryPath, entry, siteRoot, {
|
|
911
913
|
isIndex, parentRoute, parentFetch, versionContext
|
|
912
914
|
})
|
|
@@ -917,7 +919,7 @@ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig
|
|
|
917
919
|
iconCollection = mergeIconCollections(iconCollection, pageIcons)
|
|
918
920
|
pages.push(page)
|
|
919
921
|
|
|
920
|
-
// Recurse into subdirectories (
|
|
922
|
+
// Recurse into subdirectories (page mode)
|
|
921
923
|
const childParentRoute = isIndex ? parentRoute : page.route
|
|
922
924
|
const childFetch = page.fetch || parentFetch
|
|
923
925
|
const subResult = await collectPagesRecursive(entryPath, childParentRoute, siteRoot, childOrderConfig, childFetch, versionContext, 'sections')
|
|
@@ -929,7 +931,7 @@ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig
|
|
|
929
931
|
}
|
|
930
932
|
}
|
|
931
933
|
} else {
|
|
932
|
-
// Container directory in
|
|
934
|
+
// Container directory in folder mode — create minimal page, recurse
|
|
933
935
|
const containerRoute = isIndex
|
|
934
936
|
? parentRoute
|
|
935
937
|
: parentRoute === '/' ? `/${entry}` : `${parentRoute}/${entry}`
|
|
@@ -971,7 +973,7 @@ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig
|
|
|
971
973
|
|
|
972
974
|
pages.push(containerPage)
|
|
973
975
|
|
|
974
|
-
// Recurse in
|
|
976
|
+
// Recurse in folder mode
|
|
975
977
|
const subResult = await collectPagesRecursive(entryPath, containerRoute, siteRoot, childOrderConfig, parentFetch, versionContext, 'pages')
|
|
976
978
|
pages.push(...subResult.pages)
|
|
977
979
|
assetCollection = mergeAssetCollections(assetCollection, subResult.assetCollection)
|
|
@@ -1000,8 +1002,8 @@ async function collectPagesRecursive(dirPath, parentRoute, siteRoot, orderConfig
|
|
|
1000
1002
|
const isIndex = entry === indexPageName
|
|
1001
1003
|
|
|
1002
1004
|
if (dirMode === 'pages') {
|
|
1003
|
-
// Child directory switches to
|
|
1004
|
-
// create container page with empty sections, recurse in
|
|
1005
|
+
// Child directory switches to folder mode (has folder.yml) —
|
|
1006
|
+
// create container page with empty sections, recurse in folder mode
|
|
1005
1007
|
const containerRoute = isIndex
|
|
1006
1008
|
? parentRoute
|
|
1007
1009
|
: parentRoute === '/' ? `/${entry}` : `${parentRoute}/${entry}`
|