diff --git a/marketplace/plugins/azurerepos/.gitignore b/marketplace/plugins/azurerepos/.gitignore new file mode 100644 index 0000000000..23e6609462 --- /dev/null +++ b/marketplace/plugins/azurerepos/.gitignore @@ -0,0 +1,5 @@ +node_modules +lib/*.d.* +lib/*.js +lib/*.js.map +dist/* \ No newline at end of file diff --git a/marketplace/plugins/azurerepos/README.md b/marketplace/plugins/azurerepos/README.md new file mode 100644 index 0000000000..a2984ce849 --- /dev/null +++ b/marketplace/plugins/azurerepos/README.md @@ -0,0 +1,4 @@ + +# Azurerepos + +Documentation on: https://docs.tooljet.com/docs/data-sources/azurerepos \ No newline at end of file diff --git a/marketplace/plugins/azurerepos/__tests__/index.js b/marketplace/plugins/azurerepos/__tests__/index.js new file mode 100644 index 0000000000..ff3eff1fef --- /dev/null +++ b/marketplace/plugins/azurerepos/__tests__/index.js @@ -0,0 +1,7 @@ +'use strict'; + +const azurerepos = require('../lib'); + +describe('azurerepos', () => { + it.todo('needs tests'); +}); diff --git a/marketplace/plugins/azurerepos/lib/icon.svg b/marketplace/plugins/azurerepos/lib/icon.svg new file mode 100644 index 0000000000..2bddce89fd --- /dev/null +++ b/marketplace/plugins/azurerepos/lib/icon.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/marketplace/plugins/azurerepos/lib/index.ts b/marketplace/plugins/azurerepos/lib/index.ts new file mode 100644 index 0000000000..273ca4e423 --- /dev/null +++ b/marketplace/plugins/azurerepos/lib/index.ts @@ -0,0 +1,80 @@ +import { QueryError, QueryResult, QueryService } from '@tooljet-marketplace/common'; +import { SourceOptions, QueryOptions, Operation } from './types'; +import * as azdev from "azure-devops-node-api"; +import { getAzureRepositories, getProjectPullRequests, getRepositoryBranches, getRepositoryCommits, getRepositoryPushes } from './query_operations'; +import { IGitApi } from "azure-devops-node-api/GitApi"; + +export default class Azurerepos implements QueryService { + async run(sourceOptions: SourceOptions, queryOptions: QueryOptions): Promise { + + const connection = await this.getConnection(sourceOptions) + const gitApi: IGitApi = await connection.getGitApi(); + const operation: Operation = queryOptions.operation; + + let result = {}; + + try { + switch (operation) { + case Operation.GetAzureRepo: + result = await getAzureRepositories(gitApi, queryOptions); + break; + case Operation.GetProjectPullRequests: + result = await getProjectPullRequests(gitApi, queryOptions); + break; + case Operation.GetRepoCommits: + result = await getRepositoryCommits(gitApi, queryOptions); + break; + case Operation.GetRepositoryBranches: + result = await getRepositoryBranches(gitApi, queryOptions); + break; + case Operation.getRepositoryPushes: + result = await getRepositoryPushes(gitApi, queryOptions); + break; + default: + throw new QueryError('Query could not be completed', 'Invalid operation', {}); + } + } catch (error) { + throw new QueryError('Query could not be completed', error.message, {}); + } + + return { + status: 'ok', + data: result, + }; + } + async getConnection(sourceOptions: SourceOptions): Promise { + + const organization: string = sourceOptions.organization_name + const token: string = sourceOptions.personal_access_token + + const url = `https://dev.azure.com/${organization}`; + + const authHandler = azdev.getPersonalAccessTokenHandler(token); + + const connection = new azdev.WebApi(url, authHandler); + + return connection + + } + async testConnection(sourceOptions: SourceOptions): Promise { + + const connection = await this.getConnection(sourceOptions) + try { + + const status = await connection.connect(); + + if (status) { + return { + status: 'ok', + }; + } + } catch (error) { + return { + status: 'failed', + message: 'Invalid credentials', + }; + } + } + +} + diff --git a/marketplace/plugins/azurerepos/lib/manifest.json b/marketplace/plugins/azurerepos/lib/manifest.json new file mode 100644 index 0000000000..fd15e29b9f --- /dev/null +++ b/marketplace/plugins/azurerepos/lib/manifest.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://raw.githubusercontent.com/ToolJet/ToolJet/develop/plugins/schemas/manifest.schema.json", + "title": "Azurerepos datasource", + "description": "A schema defining Azurerepos datasource", + "type": "api", + "source": { + "name": "Azurerepos", + "kind": "azurerepos", + "exposedVariables": { + "isLoading": false, + "data": {}, + "rawData": {} + }, + "options": {} + }, + "defaults": {}, + "properties": { + "organization": { + "label": "Organization Name", + "key": "organization_name", + "type": "text", + "description": "Enter your organization name" + }, + "personal_access_token": { + "label": "Personal Access Token", + "key": "personal_access_token", + "type": "password", + "description": "Enter your personal access token", + "hint": "You can generate a personal access token from your Azure account settings." + } + }, + "required": [ + "organization", + "personal_access_token" + ] +} \ No newline at end of file diff --git a/marketplace/plugins/azurerepos/lib/operations.json b/marketplace/plugins/azurerepos/lib/operations.json new file mode 100644 index 0000000000..54f97a6d66 --- /dev/null +++ b/marketplace/plugins/azurerepos/lib/operations.json @@ -0,0 +1,160 @@ +{ + "$schema": "https://raw.githubusercontent.com/ToolJet/ToolJet/develop/plugins/schemas/operations.schema.json", + "title": "Azurerepos datasource", + "description": "A schema defining Azurerepos datasource", + "type": "api", + "defaults": {}, + "properties": { + "operation": { + "label": "Operation", + "key": "operation", + "type": "dropdown-component-flip", + "description": "Single select dropdown for operation", + "list": [ + { + "value": "get_azure_repo", + "name": "Get Azure repository" + }, + { + "value": "get_repo_commits", + "name": "Get repository commits" + }, + { + "value": "get_repo_branches", + "name": "Get repository branches" + }, + { + "value": "get_repo_pushes", + "name": "Get repository pushes" + }, + { + "value": "get_project_pull_requests", + "name": "Get project pull requests" + } + ] + }, + "get_azure_repo": { + "project": { + "label": "Project", + "key": "project_name", + "type": "codehinter", + "lineNumbers": false, + "description": "Enter Project name", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins", + "placeholder": "test" + } + }, + "get_project_pull_requests": { + "project": { + "label": "Project pull requests", + "key": "project_name", + "type": "codehinter", + "lineNumbers": false, + "description": "Enter Project name", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins", + "placeholder": "project name" + }, + "status": { + "label": "Status", + "key": "status", + "className": "codehinter-plugins col-4", + "type": "dropdown", + "description": "Single select dropdown for choosing state", + "list": [ + { + "value": "all", + "name": "All" + }, + { + "value": "active", + "name": "Active" + }, + { + "value": "completed", + "name": "Completed" + }, + { + "value": "abandoned", + "name": "Abandoned" + } + ] + } + }, + "get_repo_commits": { + "project": { + "label": "Project name", + "key": "project_name", + "type": "codehinter", + "lineNumbers": false, + "description": "Enter Project name", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins", + "placeholder": "project name" + }, + "repository": { + "label": "Repository commits", + "key": "repository_name", + "type": "codehinter", + "lineNumbers": false, + "description": "Enter Repository name", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins", + "placeholder": "repository name" + } + }, + "get_repo_branches": { + "project": { + "label": "Project name", + "key": "project_name", + "type": "codehinter", + "lineNumbers": false, + "description": "Enter Project name", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins", + "placeholder": "project name" + }, + "repository": { + "label": "Repository commits", + "key": "repository_name", + "type": "codehinter", + "lineNumbers": false, + "description": "Enter Repository name", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins", + "placeholder": "repository name" + } + }, + "get_repo_pushes": { + "project": { + "label": "Project name", + "key": "project_name", + "type": "codehinter", + "lineNumbers": false, + "description": "Enter Project name", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins", + "placeholder": "project name" + }, + "repository": { + "label": "Repository commits", + "key": "repository_name", + "type": "codehinter", + "lineNumbers": false, + "description": "Enter Repository name", + "width": "320px", + "height": "36px", + "className": "codehinter-plugins", + "placeholder": "repository name" + } + } + } +} \ No newline at end of file diff --git a/marketplace/plugins/azurerepos/lib/query_operations.ts b/marketplace/plugins/azurerepos/lib/query_operations.ts new file mode 100644 index 0000000000..e4674b6dbc --- /dev/null +++ b/marketplace/plugins/azurerepos/lib/query_operations.ts @@ -0,0 +1,36 @@ + +import { PullRequestStatus } from 'azure-devops-node-api/interfaces/GitInterfaces'; +import { QueryOptions } from './types'; +import { IGitApi } from "azure-devops-node-api/GitApi"; + + + +export async function getAzureRepositories(gitApi: IGitApi, queryOptions: QueryOptions) { + const repos = await gitApi.getRepositories(queryOptions.project_name); + return repos; +} + + +export async function getProjectPullRequests(gitApi: IGitApi, queryOptions: QueryOptions) { + + const pullRequests = await gitApi.getPullRequestsByProject(queryOptions.project_name, { status: queryOptions.status as unknown as PullRequestStatus }); + return pullRequests; +} + +export async function getRepositoryCommits(gitApi: IGitApi, queryOptions: QueryOptions) { + + const commits = await gitApi.getCommits(queryOptions.repository_name, {}, queryOptions.project_name); + return commits; +} + +export async function getRepositoryBranches(gitApi: IGitApi, queryOptions: QueryOptions) { + + const branchs = await gitApi.getBranches(queryOptions.repository_name, queryOptions.project_name); + return branchs; +} + +export async function getRepositoryPushes(gitApi: IGitApi, queryOptions: QueryOptions) { + + const pushes = await gitApi.getPushes(queryOptions.repository_name, queryOptions.project_name); + return pushes; +} diff --git a/marketplace/plugins/azurerepos/lib/types.ts b/marketplace/plugins/azurerepos/lib/types.ts new file mode 100644 index 0000000000..e79d48087b --- /dev/null +++ b/marketplace/plugins/azurerepos/lib/types.ts @@ -0,0 +1,18 @@ +export type SourceOptions = { + organization_name: string; + personal_access_token: string; +}; +export type QueryOptions = { + operation: Operation; + project_name: string; + repository_name: string; + status?: 'completed' | 'active' | 'abandoned' | 'all'; +}; + +export enum Operation { + GetAzureRepo = 'get_azure_repo', + GetRepoCommits = 'get_repo_commits', + GetProjectPullRequests = 'get_project_pull_requests', + GetRepositoryBranches = 'get_repo_branches', + getRepositoryPushes = 'get_repo_pushes' +} diff --git a/marketplace/plugins/azurerepos/package.json b/marketplace/plugins/azurerepos/package.json new file mode 100644 index 0000000000..9e6753bb9d --- /dev/null +++ b/marketplace/plugins/azurerepos/package.json @@ -0,0 +1,27 @@ +{ + "name": "@tooljet-marketplace/azurerepos", + "version": "1.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "directories": { + "lib": "lib", + "test": "__tests__" + }, + "files": [ + "lib" + ], + "scripts": { + "test": "echo \"Error: run tests from root\" && exit 1", + "build": "ncc build lib/index.ts -o dist", + "watch": "ncc build lib/index.ts -o dist --watch" + }, + "homepage": "https://github.com/tooljet/tooljet#readme", + "dependencies": { + "@tooljet-marketplace/common": "^1.0.0", + "azure-devops-node-api": "^14.1.0" + }, + "devDependencies": { + "@vercel/ncc": "^0.34.0", + "typescript": "^4.7.4" + } +} diff --git a/marketplace/plugins/azurerepos/tsconfig.json b/marketplace/plugins/azurerepos/tsconfig.json new file mode 100644 index 0000000000..a18a801b14 --- /dev/null +++ b/marketplace/plugins/azurerepos/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "lib" + }, + "exclude": [ + "node_modules", + "dist" + ] +} \ No newline at end of file diff --git a/server/src/assets/marketplace/plugins.json b/server/src/assets/marketplace/plugins.json index e4c3f8077a..5b257d96a9 100644 --- a/server/src/assets/marketplace/plugins.json +++ b/server/src/assets/marketplace/plugins.json @@ -111,5 +111,13 @@ "id": "qdrant", "author": "Tooljet", "timestamp": "Tue, 10 Dec 2024 02:11:32 GMT" + }, + { + "name": "azurerepos", + "description": "api plugin from azurerepos", + "version": "1.0.0", + "id": "azurerepos", + "author": "Tooljet", + "timestamp": "Mon, 23 Dec 2024 11:57:30 GMT" } ]