Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add resourceProvider methods [DANTE-1405] #2415

Merged
merged 7 commits into from
Aug 30, 2024
Merged
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
2 changes: 2 additions & 0 deletions lib/adapters/REST/endpoints/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import * as AccessToken from './access-token'
import * as PreviewApiKey from './preview-api-key'
import * as Release from './release'
import * as ReleaseAction from './release-action'
import * as ResourceProvider from './resource-provider'
import * as Role from './role'
import * as ScheduledAction from './scheduled-action'
import * as Snapshot from './snapshot'
Expand Down Expand Up @@ -94,6 +95,7 @@ export default {
PreviewApiKey,
Release,
ReleaseAction,
ResourceProvider,
Role,
ScheduledAction,
Snapshot,
Expand Down
35 changes: 35 additions & 0 deletions lib/adapters/REST/endpoints/resource-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { RawAxiosRequestHeaders } from 'axios'
import type { AxiosInstance } from 'contentful-sdk-core'
import * as raw from './raw'
import type { GetResourceProviderParams } from '../../../common-types'
import type { RestEndpoint } from '../types'
import type {
ResourceProviderProps,
UpsertResourceProviderProps,
} from '../../../entities/resource-provider'

const getBaseUrl = (params: GetResourceProviderParams) =>
`/organizations/${params.organizationId}/app_definitions/${params.appDefinitionId}/resource_provider`

export const get: RestEndpoint<'ResourceProvider', 'get'> = (
http: AxiosInstance,
params: GetResourceProviderParams
) => {
return raw.get<ResourceProviderProps>(http, getBaseUrl(params))
}

export const upsert: RestEndpoint<'ResourceProvider', 'upsert'> = (
http: AxiosInstance,
params: GetResourceProviderParams,
rawData: UpsertResourceProviderProps,
headers?: RawAxiosRequestHeaders
) => {
return raw.put<ResourceProviderProps>(http, getBaseUrl(params), rawData, { headers })
}

export const del: RestEndpoint<'ResourceProvider', 'delete'> = (
http: AxiosInstance,
params: GetResourceProviderParams
) => {
return raw.del(http, getBaseUrl(params))
}
20 changes: 20 additions & 0 deletions lib/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ import type { AppKeyProps, CreateAppKeyProps } from './entities/app-key'
import type { AppAccessTokenProps, CreateAppAccessTokenProps } from './entities/app-access-token'
import type { ConceptProps, CreateConceptProps } from './entities/concept'
import type { ConceptSchemeProps, CreateConceptSchemeProps } from './entities/concept-scheme'
import type {
ResourceProviderProps,
UpsertResourceProviderProps,
} from './entities/resource-provider'

export interface DefaultElements<TPlainObject extends object = object> {
toPlainObject(): TPlainObject
Expand Down Expand Up @@ -590,6 +594,10 @@ type MRInternal<UA extends boolean> = {
'queryForRelease'
>

(opts: MROpts<'ResourceProvider', 'get', UA>): MRReturn<'ResourceProvider', 'get'>
(opts: MROpts<'ResourceProvider', 'upsert', UA>): MRReturn<'ResourceProvider', 'upsert'>
(opts: MROpts<'ResourceProvider', 'delete', UA>): MRReturn<'ResourceProvider', 'delete'>

(opts: MROpts<'Role', 'get', UA>): MRReturn<'Role', 'get'>
(opts: MROpts<'Role', 'getMany', UA>): MRReturn<'Role', 'getMany'>
(opts: MROpts<'Role', 'getManyForOrganization', UA>): MRReturn<'Role', 'getManyForOrganization'>
Expand Down Expand Up @@ -762,6 +770,16 @@ export interface Adapter {
* @private
*/
export type MRActions = {
ResourceProvider: {
get: { params: GetResourceProviderParams; return: ResourceProviderProps }
upsert: {
params: GetResourceProviderParams
payload: UpsertResourceProviderProps
headers?: RawAxiosRequestHeaders
return: ResourceProviderProps
}
delete: { params: GetResourceProviderParams; return: any }
}
Http: {
get: { params: { url: string; config?: RawAxiosRequestConfig }; return: any }
patch: { params: { url: string; config?: RawAxiosRequestConfig }; payload: any; return: any }
Expand Down Expand Up @@ -2076,6 +2094,8 @@ export type GetWorkflowParams = GetSpaceEnvironmentParams & {
export type GetUIConfigParams = GetSpaceEnvironmentParams
export type GetUserUIConfigParams = GetUIConfigParams

export type GetResourceProviderParams = GetOrganizationParams & { appDefinitionId: string }

export type QueryParams = { query?: QueryOptions }
export type SpaceQueryParams = { query?: SpaceQueryOptions }
export type PaginationQueryParams = { query?: PaginationQueryOptions }
Expand Down
71 changes: 71 additions & 0 deletions lib/create-app-definition-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import entities from './entities'
import type { CreateAppBundleProps } from './entities/app-bundle'
import type { AppDefinitionProps } from './entities/app-definition'
import { wrapAppDefinition } from './entities/app-definition'
import type { UpsertResourceProviderProps } from './entities/resource-provider'

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

const getParams = (data: AppDefinitionProps) => ({
appDefinitionId: data.sys.id,
Expand Down Expand Up @@ -191,5 +193,74 @@ export default function createAppDefinitionApi(makeRequest: MakeRequest) {
},
})
},
/**
* Creates or updates a resource provider
* @param data representation of the ResourceProvider
* @return Promise for the newly created or updated ResourceProvider
* @example ```javascript
* const contentful = require('contentful-management')
* const client = contentful.createClient({
* accessToken: '<content_management_api_key>'
* })
*
* // You need a valid AppDefinition with an activated AppBundle that has a contentful function configured
* client.getOrganization('<org_id>')
* .then((org) => org.getAppDefinition('<app_def_id>'))
* .then((appDefinition) => appDefinition.upsertResourceProvider({
* sys: {
* id: '<resource_provider_id>'
* },
* type: 'function',
* function: {
* sys: {
* id: '<contentful_function_id>',
* type: 'Link'
* linkType: 'Function'
* }
* }
* }))
* .then((resourceProvider) => console.log(resourceProvider))
* .catch(console.error)
* ```
*/
upsertResourceProvider(data: UpsertResourceProviderProps) {
const raw = this.toPlainObject() as AppDefinitionProps
return makeRequest({
entityType: 'ResourceProvider',
action: 'upsert',
params: {
appDefinitionId: raw.sys.id,
organizationId: raw.sys.organization.sys.id,
},
payload: data,
}).then((payload) => wrapResourceProvider(makeRequest, payload))
},
/**
* Gets a Resource Provider
* @return Promise for a Resource Provider
* @example ```javascript
* const contentful = require('contentful-management')
* const client = contentful.createClient({
* accessToken: '<content_management_api_key>'
* })
*
* client.getOrganization('<org_id>')
* .then((org) => org.getAppDefinition('<app_def_id>'))
* .then((appDefinition) => appDefinition.getResourceProvider())
* .then((resourceProvider) => console.log(resourceProvider))
* .catch(console.error)
* ```
*/
getResourceProvider() {
mayakarabula marked this conversation as resolved.
Show resolved Hide resolved
const raw = this.toPlainObject() as AppDefinitionProps
return makeRequest({
entityType: 'ResourceProvider',
action: 'get',
params: {
appDefinitionId: raw.sys.id,
organizationId: raw.sys.organization.sys.id,
},
}).then((payload) => wrapResourceProvider(makeRequest, payload))
},
}
}
2 changes: 2 additions & 0 deletions lib/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import * as webhook from './webhook'
import * as workflowDefinition from './workflow-definition'
import * as concept from './concept'
import * as conceptScheme from './concept-scheme'
import * as resourceProvider from './resource-provider'

export default {
accessToken,
Expand Down Expand Up @@ -90,6 +91,7 @@ export default {
previewApiKey,
release,
releaseAction,
resourceProvider,
role,
scheduledAction,
snapshot,
Expand Down
133 changes: 133 additions & 0 deletions lib/entities/resource-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import type { BasicMetaSysProps, DefaultElements, MakeRequest, SysLink } from '../common-types'
import { toPlainObject, freezeSys } from 'contentful-sdk-core'
import copy from 'fast-copy'
import enhanceWithMethods from '../enhance-with-methods'

export type ResourceProviderProps = {
/**
* System metadata
*/
sys: Omit<BasicMetaSysProps, 'version'> & {
organization: SysLink
appDefinition: SysLink
}
/**
* Resource Provider type, value is 'function'
*/
type: 'function'
/**
* Link to a Contentful function
*/
function: SysLink
}

export type UpsertResourceProviderProps = Omit<ResourceProviderProps, 'sys'> & {
sys: { id: string }
}

export interface ResourceProvider
extends ResourceProviderProps,
DefaultElements<ResourceProviderProps> {
upsert(): Promise<ResourceProvider>
delete(): Promise<void>
}

/**
* @private
*/
function createResourceProviderApi(makeRequest: MakeRequest) {
return {
/**
* Sends an update to the server with any changes made to the object's properties
* @return Object returned from the server with updated changes.
* @example ```javascript
* const contentful = require('contentful-management')
*
* const client = contentful.createClient({
* accessToken: '<content_management_api_key>'
* })
*
* client.getOrganization('<org_id>')
* .then((org) => org.getAppDefinition('<app_def_id>'))
* .then((appDefinition) => appDefinition.getResourceProvider())
* .then((resourceProvider) => {
* resourceProvider.function.sys.id = '<new_contentful_function_id>'
* return resourceProvider.upsert()
* })
* .catch(console.error)
* ```
*/
upsert: function upsert() {
const data = this.toPlainObject() as ResourceProviderProps
return makeRequest({
entityType: 'ResourceProvider',
action: 'upsert',
params: getParams(data),
headers: {},
payload: getUpsertParams(data),
}).then((data) => wrapResourceProvider(makeRequest, data))
},
/**
* Deletes this object on the server.
* @return Promise for the deletion. It contains no data, but the Promise error case should be handled.
* @example ```javascript
* const contentful = require('contentful-management')
*
* const client = contentful.createClient({
* accessToken: '<content_management_api_key>'
* })
*
* client.getOrganization('<org_id>')
* .then((org) => org.getAppDefinition('<app_def_id>'))
* .then((appDefinition) => appDefinition.getResourceProvider())
* .then((resourceProvider) => resourceProvider.delete())
* .catch(console.error)
* ```
*/
delete: function del() {
const data = this.toPlainObject() as ResourceProviderProps
return makeRequest({
entityType: 'ResourceProvider',
action: 'delete',
params: getParams(data),
})
},
}
}
/**
* @private
* @param data - raw ResourceProvider Object
* @return Object containing the http params for the ResourceProvider request: organizationId and appDefinitionId
*/
const getParams = (data: ResourceProviderProps) => ({
organizationId: data.sys.organization.sys.id,
appDefinitionId: data.sys.appDefinition.sys.id,
})
/**
* @private
* @param data - raw ResourceProvider Object
* @return UpsertResourceProviderProps
*/
const getUpsertParams = (data: ResourceProviderProps): UpsertResourceProviderProps => ({
sys: { id: data.sys.id },
type: data.type,
function: data.function,
})

/**
* @private
* @param makeRequest - function to make requests via an adapter
* @param data - Raw Resource Provider data
* @return Wrapped Resource Provider data
*/
export function wrapResourceProvider(
makeRequest: MakeRequest,
data: ResourceProviderProps
): ResourceProvider {
const resourceProvider = toPlainObject(copy(data))
const ResourceProviderWithMethods = enhanceWithMethods(
resourceProvider,
createResourceProviderApi(makeRequest)
)
return freezeSys(ResourceProviderWithMethods)
}
5 changes: 5 additions & 0 deletions lib/export-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,8 @@ export type {
} from './entities/workflows-changelog-entry'
export type { ConceptProps, CreateConceptProps } from './entities/concept'
export type { ConceptSchemeProps, CreateConceptSchemeProps } from './entities/concept-scheme'
export type {
ResourceProvider,
ResourceProviderProps,
UpsertResourceProviderProps,
} from './entities/resource-provider'
2 changes: 2 additions & 0 deletions lib/plain/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ import type { TeamMembershipPlainClientAPI } from './entities/team-membership'
import type { AppAccessTokenPlainClientAPI } from './entities/app-access-token'
import type { ConceptPlainClientAPI } from './entities/concept'
import type { ConceptSchemePlainClientAPI } from './entities/concept-scheme'
import type { ResourceProviderPlainClientAPI } from './entities/resource-provider'

export type PlainClientAPI = {
raw: {
Expand Down Expand Up @@ -503,6 +504,7 @@ export type PlainClientAPI = {
}
appDefinition: AppDefinitionPlainClientAPI
appInstallation: AppInstallationPlainClientAPI
resourceProvider: ResourceProviderPlainClientAPI
extension: ExtensionPlainClientAPI
webhook: WebhookPlainClientAPI
snapshot: {
Expand Down
Loading