Skip to content

Commit e9b189d

Browse files
michaelphamcfclaudetylerpina
authored
feat: add Fragment getMany and get methods [DX-927] (#3000)
* feat: scaffold Fragment entity types and GetFragmentParams [DX-926] Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat: add Fragment getMany and get methods [DX-927] Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: add publish and unpublish MRInternal overloads for Fragment MRActions already defined publish and unpublish for Fragment, and the plain client wires both via wrap() — but the MRInternal overload block was missing them, leaving the overload resolution incomplete. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Tyler Pina <tyler.pina@contentful.com>
1 parent 1fe012b commit e9b189d

8 files changed

Lines changed: 375 additions & 1 deletion

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { RawAxiosRequestHeaders } from 'axios'
2+
import type { AxiosInstance } from 'contentful-sdk-core'
3+
import type {
4+
CursorPaginatedCollectionProp,
5+
GetFragmentParams,
6+
GetSpaceEnvironmentParams,
7+
} from '../../../common-types'
8+
import type { FragmentProps, FragmentQueryOptions } from '../../../entities/fragment'
9+
import type { RestEndpoint } from '../types'
10+
import * as raw from './raw'
11+
12+
const getBaseUrl = (params: GetSpaceEnvironmentParams) =>
13+
`/spaces/${params.spaceId}/environments/${params.environmentId}/fragments`
14+
15+
export const getMany: RestEndpoint<'Fragment', 'getMany'> = (
16+
http: AxiosInstance,
17+
params: GetSpaceEnvironmentParams & { query: FragmentQueryOptions },
18+
headers?: RawAxiosRequestHeaders,
19+
) => {
20+
return raw.get<CursorPaginatedCollectionProp<FragmentProps>>(http, getBaseUrl(params), {
21+
params: params.query,
22+
headers,
23+
})
24+
}
25+
26+
export const get: RestEndpoint<'Fragment', 'get'> = (
27+
http: AxiosInstance,
28+
params: GetFragmentParams,
29+
headers?: RawAxiosRequestHeaders,
30+
) => {
31+
return raw.get<FragmentProps>(http, getBaseUrl(params) + `/${params.fragmentId}`, { headers })
32+
}

lib/adapters/REST/endpoints/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import * as EnvironmentAlias from './environment-alias'
3434
import * as EnvironmentTemplate from './environment-template'
3535
import * as EnvironmentTemplateInstallation from './environment-template-installation'
3636
import * as Extension from './extension'
37+
import * as Fragment from './fragment'
3738
import * as Function from './function'
3839
import * as FunctionLog from './function-log'
3940
import * as Http from './http'
@@ -118,6 +119,7 @@ export default {
118119
EnvironmentTemplate,
119120
EnvironmentTemplateInstallation,
120121
Extension,
122+
Fragment,
121123
Function,
122124
FunctionLog,
123125
Http,

lib/common-types.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ import type {
6666
CreateComponentTypeProps,
6767
UpdateComponentTypeProps,
6868
} from './entities/component-type'
69+
import type {
70+
CreateFragmentProps,
71+
FragmentProps,
72+
FragmentQueryOptions,
73+
UpdateFragmentProps,
74+
} from './entities/fragment'
6975
import type {
7076
CreateTemplateProps,
7177
TemplateProps,
@@ -957,6 +963,14 @@ type MRInternal<UA extends boolean> = {
957963
(opts: MROpts<'TeamSpaceMembership', 'update', UA>): MRReturn<'TeamSpaceMembership', 'update'>
958964
(opts: MROpts<'TeamSpaceMembership', 'delete', UA>): MRReturn<'TeamSpaceMembership', 'delete'>
959965

966+
(opts: MROpts<'Fragment', 'getMany', UA>): MRReturn<'Fragment', 'getMany'>
967+
(opts: MROpts<'Fragment', 'get', UA>): MRReturn<'Fragment', 'get'>
968+
(opts: MROpts<'Fragment', 'create', UA>): MRReturn<'Fragment', 'create'>
969+
(opts: MROpts<'Fragment', 'update', UA>): MRReturn<'Fragment', 'update'>
970+
(opts: MROpts<'Fragment', 'delete', UA>): MRReturn<'Fragment', 'delete'>
971+
(opts: MROpts<'Fragment', 'publish', UA>): MRReturn<'Fragment', 'publish'>
972+
(opts: MROpts<'Fragment', 'unpublish', UA>): MRReturn<'Fragment', 'unpublish'>
973+
960974
(opts: MROpts<'Template', 'getMany', UA>): MRReturn<'Template', 'getMany'>
961975
(opts: MROpts<'Template', 'get', UA>): MRReturn<'Template', 'get'>
962976
(opts: MROpts<'Template', 'create', UA>): MRReturn<'Template', 'create'>
@@ -2643,6 +2657,38 @@ export type MRActions = {
26432657
}
26442658
delete: { params: GetTeamSpaceMembershipParams; return: any }
26452659
}
2660+
Fragment: {
2661+
getMany: {
2662+
params: GetSpaceEnvironmentParams & { query: FragmentQueryOptions }
2663+
return: CursorPaginatedCollectionProp<FragmentProps>
2664+
}
2665+
get: {
2666+
params: GetFragmentParams
2667+
return: FragmentProps
2668+
}
2669+
create: {
2670+
params: GetSpaceEnvironmentParams
2671+
payload: CreateFragmentProps
2672+
return: FragmentProps
2673+
}
2674+
update: {
2675+
params: GetFragmentParams
2676+
payload: UpdateFragmentProps
2677+
return: FragmentProps
2678+
}
2679+
delete: {
2680+
params: GetFragmentParams
2681+
return: void
2682+
}
2683+
publish: {
2684+
params: GetFragmentParams & { version: number }
2685+
return: FragmentProps
2686+
}
2687+
unpublish: {
2688+
params: GetFragmentParams & { version: number }
2689+
return: FragmentProps
2690+
}
2691+
}
26462692
Template: {
26472693
getMany: {
26482694
params: GetSpaceEnvironmentParams & { query: TemplateQueryOptions }

lib/entities/fragment.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
ComponentTypeViewport,
1010
DimensionedDesignPropertyValue,
1111
FragmentNode,
12+
TreeNode,
1213
} from './component-type'
1314
import type {
1415
ExperienceContentBindings,
@@ -50,7 +51,7 @@ export type FragmentProps = {
5051
dimensionKeyMap: ExperienceDimensionKeyMap
5152
contentBindings?: ExperienceContentBindings
5253
metadata?: ExoMetadataProps
53-
slots?: Record<string, Array<FragmentNode | InlineFragmentNode>>
54+
slots?: Record<string, Array<TreeNode | FragmentNode | InlineFragmentNode>>
5455
}
5556

5657
export type CreateFragmentProps = Except<FragmentProps, 'sys'> & {

lib/plain/entities/fragment.ts

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import type {
2+
CursorPaginatedCollectionProp,
3+
GetFragmentParams,
4+
GetSpaceEnvironmentParams,
5+
} from '../../common-types'
6+
import type {
7+
CreateFragmentProps,
8+
FragmentProps,
9+
FragmentQueryOptions,
10+
UpdateFragmentProps,
11+
} from '../../entities/fragment'
12+
import type { OptionalDefaults } from '../wrappers/wrap'
13+
14+
export type FragmentPlainClientAPI = {
15+
/**
16+
* Fetches all fragments for a space and environment
17+
* @param params the space, environment IDs and query options (see {@link FragmentQueryOptions})
18+
* @returns a collection of fragments
19+
* @throws if the request fails, or the space or environment is not found
20+
* @internal - Experimental endpoint, subject to breaking changes without notice
21+
* @example
22+
* ```javascript
23+
* const fragments = await client.fragment.getMany({
24+
* spaceId: '<space_id>',
25+
* environmentId: '<environment_id>',
26+
* query: {
27+
* limit: 10,
28+
* },
29+
* });
30+
* ```
31+
*/
32+
getMany(
33+
params: OptionalDefaults<GetSpaceEnvironmentParams & { query: FragmentQueryOptions }>,
34+
): Promise<CursorPaginatedCollectionProp<FragmentProps>>
35+
36+
/**
37+
* Fetches a single fragment by ID
38+
* @param params the space, environment, and fragment IDs
39+
* @returns the fragment
40+
* @throws if the request fails, or the space, environment, or fragment is not found
41+
* @internal - Experimental endpoint, subject to breaking changes without notice
42+
* @example
43+
* ```javascript
44+
* const fragment = await client.fragment.get({
45+
* spaceId: '<space_id>',
46+
* environmentId: '<environment_id>',
47+
* fragmentId: '<fragment_id>',
48+
* });
49+
* ```
50+
*/
51+
get(params: OptionalDefaults<GetFragmentParams>): Promise<FragmentProps>
52+
53+
/**
54+
* Creates a new fragment
55+
* @param params the space and environment IDs
56+
* @param data the fragment data
57+
* @returns the created fragment
58+
* @throws if the request fails, or the space or environment is not found
59+
* @internal - Experimental endpoint, subject to breaking changes without notice
60+
* @example
61+
* ```javascript
62+
* const fragment = await client.fragment.create({
63+
* spaceId: '<space_id>',
64+
* environmentId: '<environment_id>',
65+
* }, {
66+
* name: 'My Fragment',
67+
* description: 'A new fragment',
68+
* componentTypeId: '<component_type_id>',
69+
* viewports: [],
70+
* designProperties: {},
71+
* dimensionKeyMap: { designProperties: {} },
72+
* });
73+
* ```
74+
*/
75+
create(
76+
params: OptionalDefaults<GetSpaceEnvironmentParams>,
77+
data: CreateFragmentProps,
78+
): Promise<FragmentProps>
79+
80+
/**
81+
* Updates a fragment
82+
* @param params the space, environment, and fragment IDs
83+
* @param data the fragment data (including sys.version)
84+
* @returns the updated fragment
85+
* @throws if the request fails, or the space, environment, or fragment is not found
86+
* @internal - Experimental endpoint, subject to breaking changes without notice
87+
* @example
88+
* ```javascript
89+
* const fragment = await client.fragment.update({
90+
* spaceId: '<space_id>',
91+
* environmentId: '<environment_id>',
92+
* fragmentId: '<fragment_id>',
93+
* }, fragmentData);
94+
* ```
95+
*/
96+
update(
97+
params: OptionalDefaults<GetFragmentParams>,
98+
data: UpdateFragmentProps,
99+
): Promise<FragmentProps>
100+
101+
/**
102+
* Deletes a fragment
103+
* @param params the space, environment, and fragment IDs
104+
* @throws if the request fails, or the space, environment, or fragment is not found
105+
* @internal - Experimental endpoint, subject to breaking changes without notice
106+
* @example
107+
* ```javascript
108+
* await client.fragment.delete({
109+
* spaceId: '<space_id>',
110+
* environmentId: '<environment_id>',
111+
* fragmentId: '<fragment_id>',
112+
* });
113+
* ```
114+
*/
115+
delete(params: OptionalDefaults<GetFragmentParams>): Promise<void>
116+
117+
/**
118+
* Publishes a fragment
119+
* @param params the space, environment, and fragment IDs, plus the current version
120+
* @returns the published fragment
121+
* @throws if the request fails, or the space, environment, or fragment is not found
122+
* @internal - Experimental endpoint, subject to breaking changes without notice
123+
* @example
124+
* ```javascript
125+
* const fragment = await client.fragment.publish({
126+
* spaceId: '<space_id>',
127+
* environmentId: '<environment_id>',
128+
* fragmentId: '<fragment_id>',
129+
* version: 1,
130+
* });
131+
* ```
132+
*/
133+
publish(params: OptionalDefaults<GetFragmentParams & { version: number }>): Promise<FragmentProps>
134+
135+
/**
136+
* Unpublishes a fragment
137+
* @param params the space, environment, and fragment IDs, plus the current version
138+
* @returns the unpublished fragment
139+
* @throws if the request fails, or the space, environment, or fragment is not found
140+
* @internal - Experimental endpoint, subject to breaking changes without notice
141+
* @example
142+
* ```javascript
143+
* const fragment = await client.fragment.unpublish({
144+
* spaceId: '<space_id>',
145+
* environmentId: '<environment_id>',
146+
* fragmentId: '<fragment_id>',
147+
* version: 2,
148+
* });
149+
* ```
150+
*/
151+
unpublish(
152+
params: OptionalDefaults<GetFragmentParams & { version: number }>,
153+
): Promise<FragmentProps>
154+
}

lib/plain/plain-client-types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ import type { TaskPlainClientAPI } from './entities/task'
125125
import type { TeamPlainClientAPI } from './entities/team'
126126
import type { TeamMembershipPlainClientAPI } from './entities/team-membership'
127127
import type { TeamSpaceMembershipPlainClientAPI } from './entities/team-space-membership'
128+
import type { FragmentPlainClientAPI } from './entities/fragment'
128129
import type { TemplatePlainClientAPI } from './entities/template'
129130
import type { UIConfigPlainClientAPI } from './entities/ui-config'
130131
import type { UploadPlainClientAPI } from './entities/upload'
@@ -730,6 +731,7 @@ export type PlainClientAPI = {
730731
team: TeamPlainClientAPI
731732
teamMembership: TeamMembershipPlainClientAPI
732733
teamSpaceMembership: TeamSpaceMembershipPlainClientAPI
734+
fragment: FragmentPlainClientAPI
733735
template: TemplatePlainClientAPI
734736
uiConfig: UIConfigPlainClientAPI
735737
userUIConfig: UserUIConfigPlainClientAPI

lib/plain/plain-client.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,15 @@ export const createPlainClient = (
627627
update: wrap(wrapParams, 'TeamSpaceMembership', 'update'),
628628
delete: wrap(wrapParams, 'TeamSpaceMembership', 'delete'),
629629
},
630+
fragment: {
631+
getMany: wrap(wrapParams, 'Fragment', 'getMany'),
632+
get: wrap(wrapParams, 'Fragment', 'get'),
633+
create: wrap(wrapParams, 'Fragment', 'create'),
634+
update: wrap(wrapParams, 'Fragment', 'update'),
635+
delete: wrap(wrapParams, 'Fragment', 'delete'),
636+
publish: wrap(wrapParams, 'Fragment', 'publish'),
637+
unpublish: wrap(wrapParams, 'Fragment', 'unpublish'),
638+
},
630639
template: {
631640
getMany: wrap(wrapParams, 'Template', 'getMany'),
632641
get: wrap(wrapParams, 'Template', 'get'),

0 commit comments

Comments
 (0)