Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions lib/adapters/REST/endpoints/bulk-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import type {
BulkActionPublishPayload,
BulkActionUnpublishPayload,
BulkActionValidatePayload,
PublishBulkActionV2Payload,
UnpublishBulkActionV2Payload,
ValidateBulkActionV2Payload,
} from '../../../entities/bulk-action'
import type { RestEndpoint } from '../types'
import * as raw from './raw'
Expand Down Expand Up @@ -54,3 +57,53 @@ export const validate: RestEndpoint<'BulkAction', 'validate'> = (
payload
)
}

export const getV2: RestEndpoint<'BulkAction', 'getV2'> = (
http: AxiosInstance,
params: GetBulkActionParams
) => {
return raw.get(
http,
`/spaces/${params.spaceId}/environments/${params.environmentId}/bulk_actions/${params.bulkActionId}`
)
}

export const publishV2: RestEndpoint<'BulkAction', 'publishV2'> = (
http: AxiosInstance,
params: GetSpaceEnvironmentParams,
payload: PublishBulkActionV2Payload<'add'>
): Promise<BulkActionProps<PublishBulkActionV2Payload<'add'>>> => {
return raw.post(
http,
`/spaces/${params.spaceId}/environments/${params.environmentId}/bulk_actions`,
payload
)
}

export const unpublishV2: RestEndpoint<'BulkAction', 'unpublishV2'> = (
http: AxiosInstance,
params: GetSpaceEnvironmentParams,
payload: PublishBulkActionV2Payload<'remove'> | UnpublishBulkActionV2Payload
): Promise<
BulkActionProps<PublishBulkActionV2Payload<'remove'> | UnpublishBulkActionV2Payload>
> => {
return raw.post(
http,
`/spaces/${params.spaceId}/environments/${params.environmentId}/bulk_actions`,
payload
)
}

