UNPKG

@paroicms/cli

Version:
260 lines 9.77 kB
import { pathExists } from "@paroicms/internal-server-lib"; import { readFile, readdir, rename, writeFile } from "node:fs/promises"; import { join } from "node:path"; import { packageDir } from "../context.js"; export async function migrateFrom1To2(directory, siteSchema) { const lib = await loadCommonSchemaLibV1(); const l10n = {}; for (const language of siteSchema.languages) { const l10nFile = join(directory, `site-schema.l10n.${language}.json`); const obj = (await pathExists(l10nFile)) ? JSON.parse(migrateRawL10n(await readFile(l10nFile, "utf-8"))) : {}; l10n[language] = obj; } const migrating = { siteSchema, l10n, }; const { useModules, usedLibTypes } = convertUseModules(siteSchema.useModules, lib); if (useModules) { migrateUseModules(useModules); } siteSchema.useModules = useModules; const documentTypes = []; for (const documentType of siteSchema.documentTypes ?? []) { if (typeof documentType === "string") continue; migrateDocumentType(documentType); documentTypes.push(documentType); } siteSchema.documentTypes = documentTypes.length > 0 ? documentTypes : undefined; const partTypes = []; for (const partType of siteSchema.partTypes ?? []) { if (typeof partType === "string") continue; migratePartType(partType); partTypes.push(partType); } siteSchema.partTypes = partTypes.length > 0 ? partTypes : undefined; while (true) { const hasNew = importDependentTypes(migrating, usedLibTypes); if (!hasNew) break; } const { schemaEngineVersion, ...rest } = siteSchema; const newSchema = { version: "2.0", ...rest }; await rename(join(directory, "site-schema.json"), join(directory, "site-schema-v1.json")); await writeFile(join(directory, "site-schema.json"), JSON.stringify(newSchema, undefined, 2)); for (const language of siteSchema.languages) { const obj = l10n[language]; if (!obj) throw new Error(`L10n for language "${language}" not found`); cleanObjectPropertyIfEmpty(obj, "documentTypes"); cleanObjectPropertyIfEmpty(obj, "partTypes"); const l10nFile = join(directory, `site-schema.l10n.${language}.json`); if (await pathExists(l10nFile)) { await rename(l10nFile, join(directory, `site-schema-v1.l10n.${language}.json`)); } if (Object.keys(obj).length > 0) { await writeFile(join(directory, `site-schema.l10n.${language}.json`), JSON.stringify(obj, undefined, 2)); } } return newSchema; } function cleanObjectPropertyIfEmpty(obj, propName) { if (obj[propName] && Object.keys(obj[propName]).length === 0) { obj[propName] = undefined; } } function importDependentTypes(migrating, usedLibTypes) { const { siteSchema, l10n } = migrating; let hasNew = false; const newDocumentTypes = []; const newPartTypes = []; for (const documentType of siteSchema.documentTypes ?? []) { for (const typeName of getDependentDocumentTypeNames(documentType)) { if (siteSchema.documentTypes?.find((t) => t.leafType === typeName) || newDocumentTypes.find((t) => t.leafType === typeName)) { continue; } const newType = usedLibTypes.documentTypes[typeName]; if (!newType) throw new Error(`Document type "${typeName}" not found`); newDocumentTypes.push(newType); importDependentDocumentL10n(l10n, usedLibTypes, typeName); } for (const partName of getDependenPartTypeNames(documentType)) { if (siteSchema.partTypes?.find((t) => t.leafType === partName) || newPartTypes.find((t) => t.leafType === partName)) { continue; } const newType = usedLibTypes.partTypes[partName]; if (!newType) throw new Error(`Part type "${partName}" not found`); newPartTypes.push(newType); importDependentPartL10n(l10n, usedLibTypes, partName); } } if (newDocumentTypes.length > 0) { hasNew = true; if (!siteSchema.documentTypes) { siteSchema.documentTypes = []; } siteSchema.documentTypes.push(...newDocumentTypes); } if (newPartTypes.length > 0) { hasNew = true; if (!siteSchema.partTypes) { siteSchema.partTypes = []; } siteSchema.partTypes.push(...newPartTypes); } return hasNew; } function importDependentDocumentL10n(l10n, usedLibTypes, documentTypeName) { for (const language of Object.keys(usedLibTypes.l10n)) { l10n[language] ??= {}; l10n[language].documentTypes ??= {}; const l10nDocumentTypes = l10n[language].documentTypes; if (l10nDocumentTypes[documentTypeName]) continue; l10nDocumentTypes[documentTypeName] = usedLibTypes.l10n[language]?.documentTypes?.[documentTypeName]; } } function importDependentPartL10n(l10n, usedLibTypes, partTypeName) { for (const language of Object.keys(usedLibTypes.l10n)) { l10n[language] ??= {}; l10n[language].partTypes ??= {}; const l10nPartTypes = l10n[language].partTypes; if (l10nPartTypes[partTypeName]) continue; l10nPartTypes[partTypeName] = usedLibTypes.l10n[language]?.partTypes?.[partTypeName]; } } function getDependentDocumentTypeNames(documentType) { return (documentType.labeling ?? []).reduce((acc, item) => { acc.push(item.taxonomy); return acc; }, documentType.children ?? []); } function getDependenPartTypeNames(documentType) { return (documentType.lists ?? []).reduce((acc, list) => { acc.push(...list.parts); return acc; }, []); } function convertUseModules(oldUseModules, lib) { const usedLibTypes = { documentTypes: {}, partTypes: {}, l10n: {}, moduleNames: new Set(), }; if (!oldUseModules) return { useModules: undefined, usedLibTypes }; const useModules = []; for (const moduleName of oldUseModules) { const module = lib.get(moduleName); if (!module) { useModules.push(moduleName); } else { prepareUseModules(module, lib, usedLibTypes); } } return { useModules: useModules.length > 0 ? useModules : undefined, usedLibTypes, }; } function prepareUseModules(module, lib, usedLibTypes) { if (usedLibTypes.moduleNames.has(module.name)) return; usedLibTypes.moduleNames.add(module.name); for (const documentType of module.schema.documentTypes ?? []) { usedLibTypes.documentTypes[documentType.leafType] = documentType; } for (const partType of module.schema.partTypes ?? []) { usedLibTypes.partTypes[partType.leafType] = partType; } for (const language of Object.keys(module.l10n)) { usedLibTypes.l10n[language] = { ...usedLibTypes.l10n[language], ...module.l10n[language], }; } for (const moduleName of module.schema.useModules ?? []) { const subModule = lib.get(moduleName); if (!subModule) throw new Error(`Module "${moduleName}" not found`); prepareUseModules(subModule, lib, usedLibTypes); } } async function loadCommonSchemaLibV1() { const dir = join(packageDir, "site-schema-lib-v1"); const lib = new Map(); const entries = await readdir(dir); for (const entry of entries) { if (!entry.endsWith("site-schema.json")) continue; const libName = entry.substring(0, entry.length - "site-schema.json".length - 1); lib.set(libName, { name: libName, schema: JSON.parse(await readFile(join(dir, entry), "utf-8")), l10n: { en: JSON.parse(await readFile(join(dir, `${libName}.site-schema.l10n.en.json`), "utf-8")), fr: JSON.parse(await readFile(join(dir, `${libName}.site-schema.l10n.fr.json`), "utf-8")), }, }); } return lib; } function migrateUseModules(useModules) { for (let i = 0; i < useModules.length; ++i) { const moduleName = useModules[i]; if (moduleName === "media-policies") { useModules[i] = "default-media-policies"; } if (moduleName === "fields") { useModules[i] = "field-lib"; } } } function migrateDocumentType(documentType) { if (documentType.withData !== undefined) { if (!documentType.withData) { documentType.redirectTo = "parent"; } documentType.withData = undefined; } if (documentType.childOrdering) { documentType.orderChildrenBy = documentType.childOrdering; documentType.childOrdering = undefined; } if (documentType.lists) { for (const list of documentType.lists) { if (list.partLeafTypes) { list.parts = list.partLeafTypes; list.partLeafTypes = undefined; } if (list.partLimit) { list.limit = list.partLimit; list.partLimit = undefined; } } } } function migratePartType(partType) { if (partType.withData !== undefined) { partType.withData = undefined; } } function migrateRawL10n(raw) { return raw .replace(/addBtn/g, "addChild") .replace(/addChildBtn/g, "addChild") .replace(/addSectionBtn/g, "addPart"); } //# sourceMappingURL=site-schema-migration-1-to-2.js.map