Skip to content

Commit

Permalink
feat(query): add support for release perspectives (#934)
Browse files Browse the repository at this point in the history
* feat(query): add support for release perspectives

* feat(query): allow perspective=drafts
  • Loading branch information
bjoerge authored Dec 3, 2024
1 parent 5647ee2 commit 59bd477
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 8 deletions.
26 changes: 24 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,31 @@ function validateApiVersion(apiVersion: string) {
}
}

export const validateApiPerspective = function validateApiPerspective(perspective: string) {
export const validateApiPerspective = function validateApiPerspective(perspective: unknown) {
if (Array.isArray(perspective)) {
for (const perspectiveValue of perspective) {
if (perspectiveValue === 'published') {
continue
}
if (perspectiveValue === 'drafts') {
continue
}
if (
typeof perspectiveValue === 'string' &&
perspectiveValue.startsWith('r') &&
perspectiveValue !== 'raw'
) {
continue
}
throw new TypeError(
'Invalid API perspective value, expected `published`, `drafts` or a valid release identifier string',
)
}
return
}
switch (perspective as ClientPerspective) {
case 'previewDrafts':
case 'drafts':
case 'published':
case 'raw':
return
Expand Down Expand Up @@ -74,7 +96,7 @@ export const initConfig = (
throw new Error('Configuration must contain `projectId`')
}

if (typeof newConfig.perspective === 'string') {
if (typeof newConfig.perspective !== 'undefined') {
validateApiPerspective(newConfig.perspective)
}

Expand Down
15 changes: 10 additions & 5 deletions src/data/dataMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,12 +405,17 @@ export function _requestObservable<R>(
if (resultSourceMap !== undefined && resultSourceMap !== false) {
options.query = {resultSourceMap, ...options.query}
}
const perspective = options.perspective || config.perspective
if (typeof perspective === 'string' && perspective !== 'raw') {
validateApiPerspective(perspective)
options.query = {perspective, ...options.query}
const perspectiveOption = options.perspective || config.perspective
if (typeof perspectiveOption !== 'undefined') {
validateApiPerspective(perspectiveOption)
options.query = {
perspective: Array.isArray(perspectiveOption)
? perspectiveOption.join(',')
: perspectiveOption,
...options.query,
}
// If the perspective is set to `previewDrafts` we can't use the CDN, the API will throw
if (perspective === 'previewDrafts' && useCdn) {
if (perspectiveOption === 'previewDrafts' && useCdn) {
useCdn = false
printCdnPreviewDraftsWarning()
}
Expand Down
10 changes: 9 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,15 @@ export interface RequestOptions {
}

/** @public */
export type ClientPerspective = 'previewDrafts' | 'published' | 'raw'
export type ReleaseId = `r${string}`

/** @public */
export type ClientPerspective =
| 'previewDrafts'
| 'published'
| 'drafts'
| 'raw'
| ('published' | 'drafts' | ReleaseId)[]

/** @public */
export interface ClientConfig {
Expand Down
24 changes: 24 additions & 0 deletions test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,37 @@ describe('client', async () => {
expect(() => createClient({projectId: 'abc123', perspective: 'previewDrafts'})).not.toThrow(
/Invalid API perspective/,
)
expect(() => createClient({projectId: 'abc123', perspective: 'drafts'})).not.toThrow(
/Invalid API perspective/,
)
expect(() => createClient({projectId: 'abc123', perspective: 'raw'})).not.toThrow(
/Invalid API perspective/,
)
// @ts-expect-error -- we want to test that it throws an error
expect(() => createClient({projectId: 'abc123', perspective: 'preview drafts'})).toThrow(
/Invalid API perspective/,
)

// valid because it begins with `r`
const validReleaseIdentifier = 'rfoobar'
expect(() =>
createClient({
projectId: 'abc123',
perspective: ['published', 'drafts', validReleaseIdentifier],
}),
).not.toThrow(/Invalid API perspective/)

// special case – "raw" would be a valid release id given that it starts with ´r`
// but 'raw' is not possible to use with multiple perspectives and is explicitly
// banned by the backend
expect(() =>
createClient({projectId: 'abc123', perspective: ['published', 'drafts', 'raw']}),
).toThrow(/Invalid API perspective/)

expect(() =>
// @ts-expect-error -- we want to test that it throws an error
createClient({projectId: 'abc123', perspective: ['XyzAbC']}),
).toThrow(/Invalid API perspective/)
})

test('throws on invalid project ids', () => {
Expand Down

0 comments on commit 59bd477

Please sign in to comment.