export const validateV2: RestEndpoint<'BulkAction', 'validateV2'> = (
http: AxiosInstance,
params: GetSpaceEnvironmentParams,
payload: ValidateBulkActionV2Payload<'add'> | ValidateBulkActionV2Payload<'remove'>
): Promise<
BulkActionProps<ValidateBulkActionV2Payload<'add'> | ValidateBulkActionV2Payload<'remove'>>
> => {
return raw.post(
http,
`/spaces/${params.spaceId}/environments/${params.environmentId}/bulk_actions`,
payload
)
}
29 changes: 29 additions & 0 deletions lib/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ import type {
BulkActionProps,
BulkActionPublishPayload,
BulkActionUnpublishPayload,
BulkActionV2Payload,
BulkActionValidatePayload,
PublishBulkActionV2Payload,
UnpublishBulkActionV2Payload,
ValidateBulkActionV2Payload,
} from './entities/bulk-action'
import type {
CommentProps,
Expand Down Expand Up @@ -479,6 +483,10 @@ type MRInternal<UA extends boolean> = {
(opts: MROpts<'BulkAction', 'publish', UA>): MRReturn<'BulkAction', 'publish'>
(opts: MROpts<'BulkAction', 'unpublish', UA>): MRReturn<'BulkAction', 'unpublish'>
(opts: MROpts<'BulkAction', 'validate', UA>): MRReturn<'BulkAction', 'validate'>
(opts: MROpts<'BulkAction', 'getV2', UA>): MRReturn<'BulkAction', 'getV2'>
(opts: MROpts<'BulkAction', 'publishV2', UA>): MRReturn<'BulkAction', 'publishV2'>
(opts: MROpts<'BulkAction', 'unpublishV2', UA>): MRReturn<'BulkAction', 'unpublishV2'>
(opts: MROpts<'BulkAction', 'validateV2', UA>): MRReturn<'BulkAction', 'validateV2'>

(opts: MROpts<'Comment', 'get', UA>): MRReturn<'Comment', 'get'>
(opts: MROpts<'Comment', 'getMany', UA>): MRReturn<'Comment', 'getMany'>
Expand Down Expand Up @@ -1197,6 +1205,27 @@ export type MRActions = {
payload: BulkActionValidatePayload
return: BulkActionProps<BulkActionValidatePayload>
}
getV2: {
params: GetBulkActionParams
return: BulkActionProps<BulkActionV2Payload>
}
publishV2: {
params: GetSpaceEnvironmentParams
payload: PublishBulkActionV2Payload<'add'>
return: BulkActionProps<PublishBulkActionV2Payload<'add'>>
}
unpublishV2: {
params: GetSpaceEnvironmentParams
payload: PublishBulkActionV2Payload<'remove'> | UnpublishBulkActionV2Payload
return: BulkActionProps<PublishBulkActionV2Payload<'remove'> | UnpublishBulkActionV2Payload>
}
validateV2: {
params: GetSpaceEnvironmentParams
payload: ValidateBulkActionV2Payload<'add'> | ValidateBulkActionV2Payload<'remove'>
return: BulkActionProps<
ValidateBulkActionV2Payload<'add'> | ValidateBulkActionV2Payload<'remove'>
>
}
}
Comment: {
get:
Expand Down
53 changes: 48 additions & 5 deletions lib/entities/bulk-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,49 @@ export interface BulkActionPublishPayload extends MakeRequestPayload {
}
}

interface AddFieldsEntity<L extends Link<Entity> | VersionedLink<Entity>> {
entity: L
add?: {
fields: Record<'*', string[]>
}
}

interface RemoveFieldsEntity<L extends Link<Entity> | VersionedLink<Entity>> {
entity: L
remove?: {
fields: Record<'*', string[]>
}
}
type BulkActionEntity<L extends Link<Entity> | VersionedLink<Entity>> = {
entity: L
}

export interface PublishBulkActionV2Payload<PublishActionType extends 'add' | 'remove' = 'add'> {
action: 'publish'
entities: PublishActionType extends 'remove'
? RemoveFieldsEntity<VersionedLink<Entity>>[]
: AddFieldsEntity<VersionedLink<Entity>>[]
}

export interface ValidateBulkActionV2Payload<PublishActionType extends 'add' | 'remove' = 'add'> {
action: 'validate'
entities: PublishActionType extends 'remove'
? RemoveFieldsEntity<Link<Entity>>[]
: AddFieldsEntity<Link<Entity>>[]
}

export interface UnpublishBulkActionV2Payload {
action: 'unpublish'
entities: BulkActionEntity<Link<Entity>>[]
}

export type BulkActionV2Payload =
| PublishBulkActionV2Payload<'add'>
| PublishBulkActionV2Payload<'remove'>
| UnpublishBulkActionV2Payload
| ValidateBulkActionV2Payload<'add'>
| ValidateBulkActionV2Payload<'remove'>

export type BulkActionSysProps = {
id: string
type: 'BulkAction'
Expand All @@ -81,7 +124,7 @@ export type BulkActionSysProps = {
}

/** The object returned by the BulkActions API */
export interface BulkActionProps<TPayload extends BulkActionPayload = any> {
export interface BulkActionProps<TPayload extends BulkActionPayload | BulkActionV2Payload = any> {
sys: BulkActionSysProps
action: BulkActionType
/** original payload when BulkAction was created */
Expand Down Expand Up @@ -120,15 +163,15 @@ function createBulkActionApi(makeRequest: MakeRequest) {
params,
}).then((bulkAction) => wrapBulkAction(makeRequest, bulkAction))
},
async waitProcessing<TPayload extends BulkActionPayload = any>(
async waitProcessing<TPayload extends BulkActionPayload | BulkActionV2Payload = any>(
options?: AsyncActionProcessingOptions
): Promise<BulkActionProps<TPayload>> {
return pollAsyncActionStatus<BulkActionProps<TPayload>>(async () => this.get(), options)
},
}
}

export interface BulkAction<T extends BulkActionPayload = any>
export interface BulkAction<T extends BulkActionPayload | BulkActionV2Payload = any>
extends BulkActionProps<T>,
BulkActionApiMethods,
DefaultElements<BulkActionProps<T>> {}
Expand All @@ -139,9 +182,9 @@ export interface BulkAction<T extends BulkActionPayload = any>
* @param data - Raw BulkAction data
* @return Wrapped BulkAction data
*/
export function wrapBulkAction<TPayload extends BulkActionPayload = any>(
export function wrapBulkAction<TPayload extends BulkActionPayload | BulkActionV2Payload = any>(
makeRequest: MakeRequest,
data: BulkActionProps<BulkActionPayload>
data: BulkActionProps<BulkActionPayload | BulkActionV2Payload>
): BulkAction<TPayload> {
const bulkAction = toPlainObject(copy(data))
const bulkActionWithApiMethods = enhanceWithMethods(
Expand Down
4 changes: 4 additions & 0 deletions lib/export-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export type {
BulkActionType,
BulkActionUnpublishPayload,
BulkActionValidatePayload,
BulkActionV2Payload,
PublishBulkActionV2Payload,
UnpublishBulkActionV2Payload,
ValidateBulkActionV2Payload,
} from './entities/bulk-action'
export type {
Comment,
Expand Down
23 changes: 22 additions & 1 deletion lib/methods/bulk-action.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import type { BulkActionPayload, BulkActionProps } from '../entities/bulk-action'
import type {
BulkActionPayload,
BulkActionProps,
BulkActionV2Payload,
} from '../entities/bulk-action'
import type { PlainClientAPI } from '../plain/common-types'
import type { AsyncActionProcessingOptions } from './action'
import { pollAsyncActionStatus } from './action'
Expand Down Expand Up @@ -27,3 +31,20 @@ export async function waitForBulkActionProcessing<T extends BulkActionPayload =
options
)
}

/** Waits for a BulkAction V2 status to be either succeeded or failed.
* Used by the Plain client */
export async function waitForBulkActionV2Processing<T extends BulkActionV2Payload = any>(
{ plainClient, spaceId, environmentId, bulkActionId }: PlainOptions,
options?: AsyncActionProcessingOptions
): Promise<BulkActionProps<T>> {
return pollAsyncActionStatus<BulkActionProps>(
async () =>
plainClient.bulkAction.getV2({
bulkActionId,
spaceId,
environmentId,
}),
options
)
}
19 changes: 19 additions & 0 deletions lib/plain/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ import type {
BulkActionProps,
BulkActionPublishPayload,
BulkActionUnpublishPayload,
BulkActionV2Payload,
BulkActionValidatePayload,
PublishBulkActionV2Payload,
UnpublishBulkActionV2Payload,
ValidateBulkActionV2Payload,
} from '../entities/bulk-action'
import type { ContentTypeProps, CreateContentTypeProps } from '../entities/content-type'
import type { CreateEntryProps, EntryProps, EntryReferenceProps } from '../entities/entry'
Expand Down Expand Up @@ -226,6 +230,21 @@ export type PlainClientAPI = {
params: GetSpaceEnvironmentParams,
payload: BulkActionValidatePayload
): Promise<BulkActionProps<BulkActionValidatePayload>>
getV2(params: GetBulkActionParams): Promise<BulkActionProps<BulkActionV2Payload>>
publishV2(
params: GetSpaceEnvironmentParams,
payload: PublishBulkActionV2Payload<'add'>
): Promise<BulkActionProps<PublishBulkActionV2Payload<'add'>>>
unpublishV2(
params: GetSpaceEnvironmentParams,
payload: PublishBulkActionV2Payload<'remove'> | UnpublishBulkActionV2Payload
): Promise<BulkActionProps<PublishBulkActionV2Payload<'remove'> | UnpublishBulkActionV2Payload>>
validateV2(
params: GetSpaceEnvironmentParams,
payload: ValidateBulkActionV2Payload<'add'> | ValidateBulkActionV2Payload<'remove'>
): Promise<
BulkActionProps<ValidateBulkActionV2Payload<'add'> | ValidateBulkActionV2Payload<'remove'>>
>
}
comment: CommentPlainClientAPI
concept: ConceptPlainClientAPI
Expand Down
4 changes: 4 additions & 0 deletions lib/plain/plain-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ export const createPlainClient = (
publish: wrap(wrapParams, 'BulkAction', 'publish'),
unpublish: wrap(wrapParams, 'BulkAction', 'unpublish'),
validate: wrap(wrapParams, 'BulkAction', 'validate'),
getV2: wrap(wrapParams, 'BulkAction', 'getV2'),
publishV2: wrap(wrapParams, 'BulkAction', 'publishV2'),
unpublishV2: wrap(wrapParams, 'BulkAction', 'unpublishV2'),
validateV2: wrap(wrapParams, 'BulkAction', 'validateV2'),
},
comment: {
get: wrap(wrapParams, 'Comment', 'get') as PlainClientAPI['comment']['get'],
Expand Down
92 changes: 90 additions & 2 deletions test/integration/bulk-action-integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@ import type {
BulkActionPublishPayload,
BulkActionUnpublishPayload,
BulkActionValidatePayload,
UnpublishBulkActionV2Payload,
} from '../../lib/contentful-management'
import type { Environment, Space } from '../../lib/contentful-management'
import { waitForBulkActionProcessing } from '../../lib/methods/bulk-action'
import {
waitForBulkActionProcessing,
waitForBulkActionV2Processing,
} from '../../lib/methods/bulk-action'
import { TestDefaults } from '../defaults'
import { getDefaultSpace, initPlainClient, timeoutToCalmRateLimiting } from '../helpers'
import { makeLink, makeVersionedLink } from '../utils'
import {
PublishBulkActionV2Payload,
ValidateBulkActionV2Payload,
} from '../../lib/entities/bulk-action'

describe('BulkActions Api', () => {
describe('BulkActions Api v1', () => {
let testSpace: Space
let testEnvironment: Environment

Expand Down Expand Up @@ -257,3 +265,83 @@ describe('BulkActions Api', () => {
})
})
})

describe('BulkActions Api v2 (Plain Client only)', () => {
afterAll(timeoutToCalmRateLimiting)

const defaultParams = {
environmentId: TestDefaults.environmentId,
spaceId: TestDefaults.spaceId,
}
const plainClient = initPlainClient(defaultParams)

it('bulkAction.publishV2', async () => {
const entry = await plainClient.entry.get({ entryId: TestDefaults.entry.testEntryBulkActionId })

const bulkActionInProgress = await plainClient.bulkAction.publishV2(defaultParams, {
action: 'publish',
entities: [
{
entity: makeVersionedLink('Entry', entry.sys.id, entry.sys.version),
add: { fields: { '*': ['en-US'] } },
},
],
})

const bulkActionCompleted = await waitForBulkActionV2Processing<
PublishBulkActionV2Payload<'add'>
>({
...defaultParams,
plainClient,
bulkActionId: bulkActionInProgress.sys.id,
})

expect(bulkActionCompleted.sys.status).toBe('succeeded')
expect(bulkActionCompleted.action).toBe('publish')
})

it('bulkAction.unpublishV2', async () => {
const entry = await plainClient.entry.get({ entryId: TestDefaults.entry.testEntryBulkActionId })

const bulkActionInProgress = await plainClient.bulkAction.unpublishV2(defaultParams, {
action: 'unpublish',
entities: [
{
entity: makeLink('Entry', entry.sys.id),
},
],
})

const bulkActionCompleted = await waitForBulkActionV2Processing<UnpublishBulkActionV2Payload>({
...defaultParams,
plainClient,
bulkActionId: bulkActionInProgress.sys.id,
})

expect(bulkActionCompleted.sys.status).toBe('succeeded')
expect(bulkActionCompleted.action).toBe('unpublish')
})

it('bulkAction.validateV2', async () => {
const entry = await plainClient.entry.get({ entryId: TestDefaults.entry.testEntryBulkActionId })

const bulkActionInProgress = await plainClient.bulkAction.validateV2(defaultParams, {
action: 'validate',
entities: [
{
entity: makeLink('Entry', entry.sys.id),
add: { fields: { '*': ['en-US'] } },
},
],
})

const bulkActionCompleted = await waitForBulkActionV2Processing<ValidateBulkActionV2Payload>({
...defaultParams,
plainClient,
bulkActionId: bulkActionInProgress.sys.id,
})

expect(bulkActionCompleted.sys.status).toBe('succeeded')
expect(bulkActionCompleted.action).toBe('validate')
})
})