Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65e5575494 | |||
| 4da6b14dc2 | |||
| 95c5870252 | |||
| b0f56f5948 | |||
| cc00a78e2c | |||
| cf7e69e74a | |||
| 5cc3aeb27c | |||
| 098a9c64c6 | |||
| 1fd2bb8e01 | |||
| ca475fbfab | |||
| c8dc59cdf2 | |||
| 217724d836 | |||
| b0efd2671c | |||
| b80e63dc65 | |||
| 7765ff77f9 |
19
.gitignore
vendored
19
.gitignore
vendored
@@ -1,4 +1,19 @@
|
||||
node_modules/
|
||||
.nogit/
|
||||
|
||||
# artifacts
|
||||
coverage/
|
||||
public/
|
||||
pages/
|
||||
|
||||
# installs
|
||||
node_modules/
|
||||
|
||||
# caches
|
||||
.yarn/
|
||||
.cache/
|
||||
.rpt2_cache
|
||||
|
||||
# builds
|
||||
dist/
|
||||
dist_*/
|
||||
|
||||
#------# custom
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# gitzone standard
|
||||
image: hosttoday/ht-docker-node:npmci
|
||||
|
||||
cache:
|
||||
paths:
|
||||
- .yarn/
|
||||
key: "$CI_BUILD_STAGE"
|
||||
|
||||
stages:
|
||||
- test
|
||||
- release
|
||||
- trigger
|
||||
- pages
|
||||
|
||||
testLEGACY:
|
||||
stage: test
|
||||
script:
|
||||
- npmci test legacy
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
tags:
|
||||
- docker
|
||||
allow_failure: true
|
||||
|
||||
testLTS:
|
||||
stage: test
|
||||
script:
|
||||
- npmci test lts
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
tags:
|
||||
- docker
|
||||
|
||||
testSTABLE:
|
||||
stage: test
|
||||
script:
|
||||
- npmci test stable
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
tags:
|
||||
- docker
|
||||
|
||||
release:
|
||||
stage: release
|
||||
script:
|
||||
- npmci publish
|
||||
only:
|
||||
- tags
|
||||
tags:
|
||||
- docker
|
||||
|
||||
trigger:
|
||||
stage: trigger
|
||||
script:
|
||||
- npmci trigger
|
||||
only:
|
||||
- tags
|
||||
tags:
|
||||
- docker
|
||||
|
||||
pages:
|
||||
image: hosttoday/ht-docker-node:npmci
|
||||
stage: pages
|
||||
script:
|
||||
- npmci command yarn global add npmpage
|
||||
- npmci command npmpage
|
||||
tags:
|
||||
- docker
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- public
|
||||
27
changelog.md
Normal file
27
changelog.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-02-24 - 2.0.1 - fix()
|
||||
no changes detected; no version bump required
|
||||
|
||||
- No files changed in diff
|
||||
- package.json current version is 2.0.0
|
||||
|
||||
## 2026-02-24 - 2.0.0 - gitlab
|
||||
Renamed package to @apiclient.xyz/gitlab and introduced a new ESM TypeScript GitLabClient API. Breaking release that replaces the legacy @mojoio/gitlab client.
|
||||
|
||||
- BREAKING CHANGE: package renamed to @apiclient.xyz/gitlab and API migrated to a new GitLabClient (v2.0.0).
|
||||
- New modern ESM TypeScript client with support for projects, groups, CI/CD variables, and pipelines.
|
||||
- fix(core): add npm release registry configuration (release tooling improvement).
|
||||
|
||||
## 2021-10-05 - 1.0.4..1.0.10 - core maintenance
|
||||
Series of patch releases containing maintenance updates and small fixes across the 1.0.x line.
|
||||
|
||||
- Multiple "fix(core): update" commits applying minor fixes and internal updates across 1.0.4–1.0.10.
|
||||
- Mostly patch-level changes and version bumps; no documented breaking or feature changes.
|
||||
|
||||
## 2017-06-10 - 1.0.1..1.0.3 - initial release & docs
|
||||
Initial project setup and first releases.
|
||||
|
||||
- 1.0.1 — initial commit.
|
||||
- 1.0.2 — add README.
|
||||
- 1.0.3 — patch/versioned release.
|
||||
21
license.md
Normal file
21
license.md
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Lossless GmbH (https://lossless.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,18 +1,34 @@
|
||||
{
|
||||
"gitzone": {
|
||||
"projectType": "npm",
|
||||
"module": {
|
||||
"githost": "gitlab.com",
|
||||
"gitscope": "mojoio",
|
||||
"gitrepo": "gitlab",
|
||||
"shortDescription": "a gitlab api abstraction package",
|
||||
"npmPackagename": "@mojoio/gitlab",
|
||||
"license": "MIT",
|
||||
"projectDomain": "mojo.io"
|
||||
}
|
||||
},
|
||||
"npmci": {
|
||||
"npmGlobalTools": [],
|
||||
"npmAccessLevel": "public"
|
||||
},
|
||||
"gitzone": {
|
||||
"projectType": "npm",
|
||||
"module": {
|
||||
"githost": "code.foss.global",
|
||||
"gitscope": "apiclient.xyz",
|
||||
"gitrepo": "gitlab",
|
||||
"description": "A TypeScript client for the GitLab API, providing easy access to projects, groups, CI/CD variables, and pipelines.",
|
||||
"npmPackagename": "@apiclient.xyz/gitlab",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"gitlab",
|
||||
"api client",
|
||||
"TypeScript",
|
||||
"CI/CD",
|
||||
"pipelines",
|
||||
"variables",
|
||||
"devops"
|
||||
]
|
||||
}
|
||||
},
|
||||
"@git.zone/cli": {
|
||||
"release": {
|
||||
"registries": [
|
||||
"https://registry.npmjs.org"
|
||||
],
|
||||
"accessLevel": "public"
|
||||
}
|
||||
}
|
||||
}
|
||||
11625
package-lock.json
generated
11625
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
62
package.json
62
package.json
@@ -1,25 +1,55 @@
|
||||
{
|
||||
"name": "@mojoio/gitlab",
|
||||
"version": "1.0.4",
|
||||
"description": "api abstraction package for gitlab",
|
||||
"name": "@apiclient.xyz/gitlab",
|
||||
"version": "2.0.1",
|
||||
"private": false,
|
||||
"description": "A TypeScript client for the GitLab API, providing easy access to projects, groups, CI/CD variables, and pipelines.",
|
||||
"main": "dist_ts/index.js",
|
||||
"typings": "dist_ts/index.d.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "(tstest test/ --verbose --timeout 600)",
|
||||
"build": "(tsbuild --web --allowimplicitany)"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://code.foss.global/apiclient.xyz/gitlab.git"
|
||||
},
|
||||
"keywords": [
|
||||
"gitlab",
|
||||
"api client",
|
||||
"TypeScript",
|
||||
"CI/CD",
|
||||
"pipelines",
|
||||
"variables",
|
||||
"devops"
|
||||
],
|
||||
"author": "Lossless GmbH",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "(tstest test/)",
|
||||
"build": "(tsbuild --web)"
|
||||
"dependencies": {
|
||||
"@push.rocks/smartlog": "^3.1.10",
|
||||
"@push.rocks/smartrequest": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gitzone/tsbuild": "^2.1.25",
|
||||
"@gitzone/tsrun": "^1.2.12",
|
||||
"@gitzone/tstest": "^1.0.54",
|
||||
"@pushrocks/tapbundle": "^3.2.14",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-prettier": "^1.18.0"
|
||||
"@git.zone/tsbuild": "^3.1.0",
|
||||
"@git.zone/tsrun": "^2.0.0",
|
||||
"@git.zone/tstest": "^2.8.2",
|
||||
"@push.rocks/qenv": "^6.1.3",
|
||||
"@push.rocks/tapbundle": "^5.6.0",
|
||||
"@types/node": "^22.15.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pushrocks/smartrequest": "^1.1.51",
|
||||
"@pushrocks/smarturl": "^2.0.1"
|
||||
}
|
||||
"files": [
|
||||
"ts/**/*",
|
||||
"ts_web/**/*",
|
||||
"dist/**/*",
|
||||
"dist_*/**/*",
|
||||
"dist_ts/**/*",
|
||||
"dist_ts_web/**/*",
|
||||
"assets/**/*",
|
||||
"cli.js",
|
||||
"npmextra.json",
|
||||
"readme.md"
|
||||
],
|
||||
"browserslist": [
|
||||
"last 1 chrome versions"
|
||||
]
|
||||
}
|
||||
|
||||
9914
pnpm-lock.yaml
generated
Normal file
9914
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
45
readme.md
45
readme.md
@@ -1,29 +1,30 @@
|
||||
# glab
|
||||
api abstraction package for gitlab
|
||||
# @apiclient.xyz/gitlab
|
||||
|
||||
## Availabililty
|
||||
[](https://www.npmjs.com/package/glab)
|
||||
[](https://GitLab.com/mojoio/glab)
|
||||
[](https://github.com/mojoio/glab)
|
||||
[](https://mojoio.gitlab.io/glab/)
|
||||
A TypeScript client for the GitLab API, providing easy access to projects, groups, CI/CD variables, and pipelines.
|
||||
|
||||
## Status for master
|
||||
[](https://GitLab.com/mojoio/glab/commits/master)
|
||||
[](https://GitLab.com/mojoio/glab/commits/master)
|
||||
[](https://www.npmjs.com/package/glab)
|
||||
[](https://david-dm.org/mojoio/glab)
|
||||
[](https://www.bithound.io/github/mojoio/glab/master/dependencies/npm)
|
||||
[](https://www.bithound.io/github/mojoio/glab)
|
||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
||||
[](http://standardjs.com/)
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm install @apiclient.xyz/gitlab
|
||||
```
|
||||
|
||||
## Usage
|
||||
Use TypeScript for best in class instellisense.
|
||||
|
||||
For further information read the linked docs at the top of this README.
|
||||
```typescript
|
||||
import { GitLabClient } from '@apiclient.xyz/gitlab';
|
||||
|
||||
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
||||
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
|
||||
const client = new GitLabClient('https://gitlab.com', 'your-private-token');
|
||||
|
||||
[](https://mojo.io)
|
||||
// Test connection
|
||||
const result = await client.testConnection();
|
||||
|
||||
// List projects
|
||||
const projects = await client.getProjects();
|
||||
|
||||
// Manage CI/CD variables
|
||||
await client.createProjectVariable(123, 'SECRET_KEY', 'secret-value');
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
34
test/test.node.ts
Normal file
34
test/test.node.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { tap, expect } from '@push.rocks/tapbundle';
|
||||
import * as qenv from '@push.rocks/qenv';
|
||||
import { GitLabClient } from '../ts/index.js';
|
||||
|
||||
const testQenv = new qenv.Qenv('./', '.nogit/');
|
||||
|
||||
let gitlabClient: GitLabClient;
|
||||
|
||||
tap.test('should create a GitLabClient instance', async () => {
|
||||
const baseUrl = testQenv.getEnvVarOnDemand('GITLAB_BASE_URL') || 'https://gitlab.com';
|
||||
const token = testQenv.getEnvVarOnDemand('GITLAB_TOKEN') || '';
|
||||
gitlabClient = new GitLabClient(baseUrl, token);
|
||||
expect(gitlabClient).toBeInstanceOf(GitLabClient);
|
||||
});
|
||||
|
||||
tap.test('should test connection', async () => {
|
||||
const result = await gitlabClient.testConnection();
|
||||
expect(result).toHaveProperty('ok');
|
||||
console.log('Connection test:', result);
|
||||
});
|
||||
|
||||
tap.test('should get projects', async () => {
|
||||
const projects = await gitlabClient.getProjects({ perPage: 5 });
|
||||
expect(projects).toBeArray();
|
||||
console.log(`Found ${projects.length} projects`);
|
||||
});
|
||||
|
||||
tap.test('should get groups', async () => {
|
||||
const groups = await gitlabClient.getGroups({ perPage: 5 });
|
||||
expect(groups).toBeArray();
|
||||
console.log(`Found ${groups.length} groups`);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
23
test/test.ts
23
test/test.ts
@@ -1,23 +0,0 @@
|
||||
import { expect, tap } from '@pushrocks/tapbundle'
|
||||
import * as gitlab from '../ts/index';
|
||||
|
||||
let testGitlabAccount: gitlab.GitlabAccount;
|
||||
|
||||
tap.test('should create an anonymous Gitlab Account', async () => {
|
||||
testGitlabAccount = gitlab.GitlabAccount.createAnonymousAccount();
|
||||
expect(testGitlabAccount).to.be.instanceOf(gitlab.GitlabAccount);
|
||||
});
|
||||
|
||||
tap.test('should get the pushrocks group', async () => {
|
||||
const pushrocksGroup = await testGitlabAccount.getGroupByName('pushrocks');
|
||||
expect(pushrocksGroup).to.be.instanceOf(gitlab.GitlabGroup);
|
||||
console.log(pushrocksGroup);
|
||||
});
|
||||
|
||||
tap.test('should get the pushrocks group', async () => {
|
||||
const pushrocksGroup = await testGitlabAccount.getGroupByName('pushrocks');
|
||||
expect(pushrocksGroup).to.be.instanceOf(gitlab.GitlabGroup);
|
||||
await pushrocksGroup.getProjects();
|
||||
});
|
||||
|
||||
tap.start();
|
||||
8
ts/00_commitinfo_data.ts
Normal file
8
ts/00_commitinfo_data.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* autocreated commitinfo by @push.rocks/commitinfo
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@apiclient.xyz/gitlab',
|
||||
version: '2.0.1',
|
||||
description: 'A TypeScript client for the GitLab API, providing easy access to projects, groups, CI/CD variables, and pipelines.'
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import { GitlabGroup } from './gitlab.classes.group';
|
||||
import * as plugins from './gitlab.plugins';
|
||||
|
||||
export class GitlabAccount {
|
||||
public static createAnonymousAccount() {
|
||||
return new GitlabAccount();
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
public async getGroupByName(nameArg: string): Promise<GitlabGroup> {
|
||||
return GitlabGroup.getByName(nameArg, this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* handles the basic request/response patterns with the gitlab.com API
|
||||
*/
|
||||
public async request (methodArg: 'GET' | 'POST', routeArg: string, searchParamsArg: {[key: string]: string}) {
|
||||
if(!routeArg.startsWith('/')) {
|
||||
throw new Error(`"${routeArg}" -> routeArg must start with a slash`);
|
||||
}
|
||||
const smarturlInstance = plugins.smarturl.Smarturl.createFromUrl(`https://gitlab.com/api/v4${routeArg}`, {
|
||||
searchParams: searchParamsArg
|
||||
});
|
||||
const response = await plugins.smartrequest.request(smarturlInstance.toString(), {
|
||||
method: methodArg
|
||||
});
|
||||
|
||||
// lets deal with pagination headers
|
||||
const fintLinkName = (markup) => {
|
||||
const pattern = /<([^\s>]+)(\s|>)+/;
|
||||
return markup.match(pattern)[1];
|
||||
};
|
||||
if (typeof response.headers.link === 'string') {
|
||||
const links = response.headers.link.split(',');
|
||||
const linkObjects: {
|
||||
original: string;
|
||||
link: string;
|
||||
}[] = [];
|
||||
}
|
||||
return response.body;
|
||||
}
|
||||
}
|
||||
304
ts/gitlab.classes.gitlabclient.ts
Normal file
304
ts/gitlab.classes.gitlabclient.ts
Normal file
@@ -0,0 +1,304 @@
|
||||
import * as plugins from './gitlab.plugins.js';
|
||||
import { logger } from './gitlab.logging.js';
|
||||
import type {
|
||||
IGitLabUser,
|
||||
IGitLabProject,
|
||||
IGitLabGroup,
|
||||
IGitLabVariable,
|
||||
IVariableOptions,
|
||||
IGitLabPipeline,
|
||||
IGitLabJob,
|
||||
ITestConnectionResult,
|
||||
IListOptions,
|
||||
} from './gitlab.interfaces.js';
|
||||
|
||||
export class GitLabClient {
|
||||
private baseUrl: string;
|
||||
private token: string;
|
||||
|
||||
constructor(baseUrl: string, token: string) {
|
||||
// Remove trailing slash if present
|
||||
this.baseUrl = baseUrl.replace(/\/+$/, '');
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// HTTP helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
private async request<T = any>(
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
||||
path: string,
|
||||
data?: any,
|
||||
customHeaders?: Record<string, string>,
|
||||
): Promise<T> {
|
||||
const url = `${this.baseUrl}${path}`;
|
||||
|
||||
let builder = plugins.smartrequest.SmartRequest.create()
|
||||
.url(url)
|
||||
.header('PRIVATE-TOKEN', this.token)
|
||||
.header('Content-Type', 'application/json');
|
||||
|
||||
if (customHeaders) {
|
||||
for (const [k, v] of Object.entries(customHeaders)) {
|
||||
builder = builder.header(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
builder = builder.json(data);
|
||||
}
|
||||
|
||||
let response: Awaited<ReturnType<typeof builder.get>>;
|
||||
switch (method) {
|
||||
case 'GET':
|
||||
response = await builder.get();
|
||||
break;
|
||||
case 'POST':
|
||||
response = await builder.post();
|
||||
break;
|
||||
case 'PUT':
|
||||
response = await builder.put();
|
||||
break;
|
||||
case 'DELETE':
|
||||
response = await builder.delete();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`${method} ${path}: ${response.status} ${response.statusText} - ${errorText}`);
|
||||
}
|
||||
|
||||
try {
|
||||
return await response.json() as T;
|
||||
} catch {
|
||||
return undefined as unknown as T;
|
||||
}
|
||||
}
|
||||
|
||||
private async requestText(
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
||||
path: string,
|
||||
): Promise<string> {
|
||||
const url = `${this.baseUrl}${path}`;
|
||||
|
||||
let builder = plugins.smartrequest.SmartRequest.create()
|
||||
.url(url)
|
||||
.header('PRIVATE-TOKEN', this.token)
|
||||
.header('Accept', 'text/plain');
|
||||
|
||||
let response: Awaited<ReturnType<typeof builder.get>>;
|
||||
switch (method) {
|
||||
case 'GET':
|
||||
response = await builder.get();
|
||||
break;
|
||||
case 'POST':
|
||||
response = await builder.post();
|
||||
break;
|
||||
case 'PUT':
|
||||
response = await builder.put();
|
||||
break;
|
||||
case 'DELETE':
|
||||
response = await builder.delete();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`${method} ${path}: ${response.status} ${response.statusText} - ${errorText}`);
|
||||
}
|
||||
|
||||
return response.text();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Connection
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public async testConnection(): Promise<ITestConnectionResult> {
|
||||
try {
|
||||
await this.request<IGitLabUser>('GET', '/api/v4/user');
|
||||
return { ok: true };
|
||||
} catch (err) {
|
||||
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Projects
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public async getProjects(opts?: IListOptions): Promise<IGitLabProject[]> {
|
||||
const page = opts?.page || 1;
|
||||
const perPage = opts?.perPage || 50;
|
||||
let url = `/api/v4/projects?membership=true&order_by=updated_at&sort=desc&page=${page}&per_page=${perPage}`;
|
||||
if (opts?.search) {
|
||||
url += `&search=${encodeURIComponent(opts.search)}`;
|
||||
}
|
||||
return this.request<IGitLabProject[]>('GET', url);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Groups
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public async getGroups(opts?: IListOptions): Promise<IGitLabGroup[]> {
|
||||
const page = opts?.page || 1;
|
||||
const perPage = opts?.perPage || 50;
|
||||
let url = `/api/v4/groups?order_by=name&sort=asc&page=${page}&per_page=${perPage}`;
|
||||
if (opts?.search) {
|
||||
url += `&search=${encodeURIComponent(opts.search)}`;
|
||||
}
|
||||
return this.request<IGitLabGroup[]>('GET', url);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Project Variables (CI/CD)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public async getProjectVariables(projectId: number | string): Promise<IGitLabVariable[]> {
|
||||
return this.request<IGitLabVariable[]>(
|
||||
'GET',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/variables`,
|
||||
);
|
||||
}
|
||||
|
||||
public async createProjectVariable(
|
||||
projectId: number | string,
|
||||
key: string,
|
||||
value: string,
|
||||
opts?: IVariableOptions,
|
||||
): Promise<IGitLabVariable> {
|
||||
return this.request<IGitLabVariable>(
|
||||
'POST',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/variables`,
|
||||
{
|
||||
key,
|
||||
value,
|
||||
protected: opts?.protected ?? false,
|
||||
masked: opts?.masked ?? false,
|
||||
environment_scope: opts?.environment_scope ?? '*',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public async updateProjectVariable(
|
||||
projectId: number | string,
|
||||
key: string,
|
||||
value: string,
|
||||
opts?: IVariableOptions,
|
||||
): Promise<IGitLabVariable> {
|
||||
const body: any = { value };
|
||||
if (opts?.protected !== undefined) body.protected = opts.protected;
|
||||
if (opts?.masked !== undefined) body.masked = opts.masked;
|
||||
if (opts?.environment_scope !== undefined) body.environment_scope = opts.environment_scope;
|
||||
return this.request<IGitLabVariable>(
|
||||
'PUT',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/variables/${encodeURIComponent(key)}`,
|
||||
body,
|
||||
);
|
||||
}
|
||||
|
||||
public async deleteProjectVariable(projectId: number | string, key: string): Promise<void> {
|
||||
await this.request(
|
||||
'DELETE',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/variables/${encodeURIComponent(key)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Group Variables (CI/CD)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public async getGroupVariables(groupId: number | string): Promise<IGitLabVariable[]> {
|
||||
return this.request<IGitLabVariable[]>(
|
||||
'GET',
|
||||
`/api/v4/groups/${encodeURIComponent(groupId)}/variables`,
|
||||
);
|
||||
}
|
||||
|
||||
public async createGroupVariable(
|
||||
groupId: number | string,
|
||||
key: string,
|
||||
value: string,
|
||||
opts?: IVariableOptions,
|
||||
): Promise<IGitLabVariable> {
|
||||
return this.request<IGitLabVariable>(
|
||||
'POST',
|
||||
`/api/v4/groups/${encodeURIComponent(groupId)}/variables`,
|
||||
{
|
||||
key,
|
||||
value,
|
||||
protected: opts?.protected ?? false,
|
||||
masked: opts?.masked ?? false,
|
||||
environment_scope: opts?.environment_scope ?? '*',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public async updateGroupVariable(
|
||||
groupId: number | string,
|
||||
key: string,
|
||||
value: string,
|
||||
opts?: IVariableOptions,
|
||||
): Promise<IGitLabVariable> {
|
||||
const body: any = { value };
|
||||
if (opts?.protected !== undefined) body.protected = opts.protected;
|
||||
if (opts?.masked !== undefined) body.masked = opts.masked;
|
||||
if (opts?.environment_scope !== undefined) body.environment_scope = opts.environment_scope;
|
||||
return this.request<IGitLabVariable>(
|
||||
'PUT',
|
||||
`/api/v4/groups/${encodeURIComponent(groupId)}/variables/${encodeURIComponent(key)}`,
|
||||
body,
|
||||
);
|
||||
}
|
||||
|
||||
public async deleteGroupVariable(groupId: number | string, key: string): Promise<void> {
|
||||
await this.request(
|
||||
'DELETE',
|
||||
`/api/v4/groups/${encodeURIComponent(groupId)}/variables/${encodeURIComponent(key)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Pipelines
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
public async getPipelines(projectId: number | string, opts?: IListOptions): Promise<IGitLabPipeline[]> {
|
||||
const page = opts?.page || 1;
|
||||
const perPage = opts?.perPage || 30;
|
||||
return this.request<IGitLabPipeline[]>(
|
||||
'GET',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/pipelines?page=${page}&per_page=${perPage}&order_by=updated_at&sort=desc`,
|
||||
);
|
||||
}
|
||||
|
||||
public async getPipelineJobs(projectId: number | string, pipelineId: number): Promise<IGitLabJob[]> {
|
||||
return this.request<IGitLabJob[]>(
|
||||
'GET',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/jobs`,
|
||||
);
|
||||
}
|
||||
|
||||
public async getJobLog(projectId: number | string, jobId: number): Promise<string> {
|
||||
return this.requestText(
|
||||
'GET',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/jobs/${jobId}/trace`,
|
||||
);
|
||||
}
|
||||
|
||||
public async retryPipeline(projectId: number | string, pipelineId: number): Promise<void> {
|
||||
await this.request(
|
||||
'POST',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/retry`,
|
||||
);
|
||||
}
|
||||
|
||||
public async cancelPipeline(projectId: number | string, pipelineId: number): Promise<void> {
|
||||
await this.request(
|
||||
'POST',
|
||||
`/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/cancel`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
import * as plugins from './gitlab.plugins';
|
||||
import { GitlabAccount } from './gitlab.classes.account';
|
||||
import { GitlabProject } from './gitlab.classes.project';
|
||||
|
||||
export interface IGitlabGroup {
|
||||
id: number;
|
||||
web_url: string;
|
||||
name: string;
|
||||
path: string;
|
||||
description: string;
|
||||
visibility: string;
|
||||
share_with_group_lock: string;
|
||||
require_two_factor_authentication: string;
|
||||
two_factor_grace_period: number;
|
||||
project_creation_level: string;
|
||||
auto_devops_enabled: null;
|
||||
subgroup_creation_level: string;
|
||||
emails_disabled: null;
|
||||
mentions_disabled: null;
|
||||
lfs_enabled: boolean;
|
||||
default_branch_protection: number;
|
||||
avatar_url: string;
|
||||
request_access_enabled: boolean;
|
||||
full_name: string;
|
||||
full_path: string;
|
||||
created_at: string;
|
||||
parent_id: null;
|
||||
ldap_cn: null;
|
||||
ldap_access: null;
|
||||
}
|
||||
|
||||
export class GitlabGroup {
|
||||
public static async getByName(nameArg: string, gitlabAccountArg: GitlabAccount) {
|
||||
const response = await gitlabAccountArg.request('GET', '/groups', {
|
||||
search: 'pushrocks',
|
||||
});
|
||||
// console.log(response);
|
||||
const returnGroup = new GitlabGroup(response[0], gitlabAccountArg);
|
||||
return returnGroup;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
public gitlabAccountRef: GitlabAccount;
|
||||
public data: IGitlabGroup;
|
||||
|
||||
constructor(dataArg: IGitlabGroup, gitlabAccountArg: GitlabAccount) {
|
||||
this.gitlabAccountRef = gitlabAccountArg;
|
||||
this.data = dataArg;
|
||||
}
|
||||
|
||||
public async getProjects() {
|
||||
return GitlabProject.getProjectsForGroup(this);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import { GitlabGroup } from './gitlab.classes.group';
|
||||
import * as plugins from './gitlab.plugins';
|
||||
|
||||
export class GitlabProject {
|
||||
// STATIC
|
||||
public static async getProjectsForGroup(gitlabGroupArg: GitlabGroup) {
|
||||
const response = await gitlabGroupArg.gitlabAccountRef.request('GET', `/groups/${gitlabGroupArg.data.id}/projects`, {
|
||||
per_page: '100'
|
||||
});
|
||||
console.log(response);
|
||||
for (const projectData of response) {
|
||||
console.log(projectData);
|
||||
}
|
||||
console.log(response.length);
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
gitlabGroupRef: GitlabGroup;
|
||||
data: any;
|
||||
|
||||
constructor(dataArg: any, gitlabGroupRefArg: GitlabGroup) {
|
||||
this.data = dataArg;
|
||||
this.gitlabGroupRef = gitlabGroupRefArg;
|
||||
}
|
||||
|
||||
public async getReadmeAsMarkdown() {};
|
||||
}
|
||||
76
ts/gitlab.interfaces.ts
Normal file
76
ts/gitlab.interfaces.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
export interface IGitLabUser {
|
||||
id: number;
|
||||
username: string;
|
||||
name: string;
|
||||
email: string;
|
||||
avatar_url: string;
|
||||
web_url: string;
|
||||
state: string;
|
||||
}
|
||||
|
||||
export interface IGitLabProject {
|
||||
id: number;
|
||||
name: string;
|
||||
path_with_namespace: string;
|
||||
description: string;
|
||||
default_branch: string;
|
||||
web_url: string;
|
||||
visibility: string;
|
||||
topics: string[];
|
||||
last_activity_at: string;
|
||||
}
|
||||
|
||||
export interface IGitLabGroup {
|
||||
id: number;
|
||||
name: string;
|
||||
full_path: string;
|
||||
description: string;
|
||||
web_url: string;
|
||||
visibility: string;
|
||||
}
|
||||
|
||||
export interface IGitLabVariable {
|
||||
key: string;
|
||||
value: string;
|
||||
variable_type: string;
|
||||
protected: boolean;
|
||||
masked: boolean;
|
||||
environment_scope: string;
|
||||
}
|
||||
|
||||
export interface IVariableOptions {
|
||||
protected?: boolean;
|
||||
masked?: boolean;
|
||||
environment_scope?: string;
|
||||
}
|
||||
|
||||
export interface IGitLabPipeline {
|
||||
id: number;
|
||||
project_id: number;
|
||||
status: string;
|
||||
ref: string;
|
||||
sha: string;
|
||||
web_url: string;
|
||||
duration: number;
|
||||
created_at: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
export interface IGitLabJob {
|
||||
id: number;
|
||||
name: string;
|
||||
stage: string;
|
||||
status: string;
|
||||
duration: number;
|
||||
}
|
||||
|
||||
export interface ITestConnectionResult {
|
||||
ok: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface IListOptions {
|
||||
search?: string;
|
||||
page?: number;
|
||||
perPage?: number;
|
||||
}
|
||||
3
ts/gitlab.logging.ts
Normal file
3
ts/gitlab.logging.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import * as plugins from './gitlab.plugins.js';
|
||||
|
||||
export const logger = new plugins.smartlog.ConsoleLog();
|
||||
@@ -1,8 +1,4 @@
|
||||
// pushrocks scope
|
||||
import * as smartrequest from '@pushrocks/smartrequest';
|
||||
import * as smarturl from '@pushrocks/smarturl';
|
||||
import * as smartlog from '@push.rocks/smartlog';
|
||||
import * as smartrequest from '@push.rocks/smartrequest';
|
||||
|
||||
export {
|
||||
smartrequest,
|
||||
smarturl
|
||||
};
|
||||
export { smartlog, smartrequest };
|
||||
|
||||
15
ts/index.ts
15
ts/index.ts
@@ -1,2 +1,13 @@
|
||||
export * from './gitlab.classes.group';
|
||||
export * from './gitlab.classes.account';
|
||||
export { GitLabClient } from './gitlab.classes.gitlabclient.js';
|
||||
export type {
|
||||
IGitLabUser,
|
||||
IGitLabProject,
|
||||
IGitLabGroup,
|
||||
IGitLabVariable,
|
||||
IVariableOptions,
|
||||
IGitLabPipeline,
|
||||
IGitLabJob,
|
||||
ITestConnectionResult,
|
||||
IListOptions,
|
||||
} from './gitlab.interfaces.js';
|
||||
export { commitinfo } from './00_commitinfo_data.js';
|
||||
|
||||
16
tsconfig.json
Normal file
16
tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {}
|
||||
},
|
||||
"exclude": [
|
||||
"dist_*/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
17
tslint.json
17
tslint.json
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": ["tslint:latest", "tslint-config-prettier"],
|
||||
"rules": {
|
||||
"semicolon": [true, "always"],
|
||||
"no-console": false,
|
||||
"ordered-imports": false,
|
||||
"object-literal-sort-keys": false,
|
||||
"member-ordering": {
|
||||
"options":{
|
||||
"order": [
|
||||
"static-method"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultSeverity": "warning"
|
||||
}
|
||||
Reference in New Issue
Block a user