@financial-times/content-curation-client 6.2.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -190,8 +190,11 @@ function readStringProperty(error, property) {
190
190
  return typeof value === "string" && value.length > 0 ? value : void 0;
191
191
  }
192
192
 
193
+ // src/internal/response-handling.ts
194
+ import { z as z2 } from "zod/v4";
195
+
193
196
  // src/schemas/response.ts
194
- import { z } from "zod";
197
+ import { z } from "zod/v4";
195
198
  var ApiErrorCode = z.enum([
196
199
  "UNAUTHORIZED",
197
200
  "NOT_FOUND",
@@ -228,6 +231,7 @@ function ApiResponseSchema(dataSchema) {
228
231
  // src/internal/response-handling.ts
229
232
  var GATEWAY_STATUS_CODES = /* @__PURE__ */ new Set([499, 502, 503]);
230
233
  var MAX_DIAGNOSTIC_BODY_LENGTH = 2e3;
234
+ var ApiSuccessEnvelopeCandidateSchema = ApiSuccessResponseSchema(z2.unknown());
231
235
  function isGatewayStatusCode(statusCode) {
232
236
  return GATEWAY_STATUS_CODES.has(statusCode);
233
237
  }
@@ -271,8 +275,27 @@ function parseApiResponse(responseDataSchema, responseBody) {
271
275
  if (responseBody.json === void 0) {
272
276
  return null;
273
277
  }
274
- const parsedResponse = ApiResponseSchema(responseDataSchema).safeParse(responseBody.json);
275
- return parsedResponse.success ? parsedResponse.data : null;
278
+ if (hasOwnDataProperty(responseBody.json)) {
279
+ const parsedSuccess = ApiSuccessEnvelopeCandidateSchema.safeParse(responseBody.json);
280
+ if (!parsedSuccess.success) {
281
+ return null;
282
+ }
283
+ const parsedData = responseDataSchema.safeParse(parsedSuccess.data.data);
284
+ if (!parsedData.success) {
285
+ return null;
286
+ }
287
+ return {
288
+ status: "success",
289
+ statusCode: parsedSuccess.data.statusCode,
290
+ requestId: parsedSuccess.data.requestId,
291
+ data: parsedData.data
292
+ };
293
+ }
294
+ const parsedError = ApiErrorResponseSchema.safeParse(responseBody.json);
295
+ return parsedError.success ? parsedError.data : null;
296
+ }
297
+ function hasOwnDataProperty(value) {
298
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.hasOwn(value, "data");
276
299
  }
277
300
  function parseApiErrorResponse(responseBody) {
278
301
  if (responseBody.json === void 0) {
@@ -416,7 +439,7 @@ function parseSuccessfulResponse(path, url, response, responseBody, responseData
416
439
  requestId: getResponseRequestId(response)
417
440
  });
418
441
  }
419
- if ("error" in parsedResponse) {
442
+ if (parsedResponse.status === "error") {
420
443
  throw new ApiServiceError(
421
444
  parsedResponse.error,
422
445
  parsedResponse.statusCode,
@@ -524,131 +547,131 @@ function trimTrailingSlashes(value) {
524
547
  }
525
548
 
526
549
  // src/schemas/ftpink/legacyHubPage/index.ts
527
- import { z as z2 } from "zod";
528
- var LegacyFlourishChildSchema = z2.object({
529
- source: z2.literal("flourish"),
530
- properties: z2.object({
531
- id: z2.string().min(1)
550
+ import { z as z3 } from "zod/v4";
551
+ var LegacyFlourishChildSchema = z3.object({
552
+ source: z3.literal("flourish"),
553
+ properties: z3.object({
554
+ id: z3.string().min(1)
532
555
  // e.g. "visualisation/21901162"
533
556
  })
534
557
  });
535
- var LegacyListChildSchema = z2.object({
536
- source: z2.literal("list"),
537
- properties: z2.object({
538
- id: z2.string().uuid(),
539
- maxItems: z2.number().optional()
558
+ var LegacyListChildSchema = z3.object({
559
+ source: z3.literal("list"),
560
+ properties: z3.object({
561
+ id: z3.string().uuid(),
562
+ maxItems: z3.number().optional()
540
563
  })
541
564
  });
542
- var LegacyContentChildSchema = z2.object({
543
- source: z2.literal("content"),
544
- properties: z2.object({
545
- ids: z2.array(z2.string()).nonempty()
565
+ var LegacyContentChildSchema = z3.object({
566
+ source: z3.literal("content"),
567
+ properties: z3.object({
568
+ ids: z3.array(z3.string()).nonempty()
546
569
  })
547
570
  });
548
- var LegacyContainerChildSchema = z2.discriminatedUnion("source", [
571
+ var LegacyContainerChildSchema = z3.discriminatedUnion("source", [
549
572
  LegacyFlourishChildSchema,
550
573
  LegacyListChildSchema,
551
574
  LegacyContentChildSchema
552
575
  ]);
553
- var LegacyTopperSchema = z2.object({
554
- type: z2.literal("topper-basic"),
555
- properties: z2.object({
556
- title: z2.string(),
557
- sponsorText: z2.string().optional(),
558
- sponsorImage: z2.string().url().optional()
576
+ var LegacyTopperSchema = z3.object({
577
+ type: z3.literal("topper-basic"),
578
+ properties: z3.object({
579
+ title: z3.string(),
580
+ sponsorText: z3.string().optional(),
581
+ sponsorImage: z3.string().url().optional()
559
582
  })
560
583
  });
561
- var LegacyInfoBoxSchema = z2.object({
562
- type: z2.literal("info-box"),
563
- properties: z2.object({
564
- bodyHTML: z2.string(),
565
- title: z2.string().optional()
584
+ var LegacyInfoBoxSchema = z3.object({
585
+ type: z3.literal("info-box"),
586
+ properties: z3.object({
587
+ bodyHTML: z3.string(),
588
+ title: z3.string().optional()
566
589
  })
567
590
  });
568
- var LegacyContainerSchema = z2.object({
569
- type: z2.literal("container"),
570
- children: z2.array(LegacyContainerChildSchema).min(1),
571
- properties: z2.object({
572
- title: z2.string().optional(),
573
- design: z2.enum(["chart", "four-story", "freeform", "hero-lead"]).default("freeform"),
574
- backgroundColor: z2.string().optional()
591
+ var LegacyContainerSchema = z3.object({
592
+ type: z3.literal("container"),
593
+ children: z3.array(LegacyContainerChildSchema).min(1),
594
+ properties: z3.object({
595
+ title: z3.string().optional(),
596
+ design: z3.enum(["chart", "four-story", "freeform", "hero-lead"]).default("freeform"),
597
+ backgroundColor: z3.string().optional()
575
598
  })
576
599
  });
577
- var LegacyExperimentSchema = z2.object({
578
- type: z2.literal("experiment"),
579
- children: z2.tuple([]),
580
- properties: z2.object({
581
- experimentName: z2.string(),
582
- id: z2.string(),
583
- title: z2.string().optional(),
584
- config: z2.object({
585
- value: z2.unknown().optional(),
600
+ var LegacyExperimentSchema = z3.object({
601
+ type: z3.literal("experiment"),
602
+ children: z3.tuple([]),
603
+ properties: z3.object({
604
+ experimentName: z3.string(),
605
+ id: z3.string(),
606
+ title: z3.string().optional(),
607
+ config: z3.object({
608
+ value: z3.unknown().optional(),
586
609
  // Hub pages support experiments with HTML and Text.
587
610
  // For now we just support JSON. As we migrate pages, this may change.
588
- format: z2.enum(["json"]).default("json")
611
+ format: z3.enum(["json"]).default("json")
589
612
  }).partial().optional()
590
613
  })
591
614
  });
592
- var LegacyBlockSchema = z2.discriminatedUnion("type", [
615
+ var LegacyBlockSchema = z3.discriminatedUnion("type", [
593
616
  LegacyTopperSchema,
594
617
  LegacyInfoBoxSchema,
595
618
  LegacyContainerSchema,
596
619
  LegacyExperimentSchema
597
620
  ]);
598
- var LegacyPageStructureOutputSchema = z2.object({
599
- uuid: z2.string().uuid(),
600
- title: z2.string(),
601
- conceptId: z2.string().uuid().optional(),
602
- themeName: z2.string().optional(),
603
- metaDescription: z2.string().optional(),
604
- blocks: z2.array(LegacyBlockSchema)
621
+ var LegacyPageStructureOutputSchema = z3.object({
622
+ uuid: z3.string().uuid(),
623
+ title: z3.string(),
624
+ conceptId: z3.string().uuid().optional(),
625
+ themeName: z3.string().optional(),
626
+ metaDescription: z3.string().optional(),
627
+ blocks: z3.array(LegacyBlockSchema)
605
628
  });
606
629
 
607
630
  // src/schemas/ftpink/page/index.ts
608
- import { z as z4 } from "zod";
631
+ import { z as z5 } from "zod/v4";
609
632
 
610
633
  // src/schemas/prosemirror.ts
611
- import { z as z3 } from "zod";
612
- var HrefSchema = z3.string().refine((v) => /^(https?:\/\/|mailto:).+/.test(v), {
634
+ import { z as z4 } from "zod/v4";
635
+ var HrefSchema = z4.string().refine((v) => /^(https?:\/\/|mailto:).+/.test(v), {
613
636
  message: "Expected http(s):// or mailto: URL"
614
637
  });
615
- var ProseMirrorLinkMark = z3.object({
616
- type: z3.literal("link"),
617
- attrs: z3.object({
638
+ var ProseMirrorLinkMark = z4.object({
639
+ type: z4.literal("link"),
640
+ attrs: z4.object({
618
641
  href: HrefSchema
619
642
  })
620
643
  });
621
- var ProseMirrorMark = z3.discriminatedUnion("type", [
644
+ var ProseMirrorMark = z4.discriminatedUnion("type", [
622
645
  ProseMirrorLinkMark,
623
- z3.object({ type: z3.literal("bold") }),
624
- z3.object({ type: z3.literal("italic") }),
625
- z3.object({ type: z3.literal("underline") }),
626
- z3.object({ type: z3.literal("strike") })
646
+ z4.object({ type: z4.literal("bold") }),
647
+ z4.object({ type: z4.literal("italic") }),
648
+ z4.object({ type: z4.literal("underline") }),
649
+ z4.object({ type: z4.literal("strike") })
627
650
  ]);
628
- var ProseMirrorTextNode = z3.object({
629
- type: z3.literal("text"),
630
- text: z3.string(),
631
- marks: z3.array(ProseMirrorMark).optional()
651
+ var ProseMirrorTextNode = z4.object({
652
+ type: z4.literal("text"),
653
+ text: z4.string(),
654
+ marks: z4.array(ProseMirrorMark).optional()
632
655
  });
633
- var ProseMirrorParagraphNode = z3.object({
634
- type: z3.literal("paragraph"),
635
- content: z3.array(ProseMirrorTextNode)
656
+ var ProseMirrorParagraphNode = z4.object({
657
+ type: z4.literal("paragraph"),
658
+ content: z4.array(ProseMirrorTextNode)
636
659
  });
637
- var ProseMirrorNode = z3.union([ProseMirrorParagraphNode, ProseMirrorTextNode]);
638
- var ProseMirrorDocSchema = z3.object({
639
- type: z3.literal("doc"),
640
- content: z3.array(ProseMirrorNode).min(1, { message: "Document must contain at least one paragraph" })
660
+ var ProseMirrorNode = z4.union([ProseMirrorParagraphNode, ProseMirrorTextNode]);
661
+ var ProseMirrorDocSchema = z4.object({
662
+ type: z4.literal("doc"),
663
+ content: z4.array(ProseMirrorNode).min(1, { message: "Document must contain at least one paragraph" })
641
664
  });
642
665
 
643
666
  // src/schemas/ftpink/page/index.ts
644
- var HeadingSchema = z4.object({
645
- text: z4.string(),
646
- href: z4.string().url().optional()
667
+ var HeadingSchema = z5.object({
668
+ text: z5.string(),
669
+ href: z5.string().url().optional()
647
670
  });
648
- var BasePageItemProps = z4.object({
671
+ var BasePageItemProps = z5.object({
649
672
  heading: HeadingSchema.optional()
650
673
  });
651
- var ValidJSONStringSchema = z4.string().refine(
674
+ var ValidJSONStringSchema = z5.string().refine(
652
675
  (val) => {
653
676
  try {
654
677
  JSON.parse(val);
@@ -661,36 +684,36 @@ var ValidJSONStringSchema = z4.string().refine(
661
684
  );
662
685
  function defineSliceSchema(options) {
663
686
  const { typeName, propsShape } = options;
664
- const BaseSchema = z4.object({
665
- type: z4.literal(typeName),
666
- hidden: z4.boolean().optional(),
687
+ const BaseSchema = z5.object({
688
+ type: z5.literal(typeName),
689
+ hidden: z5.boolean().optional(),
667
690
  properties: propsShape
668
691
  });
669
692
  const InputSchema = BaseSchema.extend({
670
- sliceId: z4.string().uuid().optional()
693
+ sliceId: z5.string().uuid().optional()
671
694
  });
672
695
  const OutputSchema = BaseSchema.extend({
673
- sliceId: z4.string().uuid()
696
+ sliceId: z5.string().uuid()
674
697
  });
675
698
  return { InputSchema, OutputSchema };
676
699
  }
677
700
  var InteractiveSlice = defineSliceSchema({
678
701
  typeName: "Interactive",
679
702
  propsShape: BasePageItemProps.extend({
680
- flourishDescription: z4.string().optional(),
703
+ flourishDescription: z5.string().optional(),
681
704
  // Optional description for the Flourish graphic
682
- flourishId: z4.string().nonempty(),
683
- flourishAltText: z4.string().nonempty(),
684
- storyUUID: z4.string().uuid().optional(),
685
- theme: z4.string().optional()
705
+ flourishId: z5.string().nonempty(),
706
+ flourishAltText: z5.string().nonempty(),
707
+ storyUUID: z5.string().uuid().optional(),
708
+ theme: z5.string().optional()
686
709
  })
687
710
  });
688
711
  var ExperimentSlice = defineSliceSchema({
689
712
  typeName: "Experiment",
690
713
  propsShape: BasePageItemProps.extend({
691
- experimentId: z4.string().nonempty(),
714
+ experimentId: z5.string().nonempty(),
692
715
  // Unique ID for the experiment
693
- experimentName: z4.string().nonempty(),
716
+ experimentName: z5.string().nonempty(),
694
717
  // Human-readable name of the experiment
695
718
  contentJson: ValidJSONStringSchema
696
719
  // The experiment’s JSON payload as a valid JSON string
@@ -699,9 +722,9 @@ var ExperimentSlice = defineSliceSchema({
699
722
  var StripSlice = defineSliceSchema({
700
723
  typeName: "Strip",
701
724
  propsShape: BasePageItemProps.extend({
702
- listId: z4.string().uuid(),
725
+ listId: z5.string().uuid(),
703
726
  // The ID of the strip to display
704
- maxStories: z4.number().int().min(1).max(20)
727
+ maxStories: z5.number().int().min(1).max(20)
705
728
  // Maximum number of stories to display in the strip
706
729
  })
707
730
  });
@@ -709,25 +732,25 @@ var TopperSlice = defineSliceSchema({
709
732
  typeName: "Topper",
710
733
  propsShape: BasePageItemProps.extend({
711
734
  description: ProseMirrorDocSchema,
712
- strapline: z4.string().optional()
735
+ strapline: z5.string().optional()
713
736
  })
714
737
  });
715
738
  var HeroSlice = defineSliceSchema({
716
739
  typeName: "Hero",
717
740
  propsShape: BasePageItemProps.extend({
718
- listId: z4.string().uuid(),
741
+ listId: z5.string().uuid(),
719
742
  // The ID of the spark list to display
720
- maxStories: z4.number().int().min(1).max(20)
743
+ maxStories: z5.number().int().min(1).max(20)
721
744
  // Maximum number of stories to display in the hero
722
745
  })
723
746
  });
724
747
  var StoryGroupSlice = defineSliceSchema({
725
748
  typeName: "StoryGroup",
726
749
  propsShape: BasePageItemProps.extend({
727
- storySlots: z4.array(z4.string().uuid()).nonempty()
750
+ storySlots: z5.array(z5.string().uuid()).nonempty()
728
751
  })
729
752
  });
730
- var SliceApiInputSchema = z4.discriminatedUnion("type", [
753
+ var SliceApiInputSchema = z5.discriminatedUnion("type", [
731
754
  InteractiveSlice.InputSchema,
732
755
  ExperimentSlice.InputSchema,
733
756
  StripSlice.InputSchema,
@@ -735,7 +758,7 @@ var SliceApiInputSchema = z4.discriminatedUnion("type", [
735
758
  HeroSlice.InputSchema,
736
759
  StoryGroupSlice.InputSchema
737
760
  ]);
738
- var SliceApiOutputSchema = z4.discriminatedUnion("type", [
761
+ var SliceApiOutputSchema = z5.discriminatedUnion("type", [
739
762
  InteractiveSlice.OutputSchema,
740
763
  ExperimentSlice.OutputSchema,
741
764
  StripSlice.OutputSchema,
@@ -743,53 +766,56 @@ var SliceApiOutputSchema = z4.discriminatedUnion("type", [
743
766
  HeroSlice.OutputSchema,
744
767
  StoryGroupSlice.OutputSchema
745
768
  ]);
746
- var BasePagePropertiesSchema = z4.object({
747
- title: z4.string(),
748
- pageId: z4.string().uuid(),
749
- publicationId: z4.string(),
750
- conceptId: z4.string().uuid().optional(),
751
- metaDescription: z4.string().optional(),
752
- pageTheme: z4.string().optional(),
753
- sponsorText: z4.string().optional(),
754
- sponsorImage: z4.string().url().optional(),
755
- pageCategory: z4.string().optional()
769
+ var BasePagePropertiesSchema = z5.object({
770
+ title: z5.string(),
771
+ pageId: z5.string().uuid(),
772
+ publicationId: z5.string(),
773
+ conceptId: z5.string().uuid().optional(),
774
+ metaDescription: z5.string().optional(),
775
+ pageTheme: z5.string().optional(),
776
+ sponsorText: z5.string().optional(),
777
+ sponsorImage: z5.string().url().optional(),
778
+ pageCategory: z5.string().optional()
756
779
  });
757
- var PageStructureInputSchema = z4.object({
758
- properties: BasePagePropertiesSchema,
759
- children: z4.array(SliceApiInputSchema)
780
+ var PageStructureOutputPropertiesSchema = BasePagePropertiesSchema.extend({
781
+ lastPublishedDate: z5.string().datetime().optional()
760
782
  });
761
- var PageStructureOutputSchema = z4.object({
762
- type: z4.literal("Page"),
763
- schemaVersion: z4.number(),
783
+ var PageStructureInputSchema = z5.object({
764
784
  properties: BasePagePropertiesSchema,
765
- children: z4.array(SliceApiOutputSchema)
785
+ children: z5.array(SliceApiInputSchema)
786
+ });
787
+ var PageStructureOutputSchema = z5.object({
788
+ type: z5.literal("Page"),
789
+ schemaVersion: z5.number(),
790
+ properties: PageStructureOutputPropertiesSchema,
791
+ children: z5.array(SliceApiOutputSchema)
766
792
  });
767
- var ListPagesOutputSchema = z4.array(PageStructureOutputSchema);
793
+ var ListPagesOutputSchema = z5.array(PageStructureOutputSchema);
768
794
 
769
795
  // src/schemas/ftpink/draft/index.ts
770
- import { z as z5 } from "zod";
771
- var DraftContributorInputSchema = z5.object({
772
- userId: z5.string().min(1),
773
- displayName: z5.string().min(1),
774
- email: z5.string().email().optional()
796
+ import { z as z6 } from "zod/v4";
797
+ var DraftContributorInputSchema = z6.object({
798
+ userId: z6.string().min(1),
799
+ displayName: z6.string().min(1),
800
+ email: z6.string().email().optional()
775
801
  });
776
802
  var DraftContributorSchema = DraftContributorInputSchema.extend({
777
- userId: z5.string().min(1),
778
- displayName: z5.string().min(1),
779
- firstTouchedAt: z5.string().datetime(),
780
- lastTouchedAt: z5.string().datetime()
803
+ userId: z6.string().min(1),
804
+ displayName: z6.string().min(1),
805
+ firstTouchedAt: z6.string().datetime(),
806
+ lastTouchedAt: z6.string().datetime()
781
807
  });
782
- var DraftMetadataSchema = z5.object({
783
- draftId: z5.string().uuid(),
784
- createdAt: z5.string().datetime(),
785
- updatedAt: z5.string().datetime(),
786
- contributors: z5.array(DraftContributorSchema)
808
+ var DraftMetadataSchema = z6.object({
809
+ draftId: z6.string().uuid(),
810
+ createdAt: z6.string().datetime(),
811
+ updatedAt: z6.string().datetime(),
812
+ contributors: z6.array(DraftContributorSchema)
787
813
  });
788
814
  var PageDraftSchema = DraftMetadataSchema.extend({
789
815
  structure: PageStructureOutputSchema
790
816
  });
791
817
  var DraftSchema = PageDraftSchema;
792
- var PersistPageDraftInputSchema = z5.object({
818
+ var PersistPageDraftInputSchema = z6.object({
793
819
  structure: PageStructureInputSchema,
794
820
  contributor: DraftContributorInputSchema
795
821
  });