Skip to content

Commit ecc849a

Browse files
authored
New Components - contentstack (#15037)
* contentstack init * new components * pnpm-lock.yaml * update
1 parent ac7fe45 commit ecc849a

File tree

15 files changed

+1675
-12
lines changed

15 files changed

+1675
-12
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import contentstack from "../../contentstack.app.mjs";
2+
import {
3+
parseArray, parseEntry,
4+
} from "../../common/utils.mjs";
5+
6+
const createDocLink = "https://www.contentstack.com/docs/developers/apis/content-management-api#create-an-entry";
7+
const updateDocLink = "https://www.contentstack.com/docs/developers/apis/content-management-api#update-an-entry";
8+
9+
export default {
10+
props: {
11+
contentstack,
12+
contentType: {
13+
propDefinition: [
14+
contentstack,
15+
"contentType",
16+
],
17+
reloadProps: true,
18+
},
19+
},
20+
async additionalProps() {
21+
if (!this.contentType) {
22+
return {};
23+
}
24+
try {
25+
return await this.buildFieldProps(this.contentType);
26+
} catch {
27+
return {
28+
entryObj: {
29+
type: "object",
30+
label: "Entry",
31+
description: `Enter the entry object as JSON. [See the documentation](${this.isUpdate()
32+
? updateDocLink
33+
: createDocLink}) for more information.`,
34+
},
35+
};
36+
}
37+
},
38+
methods: {
39+
getType(field) {
40+
if (field.data_type === "boolean") {
41+
return "boolean";
42+
}
43+
if (field.data_type === "json") {
44+
return "object";
45+
}
46+
return field.multiple
47+
? "string[]"
48+
: "string";
49+
},
50+
isUpdate() {
51+
return false;
52+
},
53+
async getOptions(field) {
54+
if (field.data_type === "reference") {
55+
const referenceContentType = field.reference_to[0];
56+
const { entries } = await this.contentstack.listEntries({
57+
contentType: referenceContentType,
58+
});
59+
return entries?.map(({
60+
uid: value, title: label,
61+
}) => ({
62+
value,
63+
label: label ?? value,
64+
})) || [];
65+
}
66+
if (field.data_type === "file") {
67+
const { assets } = await this.contentstack.listAssets();
68+
return assets?.map(({
69+
uid: value, title: label,
70+
}) => ({
71+
value,
72+
label: label ?? value,
73+
})) || [];
74+
}
75+
return undefined;
76+
},
77+
async buildFieldProps(contentType) {
78+
const props = {};
79+
const { content_type: { schema } } = await this.contentstack.getContentType({
80+
contentType,
81+
});
82+
for (const field of schema) {
83+
props[field.uid] = {
84+
type: this.getType(field),
85+
label: field.display_name ?? field.uid,
86+
description: `Value of field ${field.display_name}. Field type: \`${field.data_type}\``,
87+
optional: this.isUpdate()
88+
? true
89+
: !field.mandatory,
90+
options: await this.getOptions(field),
91+
};
92+
}
93+
return props;
94+
},
95+
async buildEntry() {
96+
if (this.entryObj) {
97+
return parseEntry(this.entryObj);
98+
}
99+
const { content_type: { schema } } = await this.contentstack.getContentType({
100+
contentType: this.contentType,
101+
});
102+
const entry = {};
103+
for (const field of schema) {
104+
if (!this[field.uid]) {
105+
continue;
106+
}
107+
if (field.data_type === "reference") {
108+
if (field.multiple) {
109+
const referenceField = parseArray(this[field.uid]);
110+
entry[field.uid] = referenceField?.map((value) => ({
111+
uid: value,
112+
_content_type_uid: field.reference_to[0],
113+
}));
114+
} else {
115+
entry[field.uid] = {
116+
uid: this[field.uid],
117+
_content_type_uid: field.reference_to[0],
118+
};
119+
}
120+
continue;
121+
}
122+
entry[field.uid] = this[field.uid];
123+
}
124+
return parseEntry(entry);
125+
},
126+
},
127+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import common from "../common/entries.mjs";
2+
3+
export default {
4+
...common,
5+
key: "contentstack-create-entry",
6+
name: "Create Entry",
7+
description: "Creates a new entry in Contentstack. [See the documentation](https://www.contentstack.com/docs/developers/apis/content-management-api#create-an-entry).",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
...common.props,
12+
locale: {
13+
propDefinition: [
14+
common.props.contentstack,
15+
"locale",
16+
],
17+
},
18+
},
19+
async run({ $ }) {
20+
const response = await this.contentstack.createEntry({
21+
$,
22+
contentType: this.contentType,
23+
params: {
24+
locale: this.locale,
25+
},
26+
data: {
27+
entry: await this.buildEntry(),
28+
},
29+
});
30+
$.export("$summary", `Created entry "${response.entry.title}" with UID ${response.entry.uid}`);
31+
return response;
32+
},
33+
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import contentstack from "../../contentstack.app.mjs";
2+
import { parseArray } from "../../common/utils.mjs";
3+
4+
export default {
5+
key: "contentstack-publish-entry",
6+
name: "Publish Entry",
7+
description: "Publishes a specific entry using its UID. [See the documentation](https://www.contentstack.com/docs/developers/apis/content-management-api#publish-entry)",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
contentstack,
12+
contentType: {
13+
propDefinition: [
14+
contentstack,
15+
"contentType",
16+
],
17+
},
18+
entryId: {
19+
propDefinition: [
20+
contentstack,
21+
"entryId",
22+
(c) => ({
23+
contentType: c.contentType,
24+
}),
25+
],
26+
},
27+
environments: {
28+
propDefinition: [
29+
contentstack,
30+
"environments",
31+
],
32+
},
33+
locales: {
34+
propDefinition: [
35+
contentstack,
36+
"locale",
37+
],
38+
type: "string[]",
39+
label: "Locale",
40+
description: "The code of the language in which you want your entry to be localized in",
41+
},
42+
scheduledAt: {
43+
type: "string",
44+
label: "Scheduled At",
45+
description: "The date/time in the ISO format to publish the entry. Example: `2016-10-07T12:34:36.000Z`",
46+
optional: true,
47+
},
48+
},
49+
async run({ $ }) {
50+
const { entry } = await this.contentstack.getEntry({
51+
$,
52+
contentType: this.contentType,
53+
entryId: this.entryId,
54+
});
55+
56+
const response = await this.contentstack.publishEntry({
57+
$,
58+
contentType: this.contentType,
59+
entryId: this.entryId,
60+
data: {
61+
entry: {
62+
environments: parseArray(this.environments),
63+
locales: parseArray(this.locales),
64+
},
65+
locale: entry.locale,
66+
version: entry._version,
67+
scheduled_at: this.scheduledAt,
68+
},
69+
});
70+
$.export("$summary", `Successfully published entry with UID ${this.entryId}`);
71+
return response;
72+
},
73+
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import common from "../common/entries.mjs";
2+
3+
export default {
4+
...common,
5+
key: "contentstack-update-entry",
6+
name: "Update Entry",
7+
description: "Updates an existing Contentstack entry. [See the documentation](https://www.contentstack.com/docs/developers/apis/content-management-api#update-an-entry).",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
...common.props,
12+
entryId: {
13+
propDefinition: [
14+
common.props.contentstack,
15+
"entryId",
16+
(c) => ({
17+
contentType: c.contentType,
18+
}),
19+
],
20+
},
21+
locale: {
22+
propDefinition: [
23+
common.props.contentstack,
24+
"locale",
25+
],
26+
optional: true,
27+
},
28+
},
29+
methods: {
30+
...common.methods,
31+
isUpdate() {
32+
return true;
33+
},
34+
},
35+
async run({ $ }) {
36+
const response = await this.contentstack.updateEntry({
37+
$,
38+
contentType: this.contentType,
39+
entryId: this.entryId,
40+
params: {
41+
locale: this.locale,
42+
},
43+
data: {
44+
entry: await this.buildEntry(),
45+
},
46+
});
47+
$.export("$summary", `Entry ${this.entryId} updated successfully`);
48+
return response;
49+
},
50+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
export function parseArray(value) {
2+
if (!value) {
3+
return undefined;
4+
}
5+
if (typeof value === "string") {
6+
try {
7+
return JSON.parse(value);
8+
} catch {
9+
throw new Error(`Could not parse as array: ${value}`);
10+
}
11+
}
12+
return value;
13+
}
14+
15+
export function parseEntry(entry) {
16+
if (!entry) {
17+
return undefined;
18+
}
19+
if (typeof entry === "string") {
20+
try {
21+
return JSON.parse(entry);
22+
} catch {
23+
throw new Error("Could not parse entry as JSON");
24+
}
25+
}
26+
const parsedEntry = {};
27+
for (const [
28+
key,
29+
value,
30+
] of Object.entries(entry)) {
31+
if (typeof value === "string") {
32+
try {
33+
parsedEntry[key] = JSON.parse(value);
34+
} catch {
35+
parsedEntry[key] = value;
36+
}
37+
} else {
38+
parsedEntry[key] = value;
39+
}
40+
}
41+
return parsedEntry;
42+
}

0 commit comments

Comments
 (0)