@stackbit/cms-contentful 0.4.45-staging.1 → 0.4.46-feature-document-statuses.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contentful-api-client.d.ts +4 -1
- package/dist/contentful-api-client.d.ts.map +1 -1
- package/dist/contentful-api-client.js +13 -1
- package/dist/contentful-api-client.js.map +1 -1
- package/dist/contentful-content-source.d.ts +14 -1
- package/dist/contentful-content-source.d.ts.map +1 -1
- package/dist/contentful-content-source.js +65 -0
- package/dist/contentful-content-source.js.map +1 -1
- package/dist/contentful-entries-converter.d.ts.map +1 -1
- package/dist/contentful-entries-converter.js +4 -2
- package/dist/contentful-entries-converter.js.map +1 -1
- package/package.json +5 -5
- package/src/contentful-api-client.ts +18 -1
- package/src/contentful-content-source.ts +87 -2
- package/src/contentful-entries-converter.ts +5 -2
|
@@ -27,7 +27,8 @@ import {
|
|
|
27
27
|
ScheduledActionProps,
|
|
28
28
|
CursorPaginatedCollectionProp,
|
|
29
29
|
ReleasePayload,
|
|
30
|
-
ReleaseQueryOptions
|
|
30
|
+
ReleaseQueryOptions,
|
|
31
|
+
BulkActionUnpublishPayload
|
|
31
32
|
} from 'contentful-management';
|
|
32
33
|
import { Logger } from '@stackbit/types';
|
|
33
34
|
import { convertScheduledAction, findScheduleForRelease } from './contentful-scheduled-actions-converter';
|
|
@@ -77,6 +78,14 @@ export async function unpublishEntry(client: PlainClientAPI, entryId: string) {
|
|
|
77
78
|
return client.entry.unpublish({ entryId });
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
export async function archiveEntry(client: PlainClientAPI, entryId: string) {
|
|
82
|
+
return client.entry.archive({ entryId });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function unarchiveEntry(client: PlainClientAPI, entryId: string) {
|
|
86
|
+
return client.entry.unarchive({ entryId });
|
|
87
|
+
}
|
|
88
|
+
|
|
80
89
|
export async function deleteEntry(client: PlainClientAPI, entryId: string) {
|
|
81
90
|
return client.entry.delete({ entryId });
|
|
82
91
|
}
|
|
@@ -113,6 +122,14 @@ export async function createPublishBulkAction(
|
|
|
113
122
|
return client.bulkAction.publish(options, data);
|
|
114
123
|
}
|
|
115
124
|
|
|
125
|
+
export async function createUnpublishBulkAction(
|
|
126
|
+
client: PlainClientAPI,
|
|
127
|
+
options: GetSpaceEnvironmentParams,
|
|
128
|
+
data: BulkActionUnpublishPayload
|
|
129
|
+
): Promise<BulkActionProps<BulkActionUnpublishPayload>> {
|
|
130
|
+
return client.bulkAction.unpublish(options, data);
|
|
131
|
+
}
|
|
132
|
+
|
|
116
133
|
export async function createWebhook(client: PlainClientAPI, data: CreateWebhooksProps) {
|
|
117
134
|
return client.webhook.create({}, data);
|
|
118
135
|
}
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
SnapshotProps
|
|
19
19
|
} from 'contentful-management';
|
|
20
20
|
|
|
21
|
-
import
|
|
21
|
+
import { DocumentVersion, DocumentVersionWithDocument, FieldList, FieldSpecificProps, Model, Schema } from '@stackbit/types';
|
|
22
22
|
import type * as ContentSourceTypes from '@stackbit/types';
|
|
23
23
|
import * as stackbitUtils from '@stackbit/types';
|
|
24
24
|
import { TaskQueue } from '@stackbit/utils';
|
|
@@ -59,7 +59,10 @@ import {
|
|
|
59
59
|
getScheduledAction,
|
|
60
60
|
fetchScheduleById,
|
|
61
61
|
fetchEntityVersions,
|
|
62
|
-
fetchEntityVersion
|
|
62
|
+
fetchEntityVersion,
|
|
63
|
+
createUnpublishBulkAction,
|
|
64
|
+
archiveEntry,
|
|
65
|
+
unarchiveEntry
|
|
63
66
|
} from './contentful-api-client';
|
|
64
67
|
import { convertSchema } from './contentful-schema-converter';
|
|
65
68
|
import {
|
|
@@ -809,6 +812,88 @@ export class ContentfulContentSource implements ContentSourceTypes.ContentSource
|
|
|
809
812
|
);
|
|
810
813
|
}
|
|
811
814
|
|
|
815
|
+
async unpublishDocuments({
|
|
816
|
+
documents,
|
|
817
|
+
assets,
|
|
818
|
+
userContext
|
|
819
|
+
}: {
|
|
820
|
+
documents: ContextualDocument[];
|
|
821
|
+
assets: ContextualAsset[];
|
|
822
|
+
userContext?: UserContext;
|
|
823
|
+
}): Promise<void> {
|
|
824
|
+
const apiClient = this.getPlainApiClientForUser({ userContext });
|
|
825
|
+
|
|
826
|
+
const entities = [...documents, ...assets];
|
|
827
|
+
// Max active bulk actions per space is limited to 5.
|
|
828
|
+
// Max of 200 items per bulk action.
|
|
829
|
+
const taskQueue = new TaskQueue({ limit: 5 });
|
|
830
|
+
const linkChunks: Link<'Entry' | 'Asset'>[][] = _.chunk(
|
|
831
|
+
entities.map((entity) => ({
|
|
832
|
+
sys: {
|
|
833
|
+
type: 'Link',
|
|
834
|
+
id: entity.id,
|
|
835
|
+
linkType: entity.type === 'document' ? 'Entry' : 'Asset'
|
|
836
|
+
}
|
|
837
|
+
})),
|
|
838
|
+
200
|
|
839
|
+
);
|
|
840
|
+
|
|
841
|
+
await Promise.all(
|
|
842
|
+
linkChunks.map((links) => {
|
|
843
|
+
return taskQueue.addTask(async (): Promise<void> => {
|
|
844
|
+
const bulkActionOptions = {
|
|
845
|
+
spaceId: this.spaceId,
|
|
846
|
+
environmentId: this.environment
|
|
847
|
+
};
|
|
848
|
+
const bulkActionCreateResult = await createUnpublishBulkAction(apiClient, bulkActionOptions, {
|
|
849
|
+
entities: {
|
|
850
|
+
sys: { type: 'Array' },
|
|
851
|
+
items: links
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
await waitBulkActionToComplete(bulkActionCreateResult, apiClient, bulkActionOptions);
|
|
855
|
+
});
|
|
856
|
+
})
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
async archiveDocument({ document, userContext }: { document: ContextualDocument; userContext?: UserContext }): Promise<void> {
|
|
861
|
+
this.logger.debug('archiveDocument');
|
|
862
|
+
const documentId = document.id;
|
|
863
|
+
try {
|
|
864
|
+
const entry = await fetchEntryById(this.plainClient, documentId);
|
|
865
|
+
const apiClient = this.getPlainApiClientForUser({ userContext });
|
|
866
|
+
// Contentful won't let us archive a published entry, so if the entry is
|
|
867
|
+
// published we must unpublish it first.
|
|
868
|
+
if (_.get(entry, 'sys.publishedVersion')) {
|
|
869
|
+
await unpublishEntry(apiClient, documentId);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
await archiveEntry(apiClient, documentId);
|
|
873
|
+
} catch (err) {
|
|
874
|
+
this.logger.error('Contentful: Failed to archive object', {
|
|
875
|
+
documentId: documentId,
|
|
876
|
+
error: err
|
|
877
|
+
});
|
|
878
|
+
throw err;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
async unarchiveDocument({ document, userContext }: { document: ContextualDocument; userContext?: UserContext }): Promise<void> {
|
|
883
|
+
this.logger.debug('unarchiveDocument');
|
|
884
|
+
const documentId = document.id;
|
|
885
|
+
try {
|
|
886
|
+
const apiClient = this.getPlainApiClientForUser({ userContext });
|
|
887
|
+
await unarchiveEntry(apiClient, documentId);
|
|
888
|
+
} catch (err) {
|
|
889
|
+
this.logger.error('Contentful: Failed to archive object', {
|
|
890
|
+
documentId: documentId,
|
|
891
|
+
error: err
|
|
892
|
+
});
|
|
893
|
+
throw err;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
812
897
|
async onWebhook({ data, headers }: { data: unknown; headers: Record<string, string> }) {
|
|
813
898
|
const topic = headers['x-contentful-topic'] || '';
|
|
814
899
|
const didContentTypeChange = topic.startsWith('ContentManagement.ContentType.');
|
|
@@ -234,9 +234,12 @@ function commonFields(
|
|
|
234
234
|
updatedBy?: string[];
|
|
235
235
|
} {
|
|
236
236
|
// currently we only expose isChanged that is treated as isDraft and isChanged because in Sanity there is no way to tell the difference
|
|
237
|
-
const
|
|
237
|
+
const isArchived = !!entity.sys?.archivedVersion;
|
|
238
|
+
const isPublished = !!entity.sys?.publishedVersion;
|
|
239
|
+
// unpublished and deleted appear the same in contentful's API response.
|
|
238
240
|
const isChanged = !!entity.sys?.publishedVersion && entity.sys?.version >= entity.sys?.publishedVersion + 2;
|
|
239
|
-
const status =
|
|
241
|
+
const status = isChanged ? 'modified' : isArchived ? 'archived' : isPublished ? 'published' : 'added'; // draft is the remaining possible status due to isArchived and isPublished being false.
|
|
242
|
+
|
|
240
243
|
const createdByEmail = getUserEmailById(entity.sys?.createdBy?.sys?.id, userMap);
|
|
241
244
|
const updatedByEmail = getUserEmailById(entity.sys?.updatedBy?.sys?.id, userMap);
|
|
242
245
|
const updatedByList = updatedByEmail ? [updatedByEmail] : [];
|