@stackbit/cms-contentful
Version:
Stackbit Contentful CMS Interface
389 lines • 17.1 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchAllItemsCursor = exports.fetchAllItems = exports.getScheduledAction = exports.cancelScheduledAction = exports.updateScheduledAction = exports.createScheduledAction = exports.fetchEntityVersion = exports.fetchEntityVersions = exports.fetchScheduleById = exports.fetchAllSchedules = exports.fetchAllReleases = exports.fetchAllWebhooks = exports.fetchAllAppInstallations = exports.fetchAllEditorInterfaces = exports.fetchContentTypesUpdatedAfter = exports.hasContentTypesUpdatedAfter = exports.fetchAllContentTypes = exports.fetchAllUsers = exports.fetchAllLocales = exports.fetchAssetsUpdatedAfter = exports.fetchAllAssets = exports.fetchEntriesUpdatedAfter = exports.fetchAllEntries = exports.fetchAssetsByIds = exports.fetchEntriesByIds = exports.getBulkAction = exports.createWebhook = exports.createUnpublishBulkAction = exports.createPublishBulkAction = exports.createValidateBulkAction = exports.publishAsset = exports.processAssetForAllLocales = exports.createAssetFromFile = exports.updateAsset = exports.createAsset = exports.deleteEntry = exports.unarchiveEntry = exports.archiveEntry = exports.unpublishEntry = exports.publishEntry = exports.updateEntry = exports.createEntry = exports.fetchAssetById = exports.fetchEntryById = exports.createPlainApiClient = void 0;
const lodash_1 = __importDefault(require("lodash"));
const contentful_management_1 = require("contentful-management");
const contentful_scheduled_actions_converter_1 = require("./contentful-scheduled-actions-converter");
function createPlainApiClient({ accessToken, spaceId, environment, managementHost, uploadHost }) {
return (0, contentful_management_1.createClient)({
accessToken: accessToken,
...(managementHost ? { host: managementHost } : null),
...(uploadHost ? { hostUpload: uploadHost } : null)
}, {
type: 'plain',
defaults: {
spaceId: spaceId,
environmentId: environment
}
});
}
exports.createPlainApiClient = createPlainApiClient;
async function fetchEntryById(client, entryId) {
return client.entry.get({ entryId });
}
exports.fetchEntryById = fetchEntryById;
async function fetchAssetById(client, assetId) {
return client.asset.get({ assetId });
}
exports.fetchAssetById = fetchAssetById;
async function createEntry(client, contentTypeId, data) {
return client.entry.create({ contentTypeId }, data);
}
exports.createEntry = createEntry;
async function updateEntry(client, entryId, entry) {
return client.entry.update({ entryId }, entry);
}
exports.updateEntry = updateEntry;
async function publishEntry(client, entry) {
return client.entry.publish({ entryId: entry.sys.id }, entry);
}
exports.publishEntry = publishEntry;
async function unpublishEntry(client, entryId) {
return client.entry.unpublish({ entryId });
}
exports.unpublishEntry = unpublishEntry;
async function archiveEntry(client, entryId) {
return client.entry.archive({ entryId });
}
exports.archiveEntry = archiveEntry;
async function unarchiveEntry(client, entryId) {
return client.entry.unarchive({ entryId });
}
exports.unarchiveEntry = unarchiveEntry;
async function deleteEntry(client, entryId) {
return client.entry.delete({ entryId });
}
exports.deleteEntry = deleteEntry;
async function createAsset(client, data) {
return client.asset.create({}, data);
}
exports.createAsset = createAsset;
async function updateAsset(client, assetId, asset) {
return client.asset.update({ assetId }, asset);
}
exports.updateAsset = updateAsset;
async function createAssetFromFile(client, data) {
return client.asset.createFromFiles({}, data);
}
exports.createAssetFromFile = createAssetFromFile;
async function processAssetForAllLocales(client, data) {
return client.asset.processForAllLocales({}, data);
}
exports.processAssetForAllLocales = processAssetForAllLocales;
async function publishAsset(client, data) {
return client.asset.publish({ assetId: data.sys.id }, data);
}
exports.publishAsset = publishAsset;
async function createValidateBulkAction(client, options, data) {
return client.bulkAction.validate(options, data);
}
exports.createValidateBulkAction = createValidateBulkAction;
async function createPublishBulkAction(client, options, data) {
return client.bulkAction.publish(options, data);
}
exports.createPublishBulkAction = createPublishBulkAction;
async function createUnpublishBulkAction(client, options, data) {
return client.bulkAction.unpublish(options, data);
}
exports.createUnpublishBulkAction = createUnpublishBulkAction;
async function createWebhook(client, data) {
return client.webhook.create({}, data);
}
exports.createWebhook = createWebhook;
async function getBulkAction(client, data) {
return client.bulkAction.get(data);
}
exports.getBulkAction = getBulkAction;
async function fetchEntriesByIds(client, entryIds, query) {
const entryIdChunks = lodash_1.default.chunk(entryIds, 100);
let entries = [];
for (const entryIdsChunk of entryIdChunks) {
const result = await client.entry.getMany({
query: {
'sys.id[in]': entryIdsChunk.join(','),
limit: 1000,
...query
}
});
entries = entries.concat(result.items);
}
return entries;
}
exports.fetchEntriesByIds = fetchEntriesByIds;
async function fetchAssetsByIds(client, assetIds, query) {
const assetIdChunks = lodash_1.default.chunk(assetIds, 100);
let assets = [];
for (const entryIdsChunk of assetIdChunks) {
const result = await client.asset.getMany({
query: {
'sys.id[in]': entryIdsChunk.join(','),
limit: 1000,
...query
}
});
assets = assets.concat(result.items);
}
return assets;
}
exports.fetchAssetsByIds = fetchAssetsByIds;
async function fetchAllEntries(client, logger) {
return fetchAllItems({ getMany: client.entry.getMany, logger });
}
exports.fetchAllEntries = fetchAllEntries;
async function fetchEntriesUpdatedAfter(client, date, logger) {
return fetchAllItems({
getMany: client.entry.getMany,
logger,
query: {
'sys.updatedAt[gt]': date
}
});
}
exports.fetchEntriesUpdatedAfter = fetchEntriesUpdatedAfter;
async function fetchAllAssets(client, logger) {
return fetchAllItems({ getMany: client.asset.getMany, logger });
}
exports.fetchAllAssets = fetchAllAssets;
async function fetchAssetsUpdatedAfter(client, date, logger) {
return fetchAllItems({
getMany: client.asset.getMany,
logger,
query: {
'sys.updatedAt[gt]': date
}
});
}
exports.fetchAssetsUpdatedAfter = fetchAssetsUpdatedAfter;
async function fetchAllLocales(client, logger) {
return fetchAllItems({ getMany: client.locale.getMany, logger });
}
exports.fetchAllLocales = fetchAllLocales;
async function fetchAllUsers(client, logger) {
return fetchAllItems({ getMany: client.user.getManyForSpace, logger });
}
exports.fetchAllUsers = fetchAllUsers;
async function fetchAllContentTypes(client, logger) {
return fetchAllItems({ getMany: client.contentType.getMany, logger });
}
exports.fetchAllContentTypes = fetchAllContentTypes;
async function hasContentTypesUpdatedAfter(client, date, logger) {
const updatedContentTypes = await fetchAllItems({
getMany: client.contentType.getMany,
logger,
query: {
'sys.updatedAt[gt]': date,
limit: 1
}
});
return updatedContentTypes.length > 0;
}
exports.hasContentTypesUpdatedAfter = hasContentTypesUpdatedAfter;
async function fetchContentTypesUpdatedAfter(client, date, logger) {
return fetchAllItems({
getMany: client.contentType.getMany,
logger,
query: {
'sys.updatedAt[gt]': date
}
});
}
exports.fetchContentTypesUpdatedAfter = fetchContentTypesUpdatedAfter;
async function fetchAllEditorInterfaces(client, logger) {
return fetchAllItems({ getMany: client.editorInterface.getMany, logger });
}
exports.fetchAllEditorInterfaces = fetchAllEditorInterfaces;
async function fetchAllAppInstallations(client, logger) {
return fetchAllItems({ getMany: client.appInstallation.getMany, logger });
}
exports.fetchAllAppInstallations = fetchAllAppInstallations;
async function fetchAllWebhooks(client, logger) {
return fetchAllItems({ getMany: client.webhook.getMany, logger });
}
exports.fetchAllWebhooks = fetchAllWebhooks;
async function fetchAllReleases(client, logger) {
return fetchAllItemsCursor(client.release.query, {}, logger);
}
exports.fetchAllReleases = fetchAllReleases;
async function fetchAllSchedules(client, params, logger) {
return fetchAllItemsCursor(client.scheduledActions.getMany, {
'environment.sys.id': params.environment,
'entity.sys.id': params.entityId,
'sys.status': params.status
}, logger);
}
exports.fetchAllSchedules = fetchAllSchedules;
async function fetchScheduleById(client, params) {
return client.scheduledActions.get({ scheduledActionId: params.scheduleId, environmentId: params.environment });
}
exports.fetchScheduleById = fetchScheduleById;
async function fetchEntityVersions(client, params) {
return client.snapshot.getManyForEntry({ entryId: params.entityId, environmentId: params.environment });
}
exports.fetchEntityVersions = fetchEntityVersions;
async function fetchEntityVersion(client, params) {
return client.snapshot.getForEntry({ entryId: params.entityId, snapshotId: params.versionId, environmentId: params.environment });
}
exports.fetchEntityVersion = fetchEntityVersion;
async function createScheduledAction(client, options) {
const contentfulRelease = await client.release.create({}, {
entities: {
sys: { type: 'Array' },
items: options.documentIds.map((docId) => ({ sys: { linkType: 'Entry', type: 'Link', id: docId } }))
},
title: options.name
});
const contentfulSchedule = await client.scheduledActions.create({}, {
entity: { sys: { type: 'Link', linkType: 'Release', id: contentfulRelease.sys.id } },
environment: { sys: { type: 'Link', linkType: 'Environment', id: options.environment } },
scheduledFor: { datetime: options.executeAt },
action: options.action
});
return { schedule: (0, contentful_scheduled_actions_converter_1.convertScheduledAction)(contentfulRelease, contentfulSchedule), contentfulRelease, contentfulSchedule };
}
exports.createScheduledAction = createScheduledAction;
async function updateScheduledAction(client, scheduledActionId, options) {
let contentfulRelease = await client.release.get({ releaseId: scheduledActionId });
if (!contentfulRelease) {
throw new Error('Contentful release not found for scheduled action');
}
const releaseUpdateObj = {
...lodash_1.default.pick(contentfulRelease, ['title', 'entities']),
...(options.documentIds
? { entities: { sys: { type: 'Array' }, items: options.documentIds.map((docId) => ({ sys: { linkType: 'Entry', type: 'Link', id: docId } })) } }
: {}),
...(options.name ? { title: options.name } : {})
};
contentfulRelease = await client.release.update({ releaseId: scheduledActionId, version: contentfulRelease.sys.version }, releaseUpdateObj);
const contentfulSchedules = await fetchAllSchedules(client, {
environment: options.environment,
entityId: contentfulRelease.sys.id,
status: 'scheduled'
});
const releaseSchedule = (0, contentful_scheduled_actions_converter_1.findScheduleForRelease)(lodash_1.default.sortBy(contentfulSchedules, ['scheduledFor.datetime']));
if (!releaseSchedule) {
throw new Error('Contentful schedule not found for scheduled action, or schedule is already executed or cancelled');
}
const scheduleUpdateObj = {
...lodash_1.default.pick(releaseSchedule, ['action', 'entity', 'environment']),
scheduledFor: {
...releaseSchedule.scheduledFor,
...(options.executeAt ? { datetime: options.executeAt } : {})
}
};
const contentfulSchedule = await client.scheduledActions.update({ scheduledActionId: releaseSchedule.sys.id, version: releaseSchedule.sys.version }, scheduleUpdateObj);
return (0, contentful_scheduled_actions_converter_1.convertScheduledAction)(contentfulRelease, contentfulSchedule);
}
exports.updateScheduledAction = updateScheduledAction;
async function cancelScheduledAction(client, scheduledActionId, options) {
const contentfulRelease = await client.release.get({ releaseId: scheduledActionId });
if (!contentfulRelease) {
throw new Error('Contentful release not found for scheduled action');
}
const contentfulSchedules = await fetchAllSchedules(client, {
environment: options.environment,
entityId: contentfulRelease.sys.id,
status: 'scheduled'
});
let releaseSchedule = (0, contentful_scheduled_actions_converter_1.findScheduleForRelease)(lodash_1.default.sortBy(contentfulSchedules, ['scheduledFor.datetime']));
if (!releaseSchedule) {
throw new Error('Contentful schedule not found for scheduled action');
}
releaseSchedule = await client.scheduledActions.delete({ scheduledActionId: releaseSchedule.sys.id, environmentId: options.environment });
return (0, contentful_scheduled_actions_converter_1.convertScheduledAction)(contentfulRelease, releaseSchedule);
}
exports.cancelScheduledAction = cancelScheduledAction;
async function getScheduledAction(client, scheduledActionId, options) {
const contentfulRelease = await client.release.get({ releaseId: scheduledActionId });
if (!contentfulRelease) {
return null;
}
const contentfulSchedules = await fetchAllSchedules(client, {
environment: options.environment,
entityId: contentfulRelease.sys.id
});
const releaseSchedule = (0, contentful_scheduled_actions_converter_1.findScheduleForRelease)(lodash_1.default.sortBy(contentfulSchedules, ['scheduledFor.datetime']));
if (!releaseSchedule) {
return null;
}
return (0, contentful_scheduled_actions_converter_1.convertScheduledAction)(contentfulRelease, releaseSchedule);
}
exports.getScheduledAction = getScheduledAction;
async function fetchAllItems({ getMany, logger, query }) {
let limit = 1000;
let items = [];
let hasMoreItems = true;
let retries = 0;
while (hasMoreItems) {
try {
const result = await getMany({
query: {
skip: items.length,
limit: limit,
...query
}
});
items = items.concat(result.items);
hasMoreItems = result.total > items.length && result.items.length === limit;
retries = 0;
limit = 1000;
if (result.total > 1000) {
logger?.info(`Fetched ${items.length} of ${result.total} items`);
}
}
catch (err) {
if (retries > 4) {
throw err;
}
if (lodash_1.default.get(err, 'message')?.includes('Response size too big')) {
limit = Math.trunc(limit / 2);
}
else {
throw err;
}
retries++;
}
}
return items;
}
exports.fetchAllItems = fetchAllItems;
async function fetchAllItemsCursor(fn, query, logger) {
// Contentful didn't do a good job of typing scheduledActions.getMany, so the type names here are specific to Release,
// but apply to ScheduledActions as well, as both are implemented as cursorPaginatedCollections
let limit = 1000;
let items = [];
let hasMoreItems = true;
let pageNext = undefined;
let retries = 0;
while (hasMoreItems) {
try {
const result = await fn({
query: { ...query, pageNext, limit }
});
items = items.concat(result.items);
hasMoreItems = !!result.pages?.next;
const nextUrlParams = result.pages?.next?.split('?')[1];
pageNext = new URLSearchParams(nextUrlParams).get('pageNext') ?? undefined;
retries = 0;
limit = 1000;
logger?.info(`Fetched ${items.length} items`);
}
catch (err) {
if (retries > 4) {
throw err;
}
if (lodash_1.default.get(err, 'message')?.includes('Response size too big')) {
limit = Math.trunc(limit / 2);
}
else {
throw err;
}
retries++;
}
}
return items;
}
exports.fetchAllItemsCursor = fetchAllItemsCursor;
//# sourceMappingURL=contentful-api-client.js.map