93 lines
2.8 KiB
JavaScript
93 lines
2.8 KiB
JavaScript
const path = require('path');
|
|
const protoLoader = require('@grpc/proto-loader');
|
|
const grpc = require('@grpc/grpc-js');
|
|
const fs = require('fs');
|
|
|
|
/**
|
|
* gRPC proto 로딩 결과를 캐싱하기 위한 변수
|
|
*/
|
|
let _cache = null;
|
|
|
|
const findProtoPath = () => {
|
|
const attemptedPaths = [];
|
|
|
|
// 1. Try explicit environment variable
|
|
if (process.env.KORD_PROTO_PATH) {
|
|
if (fs.existsSync(process.env.KORD_PROTO_PATH)) return process.env.KORD_PROTO_PATH;
|
|
attemptedPaths.push(`Env: ${process.env.KORD_PROTO_PATH}`);
|
|
}
|
|
|
|
// 2. Try standard __dirname (most reliable for direct node/tsx runs)
|
|
const dirnamePath = path.resolve(__dirname, 'kord.proto');
|
|
if (fs.existsSync(dirnamePath)) return dirnamePath;
|
|
attemptedPaths.push(`Dirname: ${dirnamePath}`);
|
|
|
|
// 3. Try monorepo root via process.cwd()
|
|
const rootPath = path.resolve(process.cwd(), 'packages/grpc-contracts/src/kord.proto');
|
|
if (fs.existsSync(rootPath)) return rootPath;
|
|
attemptedPaths.push(`CWD Root: ${rootPath}`);
|
|
|
|
// 4. Try relative from apps/ (Next.js context)
|
|
const relativePath = path.resolve(process.cwd(), '../../packages/grpc-contracts/src/kord.proto');
|
|
if (fs.existsSync(relativePath)) return relativePath;
|
|
attemptedPaths.push(`Relative: ${relativePath}`);
|
|
|
|
// 5. Try shared node_modules depth (monorepo artifacts)
|
|
const nmPath = path.resolve(process.cwd(), 'node_modules/@kord/grpc-contracts/src/kord.proto');
|
|
if (fs.existsSync(nmPath)) return nmPath;
|
|
attemptedPaths.push(`NodeModules: ${nmPath}`);
|
|
|
|
return { error: true, attemptedPaths };
|
|
};
|
|
|
|
const initialize = () => {
|
|
if (_cache) return _cache;
|
|
|
|
// browser환경이나 분석 단계에서 fs가 없을 경우를 대비하여 체크 (Turbopack 대응)
|
|
if (!fs || !fs.existsSync) {
|
|
return { kordProto: null, protoPath: null };
|
|
}
|
|
|
|
const result = findProtoPath();
|
|
if (result.error) {
|
|
// 런타임에 에러가 발생하도록 경고를 출력하되, 빌드/분석 단계에서는 치명적 에러가 되지 않도록 함
|
|
console.warn('⚠️ [grpc-contracts] Failed to locate kord.proto during initialization.');
|
|
return { kordProto: null, protoPath: null };
|
|
}
|
|
|
|
const PROTO_PATH = result;
|
|
let packageDefinition;
|
|
try {
|
|
packageDefinition = protoLoader.loadSync(PROTO_PATH, {
|
|
keepCase: true,
|
|
longs: String,
|
|
enums: String,
|
|
defaults: true,
|
|
oneofs: true,
|
|
});
|
|
} catch (error) {
|
|
console.error(`Failed to load gRPC proto from: ${PROTO_PATH}`);
|
|
throw error;
|
|
}
|
|
|
|
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
|
|
|
|
_cache = {
|
|
kordProto: protoDescriptor.kord,
|
|
protoPath: PROTO_PATH
|
|
};
|
|
|
|
return _cache;
|
|
};
|
|
|
|
module.exports = {
|
|
// getter를 사용하여 실제 접근 시점에 로딩되도록 함 (Lazy Initialization)
|
|
get kordProto() {
|
|
return initialize().kordProto;
|
|
},
|
|
get protoPath() {
|
|
return initialize().protoPath;
|
|
}
|
|
};
|
|
|