UNPKG

@contentstack/cli-variants

Version:

Variants plugin

357 lines (356 loc) 20.8 kB
"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, _e; 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 }); } cli_utilities_1.log.debug('VariantHttpClient initialization completed', (_e = this.exportConfig) === null || _e === void 0 ? void 0 : _e.context); }); } 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, log } = apiParams; const variantConfig = this.config.modules.variantEntry; const { locale = variantConfig.query.locale || 'en-us', variant_id, entry_uid, content_type_uid } = options; 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); } log.debug(`Making API call to: ${endpoint}`, (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context); const onSuccess = (response) => { var _a; log.debug(`Variant entry created successfully: ${variantUid}`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context); resolve({ response, apiData: { variantUid, entryUid: entry_uid }, log }); }; const onReject = (error) => { var _a; log.debug(`Failed to create variant entry: ${variantUid}`, (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context); reject({ error, apiData: { variantUid, entryUid: entry_uid }, 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, log, variantUid } = apiParams; const { entry_uid, content_type_uid } = options; 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`; log.debug(`Making API call to: ${endpoint}`, (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context); const onSuccess = (response) => { var _a; 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 }); }; const onReject = (error) => { var _a; 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, }); }; 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* () { var _a, _b; cli_utilities_1.log.debug('Initializing VariantManagementSDK...', (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context); this.apiClient = yield (0, cli_utilities_1.managementSDKClient)(this.config); cli_utilities_1.log.debug('VariantManagementSDK initialized successfully', (_b = this.exportConfig) === null || _b === void 0 ? void 0 : _b.context); }); } variantEntry(options) { return __awaiter(this, void 0, void 0, function* () { var _a; cli_utilities_1.log.debug('VariantEntry method called (SDK placeholder implementation)', (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context); // TODO SDK implementation return { entry: {} }; }); } variantEntries(options) { return __awaiter(this, void 0, void 0, function* () { var _a; cli_utilities_1.log.debug('VariantEntries method called (SDK placeholder implementation)', (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context); // TODO SDK implementation return { entries: [{}] }; }); } createVariantEntry(input, options, apiParams) { var _a; cli_utilities_1.log.debug('CreateVariantEntry method called (SDK placeholder implementation)', (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context); // FIXME placeholder return Promise.resolve({}); } handleVariantAPIRes(res) { return __awaiter(this, void 0, void 0, function* () { var _a; cli_utilities_1.log.debug('HandleVariantAPIRes method called (SDK implementation)', (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.context); 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;