@platecms/delta-client 1.6.0 → 1.6.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platecms/delta-client",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Utilities and functions to interact with the Delta CMS.",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {
@@ -18,7 +18,7 @@
18
18
  "src/**/*"
19
19
  ],
20
20
  "peerDependencies": {
21
- "@platecms/delta-cast": "1.6.0",
21
+ "@platecms/delta-cast": "1.6.1",
22
22
  "@graphql-typed-document-node/core": "3.2.0",
23
23
  "graphql": "16.11.0",
24
24
  "tslib": "2.8.1",
@@ -145,10 +145,10 @@ describe("Schema", () => {
145
145
  title: [schema.number(), schema.string()],
146
146
  description: schema.smartText(),
147
147
  vegatables: schema.array(
148
- schema.contentItem({
148
+ schema.relatedContentItem({
149
149
  name: [schema.string(), schema.number()],
150
150
  calories: schema.number(),
151
- author: schema.contentItem({
151
+ author: schema.relatedContentItem({
152
152
  name: schema.string(),
153
153
  email: schema.string(),
154
154
  }),
@@ -217,4 +217,52 @@ describe("Schema", () => {
217
217
  },
218
218
  });
219
219
  });
220
+
221
+ it("should parse a content item and its related content item with its values", () => {
222
+ const book: ContentItem = {
223
+ contentValues: [
224
+ {
225
+ contentField: {
226
+ name: "name",
227
+ slug: "name",
228
+ },
229
+ primitiveValue: "The Great Gatsby",
230
+ },
231
+ {
232
+ contentField: {
233
+ name: "year",
234
+ slug: "year",
235
+ },
236
+ primitiveValue: 1925,
237
+ },
238
+ {
239
+ contentField: {
240
+ name: "author",
241
+ slug: "author",
242
+ },
243
+ relatedContentItem: johnDoe,
244
+ },
245
+ ],
246
+ } as unknown as ContentItem;
247
+
248
+ const contentItem = schema.contentItem({
249
+ name: schema.string(),
250
+ year: schema.number(),
251
+ author: schema.relatedContentItem({
252
+ name: schema.string(),
253
+ email: schema.string(),
254
+ }),
255
+ });
256
+
257
+ const result = contentItem.parse(book);
258
+
259
+ expect(result).toEqual({
260
+ name: "The Great Gatsby",
261
+ year: 1925,
262
+ author: {
263
+ name: "John Doe",
264
+ email: "john.doe@example.com",
265
+ },
266
+ });
267
+ });
220
268
  });
@@ -96,7 +96,7 @@ describe("Array schema", () => {
96
96
 
97
97
  it("should parse an array of content values", () => {
98
98
  const testSchema = schemaBuilder.array(
99
- schemaBuilder.contentItem({
99
+ schemaBuilder.relatedContentItem({
100
100
  name: schemaBuilder.string(),
101
101
  }),
102
102
  );
@@ -19,16 +19,14 @@ describe("ContentItem schema", () => {
19
19
  });
20
20
 
21
21
  const result = contentItemSchema.parse({
22
- relatedContentItem: {
23
- contentValues: [
24
- {
25
- contentField: {
26
- slug: "title",
27
- },
28
- primitiveValue: "hello",
22
+ contentValues: [
23
+ {
24
+ contentField: {
25
+ slug: "title",
29
26
  },
30
- ],
31
- },
27
+ primitiveValue: "hello",
28
+ },
29
+ ],
32
30
  });
33
31
 
34
32
  expect(result).toEqual({
@@ -42,16 +40,14 @@ describe("ContentItem schema", () => {
42
40
  });
43
41
 
44
42
  const result = contentItemSchema.parse({
45
- relatedContentItem: {
46
- contentValues: [
47
- {
48
- contentField: {
49
- slug: "title",
50
- },
51
- primitiveValue: "hello",
43
+ contentValues: [
44
+ {
45
+ contentField: {
46
+ slug: "title",
52
47
  },
53
- ],
54
- },
48
+ primitiveValue: "hello",
49
+ },
50
+ ],
55
51
  });
56
52
 
57
53
  expect(result).toEqual({
@@ -1,5 +1,5 @@
1
1
  import { ObjectSchema, Schema, SchemaConfig } from ".";
2
- import { isContentValue } from "../utils/isContentValue";
2
+ import { isContentItem } from "../utils/isContentValue";
3
3
  import { isArray } from "../utils";
4
4
  export class ContentItemSchema<T extends Record<string, Schema | Schema[]>>
5
5
  implements Schema<ObjectSchema<T>, unknown>
@@ -22,10 +22,10 @@ export class ContentItemSchema<T extends Record<string, Schema | Schema[]>>
22
22
 
23
23
  return Object.entries(this.structure).reduce(
24
24
  (acc, [key, value]) => {
25
- const relatedContentItem = isContentValue(data) ? data.relatedContentItem : null;
25
+ const contentItem = isContentItem(data) ? data : null;
26
26
 
27
27
  const contentValuesForKey =
28
- relatedContentItem?.contentValues.filter((contentValue) => contentValue.contentField?.slug === key) ?? [];
28
+ contentItem?.contentValues.filter((contentValue) => contentValue.contentField?.slug === key) ?? [];
29
29
  const shapes = Array.isArray(value) ? value : [value];
30
30
  const parsedValues = shapes.map((shape) => shape.parse(contentValuesForKey, config));
31
31
 
@@ -13,6 +13,7 @@ import { TagSchema } from "./tag";
13
13
  import { ContentTypeSchema } from "./contentType";
14
14
  import { Asset, ContentType, GridPlacement, PathPart, Tag } from "../../../__generated__/graphql";
15
15
  import { Root } from "@platecms/delta-cast";
16
+ import { RelatedContentItemSchema } from "./relatedContentItem";
16
17
 
17
18
  export type ResultType =
18
19
  | Asset
@@ -47,6 +48,8 @@ export interface SchemaConfig {
47
48
  export const schema = {
48
49
  buildingBlock: <T extends Record<string, Schema | Schema[]>>(structure: T): BuildingBlockSchema<T> =>
49
50
  new BuildingBlockSchema(structure),
51
+ relatedContentItem: <T extends Record<string, Schema | Schema[]>>(structure: T): RelatedContentItemSchema<T> =>
52
+ new RelatedContentItemSchema(structure),
50
53
  contentItem: <T extends Record<string, Schema | Schema[]>>(structure: T): ContentItemSchema<T> =>
51
54
  new ContentItemSchema(structure),
52
55
  array: <T extends Schema | Schema[]>(structure: T): ArraySchema<T> => new ArraySchema(structure),
@@ -0,0 +1,61 @@
1
+ import { describe, it } from "vitest";
2
+ import { schema } from ".";
3
+ import { RelatedContentItemSchema } from "./relatedContentItem";
4
+
5
+ describe("RelatedContentItem schema", () => {
6
+ it("should parse an empty content item", () => {
7
+ const relatedContentItemSchema = new RelatedContentItemSchema({});
8
+
9
+ const result = relatedContentItemSchema.parse({
10
+ contentValues: [],
11
+ });
12
+
13
+ expect(result).toEqual({});
14
+ });
15
+
16
+ it("should parse a content item with its values", () => {
17
+ const relatedContentItemSchema = new RelatedContentItemSchema({
18
+ title: schema.string(),
19
+ });
20
+
21
+ const result = relatedContentItemSchema.parse({
22
+ relatedContentItem: {
23
+ contentValues: [
24
+ {
25
+ contentField: {
26
+ slug: "title",
27
+ },
28
+ primitiveValue: "hello",
29
+ },
30
+ ],
31
+ },
32
+ });
33
+
34
+ expect(result).toEqual({
35
+ title: "hello",
36
+ });
37
+ });
38
+
39
+ it("should parse a content item with multiple values", () => {
40
+ const relatedContentItemSchema = new RelatedContentItemSchema({
41
+ title: [schema.number(), schema.string()],
42
+ });
43
+
44
+ const result = relatedContentItemSchema.parse({
45
+ relatedContentItem: {
46
+ contentValues: [
47
+ {
48
+ contentField: {
49
+ slug: "title",
50
+ },
51
+ primitiveValue: "hello",
52
+ },
53
+ ],
54
+ },
55
+ });
56
+
57
+ expect(result).toEqual({
58
+ title: "hello",
59
+ });
60
+ });
61
+ });
@@ -0,0 +1,39 @@
1
+ import { ObjectSchema, Schema, SchemaConfig } from ".";
2
+ import { isContentValue } from "../utils/isContentValue";
3
+ import { isArray } from "../utils";
4
+ export class RelatedContentItemSchema<T extends Record<string, Schema | Schema[]>>
5
+ implements Schema<ObjectSchema<T>, unknown>
6
+ {
7
+ public constructor(private readonly structure: T) {}
8
+
9
+ public parse(
10
+ data: unknown,
11
+ config?: SchemaConfig,
12
+ ): {
13
+ [key in keyof T]: T[key] extends Schema[]
14
+ ? ReturnType<T[key][number]["parse"]>
15
+ : T[key] extends Schema
16
+ ? ReturnType<T[key]["parse"]>
17
+ : never;
18
+ } {
19
+ if (isArray(data)) {
20
+ data = data[0];
21
+ }
22
+
23
+ return Object.entries(this.structure).reduce(
24
+ (acc, [key, value]) => {
25
+ const relatedContentItem = isContentValue(data) ? data.relatedContentItem : null;
26
+
27
+ const contentValuesForKey =
28
+ relatedContentItem?.contentValues.filter((contentValue) => contentValue.contentField?.slug === key) ?? [];
29
+ const shapes = Array.isArray(value) ? value : [value];
30
+ const parsedValues = shapes.map((shape) => shape.parse(contentValuesForKey, config));
31
+
32
+ acc[key as keyof T] = (parsedValues.find((parsedValue) => parsedValue !== null) ??
33
+ null) as ObjectSchema<T>[keyof T];
34
+ return acc;
35
+ },
36
+ {} as unknown as ObjectSchema<T>,
37
+ );
38
+ }
39
+ }
@@ -1,4 +1,4 @@
1
- import { ContentValue } from "../../../__generated__/graphql";
1
+ import { ContentItem, ContentValue } from "../../../__generated__/graphql";
2
2
 
3
3
  export function isContentValue(data: unknown): data is ContentValue {
4
4
  return (
@@ -15,3 +15,7 @@ export function isContentValue(data: unknown): data is ContentValue {
15
15
  "interpolatedSmartText" in data)
16
16
  );
17
17
  }
18
+
19
+ export function isContentItem(data: unknown): data is ContentItem {
20
+ return data !== null && typeof data === "object" && "contentValues" in data;
21
+ }