@contentstack/cli-variants
Version:
Variants plugin
339 lines (338 loc) • 19.3 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VariantAdapter = exports.VariantManagementSDK = exports.VariantHttpClient = void 0;
const omit_1 = __importDefault(require("lodash/omit"));
const fs_1 = require("fs");
const cli_utilities_1 = require("@contentstack/cli-utilities");
const messages_1 = __importDefault(require("../messages"));
const adapter_helper_1 = require("./adapter-helper");
const error_helper_1 = require("./error-helper");
class VariantHttpClient extends adapter_helper_1.AdapterHelper {
constructor(config, options) {
var _a, _b;
super(config, options);
this.baseURL = ((_a = config.baseURL) === null || _a === void 0 ? void 0 : _a.includes('http')) ? `${config.baseURL}/v3` : `https://${config.baseURL}/v3`;
this.apiClient.baseUrl(this.baseURL);
cli_utilities_1.log.debug(`VariantHttpClient initialized with base URL: ${this.baseURL}`, (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context);
}
init() {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
cli_utilities_1.log.debug('Initializing VariantHttpClient...', (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
yield cli_utilities_1.authenticationHandler.getAuthDetails();
const token = cli_utilities_1.authenticationHandler.accessToken;
cli_utilities_1.log.debug(`Authentication type: ${cli_utilities_1.authenticationHandler.isOauthEnabled ? 'OAuth' : 'Token'}`, (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context);
if (cli_utilities_1.authenticationHandler.isOauthEnabled) {
cli_utilities_1.log.debug('Setting OAuth authorization header...', (_c = this.exportConfig) === null || _c === void 0 ? void 0 : _c.context);
this.apiClient.headers({ authorization: token });
}
else {
cli_utilities_1.log.debug('Setting authtoken header...', (_d = this.exportConfig) === null || _d === void 0 ? void 0 : _d.context);
this.apiClient.headers({ authtoken: token });
}
});
}
variantEntry(options) {
return __awaiter(this, void 0, void 0, function* () {
cli_utilities_1.log.debug('VariantEntry method called (placeholder implementation)', { module: 'variant-api-adapter' });
// TODO single entry variant
return { entry: {} };
});
}
/**
* The function `variantEntries` retrieves variant entries based on specified options and stores them
* in an array.
* @param {VariantsOption} options - The `options` parameter in the `variantEntries` function is an
* object that contains the following properties:
* @param {Record<string, any>[]} entries - The `entries` parameter in the `variantEntries` function
* is an array of objects where each object represents a record with key-value pairs. This parameter
* is used to store the entries retrieved from the API response or passed down recursively when
* fetching all data.
* @returns The function `variantEntries` returns a Promise that resolves to an object with an
* `entries` property containing an array of record objects or an unknown array. The function can
* also return void if certain conditions are not met.
*/
variantEntries(options_1) {
return __awaiter(this, arguments, void 0, function* (options, entries = []) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
const variantConfig = this.config.modules.variantEntry;
const { callback, entry_uid, getAllData, returnResult, content_type_uid, locale, skip = variantConfig.query.skip || 0, limit = variantConfig.query.limit || 100, include_variant = variantConfig.query.include_variant || true, include_count = variantConfig.query.include_count || true, include_publish_details = variantConfig.query.include_publish_details || true, } = options;
cli_utilities_1.log.debug(`Fetching variant entries for content type: ${content_type_uid}, entry: ${entry_uid}, locale: ${locale}`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
cli_utilities_1.log.debug(`Query parameters - skip: ${skip}, limit: ${limit}, include_variant: ${include_variant}, include_count: ${include_count}, include_publish_details: ${include_publish_details}`, (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context);
if (variantConfig.serveMockData && callback) {
cli_utilities_1.log.debug('Using mock data for variant entries...', (_c = this.exportConfig) === null || _c === void 0 ? void 0 : _c.context);
let data = [];
if ((0, fs_1.existsSync)(variantConfig.mockDataPath)) {
cli_utilities_1.log.debug(`Loading mock data from: ${variantConfig.mockDataPath}`, (_d = this.exportConfig) === null || _d === void 0 ? void 0 : _d.context);
data = require(variantConfig.mockDataPath);
}
callback(data);
return;
}
if (!locale) {
cli_utilities_1.log.debug('No locale provided, skipping variant entries fetch', (_e = this.exportConfig) === null || _e === void 0 ? void 0 : _e.context);
return;
}
const start = Date.now();
let endpoint = `/content_types/${content_type_uid}/entries/${entry_uid}/variants?locale=${locale}`;
if (skip) {
endpoint = endpoint.concat(`&skip=${skip}`);
}
if (limit) {
endpoint = endpoint.concat(`&limit=${limit}`);
}
if (include_variant) {
endpoint = endpoint.concat(`&include_variant=${include_variant}`);
}
if (include_count) {
endpoint = endpoint.concat(`&include_count=${include_count}`);
}
if (include_publish_details) {
endpoint = endpoint.concat(`&include_publish_details=${include_publish_details}`);
}
const query = this.constructQuery((0, omit_1.default)(variantConfig.query, [
'skip',
'limit',
'locale',
'include_variant',
'include_count',
'include_publish_details',
]));
if (query) {
endpoint = endpoint.concat(query);
}
cli_utilities_1.log.debug(`Making API call to: ${endpoint}`, (_f = this.exportConfig) === null || _f === void 0 ? void 0 : _f.context);
const data = yield this.apiClient.get(endpoint);
const response = (yield this.handleVariantAPIRes(data));
if ((_g = response === null || response === void 0 ? void 0 : response.entries) === null || _g === void 0 ? void 0 : _g.length) {
cli_utilities_1.log.debug(`Received ${(_h = response.entries) === null || _h === void 0 ? void 0 : _h.length} variant entries out of total ${response.count}`, (_j = this.exportConfig) === null || _j === void 0 ? void 0 : _j.context);
}
if (callback) {
cli_utilities_1.log.debug('Executing callback with variant entries...', (_k = this.exportConfig) === null || _k === void 0 ? void 0 : _k.context);
callback(response.entries);
}
else {
cli_utilities_1.log.debug('Adding variant entries to collection...', (_l = this.exportConfig) === null || _l === void 0 ? void 0 : _l.context);
entries = entries.concat(response.entries);
}
if (getAllData && skip + limit < response.count) {
const end = Date.now();
const exeTime = end - start;
if (exeTime < 1000) {
// 1 API call per second
cli_utilities_1.log.debug(`Rate limiting: waiting ${1000 - exeTime}ms before next request`, (_m = this.exportConfig) === null || _m === void 0 ? void 0 : _m.context);
yield this.delay(1000 - exeTime);
}
if (!options.skip) {
options['skip'] = 0;
}
options.skip += limit;
cli_utilities_1.log.debug(`Continuing to fetch variant entries with skip: ${options.skip}`, (_o = this.exportConfig) === null || _o === void 0 ? void 0 : _o.context);
return yield this.variantEntries(options, entries);
}
if (returnResult) {
cli_utilities_1.log.debug('Returning variant entries result...', (_p = this.exportConfig) === null || _p === void 0 ? void 0 : _p.context);
return { entries };
}
});
}
/**
* Creates a variant entry.
*
* @param input - The input data for the variant entry.
* @param options - The options for creating the variant entry.
* @param apiParams - Additional parameters for the API.
* @returns A Promise that resolves to a VariantEntryStruct, a string, or void.
*/
createVariantEntry(input, options, apiParams) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const { reject, resolve, variantUid } = apiParams;
const variantConfig = this.config.modules.variantEntry;
const { locale = variantConfig.query.locale || 'en-us', variant_id, entry_uid, content_type_uid } = options;
cli_utilities_1.log.debug(`Creating variant entry for content type: ${content_type_uid}, entry: ${entry_uid}, variant: ${variant_id}`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
let endpoint = `content_types/${content_type_uid}/entries/${entry_uid}/variants/${variant_id}?locale=${locale}`;
const query = this.constructQuery((0, omit_1.default)(variantConfig.query, ['locale']));
if (query) {
endpoint = endpoint.concat(query);
}
cli_utilities_1.log.debug(`Making API call to: ${endpoint}`, (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context);
const onSuccess = (response) => {
resolve({ response, apiData: { variantUid, entryUid: entry_uid }, log: cli_utilities_1.log });
};
const onReject = (error) => {
reject({
error,
apiData: { variantUid, entryUid: entry_uid },
log: cli_utilities_1.log,
});
};
try {
this.apiClient.headers({ api_version: undefined });
const res = yield this.apiClient.put(endpoint, { entry: input });
const data = yield this.handleVariantAPIRes(res);
if (res.status >= 200 && res.status < 300) {
onSuccess(data);
}
else {
onReject(data);
}
}
catch (error) {
onReject(error);
}
});
}
/**
* Publishes a variant entry.
*
* @param input - The input data for publishing the variant entry.
* @param options - The options for publishing the variant entry.
* @param apiParams - Additional API parameters.
* @returns A Promise that resolves to the published variant entry response.
*/
publishVariantEntry(input, options, apiParams) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const { reject, resolve, variantUid } = apiParams;
const { entry_uid, content_type_uid } = options;
cli_utilities_1.log.debug(`Publishing variant entry for content type: ${content_type_uid}, entry: ${entry_uid}`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
let endpoint = `content_types/${content_type_uid}/entries/${entry_uid}/publish`;
cli_utilities_1.log.debug(`Making API call to: ${endpoint}`, (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context);
const onSuccess = (response) => {
var _a;
cli_utilities_1.log.debug(`Variant entry published successfully: ${entry_uid}`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
resolve({ response, apiData: { entryUid: entry_uid, variantUid, locales: input.entry.locales }, log: cli_utilities_1.log });
};
const onReject = (error) => {
var _a;
cli_utilities_1.log.debug(`Failed to publish variant entry: ${entry_uid}`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
reject({
error,
apiData: { entryUid: entry_uid, variantUid, locales: input.entry.locales },
log: cli_utilities_1.log,
});
};
try {
this.apiClient.headers({ api_version: 3.2 });
const res = yield this.apiClient.post(endpoint, input);
const data = yield this.handleVariantAPIRes(res);
if (res.status >= 200 && res.status < 300) {
onSuccess(data);
}
else {
onReject(data);
}
}
catch (error) {
onReject(error);
}
});
}
/**
* Handles the API response for variant requests.
* @param res - The API response object.
* @returns The variant API response data.
* @throws If the API response status is not within the success range, an error message is thrown.
*/
handleVariantAPIRes(res) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const { status, data } = res;
cli_utilities_1.log.debug(`API response status: ${status}`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
if (status >= 200 && status < 300) {
cli_utilities_1.log.debug('API request successful.', (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context);
return data;
}
cli_utilities_1.log.debug(`API request failed with status: ${status}`, (_c = this.exportConfig) === null || _c === void 0 ? void 0 : _c.context);
// Refresh the access token if the response status is 401
yield cli_utilities_1.authenticationHandler.refreshAccessToken(res);
const errorMsg = (data === null || data === void 0 ? void 0 : data.errors) ? (0, error_helper_1.formatErrors)(data.errors) : (data === null || data === void 0 ? void 0 : data.error_message) || (data === null || data === void 0 ? void 0 : data.message) || data;
cli_utilities_1.log.debug(`API error: ${errorMsg}`, (_d = this.exportConfig) === null || _d === void 0 ? void 0 : _d.context);
throw errorMsg;
});
}
}
exports.VariantHttpClient = VariantHttpClient;
class VariantManagementSDK extends adapter_helper_1.AdapterHelper {
init() {
return __awaiter(this, void 0, void 0, function* () {
this.apiClient = yield (0, cli_utilities_1.managementSDKClient)(this.config);
});
}
variantEntry(options) {
return __awaiter(this, void 0, void 0, function* () {
// TODO SDK implementation
return { entry: {} };
});
}
variantEntries(options) {
return __awaiter(this, void 0, void 0, function* () {
// TODO SDK implementation
return { entries: [{}] };
});
}
createVariantEntry(input, options, apiParams) {
// FIXME placeholder
return Promise.resolve({});
}
handleVariantAPIRes(res) {
return __awaiter(this, void 0, void 0, function* () {
return res.data;
});
}
constructQuery(query) {
var _a;
cli_utilities_1.log.debug('ConstructQuery method called (SDK placeholder implementation)', (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
}
delay(ms) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
cli_utilities_1.log.debug(`Delay method called for ${ms}ms (SDK placeholder implementation)`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
});
}
}
exports.VariantManagementSDK = VariantManagementSDK;
class VariantAdapter {
constructor(config, options) {
var _a, _b, _c, _d;
cli_utilities_1.log.debug('Initializing VariantAdapter...', (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context);
if (config.httpClient) {
cli_utilities_1.log.debug('Using HTTP client variant instance.', (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context);
const { httpClient, Adapter } = config, restConfig = __rest(config, ["httpClient", "Adapter"]);
this.variantInstance = new Adapter(restConfig, options);
}
else {
cli_utilities_1.log.debug('Using SDK variant instance.', (_c = this.exportConfig) === null || _c === void 0 ? void 0 : _c.context);
const { Adapter } = config, restConfig = __rest(config, ["Adapter"]);
this.variantInstance = new Adapter(restConfig);
}
this.messages = messages_1.default;
cli_utilities_1.log.debug('VariantAdapter initialized successfully.', (_d = this.exportConfig) === null || _d === void 0 ? void 0 : _d.context);
}
}
exports.VariantAdapter = VariantAdapter;
exports.default = VariantAdapter;