Skip to content

Commit

Permalink
Package Registry Support (#1822)
Browse files Browse the repository at this point in the history
* Adding support for Package Registry API
  • Loading branch information
jdalrymple authored Jun 7, 2021
1 parent f07403a commit 0255a0e
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 15 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,13 @@ Available instantiating options:
| `sudo` | Yes | `false` | [Sudo](https://docs.gitlab.com/ee/api/#sudo) query parameter |
| `version` | Yes | `4` | API Version ID |
| `camelize` | Yes | `false` | Camelizes all response body keys |
| `requesterFn` | Yes\* | @gitbeaker/node & @gitbeaker/cli : Got-based, @gitbeaker/browser: Ky-based. The @gitbeaker/core package **does not** have a default and thus must be set explicitly | Request Library Wrapper |
| `requesterFn` | Yes | @gitbeaker/node & @gitbeaker/cli : Got-based, @gitbeaker/browser: Ky-based. The @gitbeaker/core package **does not** have a default and thus must be set explicitly | Request Library Wrapper |
| `requestTimeout` | Yes | `300000` | Request Library Timeout in ms |
| `profileToken` | Yes | N/A | [Requests Profiles Token](https://docs.gitlab.com/ee/administration/monitoring/performance/request_profiling.html) |
| `profileMode` | Yes | `execution` | [Requests Profiles Token](https://docs.gitlab.com/ee/administration/monitoring/performance/request_profiling.html) |

>*One of these options must be supplied.
### CLI Support

The CLI export functions in a similar manner, following the pattern:
Expand Down Expand Up @@ -253,6 +255,7 @@ MergeRequestAwardEmojis
MergeRequestDiscussions
MergeRequestNotes
Packages
PackageRegistry
Pipelines
PipelineSchedules
PipelineScheduleVariables
Expand Down
1 change: 1 addition & 0 deletions packages/browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const {
MergeRequestDiscussions,
MergeRequestNotes,
Packages,
PackageRegistry,
Pipelines,
PipelineSchedules,
PipelineScheduleVariables,
Expand Down
41 changes: 41 additions & 0 deletions packages/core/src/services/PackageRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { BaseService } from '@gitbeaker/requester-utils';
import { RequestHelper, Sudo } from '../infrastructure';

export class PackageRegistry<C extends boolean = false> extends BaseService<C> {
publish(
projectId: string | number,
packageName: string,
packageVersion: string,
filename: string,
content: string,
options?: { status?: 'default' | 'hidden' },
) {
const pId = encodeURIComponent(projectId);

return RequestHelper.put<{ message: string }>()(
this,
`projects/${pId}/packages/generic/${packageName}/${packageVersion}/${filename}`,
{
isForm: true,
file: [content, { filename }],
...options,
},
);
}

download(
projectId: string | number,
packageName: string,
packageVersion: string,
filename: string,
options?: Sudo,
) {
const pId = encodeURIComponent(projectId);

return RequestHelper.get<{ message: string }>()(
this,
`projects/${pId}/packages/generic/${packageName}/${packageVersion}/${filename}`,
options,
);
}
}
42 changes: 31 additions & 11 deletions packages/core/src/services/Packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { BaseService } from '@gitbeaker/requester-utils';
import { PipelineSchema } from './Pipelines';
import { PaginatedRequestOptions, RequestHelper, Sudo } from '../infrastructure';

// TODO: Add group support

export interface PackageSchema extends Record<string, unknown> {
id: number;
name: string;
Expand All @@ -24,30 +22,52 @@ export interface PackageFileSchema extends Record<string, unknown> {
}

export class Packages<C extends boolean = false> extends BaseService<C> {
all(projectId: string | number, options?: PaginatedRequestOptions) {
const pId = encodeURIComponent(projectId);
all({
projectId,
groupId,
...options
}: { projectId?: string | number; groupId?: string | number } & PaginatedRequestOptions = {}) {
let url: string;

if (projectId) {
url = `projects/${encodeURIComponent(projectId)}/packages`;
} else if (groupId) {
url = `groups/${encodeURIComponent(groupId)}/packages`;
} else {
throw new Error('projectId or groupId must be passed');
}

return RequestHelper.get<PackageSchema[]>()(this, `projects/${pId}/packages`, options);
return RequestHelper.get<PackageSchema[]>()(this, url, options);
}

remove(projectId: string | number, packageId: number, options?: Sudo) {
const [pId, pkId] = [projectId, packageId].map(encodeURIComponent);
const [pId, pkgId] = [projectId, packageId].map(encodeURIComponent);

return RequestHelper.del()(this, `projects/${pId}/packages/${pkgId}`, options);
}

return RequestHelper.del()(this, `projects/${pId}/packages/${pkId}`, options);
removeFile(projectId: string | number, packageId: number, projectFileId: number, options?: Sudo) {
const [pId, pkgId, pfId] = [projectId, packageId, projectFileId].map(encodeURIComponent);

return RequestHelper.del()(
this,
`projects/${pId}/packages/${pkgId}/package_files/${pfId}`,
options,
);
}

show(projectId: string | number, packageId: number, options?: Sudo) {
const [pId, pkId] = [projectId, packageId].map(encodeURIComponent);
const [pId, pkgId] = [projectId, packageId].map(encodeURIComponent);

return RequestHelper.get<PackageSchema>()(this, `projects/${pId}/packages/${pkId}`, options);
return RequestHelper.get<PackageSchema>()(this, `projects/${pId}/packages/${pkgId}`, options);
}

showFiles(projectId: string | number, packageId: number, options?: Sudo) {
const [pId, pkId] = [projectId, packageId].map(encodeURIComponent);
const [pId, pkgId] = [projectId, packageId].map(encodeURIComponent);

return RequestHelper.get<PackageFileSchema[]>()(
this,
`projects/${pId}/packages/${pkId}/package_files`,
`projects/${pId}/packages/${pkgId}/package_files`,
options,
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export { MergeRequestAwardEmojis } from './MergeRequestAwardEmojis';
export { MergeRequestDiscussions } from './MergeRequestDiscussions';
export { MergeRequestNotes } from './MergeRequestNotes';
export { Packages } from './Packages';
export { PackageRegistry } from './PackageRegistry';
export { Pipelines } from './Pipelines';
export { PipelineSchedules } from './PipelineSchedules';
export { PipelineScheduleVariables } from './PipelineScheduleVariables';
Expand Down
54 changes: 54 additions & 0 deletions packages/core/test/unit/services/PackageRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { RequestHelper } from '../../../src/infrastructure';
import { PackageRegistry } from '../../../src';

jest.mock(
'../../../src/infrastructure/RequestHelper',
() => require('../../__mocks__/RequestHelper').default,
);

let service: PackageRegistry;

beforeEach(() => {
service = new PackageRegistry({
requesterFn: jest.fn(),
token: 'abcdefg',
requestTimeout: 3000,
});
});

describe('Instantiating PackageRegistry service', () => {
it('should create a valid service object', () => {
expect(service).toBeInstanceOf(PackageRegistry);
expect(service.url).toBeDefined();
expect(service.rejectUnauthorized).toBeTruthy();
expect(service.headers).toMatchObject({ 'private-token': 'abcdefg' });
expect(service.requestTimeout).toBe(3000);
});
});

describe('PackageRegistry.publish', () => {
it('should request PUT projects/:projectId/packages/generic/:packageName/:packageVersion/:filename', async () => {
await service.publish(1, 'name', 'v1.0', 'filename.txt', 'content');

expect(RequestHelper.put()).toHaveBeenCalledWith(
service,
`projects/1/packages/generic/name/v1.0/filename.txt`,
{
isForm: true,
file: ['content', { filename: 'filename.txt' }],
},
);
});
});

describe('PackageRegistry.download', () => {
it('should request GET projects/:projectId/packages/generic/:packageName/:packageVersion/:filename', async () => {
await service.download(1, 'name', 'v1.0', 'filename.txt');

expect(RequestHelper.get()).toHaveBeenCalledWith(
service,
`projects/1/packages/generic/name/v1.0/filename.txt`,
undefined,
);
});
});
26 changes: 24 additions & 2 deletions packages/core/test/unit/services/Packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,19 @@ describe('Instantiating Packages service', () => {

describe('Packages.all', () => {
it('should request GET /projects/:id/packages', async () => {
await service.all(1);
await service.all({ projectId: 1 });

expect(RequestHelper.get()).toHaveBeenCalledWith(service, 'projects/1/packages', undefined);
expect(RequestHelper.get()).toHaveBeenCalledWith(service, 'projects/1/packages', {});
});

it('should request GET /groups/:id/packages', async () => {
await service.all({ groupId: 1 });

expect(RequestHelper.get()).toHaveBeenCalledWith(service, 'groups/1/packages', {});
});

it('should throw an error is neither groupId or projectId is passed', () => {
expect(() => service.all()).toThrow('projectId or groupId must be passed');
});
});

Expand All @@ -42,6 +52,18 @@ describe('Packages.remove', () => {
});
});

describe('Packages.removeFile', () => {
it('should request DEL /projects/:id/packages/:id/package_files', async () => {
await service.removeFile(1, 2, 3);

expect(RequestHelper.del()).toHaveBeenCalledWith(
service,
'projects/1/packages/2/package_files/3',
undefined,
);
});
});

describe('Packages.show', () => {
it('should request GET /projects/:id/packages/:id', async () => {
await service.show(1, 2);
Expand Down
1 change: 1 addition & 0 deletions packages/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const {
MergeRequestDiscussions,
MergeRequestNotes,
Packages,
PackageRegistry,
Pipelines,
PipelineSchedules,
PipelineScheduleVariables,
Expand Down
2 changes: 1 addition & 1 deletion scripts/auto-before-commit-changelog-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = class LintDocsPlugin {
*/
apply(auto) {
auto.hooks.beforeCommitChangelog.tapPromise(this.name, async () => {
await execPromise('yarn', ['lint:doc:fix']);
await execPromise('yarn', ['lint:docs:fix']);
await execPromise('git', ['add', '.']);
});
}
Expand Down

0 comments on commit 0255a0e

Please sign in to comment.