From 5330eaf3a5854cbe6eeccea0c1008370a82fb803 Mon Sep 17 00:00:00 2001 From: Michael Pham Date: Thu, 4 Sep 2025 09:28:24 -0600 Subject: [PATCH] feat: add release.entry.create method --- lib/adapters/REST/endpoints/release-entry.ts | 36 +++++++++++++++++++ lib/common-types.ts | 22 ++++++++++++ lib/plain/common-types.ts | 19 ++++++++++ lib/plain/plain-client.ts | 1 + .../REST/endpoints/release-entry.test.ts | 28 +++++++++++++++ 5 files changed, 106 insertions(+) diff --git a/lib/adapters/REST/endpoints/release-entry.ts b/lib/adapters/REST/endpoints/release-entry.ts index b54d9a7d3e..6aefa80b91 100644 --- a/lib/adapters/REST/endpoints/release-entry.ts +++ b/lib/adapters/REST/endpoints/release-entry.ts @@ -1,5 +1,6 @@ import type { AxiosInstance } from 'contentful-sdk-core' import type { + CreateReleaseEntryParams, GetReleaseEntryParams, GetManyReleaseEntryParams, KeyValueMap, @@ -95,6 +96,41 @@ export const patch: RestEndpoint<'ReleaseEntry', 'patch'> = = ( + http: AxiosInstance, + params: CreateReleaseEntryParams & QueryParams, + rawData: CreateEntryProps, + headers?: RawAxiosRequestHeaders +) => { + params.query = { ...params.query, 'sys.schemaVersion': 'Release.V2' } + const data = copy(rawData) + + return raw.post< + EntryProps< + T, + { + release: { + sys: { + type: 'Link' + linkType: 'Entry' | 'Asset' + id: string + } + } + } + > + >( + http, + `/spaces/${params.spaceId}/environments/${params.environmentId}/releases/${params.releaseId}/entries`, + data, + { + headers: { + 'X-Contentful-Content-Type': params.contentTypeId, + ...headers, + }, + } + ) +} + export const createWithId: RestEndpoint<'ReleaseEntry', 'createWithId'> = < T extends KeyValueMap = KeyValueMap >( diff --git a/lib/common-types.ts b/lib/common-types.ts index 9e0dbc4ab6..a28240cb1f 100644 --- a/lib/common-types.ts +++ b/lib/common-types.ts @@ -719,6 +719,7 @@ type MRInternal = { (opts: MROpts<'ReleaseEntry', 'getMany', UA>): MRReturn<'ReleaseEntry', 'getMany'> (opts: MROpts<'ReleaseEntry', 'update', UA>): MRReturn<'ReleaseEntry', 'update'> (opts: MROpts<'ReleaseEntry', 'patch', UA>): MRReturn<'ReleaseEntry', 'patch'> + (opts: MROpts<'ReleaseEntry', 'create', UA>): MRReturn<'ReleaseEntry', 'create'> (opts: MROpts<'ReleaseEntry', 'createWithId', UA>): MRReturn<'ReleaseEntry', 'createWithId'> (opts: MROpts<'Resource', 'getMany', UA>): MRReturn<'Resource', 'getMany'> @@ -1903,6 +1904,23 @@ export type MRActions = { } > } + create: { + params: CreateReleaseEntryParams + payload: CreateEntryProps + headers?: RawAxiosRequestHeaders + return: EntryProps< + any, + { + release: { + sys: { + type: 'Link' + linkType: 'Entry' | 'Asset' + id: string + } + } + } + > + } createWithId: { params: GetSpaceEnvironmentParams & { releaseId: string @@ -2425,6 +2443,10 @@ export type PatchReleaseEntryParams = GetSpaceEnvironmentParams & { entryId: string version: number } +export type CreateReleaseEntryParams = GetSpaceEnvironmentParams & { + releaseId: string + contentTypeId: string +} export type CreateWithIdReleaseEntryParams = GetSpaceEnvironmentParams & { releaseId: string entryId: string diff --git a/lib/plain/common-types.ts b/lib/plain/common-types.ts index ddb7e8a307..52aad02be4 100644 --- a/lib/plain/common-types.ts +++ b/lib/plain/common-types.ts @@ -3,6 +3,7 @@ import type { OpPatch } from 'json-patch' import type { BasicCursorPaginationOptions, CollectionProp, + CreateReleaseEntryParams, CreateWithIdReleaseEntryParams, CursorPaginatedCollectionProp, EnvironmentTemplateParams, @@ -543,6 +544,24 @@ export type PlainClientAPI = { } > > + create( + params: OptionalDefaults, + rawData: CreateEntryProps, + headers?: RawAxiosRequestHeaders + ): Promise< + EntryProps< + T, + { + release: { + sys: { + type: 'Link' + linkType: 'Entry' | 'Asset' + id: string + } + } + } + > + > createWithId( params: OptionalDefaults, rawData: CreateEntryProps, diff --git a/lib/plain/plain-client.ts b/lib/plain/plain-client.ts index 72c6952878..a05dcd6245 100644 --- a/lib/plain/plain-client.ts +++ b/lib/plain/plain-client.ts @@ -347,6 +347,7 @@ export const createPlainClient = ( getMany: wrap(wrapParams, 'ReleaseEntry', 'getMany'), update: wrap(wrapParams, 'ReleaseEntry', 'update'), patch: wrap(wrapParams, 'ReleaseEntry', 'patch'), + create: wrap(wrapParams, 'ReleaseEntry', 'create'), createWithId: wrap(wrapParams, 'ReleaseEntry', 'createWithId'), }, archive: wrap(wrapParams, 'Release', 'archive'), diff --git a/test/unit/adapters/REST/endpoints/release-entry.test.ts b/test/unit/adapters/REST/endpoints/release-entry.test.ts index 20a2b2c03a..b0ddb8b26e 100644 --- a/test/unit/adapters/REST/endpoints/release-entry.test.ts +++ b/test/unit/adapters/REST/endpoints/release-entry.test.ts @@ -109,6 +109,34 @@ describe('Rest ReleaseEntry', () => { }) }) + test('create', async () => { + const { httpMock, adapterMock, entityMock } = setup(Promise.resolve({})) + + httpMock.post.mockReturnValue(Promise.resolve({ data: entityMock })) + + return adapterMock + .makeRequest({ + entityType: 'ReleaseEntry', + action: 'create', + userAgent: 'mocked', + params: { + spaceId: 'space123', + environmentId: 'master', + releaseId: 'black-friday', + entryId: 'abc123', + contentTypeId: 'contentType123', + }, + payload: entityMock, + }) + .then((r) => { + expect(r).to.eql(entityMock) + expect(httpMock.post.mock.calls[0][0]).to.eql( + '/spaces/space123/environments/master/releases/black-friday/entries' + ) + expect(httpMock.post.mock.calls[0][1]).to.eql(entityMock) + }) + }) + test('createWithId', async () => { const { httpMock, adapterMock, entityMock } = setup(Promise.resolve({}))