Skip to content

Commit

Permalink
feat: add function logs
Browse files Browse the repository at this point in the history
- Added function log entity and plain client
- Added unit tests for function log
- Added js docstrings
  • Loading branch information
michaelpineirocontentful committed Jan 22, 2025
1 parent 0486089 commit 9bf52a4
Show file tree
Hide file tree
Showing 12 changed files with 426 additions and 0 deletions.
41 changes: 41 additions & 0 deletions lib/adapters/REST/endpoints/function-log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { AxiosInstance } from 'contentful-sdk-core'
import * as raw from './raw'
import type {
CollectionProp,
GetFunctionLogParams,
GetAllFunctionLogParams,
} from '../../../common-types'
import type { RestEndpoint } from '../types'
import type { FunctionLogProps } from '../../../entities/function-log'

const FunctionLogAlphaHeaders = {
'x-contentful-enable-alpha-feature': 'function-logs',
}

const baseURL = (params: GetAllFunctionLogParams) =>
`/spaces/${params.spaceId}/environments/${params.environmentId}/app_installations/${params.appInstallationId}/functions/${params.functionId}/logs`

const getURL = (params: GetFunctionLogParams) =>
`/spaces/${params.spaceId}/environments/${params.environmentId}/app_installations/${params.appInstallationId}/functions/${params.functionId}/logs/${params.logId}`

export const get: RestEndpoint<'FunctionLog', 'get'> = (
http: AxiosInstance,
params: GetFunctionLogParams
) => {
return raw.get<FunctionLogProps>(http, getURL(params), {
headers: {
...FunctionLogAlphaHeaders,
},
})
}

