@platecms/delta-client 1.5.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 +2 -2
- package/src/schema/index.spec.ts +50 -2
- package/src/schema/lib/schemas/array.spec.ts +1 -1
- package/src/schema/lib/schemas/contentItem.spec.ts +14 -18
- package/src/schema/lib/schemas/contentItem.ts +3 -3
- package/src/schema/lib/schemas/index.ts +3 -0
- package/src/schema/lib/schemas/relatedContentItem.spec.ts +61 -0
- package/src/schema/lib/schemas/relatedContentItem.ts +39 -0
- package/src/schema/lib/utils/isContentValue.ts +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platecms/delta-client",
|
|
3
|
-
"version": "1.
|
|
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.
|
|
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",
|
package/src/schema/index.spec.ts
CHANGED
|
@@ -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.
|
|
148
|
+
schema.relatedContentItem({
|
|
149
149
|
name: [schema.string(), schema.number()],
|
|
150
150
|
calories: schema.number(),
|
|
151
|
-
author: schema.
|
|
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
|
});
|
|
@@ -19,16 +19,14 @@ describe("ContentItem schema", () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
const result = contentItemSchema.parse({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
{
|
|
25
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
{
|
|
48
|
-
|
|
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 {
|
|
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
|
|
25
|
+
const contentItem = isContentItem(data) ? data : null;
|
|
26
26
|
|
|
27
27
|
const contentValuesForKey =
|
|
28
|
-
|
|
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
|
+
}
|