Skip to content

Commit d0b5247

Browse files
feat: add resourceProvider methods [DANTE-1405] (#2415)
* feat: first draft of the resourceProvider methods * fix: add function repo to the app build * feat: add resourceProvider methods to the legacy client * feat: add resourceProvider methods to the plain client * test: resourceProvider methods test * test: adding unit tests --------- Co-authored-by: Cyberxon <[email protected]>
1 parent 6cbd7a4 commit d0b5247

File tree

16 files changed

+717
-0
lines changed

16 files changed

+717
-0
lines changed

lib/adapters/REST/endpoints/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import * as AccessToken from './access-token'
3535
import * as PreviewApiKey from './preview-api-key'
3636
import * as Release from './release'
3737
import * as ReleaseAction from './release-action'
38+
import * as ResourceProvider from './resource-provider'
3839
import * as Role from './role'
3940
import * as ScheduledAction from './scheduled-action'
4041
import * as Snapshot from './snapshot'
@@ -94,6 +95,7 @@ export default {
9495
PreviewApiKey,
9596
Release,
9697
ReleaseAction,
98+
ResourceProvider,
9799
Role,
98100
ScheduledAction,
99101
Snapshot,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type { RawAxiosRequestHeaders } from 'axios'
2+
import type { AxiosInstance } from 'contentful-sdk-core'
3+
import * as raw from './raw'
4+
import type { GetResourceProviderParams } from '../../../common-types'
5+
import type { RestEndpoint } from '../types'
6+
import type {
7+
ResourceProviderProps,
8+
UpsertResourceProviderProps,
9+
} from '../../../entities/resource-provider'
10+
11+
const getBaseUrl = (params: GetResourceProviderParams) =>
12+
`/organizations/${params.organizationId}/app_definitions/${params.appDefinitionId}/resource_provider`
13+
14+
export const get: RestEndpoint<'ResourceProvider', 'get'> = (
15+
http: AxiosInstance,
16+
params: GetResourceProviderParams
17+
) => {
18+
return raw.get<ResourceProviderProps>(http, getBaseUrl(params))
19+
}
20+
21+
export const upsert: RestEndpoint<'ResourceProvider', 'upsert'> = (
22+
http: AxiosInstance,
23+
params: GetResourceProviderParams,
24+
rawData: UpsertResourceProviderProps,
25+
headers?: RawAxiosRequestHeaders
26+
) => {
27+
return raw.put<ResourceProviderProps>(http, getBaseUrl(params), rawData, { headers })
28+
}
29+
30+
export const del: RestEndpoint<'ResourceProvider', 'delete'> = (
31+
http: AxiosInstance,
32+
params: GetResourceProviderParams
33+
) => {
34+
return raw.del(http, getBaseUrl(params))
35+
}

lib/common-types.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ import type { AppKeyProps, CreateAppKeyProps } from './entities/app-key'
161161
import type { AppAccessTokenProps, CreateAppAccessTokenProps } from './entities/app-access-token'
162162
import type { ConceptProps, CreateConceptProps } from './entities/concept'
163163
import type { ConceptSchemeProps, CreateConceptSchemeProps } from './entities/concept-scheme'
164+
import type {
165+
ResourceProviderProps,
166+
UpsertResourceProviderProps,
167+
} from './entities/resource-provider'
164168

165169
export interface DefaultElements<TPlainObject extends object = object> {
166170
toPlainObject(): TPlainObject
@@ -590,6 +594,10 @@ type MRInternal<UA extends boolean> = {
590594
'queryForRelease'
591595
>
592596

597+
(opts: MROpts<'ResourceProvider', 'get', UA>): MRReturn<'ResourceProvider', 'get'>
598+
(opts: MROpts<'ResourceProvider', 'upsert', UA>): MRReturn<'ResourceProvider', 'upsert'>
599+
(opts: MROpts<'ResourceProvider', 'delete', UA>): MRReturn<'ResourceProvider', 'delete'>
600+
593601
(opts: MROpts<'Role', 'get', UA>): MRReturn<'Role', 'get'>
594602
(opts: MROpts<'Role', 'getMany', UA>): MRReturn<'Role', 'getMany'>
595603
(opts: MROpts<'Role', 'getManyForOrganization', UA>): MRReturn<'Role', 'getManyForOrganization'>
@@ -762,6 +770,16 @@ export interface Adapter {
762770
* @private
763771
*/
764772
export type MRActions = {
773+
ResourceProvider: {
774+
get: { params: GetResourceProviderParams; return: ResourceProviderProps }
775+
upsert: {
776+
params: GetResourceProviderParams
777+
payload: UpsertResourceProviderProps
778+
headers?: RawAxiosRequestHeaders
779+
return: ResourceProviderProps
780+
}
781+
delete: { params: GetResourceProviderParams; return: any }
782+
}
765783
Http: {
766784
get: { params: { url: string; config?: RawAxiosRequestConfig }; return: any }
767785
patch: { params: { url: string; config?: RawAxiosRequestConfig }; payload: any; return: any }
@@ -2076,6 +2094,8 @@ export type GetWorkflowParams = GetSpaceEnvironmentParams & {
20762094
export type GetUIConfigParams = GetSpaceEnvironmentParams
20772095
export type GetUserUIConfigParams = GetUIConfigParams
20782096

2097+
export type GetResourceProviderParams = GetOrganizationParams & { appDefinitionId: string }
2098+
20792099
export type QueryParams = { query?: QueryOptions }
20802100
export type SpaceQueryParams = { query?: SpaceQueryOptions }
20812101
export type PaginationQueryParams = { query?: PaginationQueryOptions }

lib/create-app-definition-api.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import entities from './entities'
33
import type { CreateAppBundleProps } from './entities/app-bundle'
44
import type { AppDefinitionProps } from './entities/app-definition'
55
import { wrapAppDefinition } from './entities/app-definition'
6+
import type { UpsertResourceProviderProps } from './entities/resource-provider'
67

78
/**
89
* @private
@@ -14,6 +15,7 @@ export type ContentfulAppDefinitionAPI = ReturnType<typeof createAppDefinitionAp
1415
*/
1516
export default function createAppDefinitionApi(makeRequest: MakeRequest) {
1617
const { wrapAppBundle, wrapAppBundleCollection } = entities.appBundle
18+
const { wrapResourceProvider } = entities.resourceProvider
1719

1820
const getParams = (data: AppDefinitionProps) => ({
1921
appDefinitionId: data.sys.id,
@@ -191,5 +193,74 @@ export default function createAppDefinitionApi(makeRequest: MakeRequest) {
191193
},
192194
})
193195
},
196+
/**
197+
* Creates or updates a resource provider
198+
* @param data representation of the ResourceProvider
199+
* @return Promise for the newly created or updated ResourceProvider
200+
* @example ```javascript
201+
* const contentful = require('contentful-management')
202+
* const client = contentful.createClient({
203+
* accessToken: '<content_management_api_key>'
204+
* })
205+
*
206+
* // You need a valid AppDefinition with an activated AppBundle that has a contentful function configured
207+
* client.getOrganization('<org_id>')
208+
* .then((org) => org.getAppDefinition('<app_def_id>'))
209+
* .then((appDefinition) => appDefinition.upsertResourceProvider({
210+
* sys: {
211+
* id: '<resource_provider_id>'
212+
* },
213+
* type: 'function',
214+
* function: {
215+
* sys: {
216+
* id: '<contentful_function_id>',
217+
* type: 'Link'
218+
* linkType: 'Function'
219+
* }
220+
* }
221+
* }))
222+
* .then((resourceProvider) => console.log(resourceProvider))
223+
* .catch(console.error)
224+
* ```
225+
*/
226+
upsertResourceProvider(data: UpsertResourceProviderProps) {
227+
const raw = this.toPlainObject() as AppDefinitionProps
228+
return makeRequest({
229+
entityType: 'ResourceProvider',
230+
action: 'upsert',
231+
params: {
232+
appDefinitionId: raw.sys.id,
233+
organizationId: raw.sys.organization.sys.id,
234+
},
235+
payload: data,
236+
}).then((payload) => wrapResourceProvider(makeRequest, payload))
237+
},
238+
/**
239+
* Gets a Resource Provider
240+
* @return Promise for a Resource Provider
241+
* @example ```javascript
242+
* const contentful = require('contentful-management')
243+
* const client = contentful.createClient({
244+
* accessToken: '<content_management_api_key>'
245+
* })
246+
*
247+
* client.getOrganization('<org_id>')
248+
* .then((org) => org.getAppDefinition('<app_def_id>'))
249+
* .then((appDefinition) => appDefinition.getResourceProvider())
250+
* .then((resourceProvider) => console.log(resourceProvider))
251+
* .catch(console.error)
252+
* ```
253+
*/
254+
getResourceProvider() {
255+
const raw = this.toPlainObject() as AppDefinitionProps
256+
return makeRequest({
257+
entityType: 'ResourceProvider',
258+
action: 'get',
259+
params: {
260+
appDefinitionId: raw.sys.id,
261+
organizationId: raw.sys.organization.sys.id,
262+
},
263+
}).then((payload) => wrapResourceProvider(makeRequest, payload))
264+
},
194265
}
195266
}

lib/entities/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import * as webhook from './webhook'
5252
import * as workflowDefinition from './workflow-definition'
5353
import * as concept from './concept'
5454
import * as conceptScheme from './concept-scheme'
55+
import * as resourceProvider from './resource-provider'
5556

5657
export default {
5758
accessToken,
@@ -90,6 +91,7 @@ export default {
9091
previewApiKey,
9192
release,
9293
releaseAction,
94+
resourceProvider,
9395
role,
9496
scheduledAction,
9597
snapshot,

lib/entities/resource-provider.ts

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

lib/export-types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,3 +282,8 @@ export type {
282282
} from './entities/workflows-changelog-entry'
283283
export type { ConceptProps, CreateConceptProps } from './entities/concept'
284284
export type { ConceptSchemeProps, CreateConceptSchemeProps } from './entities/concept-scheme'
285+
export type {
286+
ResourceProvider,
287+
ResourceProviderProps,
288+
UpsertResourceProviderProps,
289+
} from './entities/resource-provider'

lib/plain/common-types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ import type { TeamMembershipPlainClientAPI } from './entities/team-membership'
113113
import type { AppAccessTokenPlainClientAPI } from './entities/app-access-token'
114114
import type { ConceptPlainClientAPI } from './entities/concept'
115115
import type { ConceptSchemePlainClientAPI } from './entities/concept-scheme'
116+
import type { ResourceProviderPlainClientAPI } from './entities/resource-provider'
116117

117118
export type PlainClientAPI = {
118119
raw: {
@@ -503,6 +504,7 @@ export type PlainClientAPI = {
503504
}
504505
appDefinition: AppDefinitionPlainClientAPI
505506
appInstallation: AppInstallationPlainClientAPI
507+
resourceProvider: ResourceProviderPlainClientAPI
506508
extension: ExtensionPlainClientAPI
507509
webhook: WebhookPlainClientAPI
508510
snapshot: {

0 commit comments

Comments
 (0)