Skip to content

Commit 8fa9399

Browse files
feat: add Resource Type to contentful-management [DANTE-1832] (#2429)
* feat: add Resource Type to contentful-management [DANTE-1832] * feat: add tests * feat: add getMany and orgId to ResourceType APIs * fix: unit test * fix: remove resource type id in test * feat: update comments, add more tests * fix: wait 1s after deletion * fix: remove type id from getMany * feat: clean up urls * fix: types * fix: remove empty headers --------- Co-authored-by: Marouen Ben Salem <[email protected]>
1 parent 0b42925 commit 8fa9399

File tree

16 files changed

+916
-6
lines changed

16 files changed

+916
-6
lines changed

lib/adapters/REST/endpoints/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import * as PreviewApiKey from './preview-api-key'
3636
import * as Release from './release'
3737
import * as ReleaseAction from './release-action'
3838
import * as ResourceProvider from './resource-provider'
39+
import * as ResourceType from './resource-type'
3940
import * as Role from './role'
4041
import * as ScheduledAction from './scheduled-action'
4142
import * as Snapshot from './snapshot'
@@ -96,6 +97,7 @@ export default {
9697
Release,
9798
ReleaseAction,
9899
ResourceProvider,
100+
ResourceType,
99101
Role,
100102
ScheduledAction,
101103
Snapshot,
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { RawAxiosRequestHeaders } from 'axios'
2+
import type { AxiosInstance } from 'contentful-sdk-core'
3+
import * as raw from './raw'
4+
import copy from 'fast-copy'
5+
import type { CollectionProp } from '../../../common-types'
6+
import { type GetResourceTypeParams } from '../../../common-types'
7+
import type { RestEndpoint } from '../types'
8+
import type { ResourceTypeProps, UpsertResourceTypeProps } from '../../../entities/resource-type'
9+
10+
const getBaseUrl = (
11+
params: GetResourceTypeParams | Omit<GetResourceTypeParams, 'resourceTypeId'>
12+
) =>
13+
`/organizations/${params.organizationId}/app_definitions/${params.appDefinitionId}/resource_provider/resource_types`
14+
15+
const getEntityUrl = (params: GetResourceTypeParams) =>
16+
`${getBaseUrl(params)}/${params.resourceTypeId}`
17+
18+
export const get: RestEndpoint<'ResourceType', 'get'> = (
19+
http: AxiosInstance,
20+
params: GetResourceTypeParams
21+
) => {
22+
return raw.get<ResourceTypeProps>(http, getEntityUrl(params))
23+
}
24+
25+
export const upsert: RestEndpoint<'ResourceType', 'upsert'> = (
26+
http: AxiosInstance,
27+
params: GetResourceTypeParams,
28+
rawData: UpsertResourceTypeProps,
29+
headers?: RawAxiosRequestHeaders
30+
) => {
31+
const data = copy(rawData)
32+
33+
return raw.put<ResourceTypeProps>(http, getEntityUrl(params), data, { headers })
34+
}
35+
36+
export const del: RestEndpoint<'ResourceType', 'delete'> = (
37+
http: AxiosInstance,
38+
params: GetResourceTypeParams
39+
) => {
40+
return raw.del(http, getEntityUrl(params))
41+
}
42+
43+
export const getMany: RestEndpoint<'ResourceType', 'getMany'> = (
44+
http: AxiosInstance,
45+
params: Omit<GetResourceTypeParams, 'resourceTypeId'>
46+
) => {
47+
return raw.get<CollectionProp<ResourceTypeProps>>(http, getBaseUrl(params))
48+
}

lib/common-types.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ import type {
165165
ResourceProviderProps,
166166
UpsertResourceProviderProps,
167167
} from './entities/resource-provider'
168+
import type { ResourceTypeProps, UpsertResourceTypeProps } from './entities/resource-type'
168169

169170
export interface DefaultElements<TPlainObject extends object = object> {
170171
toPlainObject(): TPlainObject
@@ -598,6 +599,11 @@ type MRInternal<UA extends boolean> = {
598599
(opts: MROpts<'ResourceProvider', 'upsert', UA>): MRReturn<'ResourceProvider', 'upsert'>
599600
(opts: MROpts<'ResourceProvider', 'delete', UA>): MRReturn<'ResourceProvider', 'delete'>
600601

602+
(opts: MROpts<'ResourceType', 'get', UA>): MRReturn<'ResourceType', 'get'>
603+
(opts: MROpts<'ResourceType', 'upsert', UA>): MRReturn<'ResourceType', 'upsert'>
604+
(opts: MROpts<'ResourceType', 'delete', UA>): MRReturn<'ResourceType', 'delete'>
605+
(opts: MROpts<'ResourceType', 'getMany', UA>): MRReturn<'ResourceType', 'getMany'>
606+
601607
(opts: MROpts<'Role', 'get', UA>): MRReturn<'Role', 'get'>
602608
(opts: MROpts<'Role', 'getMany', UA>): MRReturn<'Role', 'getMany'>
603609
(opts: MROpts<'Role', 'getManyForOrganization', UA>): MRReturn<'Role', 'getManyForOrganization'>
@@ -780,6 +786,20 @@ export type MRActions = {
780786
}
781787
delete: { params: GetResourceProviderParams; return: any }
782788
}
789+
ResourceType: {
790+
get: { params: GetResourceTypeParams; return: ResourceTypeProps }
791+
getMany: {
792+
params: Omit<GetResourceTypeParams, 'resourceTypeId'>
793+
return: CollectionProp<ResourceTypeProps>
794+
}
795+
upsert: {
796+
params: GetResourceTypeParams
797+
payload: UpsertResourceTypeProps
798+
headers?: RawAxiosRequestHeaders
799+
return: ResourceTypeProps
800+
}
801+
delete: { params: GetResourceTypeParams; return: any }
802+
}
783803
Http: {
784804
get: { params: { url: string; config?: RawAxiosRequestConfig }; return: any }
785805
patch: { params: { url: string; config?: RawAxiosRequestConfig }; payload: any; return: any }
@@ -2096,6 +2116,8 @@ export type GetUserUIConfigParams = GetUIConfigParams
20962116

20972117
export type GetResourceProviderParams = GetOrganizationParams & { appDefinitionId: string }
20982118

2119+
export type GetResourceTypeParams = GetResourceProviderParams & { resourceTypeId: string }
2120+
20992121
export type QueryParams = { query?: QueryOptions }
21002122
export type SpaceQueryParams = { query?: SpaceQueryOptions }
21012123
export type PaginationQueryParams = { query?: PaginationQueryOptions }

lib/entities/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import * as workflowDefinition from './workflow-definition'
5353
import * as concept from './concept'
5454
import * as conceptScheme from './concept-scheme'
5555
import * as resourceProvider from './resource-provider'
56+
import * as resourceType from './resource-type'
5657

5758
export default {
5859
accessToken,
@@ -92,6 +93,7 @@ export default {
9293
release,
9394
releaseAction,
9495
resourceProvider,
96+
resourceType,
9597
role,
9698
scheduledAction,
9799
snapshot,

lib/entities/resource-provider.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
import type { BasicMetaSysProps, DefaultElements, MakeRequest, SysLink } from '../common-types'
1+
import type {
2+
BasicMetaSysProps,
3+
CollectionProp,
4+
DefaultElements,
5+
MakeRequest,
6+
SysLink,
7+
} from '../common-types'
28
import { toPlainObject, freezeSys } from 'contentful-sdk-core'
39
import copy from 'fast-copy'
410
import enhanceWithMethods from '../enhance-with-methods'
11+
import type { ResourceType, UpsertResourceTypeProps } from './resource-type'
12+
import entities from '.'
513

614
export type ResourceProviderProps = {
715
/**
@@ -30,12 +38,17 @@ export interface ResourceProvider
3038
DefaultElements<ResourceProviderProps> {
3139
upsert(): Promise<ResourceProvider>
3240
delete(): Promise<void>
41+
upsertResourceType(id: string, data: UpsertResourceTypeProps): Promise<ResourceType>
42+
getResourceType(id: string): Promise<ResourceType>
43+
getResourceTypes(): Promise<CollectionProp<ResourceType>>
3344
}
3445

3546
/**
3647
* @private
3748
*/
3849
function createResourceProviderApi(makeRequest: MakeRequest) {
50+
const { wrapResourceType } = entities.resourceType
51+
3952
return {
4053
/**
4154
* Sends an update to the server with any changes made to the object's properties
@@ -92,6 +105,43 @@ function createResourceProviderApi(makeRequest: MakeRequest) {
92105
params: getParams(data),
93106
})
94107
},
108+
109+
getResourceType: function getResourceType(id: string) {
110+
return makeRequest({
111+
entityType: 'ResourceType',
112+
action: 'get',
113+
params: {
114+
organizationId: this.sys.organization.sys.id,
115+
appDefinitionId: this.sys.appDefinition.sys.id,
116+
resourceTypeId: id,
117+
},
118+
}).then((data) => wrapResourceType(makeRequest, data))
119+
},
120+
upsertResourceType: function upsertResourceType(id: string, data: UpsertResourceTypeProps) {
121+
return makeRequest({
122+
entityType: 'ResourceType',
123+
action: 'upsert',
124+
params: {
125+
organizationId: this.sys.organization.sys.id,
126+
appDefinitionId: this.sys.appDefinition.sys.id,
127+
resourceTypeId: id,
128+
},
129+
payload: data,
130+
}).then((data) => wrapResourceType(makeRequest, data))
131+
},
132+
getResourceTypes: function getResourceTypes() {
133+
return makeRequest({
134+
entityType: 'ResourceType',
135+
action: 'getMany',
136+
params: {
137+
organizationId: this.sys.organization.sys.id,
138+
appDefinitionId: this.sys.appDefinition.sys.id,
139+
},
140+
}).then((data) => {
141+
data.items = data.items.map((item) => wrapResourceType(makeRequest, item))
142+
return data as CollectionProp<ResourceType>
143+
})
144+
},
95145
}
96146
}
97147
/**

lib/entities/resource-type.ts

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import type {
2+
BasicMetaSysProps,
3+
DefaultElements,
4+
GetResourceTypeParams,
5+
MakeRequest,
6+
SysLink,
7+
} from '../common-types'
8+
import { toPlainObject, freezeSys } from 'contentful-sdk-core'
9+
import copy from 'fast-copy'
10+
import enhanceWithMethods from '../enhance-with-methods'
11+
12+
export type ResourceTypeProps = {
13+
/**
14+
* System metadata
15+
*/
16+
sys: Omit<BasicMetaSysProps, 'version'> & {
17+
appDefinition: SysLink
18+
organization: SysLink
19+
resourceProvider: SysLink
20+
}
21+
/**
22+
* Resource Type name
23+
*/
24+
name: string
25+
/**
26+
* Resource Type defaultFieldMapping
27+
*/
28+
defaultFieldMapping: {
29+
title: string
30+
subtitle?: string
31+
description?: string
32+
externalUrl?: string
33+
image?: {
34+
url: string
35+
altText?: string
36+
}
37+
badge?: {
38+
label: string
39+
variant: string
40+
}
41+
}
42+
}
43+
44+
export type UpsertResourceTypeProps = Omit<ResourceTypeProps, 'sys'>
45+
46+
export interface ResourceType extends ResourceTypeProps, DefaultElements<ResourceTypeProps> {
47+
upsert(): Promise<ResourceType>
48+
delete(): Promise<void>
49+
}
50+
51+
/**
52+
* @private
53+
*/
54+
function createResourceTypeApi(makeRequest: MakeRequest) {
55+
return {
56+
/**
57+
* Sends an update to the server with any changes made to the object's properties
58+
* @return Object returned from the server with updated changes.
59+
* @example ```javascript
60+
* const contentful = require('contentful-management')
61+
*
62+
* const client = contentful.createClient({
63+
* accessToken: '<content_management_api_key>'
64+
* })
65+
*
66+
* client.getOrganization('<org_id>')
67+
* .then((org) => org.getAppDefinition('<app_def_id>'))
68+
* .then((appDefinition) => appDefinition.getResourceType())
69+
* .then((resourceType) => {
70+
* resourceType.name = '<new_name>'
71+
* return resourceType.upsert()
72+
* })
73+
* .catch(console.error)
74+
* ```
75+
*/
76+
upsert: function upsert() {
77+
const data = this.toPlainObject() as ResourceTypeProps
78+
79+
return makeRequest({
80+
entityType: 'ResourceType',
81+
action: 'upsert',
82+
params: getParams(data),
83+
headers: {},
84+
payload: getUpsertParams(data),
85+
}).then((data) => wrapResourceType(makeRequest, data))
86+
},
87+
/**
88+
* Deletes this object on the server.
89+
* @return Promise for the deletion. It contains no data, but the Promise error case should be handled.
90+
* @example ```javascript
91+
* const contentful = require('contentful-management')
92+
*
93+
* const client = contentful.createClient({
94+
* accessToken: '<content_management_api_key>'
95+
* })
96+
*
97+
* client.getOrganization('<org_id>')
98+
* .then((org) => org.getAppDefinition('<app_def_id>'))
99+
* .then((appDefinition) => appDefinition.getResourceType())
100+
* .then((resourceType) => resourceType.delete())
101+
* .catch(console.error)
102+
* ```
103+
*/
104+
delete: function del() {
105+
const data = this.toPlainObject() as ResourceTypeProps
106+
107+
return makeRequest({
108+
entityType: 'ResourceType',
109+
action: 'delete',
110+
params: getParams(data),
111+
})
112+
},
113+
}
114+
}
115+
116+
const getParams = (data: ResourceTypeProps): GetResourceTypeParams => ({
117+
organizationId: data.sys.organization.sys.id,
118+
appDefinitionId: data.sys.appDefinition.sys.id,
119+
resourceTypeId: data.sys.id,
120+
})
121+
122+
const getUpsertParams = (data: ResourceTypeProps): UpsertResourceTypeProps => ({
123+
name: data.name,
124+
defaultFieldMapping: data.defaultFieldMapping,
125+
})
126+
127+
/**
128+
* @private
129+
* @param makeRequest - function to make requests via an adapter
130+
* @param data - Raw Resource Type data
131+
* @return Wrapped Resource Type data
132+
*/
133+
export function wrapResourceType(makeRequest: MakeRequest, data: ResourceTypeProps): ResourceType {
134+
const resourceType = toPlainObject(copy(data))
135+
const ResourceTypeWithMethods = enhanceWithMethods(
136+
resourceType,
137+
createResourceTypeApi(makeRequest)
138+
)
139+
return freezeSys(ResourceTypeWithMethods)
140+
}

lib/export-types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,8 @@ export type {
287287
ResourceProviderProps,
288288
UpsertResourceProviderProps,
289289
} from './entities/resource-provider'
290+
export type {
291+
ResourceType,
292+
ResourceTypeProps,
293+
UpsertResourceTypeProps,
294+
} from './entities/resource-type'

lib/plain/common-types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ import type { AppAccessTokenPlainClientAPI } from './entities/app-access-token'
114114
import type { ConceptPlainClientAPI } from './entities/concept'
115115
import type { ConceptSchemePlainClientAPI } from './entities/concept-scheme'
116116
import type { ResourceProviderPlainClientAPI } from './entities/resource-provider'
117+
import type { ResourceTypePlainClientAPI } from './entities/resource-type'
117118

118119
export type PlainClientAPI = {
119120
raw: {
@@ -505,6 +506,7 @@ export type PlainClientAPI = {
505506
appDefinition: AppDefinitionPlainClientAPI
506507
appInstallation: AppInstallationPlainClientAPI
507508
resourceProvider: ResourceProviderPlainClientAPI
509+
resourceType: ResourceTypePlainClientAPI
508510
extension: ExtensionPlainClientAPI
509511
webhook: WebhookPlainClientAPI
510512
snapshot: {

0 commit comments

Comments
 (0)