@datastax/astra-db-ts
Version:
Data API TypeScript client
229 lines (228 loc) • 12.5 kB
JavaScript
;
// Copyright Datastax, Inc
// SPDX-License-Identifier: Apache-2.0
// noinspection ExceptionCaughtLocallyJS
var _AstraAdmin_defaultOpts, _AstraAdmin_httpClient, _AstraAdmin_environment;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AstraAdmin = void 0;
const tslib_1 = require("tslib");
const astra_db_admin_js_1 = require("../administration/astra-db-admin.js");
const db_js_1 = require("../db/db.js");
const utils_js_1 = require("../administration/utils.js");
const constants_js_1 = require("../lib/api/constants.js");
const devops_api_http_client_js_1 = require("../lib/api/clients/devops-api-http-client.js");
const index_js_1 = require("../lib/index.js");
const utils_js_2 = require("../lib/utils.js");
const constants_js_2 = require("../lib/constants.js");
const timeouts_js_1 = require("../lib/api/timeouts/timeouts.js");
const admin_opts_handler_js_1 = require("../client/opts-handlers/admin-opts-handler.js");
const db_opts_handler_js_1 = require("../client/opts-handlers/db-opts-handler.js");
class AstraAdmin extends index_js_1.HierarchicalLogger {
constructor(rootOpts, adminOpts) {
const defaultOpts = {
...rootOpts,
adminOptions: admin_opts_handler_js_1.AdminOptsHandler.concat([rootOpts.adminOptions, adminOpts]),
dbOptions: {
...rootOpts.dbOptions,
token: index_js_1.TokenProvider.opts.concat([rootOpts.adminOptions.adminToken, adminOpts?.adminToken, rootOpts.dbOptions.token]),
},
};
super(rootOpts.client, defaultOpts.adminOptions.logging);
_AstraAdmin_defaultOpts.set(this, void 0);
_AstraAdmin_httpClient.set(this, void 0);
_AstraAdmin_environment.set(this, void 0);
tslib_1.__classPrivateFieldSet(this, _AstraAdmin_defaultOpts, defaultOpts, "f");
tslib_1.__classPrivateFieldSet(this, _AstraAdmin_environment, tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f").adminOptions.astraEnv ?? 'prod', "f");
tslib_1.__classPrivateFieldSet(this, _AstraAdmin_httpClient, new devops_api_http_client_js_1.DevOpsAPIHttpClient({
baseUrl: tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f").adminOptions.endpointUrl ?? constants_js_1.DEFAULT_DEVOPS_API_ENDPOINTS[tslib_1.__classPrivateFieldGet(this, _AstraAdmin_environment, "f")],
logger: this,
fetchCtx: rootOpts.fetchCtx,
caller: rootOpts.caller,
tokenProvider: tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f").adminOptions.adminToken,
additionalHeaders: tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f").additionalHeaders,
timeoutDefaults: timeouts_js_1.Timeouts.cfg.concat([rootOpts.adminOptions.timeoutDefaults, tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f").adminOptions.timeoutDefaults]),
}), "f");
Object.defineProperty(this, constants_js_2.$CustomInspect, {
value: () => 'AstraAdmin()',
});
}
db(endpointOrId, regionOrOptions, maybeOptions) {
const [endpoint, dbOpts] = resolveEndpointOrIdOverload(endpointOrId, regionOrOptions, maybeOptions);
return new db_js_1.Db(tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f"), endpoint, db_opts_handler_js_1.DbOptsHandler.parse(dbOpts));
}
dbAdmin(endpointOrId, regionOrOptions, maybeOptions) {
const [endpoint, dbOpts] = resolveEndpointOrIdOverload(endpointOrId, regionOrOptions, maybeOptions);
return new astra_db_admin_js_1.AstraDbAdmin(this.db(endpoint, dbOpts), tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f"), admin_opts_handler_js_1.AdminOptsHandler.empty, tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f").dbOptions.token, endpoint);
}
async dbInfo(id, options) {
const tm = tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").tm.single('databaseAdminTimeoutMs', options);
const resp = await tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").request({
method: constants_js_1.HttpMethods.Get,
path: `/databases/${id}`,
methodName: 'admin.dbInfo',
}, tm);
return (0, utils_js_1.buildAstraDatabaseAdminInfo)(resp.data, tslib_1.__classPrivateFieldGet(this, _AstraAdmin_environment, "f"));
}
async listDatabases(options) {
const params = {};
if (typeof options?.include === 'string') {
params.include = options.include;
}
if (typeof options?.provider === 'string') {
params.provider = options.provider;
}
if (typeof options?.limit === 'number') {
params.limit = String(options.limit);
}
if (typeof options?.startingAfter === 'string') {
params.starting_after = options.startingAfter;
}
const tm = tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").tm.single('databaseAdminTimeoutMs', options);
const resp = await tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").request({
method: constants_js_1.HttpMethods.Get,
path: `/databases`,
params: params,
methodName: 'admin.listDatabases',
}, tm);
return resp.data.map((d) => (0, utils_js_1.buildAstraDatabaseAdminInfo)(d, tslib_1.__classPrivateFieldGet(this, _AstraAdmin_environment, "f")));
}
async createDatabase(nameOrConfig, configOrOptions, maybeOptions) {
let config;
let options;
if (typeof nameOrConfig === 'string') {
config = {
...configOrOptions,
name: nameOrConfig,
};
options = maybeOptions;
}
else {
config = nameOrConfig;
options = configOrOptions;
}
const definition = {
capacityUnits: 1,
tier: 'serverless',
dbType: 'vector',
keyspace: config.keyspace || constants_js_1.DEFAULT_KEYSPACE,
...config,
};
if (definition.dbType === 'nonvector') {
delete definition.dbType;
}
if (definition.pcuGroupUUID) {
await this._validatePCUGroupExists(options, definition);
}
const tm = tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").tm.multipart('databaseAdminTimeoutMs', options);
const resp = await tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").requestLongRunning({
method: constants_js_1.HttpMethods.Post,
path: '/databases',
data: definition,
methodName: 'admin.createDatabase',
}, {
id: (resp) => resp.headers.location,
target: 'ACTIVE',
legalStates: ['INITIALIZING', 'PENDING', 'ASSOCIATING'],
defaultPollInterval: 10000,
timeoutManager: tm,
options,
});
const endpoint = (0, utils_js_2.buildAstraEndpoint)(resp.headers.location, definition.region);
const db = this.db(endpoint, { ...options?.dbOptions, keyspace: definition.keyspace });
return new astra_db_admin_js_1.AstraDbAdmin(db, tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f"), admin_opts_handler_js_1.AdminOptsHandler.empty, tslib_1.__classPrivateFieldGet(this, _AstraAdmin_defaultOpts, "f").adminOptions.adminToken, endpoint);
}
async _validatePCUGroupExists(options, definition) {
try {
const groups = await this.listPCUGroups({ timeout: options?.timeout }); // technically this should use a multi-call tm but honestly it probably doesn't matter
const group = groups.find(g => g.id === definition.pcuGroupUUID);
if (!group) {
throw new Error(`Requested PCU Group ID '${definition.pcuGroupUUID}' not found for cloud provider/region ('${definition.cloudProvider}' / '${definition.region}'). Aborting database creation.`);
}
if (group.cloudProvider.toLowerCase() !== definition.cloudProvider.toLowerCase() || group.region.toLowerCase() !== definition.region.toLowerCase()) {
throw new Error(`Requested PCU Group ID '${definition.pcuGroupUUID}' is in another cloud provider and region ('${group.cloudProvider}' / '${group.region}'). Aborting database creation.`);
}
}
catch (e) {
if (e instanceof Error)
throw e;
return;
}
}
async dropDatabase(db, options) {
const id = (0, utils_js_1.idFromDbLike)(db);
const tm = tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").tm.multipart('databaseAdminTimeoutMs', options);
await tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").requestLongRunning({
method: constants_js_1.HttpMethods.Post,
path: `/databases/${id}/terminate`,
methodName: 'admin.dropDatabase',
}, {
id: id,
target: 'TERMINATED',
legalStates: ['TERMINATING'],
defaultPollInterval: 10000,
timeoutManager: tm,
options,
});
}
async findAvailableRegions(options) {
const tm = tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").tm.single('databaseAdminTimeoutMs', options);
const filterByOrg = options?.onlyOrgEnabledRegions !== false ? 'enabled' : 'disabled';
const resp = await tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").request({
method: constants_js_1.HttpMethods.Get,
path: '/regions/serverless',
params: {
'filter-by-org': filterByOrg,
'region-type': 'vector',
},
methodName: 'admin.findAvailableRegions',
}, tm);
return resp.data.map((region) => ({
classification: region.classification,
cloudProvider: region.cloudProvider,
displayName: region.displayName,
enabled: region.enabled,
name: region.name,
reservedForQualifiedUsers: region.reservedForQualifiedUsers,
zone: region.zone,
pcuTypes: region.pcu_types?.map(utils_js_1.buildAstraPCUTypeDescriptor),
}));
}
async listPCUGroups(options) {
if (options?.region !== undefined && options?.cloudProvider === undefined) {
throw new Error("If 'region' is provided, 'cloudProvider' must also be provided.");
}
const tm = tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").tm.single('databaseAdminTimeoutMs', options);
const resp = await tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f").request({
method: constants_js_1.HttpMethods.Post,
path: '/pcus/actions/get',
data: {},
methodName: 'admin.listPCUGroups',
}, tm);
const pcuGroups = resp.data.map((pg) => ({
...pg,
pcuType: pg.pcuType ? (0, utils_js_1.buildAstraPCUTypeDescriptor)(pg.pcuType) : undefined,
}));
if (options?.cloudProvider) {
return pcuGroups.filter(pg => pg.cloudProvider.toLowerCase() === options.cloudProvider.toLowerCase() &&
(!options.region || pg.region.toLowerCase() === options.region.toLowerCase()));
}
return pcuGroups;
}
get _httpClient() {
return tslib_1.__classPrivateFieldGet(this, _AstraAdmin_httpClient, "f");
}
}
exports.AstraAdmin = AstraAdmin;
_AstraAdmin_defaultOpts = new WeakMap(), _AstraAdmin_httpClient = new WeakMap(), _AstraAdmin_environment = new WeakMap();
const resolveEndpointOrIdOverload = (endpointOrId, regionOrOptions, maybeOptions) => {
const dbOpts = (typeof regionOrOptions === 'string')
? maybeOptions
: regionOrOptions;
if (typeof regionOrOptions === 'string' && (endpointOrId.startsWith('http'))) {
throw new Error('Unexpected db() argument: database id can\'t start with "http(s)://". Did you mean to call `.db(endpoint, { keyspace })`?');
}
const endpoint = (typeof regionOrOptions === 'string')
? 'https://' + endpointOrId + '-' + regionOrOptions + '.apps.astra.datastax.com'
: endpointOrId;
return [endpoint, dbOpts];
};