Skip to content

Commit 5fb72ed

Browse files
authored
Sanity.io - new components (#19137)
* new components * pnpm-lock.yaml * updates * updates
1 parent 31d63d7 commit 5fb72ed

File tree

11 files changed

+438
-8
lines changed

11 files changed

+438
-8
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import sanity from "../../sanity.app.mjs";
2+
import { parseObject } from "../../common/utils.mjs";
3+
4+
export default {
5+
key: "sanity-create-document",
6+
name: "Create Document",
7+
description: "Create a document in a dataset in Sanity. [See the documentation](https://www.sanity.io/docs/http-reference/actions)",
8+
version: "0.0.1",
9+
type: "action",
10+
annotations: {
11+
destructiveHint: false,
12+
openWorldHint: true,
13+
readOnlyHint: false,
14+
},
15+
props: {
16+
sanity,
17+
dataset: {
18+
propDefinition: [
19+
sanity,
20+
"dataset",
21+
],
22+
},
23+
documentId: {
24+
type: "string",
25+
label: "Document ID",
26+
description: "A unique identifier for the document to create",
27+
},
28+
type: {
29+
type: "string",
30+
label: "Type",
31+
description: "The type of document to create. Example: `post`",
32+
},
33+
additionalFields: {
34+
type: "object",
35+
label: "Additional Fields",
36+
description: "Additional fields to add to the document. Example: `{\"title\":\"My First Post\",\"slug\":{\"current\":\"my-first-post\"},\"body\":[{\"_type\":\"block\",\"children\":[{\"_type\":\"span\",\"text\":\"Hello world!\"}]}]}`",
37+
optional: true,
38+
},
39+
},
40+
async run({ $ }) {
41+
const response = await this.sanity.createDocument({
42+
$,
43+
dataset: this.dataset,
44+
data: {
45+
actions: [
46+
{
47+
actionType: "sanity.action.document.create",
48+
publishedId: this.documentId,
49+
document: {
50+
_id: `drafts.${this.documentId}`,
51+
_type: this.type,
52+
...parseObject(this.additionalFields),
53+
},
54+
},
55+
],
56+
},
57+
});
58+
59+
$.export("$summary", "Successfully created document");
60+
return response;
61+
},
62+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import sanity from "../../sanity.app.mjs";
2+
3+
export default {
4+
key: "sanity-get-document",
5+
name: "Get Document",
6+
description: "Get a document from a dataset in Sanity. [See the documentation](https://www.sanity.io/docs/http-reference/doc#getDocuments)",
7+
version: "0.0.1",
8+
type: "action",
9+
annotations: {
10+
destructiveHint: false,
11+
openWorldHint: true,
12+
readOnlyHint: true,
13+
},
14+
props: {
15+
sanity,
16+
dataset: {
17+
propDefinition: [
18+
sanity,
19+
"dataset",
20+
],
21+
},
22+
documentId: {
23+
propDefinition: [
24+
sanity,
25+
"documentId",
26+
({ dataset }) => ({
27+
dataset,
28+
}),
29+
],
30+
},
31+
},
32+
async run({ $ }) {
33+
const response = await this.sanity.getDocument({
34+
$,
35+
dataset: this.dataset,
36+
documentId: this.documentId,
37+
});
38+
39+
$.export("$summary", "Successfully retrieved document");
40+
return response;
41+
},
42+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import sanity from "../../sanity.app.mjs";
2+
3+
export default {
4+
key: "sanity-query-dataset",
5+
name: "Query Dataset",
6+
description: "Query a dataset in Sanity. [See the documentation](https://www.sanity.io/docs/http-reference/query)",
7+
version: "0.0.1",
8+
type: "action",
9+
annotations: {
10+
destructiveHint: false,
11+
openWorldHint: true,
12+
readOnlyHint: true,
13+
},
14+
props: {
15+
sanity,
16+
dataset: {
17+
propDefinition: [
18+
sanity,
19+
"dataset",
20+
],
21+
},
22+
query: {
23+
type: "string",
24+
label: "Query",
25+
description: "The GROQ query to run. Example: `*[_type == 'movie']`. Note: The default query `*` returns all documents in the dataset.",
26+
default: "*",
27+
},
28+
},
29+
async run({ $ }) {
30+
const response = await this.sanity.queryDataset({
31+
$,
32+
dataset: this.dataset,
33+
params: {
34+
query: this.query,
35+
},
36+
});
37+
38+
$.export("$summary", "Successfully queried dataset");
39+
return response;
40+
},
41+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const API_VERSION = "v2025-02-19";
2+
const DEFAULT_LIMIT = 50;
3+
4+
export {
5+
API_VERSION,
6+
DEFAULT_LIMIT,
7+
};

components/sanity/common/utils.mjs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const parseObject = (obj) => {
2+
if (!obj) {
3+
return undefined;
4+
}
5+
if (typeof obj === "string") {
6+
try {
7+
return JSON.parse(obj);
8+
} catch (e) {
9+
return obj;
10+
}
11+
}
12+
if (Array.isArray(obj)) {
13+
return obj.map(parseObject);
14+
}
15+
if (typeof obj === "object") {
16+
return Object.fromEntries(
17+
Object.entries(obj).map(([
18+
key,
19+
value,
20+
]) => [
21+
key,
22+
parseObject(value),
23+
]),
24+
);
25+
}
26+
return obj;
27+
};
28+
29+
export {
30+
parseObject,
31+
};

components/sanity/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/sanity",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Pipedream Sanity Components",
55
"main": "sanity.app.mjs",
66
"keywords": [
@@ -11,5 +11,8 @@
1111
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
1212
"publishConfig": {
1313
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.1.1"
1417
}
15-
}
18+
}

components/sanity/sanity.app.mjs

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,93 @@
1+
import { axios } from "@pipedream/platform";
2+
import {
3+
API_VERSION, DEFAULT_LIMIT,
4+
} from "./common/constants.mjs";
5+
16
export default {
27
type: "app",
38
app: "sanity",
4-
propDefinitions: {},
9+
propDefinitions: {
10+
dataset: {
11+
type: "string",
12+
label: "Dataset",
13+
description: "The dataset to use",
14+
},
15+
documentId: {
16+
type: "string",
17+
label: "Document ID",
18+
description: "The document ID to use",
19+
async options({
20+
dataset, page,
21+
}) {
22+
const response = await this.queryDataset({
23+
dataset,
24+
params: {
25+
query: `* | order(_id) [${DEFAULT_LIMIT * page}...${DEFAULT_LIMIT * (page + 1)}]`,
26+
},
27+
});
28+
return response.result?.map(({ _id }) => _id) || [];
29+
},
30+
},
31+
},
532
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
33+
_projectId() {
34+
return this.$auth.project_id;
35+
},
36+
_baseUrl(version = API_VERSION) {
37+
return `https://${this._projectId()}.api.sanity.io/${version}`;
38+
},
39+
_makeRequest({
40+
$ = this, path, version, ...opts
41+
}) {
42+
return axios($, {
43+
url: `${this._baseUrl(version)}${path}`,
44+
headers: {
45+
"Authorization": `Bearer ${this.$auth.api_token}`,
46+
"Content-Type": "application/json",
47+
},
48+
...opts,
49+
});
50+
},
51+
createWebhook(opts = {}) {
52+
return this._makeRequest({
53+
path: `/hooks/projects/${this._projectId()}`,
54+
method: "POST",
55+
...opts,
56+
});
57+
},
58+
deleteWebhook({
59+
hookId, ...opts
60+
}) {
61+
return this._makeRequest({
62+
path: `/hooks/projects/${this._projectId()}/${hookId}`,
63+
method: "DELETE",
64+
...opts,
65+
});
66+
},
67+
getDocument({
68+
dataset, documentId, ...opts
69+
}) {
70+
return this._makeRequest({
71+
path: `/data/doc/${dataset}/${documentId}`,
72+
...opts,
73+
});
74+
},
75+
queryDataset({
76+
dataset, ...opts
77+
}) {
78+
return this._makeRequest({
79+
path: `/data/query/${dataset}`,
80+
...opts,
81+
});
82+
},
83+
createDocument({
84+
dataset, ...opts
85+
}) {
86+
return this._makeRequest({
87+
path: `/data/actions/${dataset}`,
88+
method: "POST",
89+
...opts,
90+
});
991
},
1092
},
11-
};
93+
};
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import sanity from "../../sanity.app.mjs";
2+
import { ConfigurationError } from "@pipedream/platform";
3+
import { API_VERSION } from "../../common/constants.mjs";
4+
5+
export default {
6+
props: {
7+
sanity,
8+
db: "$.service.db",
9+
http: {
10+
type: "$.interface.http",
11+
customResponse: true,
12+
},
13+
name: {
14+
type: "string",
15+
label: "Webhook Name",
16+
description: "The name of the webhook",
17+
},
18+
dataset: {
19+
propDefinition: [
20+
sanity,
21+
"dataset",
22+
],
23+
},
24+
},
25+
methods: {
26+
_getHookId() {
27+
return this.db.get("hookId");
28+
},
29+
_setHookId(hookId) {
30+
this.db.set("hookId", hookId);
31+
},
32+
getWebhookArgs() {
33+
throw new ConfigurationError("getWebhookArgs is not implemented");
34+
},
35+
generateMeta() {
36+
throw new ConfigurationError("generateMeta is not implemented");
37+
},
38+
},
39+
hooks: {
40+
async activate() {
41+
const webhookArgs = this.getWebhookArgs();
42+
const { id } = await this.sanity.createWebhook({
43+
data: {
44+
name: this.name,
45+
url: this.http.endpoint,
46+
dataset: this.dataset,
47+
apiVersion: API_VERSION,
48+
...webhookArgs,
49+
},
50+
});
51+
this._setHookId(id);
52+
},
53+
async deactivate() {
54+
const hookId = this._getHookId();
55+
if (hookId) {
56+
await this.sanity.deleteWebhook({
57+
hookId,
58+
});
59+
}
60+
},
61+
},
62+
async run({ body }) {
63+
if (!body) {
64+
return;
65+
}
66+
67+
this.http.respond({
68+
status: 200,
69+
});
70+
71+
const meta = this.generateMeta(body);
72+
this.$emit(body, meta);
73+
},
74+
};

0 commit comments

Comments
 (0)