Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 72 additions & 47 deletions scripts/ipfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,98 @@ import { globby } from 'globby';
import { Agent } from 'https';
import { writeFile } from 'fs/promises';

const ipfsAuth = process.env['IPFS_AUTH'] || "";
const ipfsHost = process.env['IPFS_HOST'];
const ipfsPort = process.env['IPFS_PORT'] ? parseInt(process.env['IPFS_PORT']) : 5001;
const ipfsProtocol = process.env['IPFS_SSL'] === 'false' ? 'http' : 'https';
// Ortam değişkenleri için güvenli varsayılanlar ve tip dönüşümleri
const IPFS_CONFIG = {
host: process.env['IPFS_HOST'],
port: parseInt(process.env['IPFS_PORT'] || '5001'),
protocol: process.env['IPFS_SSL'] === 'false' ? 'http' : 'https',
auth: process.env['IPFS_AUTH'] || "",
};

if (!ipfsHost) {
console.error("Must set IPFS_HOST");
if (!IPFS_CONFIG.host) {
console.error("❌ Hata: IPFS_HOST ortam değişkeni ayarlanmamış.");
process.exit(1);
}

let authorization = `Basic ${Buffer.from(ipfsAuth).toString('base64')}`;
// Authorization header'ı bir kez oluşturulur
const authHeader = `Basic ${Buffer.from(IPFS_CONFIG.auth).toString('base64')}`;

/**
* IPFS İstemcisini yapılandırır.
* keepAlive: true ayarı, ardışık dosya yüklemelerinde TCP el sıkışma yükünü azaltır.
*/
function buildIpfsClient() {
return create({
host: ipfsHost,
port: ipfsPort,
protocol: ipfsProtocol,
headers: {
authorization
},
host: IPFS_CONFIG.host,
port: IPFS_CONFIG.port,
protocol: IPFS_CONFIG.protocol,
headers: { authorization: authHeader },
apiPath: '/api/v0',
agent: new Agent({
keepAlive: false,
maxSockets: Infinity
keepAlive: true, // Performans için true olmalı
maxSockets: 32, // Sonsuz yerine makul bir sınır, sistem kaynaklarını korur
}),
timeout: '10m'
timeout: '15m' // Büyük build'ler için süre biraz daha artırıldı
});
}

(async function() {
const allDeployableFiles = await globby(['build/**/*']);
const expectedFileCount = allDeployableFiles.length;

let ipfs = buildIpfsClient();

// Inspired from: https://community.infura.io/t/upload-files-from-a-folder-under-a-wrapping-directory-cid-using-the-kubo-rpc-client-and-nodejs/6045
const filesUploaded = [];
for await (const file of ipfs.addAll(globSource('build', '**/*'), { wrapWithDirectory: true })) {
filesUploaded.push(file);
console.log(`Pushed ${file.path} [size=${file.size}, cid=${file.cid}]`);
}
(async function deploy() {
try {
const buildDir = 'build';
const allFiles = await globby([`${buildDir}/**/*`]);
const expectedCount = allFiles.length;

console.log(`Uploaded ${filesUploaded.length} total files.`);
if (expectedCount === 0) {
throw new Error(`'${buildDir}' dizini boş veya bulunamadı.`);
}

// Verify the number of files uploaded matches the number
// of files we counted in the deploy directory.
if (filesUploaded.length < expectedFileCount) {
console.log(`Expected number of files to upload: ${expectedFileCount}`);
console.log(`Uploaded total number of files: ${filesUploaded.length}`);
console.log(`🚀 ${expectedCount} dosya IPFS'e yüklenmeye hazırlanıyor...`);

throw new Error('Failed to upload enough files.');
}
const ipfs = buildIpfsClient();
const uploadedFiles = [];

// Dosya yükleme akışı
for await (const file of ipfs.addAll(globSource(buildDir, '**/*'), {
wrapWithDirectory: true,
pin: true, // Kalıcılık için otomatik pinleme
progress: (prog) => console.log(`Transfer: ${prog} bytes`)
})) {
uploadedFiles.push(file);
// Sadece önemli dosyaları veya ilerlemeyi logla (gürültüyü azalt)
if (file.path === "") console.log(`✅ Root CID Oluşturuldu: ${file.cid}`);
}

// Doğrulama mantığı: wrapWithDirectory kullanıldığında uploadedFiles.length = expectedCount + 1 (root dizini)
if (uploadedFiles.length <= expectedCount) {
throw new Error(`Yükleme eksik kaldı. Beklenen: >${expectedCount}, Yüklenen: ${uploadedFiles.length}`);
}

// Not a fan of how the new kubo client only supports addAll
// and used the last file as the directory... -_-
const app = filesUploaded[filesUploaded.length - 1];
// Root CID her zaman path'i boş ("") olan son nesnedir.
const rootFolder = uploadedFiles.find(f => f.path === "");
if (!rootFolder) {
throw new Error("Root dizini CID'si belirlenemedi.");
}

const urls = [
["IPFS Url", `https://ipfs.io/ipfs/${app.cid}`],
["Infura Url", `https://compound-app.infura-ipfs.io/ipfs/${app.cid}`],
];
const urlText = urls.map(([name, url]) => ` * ${name}: ${url}`).join("\n");
const rootCID = rootFolder.cid.toString();

console.log("\n\n");
console.log("🗺 App successfully deployed to ipfs:\n");
console.log(urlText);
console.log("\n");
// Sonuçları raporla
const gateways = [
{ name: "IPFS Gateway", url: `https://ipfs.io/ipfs/${rootCID}` },
{ name: "Infura Gateway", url: `https://compound-app.infura-ipfs.io/ipfs/${rootCID}` },
];

writeFile('.release', `${app.cid}`, 'utf8');
console.log("\n🗺 App başarıyla IPFS'e dağıtıldı:");
gateways.forEach(gw => console.log(` * ${gw.name}: ${gw.url}`));

// CID'yi dosyaya yaz (Release takibi için)
await writeFile('.release', rootCID, 'utf8');
console.log(`\n💾 Root CID '${rootCID}' .release dosyasına kaydedildi.`);

} catch (error) {
console.error("\n❌ Dağıtım sırasında kritik hata oluştu:");
console.error(error.message);
process.exit(1);
}
})();