From 7c79e93927b7ece4aa1ae3dacc4dd0a966f6b587 Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Tue, 30 Apr 2024 16:17:12 -0400 Subject: [PATCH 01/19] initial draft modeler api --- .env.example | 6 ++++- modeler.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 modeler.js diff --git a/.env.example b/.env.example index 21aa38e..f486b1d 100644 --- a/.env.example +++ b/.env.example @@ -16,4 +16,8 @@ COMPONENTS_CLIENT_SECRET=fill-this-in # Required for Optimize API tutorial, to access API OPTIMIZE_BASE_URL=fill-this-in -OPTIMIZE_AUDIENCE=https://optimize.camunda.io \ No newline at end of file +OPTIMIZE_AUDIENCE=https://optimize.camunda.io + +# Required for Web Modeler API tutorial, to access API +MODELER_BASE_URL=fill-this-in +MODELER_AUDIENCE=https://modeler.cloud.camunda.io/api/v1/info \ No newline at end of file diff --git a/modeler.js b/modeler.js new file mode 100644 index 0000000..6bc64d8 --- /dev/null +++ b/modeler.js @@ -0,0 +1,73 @@ +import axios from "axios"; +import { getAccessToken } from "./auth.js"; + +// An action that retrieves a file. +async function retrieveFile([fileId]) { + const modelerAudience = process.env.MODELER_AUDIENCE; + const accessToken = await getAccessToken("components", modelerAudience); + + const modelerApiUrl = process.env.MODELER_BASE_URL; + + const url = `${modelerApiUrl}/api/v1/files/${fileId}`; + +// Configure the API call. + const options = { + method: "GET", + url, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + } + }; + + try { + const response = await axios(options); + const results = response.data; + + results.forEach(x => console.log(`ID: ${x.fileId}`)); + } catch (error) { + // Emit an error from the server. + console.error(error.message); + } +} + +async function deleteFile([fileId]) { + console.log(`deleting file ${fileId}`); + + const modelerAudience = process.env.MODELER_AUDIENCE; + const accessToken = await getAccessToken("components", modelerAudience); + const modelerApiUrl = process.env.MODELER_API_URL; + + const url = `${modelerApiUrl}/api/v1/files/${fileId}`; + + // Configure the API call. + const options = { + method: "DELETE", + url, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + } + }; + + try { + // Call the delete endpoint. + const response = await axios(options); + + // Process the results from the API call. + if (response.status === 204) { + console.log(`File ${fileId} was deleted!`); + } else { + // Emit an unexpected error message. + console.error("Unable to delete file!"); + } + } catch (error) { + // Emit an error from the server. + console.error(error.message); + } + } + +export default { + retrieve: retrieveFile, + delete: deleteFile + }; \ No newline at end of file From 71fddd1ea29441f18f072158932505bb66495fb6 Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Wed, 8 May 2024 10:48:21 -0400 Subject: [PATCH 02/19] draft up changes for modeler api tutorial --- .env.example | 3 +-- modeler.js | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index f486b1d..e84fe6f 100644 --- a/.env.example +++ b/.env.example @@ -19,5 +19,4 @@ OPTIMIZE_BASE_URL=fill-this-in OPTIMIZE_AUDIENCE=https://optimize.camunda.io # Required for Web Modeler API tutorial, to access API -MODELER_BASE_URL=fill-this-in -MODELER_AUDIENCE=https://modeler.cloud.camunda.io/api/v1/info \ No newline at end of file +MODELER_AUDIENCE=https://modeler.cloud.camunda.io/api/v1 \ No newline at end of file diff --git a/modeler.js b/modeler.js index 6bc64d8..a34f4fc 100644 --- a/modeler.js +++ b/modeler.js @@ -6,9 +6,7 @@ async function retrieveFile([fileId]) { const modelerAudience = process.env.MODELER_AUDIENCE; const accessToken = await getAccessToken("components", modelerAudience); - const modelerApiUrl = process.env.MODELER_BASE_URL; - - const url = `${modelerApiUrl}/api/v1/files/${fileId}`; + const url = `process.env.MODELER_AUDIENCE/files/${fileId}`; // Configure the API call. const options = { @@ -24,7 +22,7 @@ async function retrieveFile([fileId]) { const response = await axios(options); const results = response.data; - results.forEach(x => console.log(`ID: ${x.fileId}`)); + results.forEach(x => console.log(`File retrieved! ID: ${id}. Name: ${name}`)); } catch (error) { // Emit an error from the server. console.error(error.message); From 8c186f296a6f377571e87a0422d37bb5d6e6d9df Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Wed, 8 May 2024 10:49:36 -0400 Subject: [PATCH 03/19] fix endpoint --- modeler.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modeler.js b/modeler.js index a34f4fc..efbc85c 100644 --- a/modeler.js +++ b/modeler.js @@ -34,9 +34,8 @@ async function deleteFile([fileId]) { const modelerAudience = process.env.MODELER_AUDIENCE; const accessToken = await getAccessToken("components", modelerAudience); - const modelerApiUrl = process.env.MODELER_API_URL; - - const url = `${modelerApiUrl}/api/v1/files/${fileId}`; + + const url = `process.env.MODELER_AUDIENCE/files/${fileId}`; // Configure the API call. const options = { From f254f459367a2a5f80b3ee65f4107620fe35e200 Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Thu, 9 May 2024 16:28:00 -0600 Subject: [PATCH 04/19] Update modeler.js Co-authored-by: Steven Hicks --- modeler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modeler.js b/modeler.js index efbc85c..1b1e7b3 100644 --- a/modeler.js +++ b/modeler.js @@ -6,7 +6,7 @@ async function retrieveFile([fileId]) { const modelerAudience = process.env.MODELER_AUDIENCE; const accessToken = await getAccessToken("components", modelerAudience); - const url = `process.env.MODELER_AUDIENCE/files/${fileId}`; + const url = `${process.env.MODELER_BASE_URL}/files/${fileId}`; // Configure the API call. const options = { From 6e943b9ab603c544f9fb999e2d202dd2d78ee0a8 Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Thu, 9 May 2024 18:35:39 -0400 Subject: [PATCH 05/19] clean up audience/baseurl references --- .env.example | 5 +++-- modeler.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index e84fe6f..8c0b984 100644 --- a/.env.example +++ b/.env.example @@ -16,7 +16,8 @@ COMPONENTS_CLIENT_SECRET=fill-this-in # Required for Optimize API tutorial, to access API OPTIMIZE_BASE_URL=fill-this-in -OPTIMIZE_AUDIENCE=https://optimize.camunda.io +OPTIMIZE_AUDIENCE=optimize.camunda.io # Required for Web Modeler API tutorial, to access API -MODELER_AUDIENCE=https://modeler.cloud.camunda.io/api/v1 \ No newline at end of file +MODELER_BASE_URL=https://modeler.cloud.camunda.io/api/v1 +MODELER_AUDIENCE=modeler.cloud.camunda.io \ No newline at end of file diff --git a/modeler.js b/modeler.js index 1b1e7b3..b17b508 100644 --- a/modeler.js +++ b/modeler.js @@ -35,7 +35,7 @@ async function deleteFile([fileId]) { const modelerAudience = process.env.MODELER_AUDIENCE; const accessToken = await getAccessToken("components", modelerAudience); - const url = `process.env.MODELER_AUDIENCE/files/${fileId}`; + const url = `${process.env.MODELER_BASE_URL}/files/${fileId}`; // Configure the API call. const options = { From 135ee4b1e516dd4155dcd552514a289544792132 Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Fri, 7 Jun 2024 15:34:08 -0400 Subject: [PATCH 06/19] clean up PR based on auth changes --- .env.example | 2 ++ cli.js | 3 ++- modeler.js | 21 ++++++++++++++------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.env.example b/.env.example index 065941e..d798fdf 100644 --- a/.env.example +++ b/.env.example @@ -33,5 +33,7 @@ OPTIMIZE_AUDIENCE=optimize.camunda.io # Required for Web Modeler API tutorial, to access API MODELER_BASE_URL=https://modeler.cloud.camunda.io/api/v1 MODELER_AUDIENCE=modeler.cloud.camunda.io +MODELER_CLIENT_ID=fill-this-in +MODELER_CLIENT_SECRET=fill-this-in diff --git a/cli.js b/cli.js index f011bdd..3e38817 100644 --- a/cli.js +++ b/cli.js @@ -3,11 +3,12 @@ import "dotenv/config"; import admin from "./administration.js"; import optimize from "./optimize.js"; +import modeler from "./modeler.js"; // All API objects accessible to the CLI app are included here. // The name of each property translates to an API object that can be called by the CLI. // e.g. if we export a property named `admin`, you can run `npm run cli admin `. -const APIs = { admin, optimize }; +const APIs = { admin, optimize, modeler }; // Parse the arguments passed into the CLI, and direct a specific action to a specific API object. // Example: `npm run cli administration list` will find the arguments `administration` and `list`, diff --git a/modeler.js b/modeler.js index b17b508..ac437c4 100644 --- a/modeler.js +++ b/modeler.js @@ -1,12 +1,19 @@ import axios from "axios"; import { getAccessToken } from "./auth.js"; +const authorizationConfiguration = { + clientId: process.env.MODELER_CLIENT_ID, + clientSecret: process.env.MODELER_CLIENT_SECRET, + audience: process.env.MODELER_AUDIENCE +}; + // An action that retrieves a file. async function retrieveFile([fileId]) { - const modelerAudience = process.env.MODELER_AUDIENCE; - const accessToken = await getAccessToken("components", modelerAudience); + const accessToken = await getAccessToken(authorizationConfiguration); + + const ModelerBaseUrl = process.env.MODELER_BASE_URL; - const url = `${process.env.MODELER_BASE_URL}/files/${fileId}`; + const url = `${ModelerBaseUrl}/files/${fileId}`; // Configure the API call. const options = { @@ -31,11 +38,11 @@ async function retrieveFile([fileId]) { async function deleteFile([fileId]) { console.log(`deleting file ${fileId}`); - - const modelerAudience = process.env.MODELER_AUDIENCE; - const accessToken = await getAccessToken("components", modelerAudience); - const url = `${process.env.MODELER_BASE_URL}/files/${fileId}`; + const accessToken = await getAccessToken(authorizationConfiguration); + + const ModelerBaseUrl = process.env.MODELER_BASE_URL; + const url = `${ModelerBaseUrl}/files/${fileId}`; // Configure the API call. const options = { From e2c234450ec506894a170495b329b0a22bf55126 Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Tue, 18 Jun 2024 10:33:49 -0400 Subject: [PATCH 07/19] adjust list file to create file call --- modeler.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/modeler.js b/modeler.js index ac437c4..2adadc6 100644 --- a/modeler.js +++ b/modeler.js @@ -7,29 +7,38 @@ const authorizationConfiguration = { audience: process.env.MODELER_AUDIENCE }; -// An action that retrieves a file. -async function retrieveFile([fileId]) { +// An action that creates a file. +async function createFile([fileName]) { const accessToken = await getAccessToken(authorizationConfiguration); const ModelerBaseUrl = process.env.MODELER_BASE_URL; - const url = `${ModelerBaseUrl}/files/${fileId}`; + const url = `${ModelerBaseUrl}/files` ; -// Configure the API call. + // Configure the API call. const options = { - method: "GET", + method: "POST", url, headers: { Accept: "application/json", Authorization: `Bearer ${accessToken}` + }, + data: { + // The body contains information about the new file. + fileName: fileName } }; try { + // Call the add endpoint. const response = await axios(options); - const results = response.data; - results.forEach(x => console.log(`File retrieved! ID: ${id}. Name: ${name}`)); + // Process the results from the API call. + const newFile = response.data; + + console.log( + `Client added! Name: ${newFile.name}. ID: ${newFile.projectId}.` + ); } catch (error) { // Emit an error from the server. console.error(error.message); @@ -72,6 +81,6 @@ async function deleteFile([fileId]) { } export default { - retrieve: retrieveFile, + create: createFile, delete: deleteFile }; \ No newline at end of file From 94ed68cd98d928a555c909dcc639d52f399f22d1 Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Fri, 21 Jun 2024 10:27:02 -0400 Subject: [PATCH 08/19] adjust to projects --- modeler.js | 133 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 44 deletions(-) diff --git a/modeler.js b/modeler.js index 2adadc6..5f24299 100644 --- a/modeler.js +++ b/modeler.js @@ -7,13 +7,16 @@ const authorizationConfiguration = { audience: process.env.MODELER_AUDIENCE }; -// An action that creates a file. -async function createFile([fileName]) { - const accessToken = await getAccessToken(authorizationConfiguration); +// An action that creates a new project. +async function createProject([projectName]) { + // Every request needs an access token. + const accessToken = await getAccessToken(authorizationConfiguration); - const ModelerBaseUrl = process.env.MODELER_BASE_URL; + // These settings come from your .env file. + const modelerApiUrl = process.env.MODELER_API_URL; - const url = `${ModelerBaseUrl}/files` ; + // This is the API endpoint to create a new project. + const url = `${modelerApiUrl}/projects`; // Configure the API call. const options = { @@ -24,8 +27,8 @@ async function createFile([fileName]) { Authorization: `Bearer ${accessToken}` }, data: { - // The body contains information about the new file. - fileName: fileName + // The body contains information about the new project. + projectName: projectName } }; @@ -34,10 +37,10 @@ async function createFile([fileName]) { const response = await axios(options); // Process the results from the API call. - const newFile = response.data; + const newProject = response.data; console.log( - `Client added! Name: ${newFile.name}. ID: ${newFile.projectId}.` + `Project added! Name: ${newProject.name}. ID: ${newProject.projectId}.` ); } catch (error) { // Emit an error from the server. @@ -45,42 +48,84 @@ async function createFile([fileName]) { } } -async function deleteFile([fileId]) { - console.log(`deleting file ${fileId}`); - - const accessToken = await getAccessToken(authorizationConfiguration); - - const ModelerBaseUrl = process.env.MODELER_BASE_URL; - const url = `${ModelerBaseUrl}/files/${fileId}`; - - // Configure the API call. - const options = { - method: "DELETE", - url, - headers: { - Accept: "application/json", - Authorization: `Bearer ${accessToken}` - } - }; - - try { - // Call the delete endpoint. - const response = await axios(options); - - // Process the results from the API call. - if (response.status === 204) { - console.log(`File ${fileId} was deleted!`); - } else { - // Emit an unexpected error message. - console.error("Unable to delete file!"); - } - } catch (error) { - // Emit an error from the server. - console.error(error.message); +// An action that views one project. +async function viewProject([projectId]) { + // Every request needs an access token. + const accessToken = await getAccessToken(authorizationConfiguration); + + // These settings come from your .env file. + const modelerApiUrl = process.env.MODELER_API_URL; + + // This is the API endpoint to view a single project. + const url = `${modelerApiUrl}/projects/${projectId}`; + + // Configure the API call. + const options = { + method: "GET", + url, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + } + }; + + try { + const response = await axios(options); + + // Process the results from the API call. + const id = response.data; + + // Emit the project details. + console.log("Project:", id); + } catch (error) { + // Emit an error from the server. + console.error(error.message); + } +} + +// An action that deletes a project. +async function deleteProject([projectId]) { + // Every request needs an access token. + const accessToken = await getAccessToken(authorizationConfiguration); + + // These settings come from your .env file. + const modelerApiUrl = process.env.MODELER_API_URL; + + // This is the API endpoint to delete a project. + const url = `${modelerApiUrl}/projects/${projectId}`; + + // Configure the API call. + const options = { + method: "DELETE", + url, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + } + }; + + try { + // Call the delete endpoint. + const response = await axios(options); + + // Process the results from the API call. + if (response.status === 204) { + console.log(`Project ${projectId} was deleted!`); + } else { + // Emit an unexpected error message. + console.error("Unable to delete project!"); } + } catch (error) { + // Emit an error from the server. + console.error(error.message); } +} +// These functions are aliased to specific command names for terseness. +// The name of each property translates to a method that can be called by the CLI. +// e.g. if we export a function named `create`, you can run `npm run cli modeler create`. export default { - create: createFile, - delete: deleteFile - }; \ No newline at end of file + create: createProject, + view: viewProject, + delete: deleteProject +}; From 85b4444da2cca85dca1830f929726c1d94bb79d4 Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:05:54 -0600 Subject: [PATCH 09/19] Update modeler.js Co-authored-by: Steven Hicks --- modeler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modeler.js b/modeler.js index 5f24299..188cc87 100644 --- a/modeler.js +++ b/modeler.js @@ -13,7 +13,7 @@ async function createProject([projectName]) { const accessToken = await getAccessToken(authorizationConfiguration); // These settings come from your .env file. - const modelerApiUrl = process.env.MODELER_API_URL; + const modelerApiUrl = process.env.MODELER_BASE_URL; // This is the API endpoint to create a new project. const url = `${modelerApiUrl}/projects`; From a3ac58cfe3ad77b0ad1e585dd93b5719cfd5ef58 Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:06:01 -0600 Subject: [PATCH 10/19] Update modeler.js Co-authored-by: Steven Hicks --- modeler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modeler.js b/modeler.js index 188cc87..ed9fbcf 100644 --- a/modeler.js +++ b/modeler.js @@ -28,7 +28,7 @@ async function createProject([projectName]) { }, data: { // The body contains information about the new project. - projectName: projectName + name: projectName } }; From 6384ab2a01df68b39fbf998b29ad55afc1a05765 Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:06:08 -0600 Subject: [PATCH 11/19] Update modeler.js Co-authored-by: Steven Hicks --- modeler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modeler.js b/modeler.js index ed9fbcf..de6d388 100644 --- a/modeler.js +++ b/modeler.js @@ -40,7 +40,7 @@ async function createProject([projectName]) { const newProject = response.data; console.log( - `Project added! Name: ${newProject.name}. ID: ${newProject.projectId}.` + `Project added! Name: ${newProject.name}. ID: ${newProject.id}.` ); } catch (error) { // Emit an error from the server. From a88ff4e46e982469d169dd49c3b10a5c2dbc17d7 Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:06:14 -0600 Subject: [PATCH 12/19] Update modeler.js Co-authored-by: Steven Hicks --- modeler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modeler.js b/modeler.js index de6d388..a705d24 100644 --- a/modeler.js +++ b/modeler.js @@ -54,7 +54,7 @@ async function viewProject([projectId]) { const accessToken = await getAccessToken(authorizationConfiguration); // These settings come from your .env file. - const modelerApiUrl = process.env.MODELER_API_URL; + const modelerApiUrl = process.env.MODELER_BASE_URL; // This is the API endpoint to view a single project. const url = `${modelerApiUrl}/projects/${projectId}`; From 56bb6a7e81bd11fa57ebf287bb7841a21bdd693e Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:06:21 -0600 Subject: [PATCH 13/19] Update modeler.js Co-authored-by: Steven Hicks --- modeler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modeler.js b/modeler.js index a705d24..e323c9d 100644 --- a/modeler.js +++ b/modeler.js @@ -89,7 +89,7 @@ async function deleteProject([projectId]) { const accessToken = await getAccessToken(authorizationConfiguration); // These settings come from your .env file. - const modelerApiUrl = process.env.MODELER_API_URL; + const modelerApiUrl = process.env.MODELER_BASE_URL; // This is the API endpoint to delete a project. const url = `${modelerApiUrl}/projects/${projectId}`; From 1a213ef909f7f4d493a75a5e17158a7b984e7af0 Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:06:26 -0600 Subject: [PATCH 14/19] Update modeler.js Co-authored-by: Steven Hicks --- modeler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modeler.js b/modeler.js index e323c9d..30b9f46 100644 --- a/modeler.js +++ b/modeler.js @@ -73,10 +73,10 @@ async function viewProject([projectId]) { const response = await axios(options); // Process the results from the API call. - const id = response.data; + const data = response.data; // Emit the project details. - console.log("Project:", id); + console.log("Project:", data); } catch (error) { // Emit an error from the server. console.error(error.message); From 5887d259b66adc149039492fabf5d8b33c86023c Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Wed, 26 Jun 2024 09:58:42 -0400 Subject: [PATCH 15/19] resolve comments --- .env.example | 6 +++++- modeler.js | 57 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/.env.example b/.env.example index d798fdf..94af0fa 100644 --- a/.env.example +++ b/.env.example @@ -30,10 +30,14 @@ OPTIMIZE_BASE_URL=fill-this-in ## This value will only change if you're not using SaaS. OPTIMIZE_AUDIENCE=optimize.camunda.io -# Required for Web Modeler API tutorial, to access API +# Web Modeler API tutorial + +## These values will only change if you're not using SaaS. MODELER_BASE_URL=https://modeler.cloud.camunda.io/api/v1 MODELER_AUDIENCE=modeler.cloud.camunda.io +### This value comes from the `CAMUNDA_CONSOLE_CLIENT_ID`. MODELER_CLIENT_ID=fill-this-in +### This value comes from the `CAMUNDA_CONSOLE_CLIENT_SECRET`. MODELER_CLIENT_SECRET=fill-this-in diff --git a/modeler.js b/modeler.js index 30b9f46..c6b14a5 100644 --- a/modeler.js +++ b/modeler.js @@ -48,73 +48,86 @@ async function createProject([projectName]) { } } -// An action that views one project. -async function viewProject([projectId]) { +// A function that adds a new collaborator to a project +async function addCollaborator([collaboratorEmail, projectId, role]) { // Every request needs an access token. const accessToken = await getAccessToken(authorizationConfiguration); // These settings come from your .env file. const modelerApiUrl = process.env.MODELER_BASE_URL; - // This is the API endpoint to view a single project. - const url = `${modelerApiUrl}/projects/${projectId}`; + // This is the API endpoint to add a new collaborator. + const url = `${modelerApiUrl}/collaborators`; // Configure the API call. const options = { - method: "GET", + method: "PUT", url, headers: { Accept: "application/json", Authorization: `Bearer ${accessToken}` + }, + data: { + // The body contains information about the new collaborator. + collaboratorEmail: collaboratorEmail, + projectId: projectId, + role: role } }; try { + // Call the endpoint. const response = await axios(options); // Process the results from the API call. - const data = response.data; + const newCollaborator = response.data; - // Emit the project details. - console.log("Project:", data); + // Emit new collaborator to output. + console.log( + `Collaborator added! Email: ${newCollaborator.email}. Role: ${newCollaborator.role}.` + ); } catch (error) { // Emit an error from the server. console.error(error.message); } } -// An action that deletes a project. -async function deleteProject([projectId]) { +// A function that searches for collaborators. +async function findCollaborator([]) { // Every request needs an access token. const accessToken = await getAccessToken(authorizationConfiguration); // These settings come from your .env file. const modelerApiUrl = process.env.MODELER_BASE_URL; - // This is the API endpoint to delete a project. - const url = `${modelerApiUrl}/projects/${projectId}`; + // This is the API endpoint to search for a collaborator. + const url = `${modelerApiUrl}/collaborators/search`; // Configure the API call. const options = { - method: "DELETE", + method: "POST", url, headers: { Accept: "application/json", Authorization: `Bearer ${accessToken}` + }, + data: { + // The body contains information about the collaborator you're searchiing for. + collaboratorEmail: collaboratorEmail } }; try { - // Call the delete endpoint. + // Call the endpoint. const response = await axios(options); // Process the results from the API call. - if (response.status === 204) { - console.log(`Project ${projectId} was deleted!`); - } else { - // Emit an unexpected error message. - console.error("Unable to delete project!"); - } + const collaboratorEmail = response.data; + + // Emit collaborator to output. + console.log( + `Collaborator found! Email: ${collaboratorEmail.email}.` + ); } catch (error) { // Emit an error from the server. console.error(error.message); @@ -126,6 +139,6 @@ async function deleteProject([projectId]) { // e.g. if we export a function named `create`, you can run `npm run cli modeler create`. export default { create: createProject, - view: viewProject, - delete: deleteProject + add: addCollaborator, + find: findCollaborator }; From d7244c47189134492070f959967f04cba1f99c67 Mon Sep 17 00:00:00 2001 From: Steven Hicks Date: Tue, 16 Jul 2024 20:31:45 -0500 Subject: [PATCH 16/19] Update modeler API client to create a project with a collaborator, and view and delete projects --- modeler.js | 100 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 40 deletions(-) diff --git a/modeler.js b/modeler.js index c6b14a5..be7760b 100644 --- a/modeler.js +++ b/modeler.js @@ -8,20 +8,22 @@ const authorizationConfiguration = { }; // An action that creates a new project. -async function createProject([projectName]) { +async function createProject([projectName, adminEmail]) { // Every request needs an access token. const accessToken = await getAccessToken(authorizationConfiguration); // These settings come from your .env file. const modelerApiUrl = process.env.MODELER_BASE_URL; + // Step 1: Create a new project. + // This is the API endpoint to create a new project. - const url = `${modelerApiUrl}/projects`; + const projectUrl = `${modelerApiUrl}/projects`; // Configure the API call. - const options = { + const projectOptions = { method: "POST", - url, + url: projectUrl, headers: { Accept: "application/json", Authorization: `Bearer ${accessToken}` @@ -33,45 +35,69 @@ async function createProject([projectName]) { }; try { - // Call the add endpoint. - const response = await axios(options); + // Call the add project endpoint. + const response = await axios(projectOptions); - // Process the results from the API call. + // Capture data from the new project. const newProject = response.data; console.log( `Project added! Name: ${newProject.name}. ID: ${newProject.id}.` ); + + // Step 2: Add a collaborator to the project. + + // This is the API endpoint to add a collaborator to a project. + const collaboratorUrl = `${modelerApiUrl}/collaborators`; + + // Configure the API call. + const collaboratorOptions = { + method: "PUT", + url: collaboratorUrl, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + }, + data: { + // The body contains information about the project and collaborator. + email: adminEmail, + projectId: newProject.id, + role: "project_admin" + } + }; + + // Call the add collaborator endpoint. + const collaboratorResponse = await axios(collaboratorOptions); + + if (collaboratorResponse.status === 204) { + console.log(`Collaborator added! Email: ${adminEmail}.`); + } else { + console.error("Unable to add collaborator!"); + } } catch (error) { // Emit an error from the server. console.error(error.message); } } -// A function that adds a new collaborator to a project -async function addCollaborator([collaboratorEmail, projectId, role]) { +// An action to view details of a project. +async function viewProject([projectId]) { // Every request needs an access token. const accessToken = await getAccessToken(authorizationConfiguration); // These settings come from your .env file. const modelerApiUrl = process.env.MODELER_BASE_URL; - // This is the API endpoint to add a new collaborator. - const url = `${modelerApiUrl}/collaborators`; + // This is the API endpoint to retrieve details of a project. + const url = `${modelerApiUrl}/projects/${projectId}`; // Configure the API call. const options = { - method: "PUT", + method: "GET", url, headers: { Accept: "application/json", Authorization: `Bearer ${accessToken}` - }, - data: { - // The body contains information about the new collaborator. - collaboratorEmail: collaboratorEmail, - projectId: projectId, - role: role } }; @@ -80,54 +106,48 @@ async function addCollaborator([collaboratorEmail, projectId, role]) { const response = await axios(options); // Process the results from the API call. - const newCollaborator = response.data; + const project = response.data; // Emit new collaborator to output. - console.log( - `Collaborator added! Email: ${newCollaborator.email}. Role: ${newCollaborator.role}.` - ); + console.log("Project:", project); } catch (error) { // Emit an error from the server. console.error(error.message); } } -// A function that searches for collaborators. -async function findCollaborator([]) { +// An action that deletes a project. +async function deleteProject([projectId]) { // Every request needs an access token. const accessToken = await getAccessToken(authorizationConfiguration); // These settings come from your .env file. const modelerApiUrl = process.env.MODELER_BASE_URL; - // This is the API endpoint to search for a collaborator. - const url = `${modelerApiUrl}/collaborators/search`; + // This is the API endpoint to delete a project. + const url = `${modelerApiUrl}/projects/${projectId}`; // Configure the API call. const options = { - method: "POST", + method: "DELETE", url, headers: { Accept: "application/json", Authorization: `Bearer ${accessToken}` - }, - data: { - // The body contains information about the collaborator you're searchiing for. - collaboratorEmail: collaboratorEmail } }; try { - // Call the endpoint. + // Call the delete endpoint. const response = await axios(options); // Process the results from the API call. - const collaboratorEmail = response.data; - - // Emit collaborator to output. - console.log( - `Collaborator found! Email: ${collaboratorEmail.email}.` - ); + if (response.status === 204) { + console.log(`Project ${projectId} was deleted!`); + } else { + // Emit an unexpected error message. + console.error("Unable to delete project!"); + } } catch (error) { // Emit an error from the server. console.error(error.message); @@ -139,6 +159,6 @@ async function findCollaborator([]) { // e.g. if we export a function named `create`, you can run `npm run cli modeler create`. export default { create: createProject, - add: addCollaborator, - find: findCollaborator + view: viewProject, + delete: deleteProject }; From 499b9fde8175fca699f592cf456faaddd9b2f041 Mon Sep 17 00:00:00 2001 From: Steven Hicks Date: Thu, 18 Jul 2024 09:13:42 -0500 Subject: [PATCH 17/19] update obsolete comment --- modeler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modeler.js b/modeler.js index be7760b..9919524 100644 --- a/modeler.js +++ b/modeler.js @@ -108,7 +108,7 @@ async function viewProject([projectId]) { // Process the results from the API call. const project = response.data; - // Emit new collaborator to output. + // Emit the project to output. console.log("Project:", project); } catch (error) { // Emit an error from the server. From 219bdaf7c3ba44cb50d3c6df357b7a2727e9547c Mon Sep 17 00:00:00 2001 From: christinaausley <84338309+christinaausley@users.noreply.github.com> Date: Wed, 7 Aug 2024 09:11:41 -0600 Subject: [PATCH 18/19] Update .env.example --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 94af0fa..abcb5db 100644 --- a/.env.example +++ b/.env.example @@ -33,7 +33,7 @@ OPTIMIZE_AUDIENCE=optimize.camunda.io # Web Modeler API tutorial ## These values will only change if you're not using SaaS. -MODELER_BASE_URL=https://modeler.cloud.camunda.io/api/v1 +MODELER_BASE_URL=https://modeler.camunda.io/api/v1 MODELER_AUDIENCE=modeler.cloud.camunda.io ### This value comes from the `CAMUNDA_CONSOLE_CLIENT_ID`. MODELER_CLIENT_ID=fill-this-in From 69463f8c9d5c11e9070ee72c19816af2ba5cdfd3 Mon Sep 17 00:00:00 2001 From: Christina Ausley Date: Wed, 7 Aug 2024 11:29:11 -0400 Subject: [PATCH 19/19] move to completed --- completed/modeler.js | 164 +++++++++++++++++++++++++++++++++++++++++++ modeler.js | 145 +------------------------------------- 2 files changed, 167 insertions(+), 142 deletions(-) create mode 100644 completed/modeler.js diff --git a/completed/modeler.js b/completed/modeler.js new file mode 100644 index 0000000..15e8acf --- /dev/null +++ b/completed/modeler.js @@ -0,0 +1,164 @@ +import axios from "axios"; +import { getAccessToken } from "../auth.js"; + +const authorizationConfiguration = { + clientId: process.env.MODELER_CLIENT_ID, + clientSecret: process.env.MODELER_CLIENT_SECRET, + audience: process.env.MODELER_AUDIENCE +}; + +// An action that creates a new project. +async function createProject([projectName, adminEmail]) { + // Every request needs an access token. + const accessToken = await getAccessToken(authorizationConfiguration); + + // These settings come from your .env file. + const modelerApiUrl = process.env.MODELER_BASE_URL; + + // Step 1: Create a new project. + + // This is the API endpoint to create a new project. + const projectUrl = `${modelerApiUrl}/projects`; + + // Configure the API call. + const projectOptions = { + method: "POST", + url: projectUrl, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + }, + data: { + // The body contains information about the new project. + name: projectName + } + }; + + try { + // Call the add project endpoint. + const response = await axios(projectOptions); + + // Capture data from the new project. + const newProject = response.data; + + console.log( + `Project added! Name: ${newProject.name}. ID: ${newProject.id}.` + ); + + // Step 2: Add a collaborator to the project. + + // This is the API endpoint to add a collaborator to a project. + const collaboratorUrl = `${modelerApiUrl}/collaborators`; + + // Configure the API call. + const collaboratorOptions = { + method: "PUT", + url: collaboratorUrl, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + }, + data: { + // The body contains information about the project and collaborator. + email: adminEmail, + projectId: newProject.id, + role: "project_admin" + } + }; + + // Call the add collaborator endpoint. + const collaboratorResponse = await axios(collaboratorOptions); + + if (collaboratorResponse.status === 204) { + console.log(`Collaborator added! Email: ${adminEmail}.`); + } else { + console.error("Unable to add collaborator!"); + } + } catch (error) { + // Emit an error from the server. + console.error(error.message); + } +} + +// An action to view details of a project. +async function viewProject([projectId]) { + // Every request needs an access token. + const accessToken = await getAccessToken(authorizationConfiguration); + + // These settings come from your .env file. + const modelerApiUrl = process.env.MODELER_BASE_URL; + + // This is the API endpoint to retrieve details of a project. + const url = `${modelerApiUrl}/projects/${projectId}`; + + // Configure the API call. + const options = { + method: "GET", + url, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + } + }; + + try { + // Call the endpoint. + const response = await axios(options); + + // Process the results from the API call. + const project = response.data; + + // Emit the project to output. + console.log("Project:", project); + } catch (error) { + // Emit an error from the server. + console.error(error.message); + } +} + +// An action that deletes a project. +async function deleteProject([projectId]) { + // Every request needs an access token. + const accessToken = await getAccessToken(authorizationConfiguration); + + // These settings come from your .env file. + const modelerApiUrl = process.env.MODELER_BASE_URL; + + // This is the API endpoint to delete a project. + const url = `${modelerApiUrl}/projects/${projectId}`; + + // Configure the API call. + const options = { + method: "DELETE", + url, + headers: { + Accept: "application/json", + Authorization: `Bearer ${accessToken}` + } + }; + + try { + // Call the delete endpoint. + const response = await axios(options); + + // Process the results from the API call. + if (response.status === 204) { + console.log(`Project ${projectId} was deleted!`); + } else { + // Emit an unexpected error message. + console.error("Unable to delete project!"); + } + } catch (error) { + // Emit an error from the server. + console.error(error.message); + } +} + +// These functions are aliased to specific command names for terseness. +// The name of each property translates to a method that can be called by the CLI. +// e.g. if we export a function named `create`, you can run `npm run cli modeler create`. +export default { + create: createProject, + view: viewProject, + delete: deleteProject +}; diff --git a/modeler.js b/modeler.js index 9919524..ccad77e 100644 --- a/modeler.js +++ b/modeler.js @@ -1,158 +1,19 @@ import axios from "axios"; -import { getAccessToken } from "./auth.js"; +import { getAccessToken } from "../auth.js"; -const authorizationConfiguration = { - clientId: process.env.MODELER_CLIENT_ID, - clientSecret: process.env.MODELER_CLIENT_SECRET, - audience: process.env.MODELER_AUDIENCE -}; - -// An action that creates a new project. async function createProject([projectName, adminEmail]) { - // Every request needs an access token. - const accessToken = await getAccessToken(authorizationConfiguration); - - // These settings come from your .env file. - const modelerApiUrl = process.env.MODELER_BASE_URL; - - // Step 1: Create a new project. - - // This is the API endpoint to create a new project. - const projectUrl = `${modelerApiUrl}/projects`; - - // Configure the API call. - const projectOptions = { - method: "POST", - url: projectUrl, - headers: { - Accept: "application/json", - Authorization: `Bearer ${accessToken}` - }, - data: { - // The body contains information about the new project. - name: projectName - } - }; - - try { - // Call the add project endpoint. - const response = await axios(projectOptions); - - // Capture data from the new project. - const newProject = response.data; - console.log( `Project added! Name: ${newProject.name}. ID: ${newProject.id}.` ); +}; - // Step 2: Add a collaborator to the project. - - // This is the API endpoint to add a collaborator to a project. - const collaboratorUrl = `${modelerApiUrl}/collaborators`; - - // Configure the API call. - const collaboratorOptions = { - method: "PUT", - url: collaboratorUrl, - headers: { - Accept: "application/json", - Authorization: `Bearer ${accessToken}` - }, - data: { - // The body contains information about the project and collaborator. - email: adminEmail, - projectId: newProject.id, - role: "project_admin" - } - }; - - // Call the add collaborator endpoint. - const collaboratorResponse = await axios(collaboratorOptions); - - if (collaboratorResponse.status === 204) { - console.log(`Collaborator added! Email: ${adminEmail}.`); - } else { - console.error("Unable to add collaborator!"); - } - } catch (error) { - // Emit an error from the server. - console.error(error.message); - } -} - -// An action to view details of a project. async function viewProject([projectId]) { - // Every request needs an access token. - const accessToken = await getAccessToken(authorizationConfiguration); - - // These settings come from your .env file. - const modelerApiUrl = process.env.MODELER_BASE_URL; - - // This is the API endpoint to retrieve details of a project. - const url = `${modelerApiUrl}/projects/${projectId}`; - - // Configure the API call. - const options = { - method: "GET", - url, - headers: { - Accept: "application/json", - Authorization: `Bearer ${accessToken}` - } - }; - - try { - // Call the endpoint. - const response = await axios(options); - - // Process the results from the API call. - const project = response.data; - - // Emit the project to output. console.log("Project:", project); - } catch (error) { - // Emit an error from the server. - console.error(error.message); - } } -// An action that deletes a project. async function deleteProject([projectId]) { - // Every request needs an access token. - const accessToken = await getAccessToken(authorizationConfiguration); - - // These settings come from your .env file. - const modelerApiUrl = process.env.MODELER_BASE_URL; - - // This is the API endpoint to delete a project. - const url = `${modelerApiUrl}/projects/${projectId}`; - - // Configure the API call. - const options = { - method: "DELETE", - url, - headers: { - Accept: "application/json", - Authorization: `Bearer ${accessToken}` - } - }; - - try { - // Call the delete endpoint. - const response = await axios(options); - - // Process the results from the API call. - if (response.status === 204) { console.log(`Project ${projectId} was deleted!`); - } else { - // Emit an unexpected error message. - console.error("Unable to delete project!"); } - } catch (error) { - // Emit an error from the server. - console.error(error.message); - } -} // These functions are aliased to specific command names for terseness. // The name of each property translates to a method that can be called by the CLI. @@ -161,4 +22,4 @@ export default { create: createProject, view: viewProject, delete: deleteProject -}; +}; \ No newline at end of file