Skip to content

Commit 21fc4f4

Browse files
committed
[DEV-12091] Declare slug property support to Story Create & Update APIs
1 parent 5d0b1d2 commit 21fc4f4

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

src/endpoints/Stories/Client.ts

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,21 @@ export class Client {
195195
return story;
196196
}
197197

198-
async create<Options extends IncludeOptions & { formats?: Formats }>(
198+
async create<Options extends IncludeOptions & { formats?: Formats; force?: boolean }>(
199199
payload: CreateRequest,
200-
options?: Exactly<Options, IncludeOptions & { formats?: Formats }>,
200+
options?: Exactly<Options, IncludeOptions & { formats?: Formats; force?: boolean }>,
201201
): Promise<ExtendedStory & InferExtraFields<Options>> {
202-
const { include, formats } = options ?? {};
202+
const { include, formats, force = false } = options ?? {};
203203

204204
const { story } = await this.apiClient.post<{
205205
story: ExtendedStory & InferExtraFields<Options>;
206206
}>(routing.storiesUrl, {
207207
headers: acceptedFormatsHeader(formats),
208+
query: {
209+
include,
210+
force: force || undefined,
211+
},
208212
payload,
209-
query: { include },
210213
});
211214
return story;
212215
}
@@ -252,15 +255,15 @@ export class Client {
252255
return story;
253256
}
254257

255-
async move<Options extends IncludeOptions & { force?: true; formats?: Formats }>(
258+
async move<Options extends IncludeOptions & { formats?: Formats; force?: boolean }>(
256259
id: StoryId,
257260
payload: MoveRequest,
258-
options?: Exactly<Options, IncludeOptions & { force?: true; formats?: Formats }>,
261+
options?: Exactly<Options, IncludeOptions & { formats?: Formats; force?: boolean }>,
259262
): Promise<
260263
| ChangeNewsroomSuccessResponse<ExtendedStory & InferExtraFields<Options>>
261264
| ChangeNewsroomUnsafeResponse
262265
> {
263-
const { include, force, formats } = options ?? {};
266+
const { include, formats, force = false } = options ?? {};
264267

265268
const url = `${routing.storiesUrl}/${id}/move`;
266269

@@ -269,7 +272,10 @@ export class Client {
269272
story: ExtendedStory & InferExtraFields<Options>;
270273
}>(url, {
271274
headers: acceptedFormatsHeader(formats),
272-
query: { include: include as string[] | undefined, force },
275+
query: {
276+
include,
277+
force: force || undefined, // only pass it if it's true
278+
},
273279
payload,
274280
});
275281

@@ -282,20 +288,23 @@ export class Client {
282288
}
283289
}
284290

285-
async update<Options extends IncludeOptions & { formats?: Formats }>(
291+
async update<Options extends IncludeOptions & { formats?: Formats; force?: boolean }>(
286292
id: StoryId,
287293
payload: UpdateRequest,
288-
options?: Exactly<Options, IncludeOptions & { formats?: Formats }>,
294+
options?: Exactly<Options, IncludeOptions & { formats?: Formats; force?: boolean }>,
289295
): Promise<ExtendedStory & InferExtraFields<Options>> {
290296
const url = `${routing.storiesUrl}/${id}`;
291-
const { include, formats } = options ?? {};
297+
const { include, formats, force = false } = options ?? {};
292298

293299
const { story } = await this.apiClient.patch<{
294300
story: ExtendedStory & InferExtraFields<Options>;
295301
}>(url, {
296302
headers: acceptedFormatsHeader(formats),
303+
query: {
304+
include,
305+
force: force || undefined, // only pass it if it's true
306+
},
297307
payload,
298-
query: { include: include as string[] | undefined },
299308
});
300309
return story;
301310
}
@@ -316,7 +325,7 @@ export class Client {
316325
}>(url, {
317326
headers: acceptedFormatsHeader(formats),
318327
payload,
319-
query: { include: include as string[] | undefined },
328+
query: { include },
320329
});
321330
return story;
322331
}
@@ -337,7 +346,7 @@ export class Client {
337346
}>(url, {
338347
headers: acceptedFormatsHeader(formats),
339348
payload,
340-
query: { include: include as string[] | undefined },
349+
query: { include },
341350
});
342351
return story;
343352
}
@@ -355,7 +364,7 @@ export class Client {
355364
}>(url, {
356365
headers: acceptedFormatsHeader(formats),
357366
payload,
358-
query: { include: include as string[] | undefined },
367+
query: { include },
359368
});
360369
return story;
361370
}
@@ -373,7 +382,7 @@ export class Client {
373382
}>(url, {
374383
headers: acceptedFormatsHeader(formats),
375384
payload,
376-
query: { include: include as string[] | undefined },
385+
query: { include },
377386
});
378387
return story;
379388
}
@@ -391,7 +400,7 @@ export class Client {
391400
}>(url, {
392401
headers: acceptedFormatsHeader(formats),
393402
payload,
394-
query: { include: include as string[] | undefined },
403+
query: { include },
395404
});
396405
return story;
397406
}
@@ -409,24 +418,24 @@ export class Client {
409418
}>(url, {
410419
headers: acceptedFormatsHeader(formats),
411420
payload,
412-
query: { include: include as string[] | undefined },
421+
query: { include },
413422
});
414423
return story;
415424
}
416425

