@gftdcojp/gftd-cli
Version:
GFTD Schema Management CLI - Drizzle-like schema management for Kafka and ksqlDB
246 lines (244 loc) • 10.1 kB
JavaScript
;
/**
* GFTD Config Manager - Configuration file management
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigManager = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const YAML = require('yaml');
class ConfigManager {
/**
* 設定ファイルの初期化
*/
static async init(options) {
const configPath = path.join(process.cwd(), ConfigManager.CONFIG_FILE);
const schemaPath = path.join(process.cwd(), ConfigManager.SCHEMA_FILE);
if (fs.existsSync(configPath) && !options.interactive) {
throw new Error('Configuration file already exists. Use --force to overwrite.');
}
const config = {
schema: '',
tables: {},
orgId: options.orgId,
project: options.project,
kafka: {
endpoint: process.env.KAFKA_ENDPOINT || '',
apiKey: process.env.KAFKA_API_KEY || '',
apiSecret: process.env.KAFKA_API_SECRET || ''
},
ksqlDB: {
endpoint: process.env.KSQLDB_ENDPOINT || '',
apiKey: process.env.KSQLDB_API_KEY || '',
apiSecret: process.env.KSQLDB_API_SECRET || ''
},
schemaPath: './gftd.schema.yml',
migrationPath: './migrations'
};
// 設定ファイルを作成
const configYaml = YAML.stringify(config, { indent: 2 });
fs.writeFileSync(configPath, configYaml);
// サンプルスキーマファイルを作成
const sampleSchema = {
orgId: options.orgId,
project: options.project,
version: '1.0.0',
topics: {
users: {
partitions: 3,
replicationFactor: 3,
configEntries: [
{ name: 'cleanup.policy', value: 'compact' },
{ name: 'retention.ms', value: '-1' },
{ name: 'compression.type', value: 'snappy' }
]
},
events: {
partitions: 5,
replicationFactor: 3,
configEntries: [
{ name: 'cleanup.policy', value: 'delete' },
{ name: 'retention.ms', value: '604800000' }, // 7 days
{ name: 'compression.type', value: 'lz4' }
]
}
},
streams: {
users: {
valueFormat: 'JSON',
keyFormat: 'KAFKA',
columns: [
{ name: 'ID', type: 'VARCHAR', key: true },
{ name: 'NAME', type: 'VARCHAR' },
{ name: 'EMAIL', type: 'VARCHAR' },
{ name: 'CREATED_AT', type: 'BIGINT' },
{ name: 'UPDATED_AT', type: 'BIGINT' }
]
},
events: {
valueFormat: 'JSON',
columns: [
{ name: 'EVENT_ID', type: 'VARCHAR' },
{ name: 'USER_ID', type: 'VARCHAR' },
{ name: 'EVENT_TYPE', type: 'VARCHAR' },
{ name: 'PAYLOAD', type: 'VARCHAR' },
{ name: 'TIMESTAMP', type: 'BIGINT' }
]
}
},
tables: {
users: {
aggregation: `
SELECT ID,
LATEST_BY_OFFSET(NAME) AS NAME,
LATEST_BY_OFFSET(EMAIL) AS EMAIL,
LATEST_BY_OFFSET(CREATED_AT) AS CREATED_AT,
LATEST_BY_OFFSET(UPDATED_AT) AS UPDATED_AT
FROM {sourceStream}
GROUP BY ID
`.trim()
}
}
};
const schemaYaml = YAML.stringify(sampleSchema, { indent: 2 });
fs.writeFileSync(schemaPath, schemaYaml);
console.log(`✅ Initialized GFTD project:`);
console.log(` Organization: ${options.orgId}`);
if (options.project) {
console.log(` Project: ${options.project}`);
}
console.log(` Config: ${configPath}`);
console.log(` Schema: ${schemaPath}`);
console.log('');
console.log('📝 Next steps:');
console.log(' 1. Edit the configuration file with your Kafka/ksqlDB credentials');
console.log(' 2. Customize the schema definition');
console.log(' 3. Run: gftd migrate');
}
/**
* 設定ファイルの読み込み
*/
static loadConfig(configPath) {
const filePath = configPath || path.join(process.cwd(), ConfigManager.CONFIG_FILE);
if (!fs.existsSync(filePath)) {
throw new Error(`Configuration file not found: ${filePath}\n` +
'Run "gftd init" to initialize a new project.');
}
const content = fs.readFileSync(filePath, 'utf8');
const config = YAML.parse(content);
// 環境変数からの設定値で上書き
if (process.env.KAFKA_ENDPOINT && config.kafka)
config.kafka.endpoint = process.env.KAFKA_ENDPOINT;
if (process.env.KAFKA_API_KEY && config.kafka)
config.kafka.apiKey = process.env.KAFKA_API_KEY;
if (process.env.KAFKA_API_SECRET && config.kafka)
config.kafka.apiSecret = process.env.KAFKA_API_SECRET;
if (process.env.KSQLDB_ENDPOINT && config.ksqlDB)
config.ksqlDB.endpoint = process.env.KSQLDB_ENDPOINT;
if (process.env.KSQLDB_API_KEY && config.ksqlDB)
config.ksqlDB.apiKey = process.env.KSQLDB_API_KEY;
if (process.env.KSQLDB_API_SECRET && config.ksqlDB)
config.ksqlDB.apiSecret = process.env.KSQLDB_API_SECRET;
ConfigManager.validateConfig(config);
return config;
}
/**
* 設定の検証
*/
static validateConfig(config) {
const errors = [];
if (!config.orgId)
errors.push('orgId is required');
if (!config.kafka?.endpoint)
errors.push('kafka.endpoint is required');
if (!config.kafka?.apiKey)
errors.push('kafka.apiKey is required');
if (!config.kafka?.apiSecret)
errors.push('kafka.apiSecret is required');
if (!config.ksqlDB?.endpoint)
errors.push('ksqlDB.endpoint is required');
if (!config.ksqlDB?.apiKey)
errors.push('ksqlDB.apiKey is required');
if (!config.ksqlDB?.apiSecret)
errors.push('ksqlDB.apiSecret is required');
if (errors.length > 0) {
throw new Error(`Configuration validation failed:\n${errors.map(e => ` - ${e}`).join('\n')}\n\n` +
'Please check your configuration file or set the required environment variables.');
}
}
/**
* プロジェクト設定の表示
*/
static showInfo(config) {
console.log('📊 GFTD Project Information:');
console.log(` Organization ID: ${config.orgId}`);
if (config.project) {
console.log(` Project: ${config.project}`);
}
console.log(` Schema Path: ${config.schemaPath || './gftd.schema.yml'}`);
console.log(` Migration Path: ${config.migrationPath || './migrations'}`);
console.log('');
console.log('🔗 Endpoints:');
console.log(` Kafka: ${config.kafka?.endpoint || 'Not configured'}`);
console.log(` ksqlDB: ${config.ksqlDB?.endpoint || 'Not configured'}`);
console.log('');
// 命名規則の例を表示
console.log('📝 Naming Convention Examples:');
console.log(` Topic: users`);
console.log(` Stream: ${config.orgId?.toUpperCase() || 'ORG'}_USERS`);
console.log(` Table: ${config.orgId?.toUpperCase() || 'ORG'}_USERS`);
}
/**
* .env ファイルの例を生成
*/
static generateEnvExample() {
return `# GFTD CLI Environment Variables
# Copy this file to .env and fill in your values
# Kafka Configuration
KAFKA_ENDPOINT=your-kafka-endpoint
KAFKA_API_KEY=your-kafka-api-key
KAFKA_API_SECRET=your-kafka-api-secret
# ksqlDB Configuration
KSQLDB_ENDPOINT=your-ksqldb-endpoint
KSQLDB_API_KEY=your-ksqldb-api-key
KSQLDB_API_SECRET=your-ksqldb-api-secret
`;
}
}
exports.ConfigManager = ConfigManager;
ConfigManager.CONFIG_FILE = 'gftd.config.yml';
ConfigManager.SCHEMA_FILE = 'gftd.schema.yml';
//# sourceMappingURL=config-manager.js.map