sheets-translate-to-json
Version:
A Node.js library that facilitates the retrieval and conversion of previously translated Google Sheets spreadsheets into structured JSON files, optimizing the management of localized resources.
1 lines • 11.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { GoogleSpreadsheet } from \"google-spreadsheet\";\nimport { JWT } from \"google-auth-library\";\nimport fs from \"fs\";\nimport path from \"path\";\n\ninterface NestedObject {\n [key: string]: string | NestedObject | undefined;\n}\n\ninterface SheetData {\n [key: string]: NestedObject;\n}\n\nexport class SheetManager {\n private doc: GoogleSpreadsheet;\n private jwt: JWT;\n\n constructor(\n privateKey: string,\n clientEmail: string,\n sheetId: string,\n ) {\n const SCOPES = [\n \"https://www.googleapis.com/auth/spreadsheets\",\n \"https://www.googleapis.com/auth/drive.file\",\n ];\n\n this.jwt = new JWT({\n email: clientEmail,\n key: privateKey,\n scopes: SCOPES,\n });\n\n this.doc = new GoogleSpreadsheet(sheetId, this.jwt); \n }\n\n async init(userPath: string, sheetNames?: string[]) {\n try {\n await this.jwt.authorize();\n \n if (sheetNames && sheetNames.length > 0) {\n // Traiter plusieurs feuilles spécifiques et les combiner\n const combinedData: SheetData = {};\n \n for (const sheetName of sheetNames) {\n const data = await this.readByName(sheetName);\n if (data && Object.keys(data).length > 0) {\n // Combiner les données de cette feuille avec les données existantes\n Object.keys(data).forEach(language => {\n if (!combinedData[language]) {\n combinedData[language] = {};\n }\n // Fusionner les données de cette langue\n this.mergeNestedObjects(combinedData[language] as NestedObject, data[language] as NestedObject);\n });\n } else {\n console.warn(`No data found in sheet: ${sheetName}`);\n }\n }\n \n if (Object.keys(combinedData).length > 0) {\n this.write(combinedData, userPath);\n }\n } else {\n // Traiter toutes les feuilles et les combiner\n const allSheetsData = await this.readAllSheets();\n const combinedData: SheetData = {};\n \n // Combiner les données de toutes les feuilles\n Object.keys(allSheetsData).forEach(sheetName => {\n const sheetData = allSheetsData[sheetName];\n Object.keys(sheetData).forEach(language => {\n if (!combinedData[language]) {\n combinedData[language] = {};\n }\n // Fusionner les données de cette langue\n this.mergeNestedObjects(combinedData[language] as NestedObject, sheetData[language] as NestedObject);\n });\n });\n \n if (Object.keys(combinedData).length > 0) {\n this.write(combinedData, userPath);\n } else {\n console.error(\"No data found in the sheet\");\n }\n }\n } catch (err) {\n console.error(\"Error during initialization:\", err);\n }\n }\n\n async read(sheetPosition: number = 0): Promise<SheetData> {\n if (sheetPosition < 0) {\n sheetPosition = 0;\n }\n await this.doc.loadInfo();\n const sheet = this.doc.sheetsByIndex[sheetPosition];\n return this.processSheet(sheet);\n }\n\n async readByName(sheetName: string): Promise<SheetData> {\n await this.doc.loadInfo();\n const sheet = this.doc.sheetsByTitle[sheetName];\n \n if (!sheet) {\n throw new Error(`Sheet with name \"${sheetName}\" not found`);\n }\n \n return this.processSheet(sheet);\n }\n\n async readAllSheets(): Promise<{ [sheetName: string]: SheetData }> {\n await this.doc.loadInfo();\n const allData: { [sheetName: string]: SheetData } = {};\n \n for (const sheet of this.doc.sheetsByIndex) {\n try {\n const data = await this.processSheet(sheet);\n if (data && Object.keys(data).length > 0) {\n allData[sheet.title] = data;\n }\n } catch (error) {\n console.error(`Error processing sheet \"${sheet.title}\":`, error);\n }\n }\n \n return allData;\n }\n\n private async processSheet(sheet: any): Promise<SheetData> {\n await sheet.loadHeaderRow();\n const colTitles = sheet.headerValues;\n const rows = await sheet.getRows({ limit: sheet.rowCount });\n\n const result: SheetData = {};\n \n rows.forEach((row: any) => {\n // Vérifier si la ligne n'est pas vide\n const keyValue = row.get(colTitles[0]);\n \n // Ignorer les lignes vides ou avec une clé vide/undefined\n if (!keyValue || keyValue.trim() === '') {\n return;\n }\n\n colTitles.slice(1).forEach((title: string) => {\n const key = keyValue.trim();\n const value = row.get(title);\n const cleanValue = value && value.trim() !== '' ? value.trim() : undefined;\n\n // Initialiser la structure pour cette colonne si elle n'existe pas\n if (!result[title]) {\n result[title] = {};\n }\n\n // Gérer les clés imbriquées avec support de plusieurs niveaux\n if (key.includes(\".\")) {\n this.setNestedValue(result[title] as NestedObject, key, cleanValue);\n } else {\n (result[title] as NestedObject)[key] = cleanValue;\n }\n });\n });\n\n return result;\n }\n\n private setNestedValue(obj: NestedObject, keyPath: string, value: string | undefined): void {\n const keys = keyPath.split(\".\");\n let current = obj;\n\n // Naviguer jusqu'à l'avant-dernier niveau\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n \n if (!current[key] || typeof current[key] !== 'object') {\n current[key] = {};\n }\n \n current = current[key] as NestedObject;\n }\n\n // Définir la valeur finale\n const finalKey = keys[keys.length - 1];\n current[finalKey] = value;\n }\n\n private mergeNestedObjects(target: NestedObject, source: NestedObject): void {\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const sourceValue = source[key];\n const targetValue = target[key];\n\n if (typeof sourceValue === 'object' && sourceValue !== null && typeof targetValue === 'object' && targetValue !== null) {\n this.mergeNestedObjects(targetValue as NestedObject, sourceValue as NestedObject);\n } else {\n target[key] = sourceValue;\n }\n }\n }\n }\n\n write(data: SheetData, directoryPath: string): void {\n if (!fs.existsSync(directoryPath)) {\n fs.mkdirSync(directoryPath, { recursive: true });\n }\n\n Object.keys(data).forEach((key) => {\n const fileName = `${key}.json`;\n const filePath = path.join(directoryPath, fileName);\n \n fs.writeFile(filePath, JSON.stringify(data[key], null, 2), (err) => {\n if (err) {\n console.error(`Error writing file ${filePath}:`, err);\n return;\n }\n console.log(`File written: ${filePath}`);\n });\n });\n }\n\n // Méthode utilitaire pour lister toutes les feuilles disponibles\n async listSheets(): Promise<string[]> {\n await this.doc.loadInfo();\n return this.doc.sheetsByIndex.map(sheet => sheet.title);\n }\n}"],"mappings":"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","names":[]}