417-
async pin<Options extends IncludeOptions & { force?: boolean; formats?: Formats }>(
426+
async pin<Options extends IncludeOptions & { formats?: Formats; force?: boolean }>(
418427
id: StoryId,
419-
options?: Exactly<Options, IncludeOptions & { force?: boolean; formats?: Formats }>,
428+
options?: Exactly<Options, IncludeOptions & { formats?: Formats; force?: boolean }>,
420429
): Promise<ExtendedStory & InferExtraFields<Options>> {
421430
const url = `${routing.storiesUrl}/${id}/pin`;
422-
const { include, force, formats } = options ?? {};
431+
const { include, formats, force = false } = options ?? {};
423432

424433
const { story } = await this.apiClient.post<{
425434
story: ExtendedStory & InferExtraFields<Options>;
426435
}>(url, {
427436
headers: acceptedFormatsHeader(formats),
428437
query: {
429-
include: include as string[] | undefined,
438+
include: include,
430439
force: force || undefined,
431440
},
432441
});
@@ -444,7 +453,7 @@ export class Client {
444453
story: ExtendedStory & InferExtraFields<Options>;
445454
}>(url, {
446455
headers: acceptedFormatsHeader(formats),
447-
query: { include: include as string[] | undefined },
456+
query: { include: include },
448457
});
449458
return story;
450459
}

src/endpoints/Stories/types.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ export interface ListResponse<S extends Story = Story> {
100100
}
101101

102102
interface GenericCreateRequest {
103+
/**
104+
* Set a custom slug for a Story.
105+
*
106+
* - If there is another story with exactly the same slug value, the Create request will throw [HTTP 409 Conflict].
107+
*
108+
* - Conflicts can be force-resolved by passing `?force` GET parameter.
109+
* This will update other conflicting stories slugs to something else (i.e. adding random suffix).
110+
*/
111+
slug?: Story['slug'];
112+
103113
newsroom?: Newsroom['id'] | Newsroom['uuid'];
104114

105115
published_at?: Iso8601DateTime;
@@ -117,6 +127,17 @@ interface GenericCreateRequest {
117127
}
118128

119129
interface GenericUpdateRequest {
130+
/**
131+
* Set a custom slug for a Story.
132+
* Updating it to `null` will revert back to automatically generated slugs.
133+
*
134+
* - If there is another story with exactly the same slug value, the Update request will throw [HTTP 409 Conflict].
135+
*
136+
* - Conflicts can be force-resolved by passing `?force` GET parameter.
137+
* This will update other conflicting stories slugs to something else (i.e. adding random suffix).
138+
*/
139+
slug?: Story['slug'] | null;
140+
120141
published_at?: Iso8601DateTime;
121142
visibility?: Story.Visibility;
122143
culture?: CultureRef['code'];

0 commit comments

Comments
 (0)