export const getAll: RestEndpoint<'FunctionLog', 'getAll'> = (
http: AxiosInstance,
params: GetAllFunctionLogParams
) => {
return raw.get<CollectionProp<FunctionLogProps>>(http, baseURL(params), {
headers: {
...FunctionLogAlphaHeaders,
},
})
}
2 changes: 2 additions & 0 deletions lib/adapters/REST/endpoints/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import * as EnvironmentTemplate from './environment-template'
import * as EnvironmentTemplateInstallation from './environment-template-installation'
import * as Extension from './extension'
import * as Function from './function'
import * as FunctionLog from './function-log'
import * as Http from './http'
import * as Locale from './locale'
import * as Organization from './organization'
Expand Down Expand Up @@ -90,6 +91,7 @@ export default {
EnvironmentTemplateInstallation,
Extension,
Function,
FunctionLog,
Http,
Locale,
Organization,
Expand Down
22 changes: 22 additions & 0 deletions lib/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ import type {
WorkflowsChangelogEntryProps,
WorkflowsChangelogQueryOptions,
} from './entities/workflows-changelog-entry'
import type { FunctionLogProps } from './entities/function-log'

export interface DefaultElements<TPlainObject extends object = object> {
toPlainObject(): TPlainObject
Expand Down Expand Up @@ -560,6 +561,9 @@ type MRInternal<UA extends boolean> = {
'getManyForEnvironment'
>

(opts: MROpts<'FunctionLog', 'get', UA>): MRReturn<'FunctionLog', 'get'>
(opts: MROpts<'FunctionLog', 'getAll', UA>): MRReturn<'FunctionLog', 'getAll'>

(opts: MROpts<'Locale', 'get', UA>): MRReturn<'Locale', 'get'>
(opts: MROpts<'Locale', 'getMany', UA>): MRReturn<'Locale', 'getMany'>
(opts: MROpts<'Locale', 'delete', UA>): MRReturn<'Locale', 'delete'>
Expand Down Expand Up @@ -1556,6 +1560,20 @@ export type MRActions = {
return: CollectionProp<FunctionProps>
}
}

FunctionLog: {
get: {
params: GetFunctionLogParams
return: FunctionLogProps
headers?: RawAxiosRequestHeaders
}
getAll: {
params: GetAllFunctionLogParams
return: CollectionProp<FunctionLogProps>
headers?: RawAxiosRequestHeaders
}
}

Locale: {
get: { params: GetSpaceEnvironmentParams & { localeId: string }; return: LocaleProps }
getMany: {
Expand Down Expand Up @@ -2154,6 +2172,10 @@ export type GetManyFunctionParams = GetAppDefinitionParams
export type GetFunctionForEnvParams = GetSpaceEnvironmentParams & {
appInstallationId: string
}
export type GetAllFunctionLogParams = GetFunctionForEnvParams & {
functionId: string
}
export type GetFunctionLogParams = GetAllFunctionLogParams & { logId: string }
export type GetOrganizationParams = { organizationId: string }
export type GetReleaseParams = GetSpaceEnvironmentParams & { releaseId: string }
export type GetSnapshotForContentTypeParams = GetSpaceEnvironmentParams & { contentTypeId: string }
Expand Down
97 changes: 97 additions & 0 deletions lib/create-function-log-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { MakeRequest } from './common-types'
import entities from './entities'
import type { FunctionLogProps } from './entities/function-log'
import { wrapFunctionLogCollection } from './entities/function-log'

/**
* @private
*/
export type ContentfulFunctionLogApi = ReturnType<typeof createFunctionLogApi>

/**
* @private
*/
export default function createFunctionLogApi(makeRequest: MakeRequest) {
const { wrapFunctionLog } = entities.functionLog

return {
/**
* Get a FunctionLog by it's log ID
* @Param spaceId - Space ID
* @Param environmentId - Environment ID
* @Param appInstallationId - App Installation ID
* @Param functionId - Function ID
* @Param logId - Log ID
* @returns a function log
* ```javascript
* const contentful = require('contentful-management')
*
* const client = contentful.createClient({
* accessToken: '<content_management_api_key>'
* })
*
* client.functionLog.get({
* spaceId: '<space_id>',
* environmentId: '<environment_id>',
* appInstallationId: '<app_installation_id>',
* functionId: '<function_id>',
* logId: '<log_id>'
* })
* .then((response) => console.log(response.items))
* .catch(console.error)
* ```
*/
get(logId: string) {
const raw = this.toPlainObject() as FunctionLogProps
return makeRequest({
entityType: 'FunctionLog',
action: 'get',
params: {
spaceId: raw.sys.space.sys.id,
environmentId: raw.sys.environment.sys.id,
appInstallationId: raw.sys.appDefinition.sys.id,
functionId: raw.sys.id,
logId: logId,
},
}).then((data) => wrapFunctionLog(makeRequest, data))
},

/**
* Get all FunctionLogs
* @Param spaceId - Space ID
* @Param environmentId - Environment ID
* @Param appInstallationId - App Installation ID
* @Param functionId - Function ID
* @returns a collection of FunctionLogs
* ```javascript
* const contentful = require('contentful-management')
*
* const client = contentful.createClient({
* accessToken: '<content_management_api_key>'
* })
*
* client.functionLog.getAll({
* spaceId: '<space_id>',
* environmentId: '<environment_id>',
* appInstallationId: '<app_installation_id>',
* functionId: '<function_id>'
* })
* .then((response) => console.log(response.items))
* .catch(console.error)
* ```
*/
getAll() {
const raw = this.toPlainObject() as FunctionLogProps
return makeRequest({
entityType: 'FunctionLog',
action: 'getAll',
params: {
spaceId: raw.sys.space.sys.id,
environmentId: raw.sys.environment.sys.id,
appInstallationId: raw.sys.appDefinition.sys.id,
functionId: raw.sys.id,
},
}).then((data) => wrapFunctionLogCollection(makeRequest, data))
},
}
}
63 changes: 63 additions & 0 deletions lib/entities/function-log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { Link, DefaultElements } from '../common-types'
import { freezeSys, toPlainObject } from 'contentful-sdk-core'
import copy from 'fast-copy'
import { wrapCollection } from '../common-utils'
import type { MakeRequest } from '../common-types'
import enhanceWithMethods from '../enhance-with-methods'
import createFunctionLogApi from '../create-function-log-api'

export type FunctionLogProps = {
sys: {
id: string
type: 'FunctionLog'
createdBy: Link<'User'> // Only users can CRUD
createdAt: string
space: Link<'Space'>
environment: Link<'Environment'>
appDefinition: Link<'AppDefinition'>
}
severity: {
info: number
warn: number
error: number
}
requestId: string
event: {
type: string
query: string
isIntrospectionQuery: boolean
variables: Record<string, any>
}
messages: Array<{
timestamp: number
type: 'INFO' | 'ERROR' | 'WARN'
message: string
}>
}

export interface FunctionLog extends FunctionLogProps, DefaultElements<FunctionLogProps> {}

/**
* @private
* @param makeRequest - function to make requests via an adapter
* @param data - raw contentful-Function data
* @return Wrapped Function data
*/
export function wrapFunctionLog(
makeRequest: MakeRequest,
data: FunctionLogProps
): FunctionLogProps & ReturnType<typeof createFunctionLogApi> {
const appAction = toPlainObject(copy(data))

const appActionWithMethods = enhanceWithMethods(appAction, createFunctionLogApi(makeRequest))

return freezeSys(appActionWithMethods)
}

/**
* @private
* @param makeRequest - function to make requests via an adapter
* @param data - raw contentful-function data
* @return Wrapped App Function collection data
*/
export const wrapFunctionLogCollection = wrapCollection(wrapFunctionLog)
2 changes: 2 additions & 0 deletions lib/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import * as environmentTemplate from './environment-template'
import * as environmentTemplateInstallation from './environment-template-installation'
import * as extension from './extension'
import * as func from './function'
import * as functionLog from './function-log'
import * as locale from './locale'
import * as organization from './organization'
import * as organizationInvitation from './organization-invitation'
Expand Down Expand Up @@ -87,6 +88,7 @@ export default {
environmentTemplateInstallation,
extension,
func,
functionLog,
locale,
organization,
organizationInvitation,
Expand Down
2 changes: 2 additions & 0 deletions lib/plain/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import type { WorkflowPlainClientAPI } from './entities/workflow'
import type { WorkflowDefinitionPlainClientAPI } from './entities/workflow-definition'
import type { WorkflowsChangelogPlainClientAPI } from './entities/workflows-changelog'
import type { DefaultParams, OptionalDefaults } from './wrappers/wrap'
import type { FunctionLogPlainClientAPI } from './entities/function-log'

export type PlainClientAPI = {
raw: {
Expand All @@ -137,6 +138,7 @@ export type PlainClientAPI = {
appSigningSecret: AppSigningSecretPlainClientAPI
appAccessToken: AppAccessTokenPlainClientAPI
function: FunctionPlainClientAPI
functionLog: FunctionLogPlainClientAPI
editorInterface: EditorInterfacePlainClientAPI
space: SpacePlainClientAPI
environment: EnvironmentPlainClientAPI
Expand Down
46 changes: 46 additions & 0 deletions lib/plain/entities/function-log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type {
CollectionProp,
GetFunctionLogParams,
GetAllFunctionLogParams,
} from '../../common-types'
import type { FunctionLogProps } from '../../entities/function-log'
import type { OptionalDefaults } from '../wrappers/wrap'

export type FunctionLogPlainClientAPI = {
/**
* Fetches the specified FunctionLog
* @param params - spaceId, environmentId, appInstallationId, functionId, logId
* @returns the FunctionLog
* @throws if the request fails, or the FunctionLog is not found
* @example
* ```javascript
* const functionLog = await client.functionLog.get({
* spaceId: '<space_id>',
* environmentId: '<environment_id>',
* appInstallationId: '<app_installation_id>',
* functionId: '<function_id>',
* logId: '<log_id>'
* });
* ```
*/
get(params: OptionalDefaults<GetFunctionLogParams>): Promise<FunctionLogProps>

/**
* Fetches all FunctionLogs for the given function
* @param params - spaceId, environmentId, appInstallationId, functionId
* @returns an object containing an array of FunctionLogs
* @throws if the request fails, or the FunctionLogs are not found
* @example
* ```javascript
* const functionLogs = await client.functionLog.getAll({
* spaceId: '<space_id>',
* environmentId: '<environment_id>',
* appInstallationId: '<app_installation_id>',
* functionId: '<function_id>'
* });
* ```
*/
getAll(
params: OptionalDefaults<GetAllFunctionLogParams>
): Promise<CollectionProp<FunctionLogProps>>
}
4 changes: 4 additions & 0 deletions lib/plain/plain-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ export const createPlainClient = (
getMany: wrap(wrapParams, 'Function', 'getMany'),
getManyForEnvironment: wrap(wrapParams, 'Function', 'getManyForEnvironment'),
},
functionLog: {
get: wrap(wrapParams, 'FunctionLog', 'get'),
getAll: wrap(wrapParams, 'FunctionLog', 'getAll'),
},
editorInterface: {
get: wrap(wrapParams, 'EditorInterface', 'get'),
getMany: wrap(wrapParams, 'EditorInterface', 'getMany'),
Expand Down
Loading

0 comments on commit 9bf52a4

Please sign in to comment.