DE / generate-data.mjs
stat2025's picture
Upload 6 files
e9af8e8 verified
Raw
History Blame Contribute Delete
2.04 kB
import fs from "node:fs/promises";
import crypto from "node:crypto";
import { FileBlob, SpreadsheetFile } from "@oai/artifact-tool";
const [inputPath, outputPath, password] = process.argv.slice(2);
if (!inputPath || !outputPath || !password) {
console.error("Usage: node generate-data.mjs <input.xlsx> <output.js> <password>");
process.exitCode = 1;
} else {
const blob = await FileBlob.load(inputPath);
const workbook = await SpreadsheetFile.importXlsx(blob);
const sheet = workbook.worksheets.getItemAt(0);
const values = sheet.getUsedRange(true).values;
const headers = values[0].map((value) => String(value ?? "").trim());
const rows = values.slice(1).map((row) =>
headers.map((_, index) => {
const value = row[index];
if (value === null || value === undefined) return "";
return typeof value === "string" ? value.trim() : String(value);
}),
);
const payload = JSON.stringify({
version: 1,
generatedAt: new Date().toISOString(),
headers,
rows,
});
const iterations = 310000;
const salt = crypto.randomBytes(16);
const iv = crypto.randomBytes(12);
const key = crypto.pbkdf2Sync(password, salt, iterations, 32, "sha256");
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
const encrypted = Buffer.concat([cipher.update(payload, "utf8"), cipher.final()]);
const authTag = cipher.getAuthTag();
const combined = Buffer.concat([encrypted, authTag]);
const output = [
"/* Generated encrypted data. Replace this file using generate-data.mjs when the workbook changes. */",
"const ENCRYPTED_DATA = Object.freeze({",
` iterations: ${iterations},`,
` salt: "${salt.toString("base64")}",`,
` iv: "${iv.toString("base64")}",`,
` payload: "${combined.toString("base64")}",`,
"});",
"",
].join("\n");
await fs.writeFile(outputPath, output, "utf8");
console.log(
JSON.stringify({
rows: rows.length,
columns: headers.length,
encryptedBytes: combined.length,
outputPath,
}),
);
}