-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add types for deliveryFunction implementation (#316)
- Loading branch information
1 parent
006f82f
commit b807a25
Showing
6 changed files
with
191 additions
and
124 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { PlainClientAPI } from 'contentful-management' | ||
|
||
export type AppActionCallContext = { | ||
cma: PlainClientAPI | ||
appActionCallContext: { | ||
spaceId: string | ||
environmentId: string | ||
appInstallationId: string | ||
userId: string | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Remove when this eslint rule covers all the cases | ||
// https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/ROADMAP.md | ||
/*eslint-disable no-unused-vars*/ | ||
|
||
export enum DeliveryFunctionRequestEventType { | ||
GRAPHQL_FIELD_MAPPING = 'graphql.field.mapping', | ||
GRAPHQL_QUERY = 'graphql.query', | ||
} | ||
|
||
export type GraphQLFieldTypeMappingRequest = { | ||
fields: { contentTypeId: string; field: Field }[] | ||
} | ||
|
||
type Field = { | ||
id: string | ||
type: string | ||
} | ||
|
||
export type GraphQLFieldTypeMappingResponse = GraphQLFieldTypeMapping[] | ||
|
||
export type GraphQLFieldTypeMapping = { | ||
contentTypeId: string | ||
fieldId: string | ||
graphQLOutputType: string | ||
graphQLQueryField: string | ||
graphQLQueryArgument: string | ||
} | ||
|
||
export type GraphQLQueryRequest = { | ||
query: string | ||
variables: Record<string, unknown> | ||
operationName?: string | ||
} | ||
|
||
/** | ||
* @see https://spec.graphql.org/October2021/#sec-Response | ||
*/ | ||
export type GraphQLQueryResponse = { | ||
data?: Record<string, any> | null | ||
errors?: readonly Record<string, any>[] | ||
extensions?: Record<string, unknown> | ||
} | ||
|
||
/** | ||
* P: Possibility to type app installation parameters | ||
*/ | ||
export type DeliveryFunctionEventContext<P extends Record<string, any> = Record<string, any>> = { | ||
spaceId: string | ||
environmentId: string | ||
appInstallationParameters: P | ||
} | ||
|
||
export type DeliveryFunctionEventHandlers = { | ||
[DeliveryFunctionRequestEventType.GRAPHQL_FIELD_MAPPING]: ( | ||
event: GraphQLFieldTypeMappingRequest, | ||
context: DeliveryFunctionEventContext | ||
) => Promise<GraphQLFieldTypeMappingResponse> | ||
[DeliveryFunctionRequestEventType.GRAPHQL_QUERY]: ( | ||
event: GraphQLQueryRequest, | ||
context: DeliveryFunctionEventContext | ||
) => Promise<GraphQLQueryResponse> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './appAction' | ||
export * from './deliveryFunction' | ||
export * from './request' | ||
export * from './validators' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Remove when this eslint rule covers all the cases | ||
// https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/ROADMAP.md | ||
/*eslint-disable no-unused-vars*/ | ||
import { CanonicalRequest } from './validators' | ||
|
||
export enum ContentfulHeader { | ||
Timestamp = 'x-contentful-timestamp', | ||
SignedHeaders = 'x-contentful-signed-headers', | ||
Signature = 'x-contentful-signature', | ||
} | ||
|
||
export enum ContentfulContextHeader { | ||
SpaceId = 'x-contentful-space-id', | ||
EnvironmentId = 'x-contentful-environment-id', | ||
UserId = 'x-contentful-user-id', | ||
AppId = 'x-contentful-app-id', | ||
} | ||
|
||
export type NormalizedCanonicalRequest = { | ||
method: CanonicalRequest['method'] | ||
path: CanonicalRequest['path'] | ||
headers: [key: string, value: string][] | ||
body: CanonicalRequest['body'] | ||
} | ||
|
||
export type SubjectHeadersApp = { appId: string } | ||
export type AppContextSignedHeaders = { [ContentfulContextHeader.AppId]: string } | ||
export type SubjectHeadersUser = { userId: string } | ||
export type UserContextSignedHeaders = { [ContentfulContextHeader.UserId]: string } | ||
|
||
export type Context<SubjectContext> = { | ||
spaceId: string | ||
envId: string | ||
} & SubjectContext | ||
|
||
type SignedHeadersWithoutSubject = { | ||
[ContentfulContextHeader.SpaceId]: string | ||
[ContentfulContextHeader.EnvironmentId]: string | ||
} | ||
|
||
export type SignedContextHeaders<SubjectSignedHeaders> = SignedHeadersWithoutSubject & | ||
SubjectSignedHeaders | ||
|
||
export type SignedRequestWithoutContextHeaders = { | ||
[key in ContentfulHeader]: string | ||
} | ||
export type SignedRequestWithContextHeadersWithUser = SignedRequestWithoutContextHeaders & | ||
SignedContextHeaders<UserContextSignedHeaders> | ||
export type SignedRequestWithContextHeadersWithApp = SignedRequestWithoutContextHeaders & | ||
SignedContextHeaders<AppContextSignedHeaders> | ||
|
||
export type SignedRequestHeaders = | ||
| SignedRequestWithContextHeadersWithUser | ||
| SignedRequestWithContextHeadersWithApp | ||
| SignedRequestWithoutContextHeaders |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import * as runtypes from 'runtypes' | ||
|
||
const MethodValidator = runtypes.Union( | ||
runtypes.Literal('GET'), | ||
runtypes.Literal('PATCH'), | ||
runtypes.Literal('HEAD'), | ||
runtypes.Literal('POST'), | ||
runtypes.Literal('DELETE'), | ||
runtypes.Literal('OPTIONS'), | ||
runtypes.Literal('PUT') | ||
) | ||
|
||
const PathValidator = runtypes.String.withConstraint((s) => s.startsWith('/'), { | ||
name: 'CanonicalURI', | ||
}) | ||
|
||
const SignatureValidator = runtypes.String.withConstraint((s) => s.length === 64, { | ||
name: 'SignatureLength', | ||
}) | ||
|
||
export const CanonicalRequestValidator = runtypes | ||
.Record({ | ||
method: MethodValidator, | ||
path: PathValidator, | ||
}) | ||
.And( | ||
runtypes.Partial({ | ||
headers: runtypes.Dictionary(runtypes.String, 'string'), | ||
body: runtypes.String, | ||
}) | ||
) | ||
export type CanonicalRequest = runtypes.Static<typeof CanonicalRequestValidator> | ||
|
||
export const SecretValidator = runtypes.String.withConstraint((s) => s.length === 64, { | ||
name: 'SecretLength', | ||
}) | ||
export type Secret = runtypes.Static<typeof SecretValidator> | ||
|
||
// Only dates after 01-01-2020 | ||
export const TimestampValidator = runtypes.Number.withConstraint((n) => n > 1577836800000, { | ||
name: 'TimestampAge', | ||
}) | ||
export type Timestamp = runtypes.Static<typeof TimestampValidator> | ||
|
||
const SignedHeadersValidator = runtypes | ||
.Array(runtypes.String) | ||
.withConstraint((l) => l.length >= 2, { name: 'MissingTimestampOrSignedHeaders' }) | ||
|
||
export const RequestMetadataValidator = runtypes.Record({ | ||
signature: SignatureValidator, | ||
timestamp: TimestampValidator, | ||
signedHeaders: SignedHeadersValidator, | ||
}) | ||
export type RequestMetadata = runtypes.Static<typeof RequestMetadataValidator> | ||
|
||
export const TimeToLiveValidator = runtypes.Number.withConstraint((n) => n >= 0, { | ||
name: 'PositiveNumber', | ||
}) | ||
export type TimeToLive = runtypes.Static<typeof TimeToLiveValidator> |