UNPKG

@intlayer/chokidar

Version:

Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.

1 lines 3.24 kB
{"version":3,"file":"writeFileIfChanged.cjs","names":[],"sources":["../../src/writeFileIfChanged.ts"],"sourcesContent":["import { createHash, randomBytes } from 'node:crypto';\nimport { createReadStream, rmSync } from 'node:fs';\nimport { chmod, mkdir, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\n\nconst activeTempFiles = new Set<string>();\n\n// Synchronous cleanup on process exit\nprocess.on('exit', () => {\n for (const file of activeTempFiles) {\n try {\n rmSync(file, { force: true });\n } catch {}\n }\n});\n\n// Helper to hash existing file via stream\nconst getFileHash = (path: string): Promise<string | null> => {\n return new Promise((resolve) => {\n const hash = createHash('sha256');\n const stream = createReadStream(path);\n stream.on('data', (chunk) => hash.update(chunk));\n stream.on('end', () => resolve(hash.digest('hex')));\n stream.on('error', () => resolve(null));\n });\n};\n\nexport const writeFileIfChanged = async (\n path: string,\n data: string,\n {\n encoding = 'utf8',\n tempDir,\n }: { encoding?: BufferEncoding; tempDir?: string } = {}\n): Promise<boolean> => {\n const newDataHash = createHash('sha256').update(data, encoding).digest('hex');\n const existingHash = await getFileHash(path);\n\n if (newDataHash === existingHash) {\n return false;\n }\n\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(path)}.${Date.now()}-${randomBytes(4).toString('hex')}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${path}.${tempFileName}`;\n activeTempFiles.add(tempPath);\n\n try {\n let mode: number | undefined;\n try {\n mode = (await stat(path)).mode;\n } catch {}\n\n await writeFile(tempPath, data, { encoding });\n\n if (mode !== undefined) {\n await chmod(tempPath, mode);\n }\n\n await rename(tempPath, path);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {}\n throw error;\n } finally {\n activeTempFiles.delete(tempPath);\n }\n\n return true;\n};\n"],"mappings":";;;;;;;;AAKA,MAAM,kCAAkB,IAAI,IAAY;AAGxC,QAAQ,GAAG,cAAc;CACvB,KAAK,MAAM,QAAQ,iBACjB,IAAI;EACF,oBAAO,MAAM,EAAE,OAAO,KAAK,CAAC;CAC9B,QAAQ,CAAC;AAEb,CAAC;AAGD,MAAM,eAAe,SAAyC;CAC5D,OAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,mCAAkB,QAAQ;EAChC,MAAM,uCAA0B,IAAI;EACpC,OAAO,GAAG,SAAS,UAAU,KAAK,OAAO,KAAK,CAAC;EAC/C,OAAO,GAAG,aAAa,QAAQ,KAAK,OAAO,KAAK,CAAC,CAAC;EAClD,OAAO,GAAG,eAAe,QAAQ,IAAI,CAAC;CACxC,CAAC;AACH;AAEA,MAAa,qBAAqB,OAChC,MACA,MACA,EACE,WAAW,QACX,YACmD,CAAC,MACjC;CAIrB,gCAH+B,QAAQ,EAAE,OAAO,MAAM,QAAQ,EAAE,OAAO,KAGzD,MAAM,MAFO,YAAY,IAAI,GAGzC,OAAO;CAGT,IAAI,SACF,kCAAY,SAAS,EAAE,WAAW,KAAK,CAAC;CAG1C,MAAM,eAAe,2BAAY,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,gCAAe,CAAC,EAAE,SAAS,KAAK,EAAE;CACvF,MAAM,WAAW,8BACR,SAAS,YAAY,IAC1B,GAAG,KAAK,GAAG;CACf,gBAAgB,IAAI,QAAQ;CAE5B,IAAI;EACF,IAAI;EACJ,IAAI;GACF,QAAQ,iCAAW,IAAI,GAAG;EAC5B,QAAQ,CAAC;EAET,sCAAgB,UAAU,MAAM,EAAE,SAAS,CAAC;EAE5C,IAAI,SAAS,QACX,kCAAY,UAAU,IAAI;EAG5B,mCAAa,UAAU,IAAI;CAC7B,SAAS,OAAO;EACd,IAAI;GACF,+BAAS,UAAU,EAAE,OAAO,KAAK,CAAC;EACpC,QAAQ,CAAC;EACT,MAAM;CACR,UAAU;EACR,gBAAgB,OAAO,QAAQ;CACjC;CAEA,OAAO;AACT"}