From b736fc06b9556350bb2b02388992f5fd8746696d Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 7 Jul 2025 19:21:16 -0300 Subject: [PATCH 1/2] [Components] pencil_spaces #17478 Actions - Create Space --- .../actions/create-space/create-space.mjs | 97 ++++++++++++++++ components/pencil_spaces/common/constants.mjs | 10 ++ components/pencil_spaces/common/utils.mjs | 24 ++++ components/pencil_spaces/package.json | 7 +- .../pencil_spaces/pencil_spaces.app.mjs | 106 +++++++++++++++++- 5 files changed, 237 insertions(+), 7 deletions(-) create mode 100644 components/pencil_spaces/actions/create-space/create-space.mjs create mode 100644 components/pencil_spaces/common/constants.mjs create mode 100644 components/pencil_spaces/common/utils.mjs diff --git a/components/pencil_spaces/actions/create-space/create-space.mjs b/components/pencil_spaces/actions/create-space/create-space.mjs new file mode 100644 index 0000000000000..8e9a9561df1a4 --- /dev/null +++ b/components/pencil_spaces/actions/create-space/create-space.mjs @@ -0,0 +1,97 @@ +import { VISIBILITY_OPTIONS } from "../../common/constants.mjs"; +import { parseObject } from "../../common/utils.mjs"; +import pencilSpaces from "../../pencil_spaces.app.mjs"; + +export default { + key: "pencil_spaces-create-space", + name: "Create A Space", + description: "Create a new space in Pencil Spaces. [See the documentation](https://api.pencilspaces.com/reference#tag/spaces/POST/spaces/create)", + version: "0.0.1", + type: "action", + props: { + pencilSpaces, + title: { + type: "string", + label: "Title", + description: "The title of the Space. If not provided and `Space To Clone Id` is set, the existing Space name will be used. If not, a random Space name will be generated.", + optional: true, + }, + spaceToCloneId: { + propDefinition: [ + pencilSpaces, + "spaceToCloneId", + ], + optional: true, + }, + ownerId: { + propDefinition: [ + pencilSpaces, + "ownerId", + ], + optional: true, + }, + hostIds: { + propDefinition: [ + pencilSpaces, + "ownerId", + ], + type: "string[]", + label: "Host Ids", + description: "The hosts you wish to invite to the Space. The user associated with your API key will always be added as a host.", + optional: true, + }, + participantIds: { + propDefinition: [ + pencilSpaces, + "ownerId", + ], + type: "string[]", + label: "Participant Ids", + description: "The participants you wish to invite to the Space.", + optional: true, + }, + visibility: { + type: "string", + label: "Visibility", + description: "The visibility of the Space.", + options: VISIBILITY_OPTIONS, + optional: true, + }, + notifyInvitees: { + type: "boolean", + label: "Notify Invitees", + description: "Whether you want to automatically notify invitees when you create your Space.", + }, + siteId: { + propDefinition: [ + pencilSpaces, + "siteId", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.pencilSpaces.createSpace({ + $, + data: { + title: this.title, + spaceToCloneId: this.spaceToCloneId, + ownerId: { + userId: this.ownerId, + }, + hostIds: parseObject(this.hostIds)?.map((hostId) => ({ + userId: hostId, + })), + participantIds: parseObject(this.participantIds)?.map((participantId) => ({ + userId: participantId, + })), + visibility: this.visibility, + notifyInvitees: this.notifyInvitees, + siteId: this.siteId, + }, + }); + + $.export("$summary", `Successfully created space with ID: "${response.spaceId}"`); + return response; + }, +}; diff --git a/components/pencil_spaces/common/constants.mjs b/components/pencil_spaces/common/constants.mjs new file mode 100644 index 0000000000000..60cf4aee92c68 --- /dev/null +++ b/components/pencil_spaces/common/constants.mjs @@ -0,0 +1,10 @@ +export const VISIBILITY_OPTIONS = [ + { + label: "Public", + value: "public", + }, + { + label: "Private", + value: "private", + }, +]; diff --git a/components/pencil_spaces/common/utils.mjs b/components/pencil_spaces/common/utils.mjs new file mode 100644 index 0000000000000..dcc9cc61f6f41 --- /dev/null +++ b/components/pencil_spaces/common/utils.mjs @@ -0,0 +1,24 @@ +export const parseObject = (obj) => { + if (!obj) return undefined; + + if (Array.isArray(obj)) { + return obj.map((item) => { + if (typeof item === "string") { + try { + return JSON.parse(item); + } catch (e) { + return item; + } + } + return item; + }); + } + if (typeof obj === "string") { + try { + return JSON.parse(obj); + } catch (e) { + return obj; + } + } + return obj; +}; diff --git a/components/pencil_spaces/package.json b/components/pencil_spaces/package.json index f9293bd7e236f..1785429c1876b 100644 --- a/components/pencil_spaces/package.json +++ b/components/pencil_spaces/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/pencil_spaces", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Pencil Spaces Components", "main": "pencil_spaces.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.1.0" } -} \ No newline at end of file +} diff --git a/components/pencil_spaces/pencil_spaces.app.mjs b/components/pencil_spaces/pencil_spaces.app.mjs index 11f10c2e30aba..51460dab6e1aa 100644 --- a/components/pencil_spaces/pencil_spaces.app.mjs +++ b/components/pencil_spaces/pencil_spaces.app.mjs @@ -1,11 +1,107 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "pencil_spaces", - propDefinitions: {}, + propDefinitions: { + spaceToCloneId: { + type: "string", + label: "Space To Clone Id", + description: "The space ID of the Space you want to clone. You may only clone Spaces that are templates, Spaces for which you are a host, and Spaces which you can access as an admin due to your institution settings.", + async options({ page }) { + const { results } = await this.listSpaces({ + params: { + pageNumber: page + 1, + }, + }); + + return results.map(({ + spaceId: value, title: label, + }) => ({ + label, + value, + })); + }, + }, + ownerId: { + type: "string", + label: "Owner Id", + description: "The ID of the user who will be the owner of the space. If not provided, the current user will be the owner.", + async options({ page }) { + const { results } = await this.listUsers({ + params: { + pageNumber: page + 1, + }, + }); + + return results.map(({ + userId: value, email: label, + }) => ({ + label, + value, + })); + }, + }, + siteId: { + type: "string", + label: "Site Id", + description: "The ID of the site you want to create the Space in.", + async options() { + const { results } = await this.listSites(); + + return results.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return this.$auth.api_url; + }, + _headers(headers = {}) { + return { + ...headers, + "Authorization": `Bearer ${this.$auth.api_key}`, + "Content-Type": "application/json", + }; + }, + async _makeRequest({ + $ = this, path, headers, ...opts + }) { + return axios($, { + url: `${this._baseUrl()}${path}`, + headers: this._headers(headers), + ...opts, + }); + }, + listSpaces(opts = {}) { + return this._makeRequest({ + path: "spaces", + ...opts, + }); + }, + listUsers(opts = {}) { + return this._makeRequest({ + path: "users", + ...opts, + }); + }, + listSites(opts = {}) { + return this._makeRequest({ + path: "sites", + ...opts, + }); + }, + createSpace(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "spaces/create", + ...opts, + }); }, }, -}; \ No newline at end of file +}; From 41ea70ec55c313896886ab0b742778ce899c4d13 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 7 Jul 2025 19:25:06 -0300 Subject: [PATCH 2/2] pnpm update --- pnpm-lock.yaml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e1b833f216ee4..793aea65ac206 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9921,7 +9921,11 @@ importers: components/pembee: {} - components/pencil_spaces: {} + components/pencil_spaces: + dependencies: + '@pipedream/platform': + specifier: ^3.1.0 + version: 3.1.0 components/pendo: {} @@ -15832,14 +15836,6 @@ importers: specifier: ^6.0.0 version: 6.2.0 - modelcontextprotocol/node_modules2/@modelcontextprotocol/sdk/dist/cjs: {} - - modelcontextprotocol/node_modules2/@modelcontextprotocol/sdk/dist/esm: {} - - modelcontextprotocol/node_modules2/zod-to-json-schema/dist/cjs: {} - - modelcontextprotocol/node_modules2/zod-to-json-schema/dist/esm: {} - packages/ai: dependencies: '@pipedream/sdk': @@ -36156,7 +36152,7 @@ snapshots: '@pipedream/ramp@0.1.2': dependencies: - '@pipedream/platform': 3.0.3 + '@pipedream/platform': 3.1.0 uuid: 10.0.0 transitivePeerDependencies: - debug @@ -36200,7 +36196,7 @@ snapshots: '@pipedream/shopify@0.7.0': dependencies: - '@pipedream/platform': 3.0.3 + '@pipedream/platform': 3.1.0 async-retry: 1.3.3 bottleneck: 2.19.5 form-data: 4.0.2