UNPKG

@stackbit/cms-contentful

Version:

Stackbit Contentful CMS Interface

388 lines 15.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createPlainApiClient = createPlainApiClient; exports.fetchEntryById = fetchEntryById; exports.fetchAssetById = fetchAssetById; exports.createEntry = createEntry; exports.updateEntry = updateEntry; exports.publishEntry = publishEntry; exports.unpublishEntry = unpublishEntry; exports.archiveEntry = archiveEntry; exports.unarchiveEntry = unarchiveEntry; exports.deleteEntry = deleteEntry; exports.createAsset = createAsset; exports.updateAsset = updateAsset; exports.createAssetFromFile = createAssetFromFile; exports.processAssetForAllLocales = processAssetForAllLocales; exports.publishAsset = publishAsset; exports.createValidateBulkAction = createValidateBulkAction; exports.createPublishBulkAction = createPublishBulkAction; exports.createUnpublishBulkAction = createUnpublishBulkAction; exports.createWebhook = createWebhook; exports.getBulkAction = getBulkAction; exports.fetchEntriesByIds = fetchEntriesByIds; exports.fetchAssetsByIds = fetchAssetsByIds; exports.fetchAllEntries = fetchAllEntries; exports.fetchEntriesUpdatedAfter = fetchEntriesUpdatedAfter; exports.fetchAllAssets = fetchAllAssets; exports.fetchAssetsUpdatedAfter = fetchAssetsUpdatedAfter; exports.fetchAllLocales = fetchAllLocales; exports.fetchAllUsers = fetchAllUsers; exports.fetchAllContentTypes = fetchAllContentTypes; exports.hasContentTypesUpdatedAfter = hasContentTypesUpdatedAfter; exports.fetchContentTypesUpdatedAfter = fetchContentTypesUpdatedAfter; exports.fetchAllEditorInterfaces = fetchAllEditorInterfaces; exports.fetchAllAppInstallations = fetchAllAppInstallations; exports.fetchAllWebhooks = fetchAllWebhooks; exports.fetchAllReleases = fetchAllReleases; exports.fetchAllSchedules = fetchAllSchedules; exports.fetchScheduleById = fetchScheduleById; exports.fetchEntityVersions = fetchEntityVersions; exports.fetchEntityVersion = fetchEntityVersion; exports.createScheduledAction = createScheduledAction; exports.updateScheduledAction = updateScheduledAction; exports.cancelScheduledAction = cancelScheduledAction; exports.getScheduledAction = getScheduledAction; exports.fetchAllItems = fetchAllItems; exports.fetchAllItemsCursor = fetchAllItemsCursor; 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 } }); } async function fetchEntryById(client, entryId) { return client.entry.get({ entryId }); } async function fetchAssetById(client, assetId) { return client.asset.get({ assetId }); } async function createEntry(client, contentTypeId, data) { return client.entry.create({ contentTypeId }, data); } async function updateEntry(client, entryId, entry) { return client.entry.update({ entryId }, entry); } async function publishEntry(client, entry) { return client.entry.publish({ entryId: entry.sys.id }, entry); } async function unpublishEntry(client, entryId) { return client.entry.unpublish({ entryId }); } async function archiveEntry(client, entryId) { return client.entry.archive({ entryId }); } async function unarchiveEntry(client, entryId) { return client.entry.unarchive({ entryId }); } async function deleteEntry(client, entryId) { return client.entry.delete({ entryId }); } async function createAsset(client, data) { return client.asset.create({}, data); } async function updateAsset(client, assetId, asset) { return client.asset.update({ assetId }, asset); } async function createAssetFromFile(client, data) { return client.asset.createFromFiles({}, data); } async function processAssetForAllLocales(client, data) { return client.asset.processForAllLocales({}, data); } async function publishAsset(client, data) { return client.asset.publish({ assetId: data.sys.id }, data); } async function createValidateBulkAction(client, options, data) { return client.bulkAction.validate(options, data); } async function createPublishBulkAction(client, options, data) { return client.bulkAction.publish(options, data); } async function createUnpublishBulkAction(client, options, data) { return client.bulkAction.unpublish(options, data); } async function createWebhook(client, data) { return client.webhook.create({}, data); } async function getBulkAction(client, data) { return client.bulkAction.get(data); } 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; } 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; } async function fetchAllEntries(client, logger) { return fetchAllItems({ getMany: client.entry.getMany, logger }); } async function fetchEntriesUpdatedAfter(client, date, logger) { return fetchAllItems({ getMany: client.entry.getMany, logger, query: { 'sys.updatedAt[gt]': date } }); } async function fetchAllAssets(client, logger) { return fetchAllItems({ getMany: client.asset.getMany, logger }); } async function fetchAssetsUpdatedAfter(client, date, logger) { return fetchAllItems({ getMany: client.asset.getMany, logger, query: { 'sys.updatedAt[gt]': date } }); } async function fetchAllLocales(client, logger) { return fetchAllItems({ getMany: client.locale.getMany, logger }); } async function fetchAllUsers(client, logger) { return fetchAllItems({ getMany: client.user.getManyForSpace, logger }); } async function fetchAllContentTypes(client, logger) { return fetchAllItems({ getMany: client.contentType.getMany, logger }); } 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; } async function fetchContentTypesUpdatedAfter(client, date, logger) { return fetchAllItems({ getMany: client.contentType.getMany, logger, query: { 'sys.updatedAt[gt]': date } }); } async function fetchAllEditorInterfaces(client, logger) { return fetchAllItems({ getMany: client.editorInterface.getMany, logger }); } async function fetchAllAppInstallations(client, logger) { return fetchAllItems({ getMany: client.appInstallation.getMany, logger }); } async function fetchAllWebhooks(client, logger) { return fetchAllItems({ getMany: client.webhook.getMany, logger }); } async function fetchAllReleases(client, logger) { return fetchAllItemsCursor(client.release.query, {}, logger); } 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); } async function fetchScheduleById(client, params) { return client.scheduledActions.get({ scheduledActionId: params.scheduleId, environmentId: params.environment }); } async function fetchEntityVersions(client, params) { return client.snapshot.getManyForEntry({ entryId: params.entityId, environmentId: params.environment }); } async function fetchEntityVersion(client, params) { return client.snapshot.getForEntry({ entryId: params.entityId, snapshotId: params.versionId, environmentId: params.environment }); } 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 }; } 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); } 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); } 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); } 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; } 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; } //# sourceMappingURL=contentful-api-client.js.map