@gftdcojp/gftd-orm
Version:
Enterprise-grade real-time data platform with ksqlDB, inspired by Supabase architecture
303 lines • 10.2 kB
JavaScript
;
/**
* Schema Registry クライアント - スキーマ管理 (Avro/JSON Schema)
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.initializeSchemaRegistryClient = initializeSchemaRegistryClient;
exports.registerSchema = registerSchema;
exports.getLatestSchema = getLatestSchema;
exports.getSchemaByVersion = getSchemaByVersion;
exports.getSchemaById = getSchemaById;
exports.listSubjects = listSubjects;
exports.listVersions = listVersions;
exports.checkCompatibility = checkCompatibility;
exports.setCompatibilityLevel = setCompatibilityLevel;
exports.deleteSubject = deleteSubject;
exports.deleteSchemaVersion = deleteSchemaVersion;
exports.validateSchemaEvolution = validateSchemaEvolution;
exports.getSchemaRegistryConfig = getSchemaRegistryConfig;
exports.isSchemaRegistryConnected = isSchemaRegistryConnected;
exports.closeSchemaRegistryClient = closeSchemaRegistryClient;
const axios_1 = __importDefault(require("axios"));
let schemaRegistryClient = null;
let config = null;
/**
* Schema Registry クライアントを初期化
*/
function initializeSchemaRegistryClient(registryConfig) {
config = registryConfig;
const headers = {
'Content-Type': 'application/vnd.schemaregistry.v1+json',
};
// 認証情報がある場合は Authorization ヘッダーを追加
if (registryConfig.auth) {
const credentials = btoa(`${registryConfig.auth.user}:${registryConfig.auth.pass}`);
headers['Authorization'] = `Basic ${credentials}`;
}
else if (registryConfig.apiKey) {
headers['Authorization'] = `Bearer ${registryConfig.apiKey}`;
}
schemaRegistryClient = axios_1.default.create({
baseURL: registryConfig.url,
headers,
timeout: 15000, // 15秒のタイムアウト
});
}
/**
* スキーマを登録
*/
async function registerSchema(subject, schema, schemaType = 'AVRO') {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized. Call initializeSchemaRegistryClient() first.');
}
try {
const response = await schemaRegistryClient.post(`/subjects/${subject}/versions`, {
schemaType,
schema: JSON.stringify(schema),
});
return { id: response.data.id };
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Schema registration failed: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* スキーマを取得(最新バージョン)
*/
async function getLatestSchema(subject) {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const response = await schemaRegistryClient.get(`/subjects/${subject}/versions/latest`);
return {
id: response.data.id,
version: response.data.version,
schema: response.data.schema,
};
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Failed to get schema: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* 特定バージョンのスキーマを取得
*/
async function getSchemaByVersion(subject, version) {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const response = await schemaRegistryClient.get(`/subjects/${subject}/versions/${version}`);
return {
id: response.data.id,
version: response.data.version,
schema: response.data.schema,
};
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Failed to get schema version ${version}: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* スキーマIDでスキーマを取得
*/
async function getSchemaById(id) {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const response = await schemaRegistryClient.get(`/schemas/ids/${id}`);
return { schema: response.data.schema };
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Failed to get schema by ID ${id}: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* subject 一覧を取得
*/
async function listSubjects() {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const response = await schemaRegistryClient.get('/subjects');
return response.data;
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Failed to list subjects: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* subject のバージョン一覧を取得
*/
async function listVersions(subject) {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const response = await schemaRegistryClient.get(`/subjects/${subject}/versions`);
return response.data;
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Failed to list versions for ${subject}: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* スキーマの互換性をチェック
*/
async function checkCompatibility(subject, schema, version) {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const endpoint = version
? `/compatibility/subjects/${subject}/versions/${version}`
: `/compatibility/subjects/${subject}/versions/latest`;
const response = await schemaRegistryClient.post(endpoint, {
schema: JSON.stringify(schema),
});
return { is_compatible: response.data.is_compatible };
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Compatibility check failed: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* スキーマの互換性レベルを設定
*/
async function setCompatibilityLevel(subject, level) {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const response = await schemaRegistryClient.put(`/config/${subject}`, {
compatibility: level,
});
return { compatibility: response.data.compatibility };
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Failed to set compatibility level: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* subject を削除
*/
async function deleteSubject(subject, permanent = false) {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const params = permanent ? { permanent: 'true' } : {};
const response = await schemaRegistryClient.delete(`/subjects/${subject}`, { params });
return response.data;
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Failed to delete subject ${subject}: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* 特定バージョンのスキーマを削除
*/
async function deleteSchemaVersion(subject, version, permanent = false) {
if (!schemaRegistryClient) {
throw new Error('Schema Registry client is not initialized.');
}
try {
const params = permanent ? { permanent: 'true' } : {};
const response = await schemaRegistryClient.delete(`/subjects/${subject}/versions/${version}`, { params });
return response.data;
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
throw new Error(`Failed to delete schema version: ${error.response?.data?.message || error.message}`);
}
throw error;
}
}
/**
* スキーマの進化を確認
*/
async function validateSchemaEvolution(subject, newSchema, previousVersions = 5) {
const errors = [];
let valid = true;
try {
// 最新バージョンとの互換性チェック
const compatibility = await checkCompatibility(subject, newSchema);
if (!compatibility.is_compatible) {
valid = false;
errors.push('Schema is not compatible with latest version');
}
// 過去のバージョンとの互換性も確認
const versions = await listVersions(subject);
const recentVersions = versions.slice(-previousVersions);
for (const version of recentVersions) {
try {
const versionCompatibility = await checkCompatibility(subject, newSchema, version);
if (!versionCompatibility.is_compatible) {
errors.push(`Schema is not compatible with version ${version}`);
valid = false;
}
}
catch (error) {
// バージョンが存在しない場合は無視
}
}
}
catch (error) {
valid = false;
errors.push(`Schema evolution validation failed: ${error.message}`);
}
return { valid, errors };
}
/**
* クライアント設定を取得
*/
function getSchemaRegistryConfig() {
return config;
}
/**
* 接続状態を確認
*/
function isSchemaRegistryConnected() {
return schemaRegistryClient !== null && config !== null;
}
/**
* クライアントを閉じる
*/
function closeSchemaRegistryClient() {
schemaRegistryClient = null;
config = null;
}
//# sourceMappingURL=schema-registry.js.map