feature marketplace plugin azure repo (#11707)

* feature marketplace plugin azure repo

Fix: #5990

* chore: refactor imports, types, and naming conventions
This commit is contained in:
kushalsourav 2025-03-07 16:43:25 +05:30 committed by GitHub
parent 1ba4a2ed88
commit 3cf5f7705a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 464 additions and 0 deletions

View file

@ -0,0 +1,5 @@
node_modules
lib/*.d.*
lib/*.js
lib/*.js.map
dist/*

View file

@ -0,0 +1,4 @@
# Azurerepos
Documentation on: https://docs.tooljet.com/docs/data-sources/azurerepos

View file

@ -0,0 +1,7 @@
'use strict';
const azurerepos = require('../lib');
describe('azurerepos', () => {
it.todo('needs tests');
});

View file

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<g>
<rect x="445.176" y="222.066" width="15.208" height="32.606"/>
<path d="M465.275,103.536V55.237c0-10.89-8.859-19.75-19.749-19.75H292.721c-10.89,0-19.75,8.86-19.75,19.75v48.298h-38.498
V55.237c0-10.89-8.86-19.75-19.75-19.75H61.918c-10.891,0-19.75,8.86-19.75,19.75v48.298H0v372.977h512V103.536H465.275z
M288.178,55.237c0-2.505,2.038-4.542,4.542-4.542h152.805c2.504,0,4.541,2.038,4.541,4.542v48.298H422.47V64.268h-15.208v39.268
H288.178V55.237z M57.374,55.237c0-2.505,2.038-4.542,4.542-4.542h152.804c2.504,0,4.542,2.038,4.542,4.542v48.298h-29.126
V64.268h-15.208v39.268H57.374V55.237z M496.792,461.305h-36.404V269.298H445.18v192.007H15.208V118.743h26.959h192.305h38.498
h192.305h31.517V461.305z"/>
<path d="M385.777,275.757c-1.028-0.078-2.067-0.118-3.092-0.118c-10.329,0-20.117,3.942-27.562,11.096
c-0.054,0.051-0.105,0.101-0.159,0.15v-81.028h-81.027c0.05-0.054,0.099-0.105,0.149-0.158
c7.838-8.156,11.84-19.33,10.978-30.656c-1.449-19.026-16.24-34.353-35.171-36.443c-1.494-0.164-3.008-0.248-4.5-0.248
c-21.939,0-39.787,17.848-39.787,39.788c0,10.414,3.994,20.254,11.25,27.719h-81.031v99.334h7.604
c6.248,0,12.237-2.492,16.431-6.835c5.122-5.303,12.213-8.006,19.621-7.435c11.548,0.878,21.213,10.196,22.481,21.673
c0.787,7.121-1.381,13.948-6.105,19.223c-4.661,5.204-11.337,8.189-18.317,8.189c-6.631,0-12.846-2.602-17.502-7.328
c-3.186-3.232-7.177-5.463-11.542-6.449c-0.757-0.172-1.534-0.259-2.307-0.259c-5.715,0-10.364,4.639-10.364,10.343v88.681
h88.991c5.703,0,10.343-4.639,10.343-10.342c0-6.248-2.492-12.238-6.836-16.432c-5.285-5.103-7.994-12.256-7.435-19.622
c0.879-11.548,10.197-21.212,21.675-22.48c0.943-0.105,1.895-0.157,2.831-0.157c13.553,0,24.58,11.027,24.58,24.58
c0,6.606-2.585,12.805-7.281,17.456c-4.555,4.514-7.065,10.396-7.065,16.565c0,5.753,4.68,10.433,10.434,10.433h88.9v-81.031
c7.465,7.255,17.304,11.25,27.719,11.25c11.299,0,22.105-4.83,29.646-13.251c7.537-8.415,11.142-19.728,9.893-31.037
C420.13,291.995,404.803,277.205,385.777,275.757z M401.001,331.817c-4.661,5.205-11.338,8.19-18.317,8.19
c-6.457,0-12.557-2.486-17.174-7c-4.843-4.737-11.287-7.344-18.148-7.344h-7.604v84.126h-67.227
c0.262-0.342,0.551-0.671,0.868-0.987c7.6-7.528,11.785-17.564,11.785-28.259c0-21.94-17.848-39.788-39.788-39.788
c-1.491,0-3.005,0.084-4.5,0.248c-18.931,2.093-33.722,17.419-35.17,36.442c-0.905,11.898,3.482,23.458,12.036,31.718
c0.202,0.195,0.391,0.404,0.569,0.625h-67.295v-64.691c7.3,6.542,16.618,10.117,26.507,10.117
c11.298,0,22.104-4.83,29.646-13.251c7.537-8.415,11.142-19.728,9.892-31.038c-2.092-18.93-17.419-33.72-36.444-35.168
c-1.027-0.078-2.068-0.118-3.092-0.118c-9.906,0-19.212,3.571-26.508,10.116v-64.689l84.126-0.005v-7.604
c0-6.856-2.608-13.299-7.344-18.144c-4.515-4.618-7.001-10.716-7.001-17.174c0-13.553,11.026-24.58,24.579-24.58
c0.936,0,1.888,0.053,2.831,0.157c11.478,1.267,20.796,10.932,21.675,22.481c0.541,7.117-1.867,13.851-6.78,18.964
c-4.831,5.026-7.491,11.525-7.491,18.3v7.604h84.126v84.126h7.604c6.775,0,13.273-2.66,18.301-7.491
c5.061-4.863,11.901-7.314,18.963-6.78c11.548,0.878,21.213,10.196,22.481,21.675
C407.893,319.717,405.725,326.542,401.001,331.817z"/>
</g>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View file

@ -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<QueryResult> {
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<any> {
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<any> {
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',
};
}
}
}

View file

@ -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"
]
}

View file

@ -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"
}
}
}
}

View file

@ -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;
}

View file

@ -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'
}

View file

@ -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"
}
}

View file

@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "lib"
},
"exclude": [
"node_modules",
"dist"
]
}

View file

@ -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"
}
]