UNPKG

@stackbit/cms-contentful

Version:

Stackbit Contentful CMS Interface

389 lines 17.1 kB
"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