@hapic/harbor
Version:
A harbor http api client.
1 lines • 66.3 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/constants.ts","../src/error/connection-string.ts","../src/utils/connection-string.ts","../src/utils/query-string.ts","../src/utils/resource-id.ts","../src/utils/resource-meta.ts","../src/domains/base.ts","../src/domains/project/module.ts","../src/domains/project-repository/utils.ts","../src/domains/project-repository/module.ts","../src/domains/project-repository-artifact/module.ts","../src/domains/project-repository-artifact-label/module.ts","../src/domains/project-webhook-policy/module.ts","../src/domains/robot/constants.ts","../src/domains/robot/module.ts","../src/domains/robot/utils.ts","../src/module.ts","../src/instance.ts","../src/index.ts"],"sourcesContent":["/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport enum HeaderName {\n LOCATION = 'location',\n IS_RESOURCE_NAME = 'X-Is-Resource-Name',\n TOTAL_COUNT = 'X-Total-Count',\n}\n","/*\n * Copyright (c) 2021-2021.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport class ConnectionStringParseError extends Error {\n static connectionStringMissing(serviceName?: string) {\n const parts : string[] = ['The'];\n if (typeof serviceName === 'string') {\n parts.push(serviceName);\n }\n parts.push('connection string is not specified.');\n return new this(parts.join(' '));\n }\n\n static connectionStringInvalid(serviceName?: string) {\n const parts : string[] = ['The'];\n if (typeof serviceName === 'string') {\n parts.push(serviceName);\n }\n parts.push('connection string is not valid.');\n return new this(parts.join(' '));\n }\n}\n","/*\n * Copyright (c) 2022-2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { ConnectionOptions } from '../config';\nimport { ConnectionStringParseError } from '../error';\n\nexport function parseConnectionString(connectionString: string): ConnectionOptions {\n const parts: string[] = connectionString.split('@');\n if (parts.length !== 2) {\n throw new ConnectionStringParseError('Harbor connection string must be in the following format: user:password@host');\n }\n\n const host: string = parts[1];\n\n const authParts: string[] = parts[0].split(':');\n if (authParts.length !== 2) {\n throw new ConnectionStringParseError('Harbor connection string must be in the following format: user:password@host');\n }\n\n return {\n host,\n user: authParts[0],\n password: authParts[1],\n };\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isObject } from 'smob';\n\nexport function buildQueryString(\n input?: Record<string, any>,\n withQuestionMark = true,\n) {\n if (typeof input === 'undefined') {\n return '';\n }\n\n const searchParams = new URLSearchParams();\n\n const keys = Object.keys(input);\n for (let i = 0; i < keys.length; i++) {\n const value = input[keys[i]];\n if (isObject(value)) {\n const childKeys = Object.keys(value);\n if (childKeys.length > 0) {\n const childSearchParams = new URLSearchParams();\n for (let j = 0; j < childKeys.length; j++) {\n childSearchParams.append(\n childKeys[j],\n `${encodeURIComponent(value[childKeys[j]])}`,\n );\n }\n\n searchParams.append(keys[i], childSearchParams.toString());\n }\n } else if (Array.isArray(value)) {\n searchParams.append(keys[i], `${value.join(',')}`);\n } else {\n searchParams.append(keys[i], `${value}`);\n }\n }\n\n const queryString = searchParams.toString();\n if (queryString.length > 0 && withQuestionMark) {\n return `?${queryString}`;\n }\n\n return '';\n}\n","/*\n * Copyright (c) 2023-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Response } from 'hapic';\nimport { HeaderName } from '../constants';\n\nexport function extractResourceIDOfResponse(response: Pick<Response, 'headers'>) {\n if (\n response &&\n response.headers &&\n response.headers.has(HeaderName.LOCATION)\n ) {\n const value = response.headers.get(HeaderName.LOCATION);\n if (value) {\n const id = parseInt(value.substring(value.lastIndexOf('/') + 1), 10);\n if (!Number.isNaN(id)) {\n return id;\n }\n }\n }\n\n return undefined;\n}\n","/*\n * Copyright (c) 2023-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Response } from 'hapic';\nimport { HeaderName } from '../constants';\n\ntype Meta = {\n total?: number\n};\nexport function extractResourceMetaOfResponse(response: Response) : Meta {\n const meta : Meta = {};\n\n if (\n response.headers &&\n response.headers.has(HeaderName.TOTAL_COUNT)\n ) {\n const total = parseInt(response.headers.get(HeaderName.TOTAL_COUNT) || '0', 10);\n if (!Number.isNaN(total)) {\n meta.total = total;\n }\n }\n\n return meta;\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { createClient, isClient } from 'hapic';\nimport type { Client, RequestBaseOptions } from 'hapic';\nimport type { BaseAPIContext } from './type';\n\nexport abstract class BaseAPI {\n protected client!: Client;\n\n // -----------------------------------------------------------------------------------\n\n protected constructor(context?: BaseAPIContext) {\n context = context || {};\n\n this.setClient(context.client);\n }\n\n // -----------------------------------------------------------------------------------\n\n setClient(input?: Client | RequestBaseOptions) {\n if (isClient(input)) {\n this.client = input;\n } else {\n this.client = createClient(input);\n }\n }\n}\n","/*\n * Copyright (c) 2022-2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { HeaderName } from '../../constants';\nimport {\n buildQueryString,\n extractResourceIDOfResponse,\n extractResourceMetaOfResponse,\n} from '../../utils';\nimport { BaseAPI } from '../base';\nimport type { BaseAPIContext, ResourceCollectionResponse } from '../type';\nimport type {\n Project,\n ProjectCreatePayload,\n ProjectCreateResponse,\n ProjectGetManyOptions,\n ProjectUpdatePayload,\n} from './type';\n\nexport class ProjectAPI extends BaseAPI {\n // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor\n constructor(context: BaseAPIContext) {\n super(context);\n }\n\n async create(data: ProjectCreatePayload) : Promise<ProjectCreateResponse> {\n const response = await this.client\n .post('projects', data);\n\n return {\n id: extractResourceIDOfResponse(response),\n };\n }\n\n async delete(\n id: string | number,\n isProjectName = false,\n ) : Promise<void> {\n const headers: Record<string, any> = {};\n\n if (isProjectName) {\n headers[HeaderName.IS_RESOURCE_NAME] = true;\n }\n\n await this.client\n .delete(`projects/${id}`, headers);\n }\n\n async update(\n id: number | string,\n data: ProjectUpdatePayload,\n isProjectName = false,\n ) : Promise<void> {\n const headers: Record<string, any> = {};\n\n if (isProjectName) {\n headers[HeaderName.IS_RESOURCE_NAME] = true;\n }\n\n await this.client\n .put(`projects/${id}`, data, headers);\n }\n\n async getMany(options?: ProjectGetManyOptions) : Promise<ResourceCollectionResponse<Project>> {\n options = options || {};\n const response = await this.client\n .get(`projects${buildQueryString(options.query)}`);\n\n return {\n data: response.data,\n meta: extractResourceMetaOfResponse(response),\n };\n }\n\n async getAll(options?: ProjectGetManyOptions) : Promise<ResourceCollectionResponse<Project>> {\n options = options || {};\n options.query = options.query || {};\n\n if (!options.query.page_size) {\n options.query.page_size = 50;\n }\n\n if (!options.query.page) {\n options.query.page = 1;\n }\n\n const response = await this.getMany(options);\n if (response.data.length === options.query.page_size) {\n options.query.page++;\n\n const next = await this.getAll(options);\n\n response.data.push(...next.data);\n }\n\n return response;\n }\n\n async getOne(\n id: string | number,\n isProjectName = false,\n ): Promise<Project> {\n const headers: Record<string, any> = {};\n\n if (isProjectName) {\n headers[HeaderName.IS_RESOURCE_NAME] = true;\n }\n\n const { data } = await this.client\n .get(`projects/${id}`, headers);\n\n return data;\n }\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { ProjectRepositoryLongNameRepresentation } from './type';\n\nexport function parseLongProjectRepositoryName(name: string) : ProjectRepositoryLongNameRepresentation {\n const index = name.indexOf('/');\n if (index === -1) {\n throw new Error('The project repository name could not parsed.');\n }\n\n const projectName = name.substring(0, index);\n let repositoryName = name.substring(projectName.length + 1);\n\n let artifactDigest : string | undefined;\n if (repositoryName.indexOf('@') !== -1) {\n const index = repositoryName.indexOf('@');\n artifactDigest = repositoryName.substring(index + 1);\n repositoryName = repositoryName.substring(0, index);\n }\n\n let artifactTag : string | undefined;\n if (repositoryName.indexOf(':') !== -1) {\n const index = repositoryName.indexOf(':');\n artifactTag = repositoryName.substring(index + 1);\n repositoryName = repositoryName.substring(0, index);\n }\n\n return {\n projectName,\n repositoryName,\n ...(artifactDigest ? { artifactDigest } : {}),\n ...(artifactTag ? { artifactTag } : {}),\n };\n}\n\nexport function buildProjectRepositoryLongName(\n representation: ProjectRepositoryLongNameRepresentation,\n) : string {\n const str = `${representation.projectName}/${representation.repositoryName}`;\n\n if (representation.artifactTag) {\n return `${str}:${representation.artifactTag}`;\n }\n if (representation.artifactDigest) {\n return `${str}@${representation.artifactDigest}`;\n }\n\n return str;\n}\n","/*\n * Copyright (c) 2022-2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { buildQueryString, extractResourceMetaOfResponse } from '../../utils';\nimport { BaseAPI } from '../base';\nimport type { BaseAPIContext, ResourceCollectionResponse } from '../type';\nimport type {\n ProjectRepository,\n ProjectRepositoryDeleteContext,\n ProjectRepositoryFindOneContext,\n ProjectRepositoryGetManyContext,\n ProjectRepositoryGetOneContext,\n ProjectRepositoryUpdateContext,\n} from './type';\nimport { parseLongProjectRepositoryName } from './utils';\n\nexport class ProjectRepositoryAPI extends BaseAPI {\n // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor\n constructor(context: BaseAPIContext) {\n super(context);\n }\n\n async findOne(projectRepositoryName: string): Promise<ProjectRepository | undefined>;\n\n async findOne(context: ProjectRepositoryFindOneContext): Promise<ProjectRepository | undefined>;\n\n async findOne(input: string | ProjectRepositoryFindOneContext): Promise<ProjectRepository | undefined> {\n let context : ProjectRepositoryDeleteContext;\n if (typeof input === 'string') {\n context = parseLongProjectRepositoryName(input);\n } else {\n context = input;\n }\n\n const { data } = await this.getMany({\n projectName: context.projectName,\n query: {\n q: {\n name: `~${context.repositoryName}`,\n },\n page_size: 1,\n },\n });\n\n return data.shift();\n }\n\n async getOne(projectRepositoryName: string) : Promise<ProjectRepository>;\n\n async getOne(context: ProjectRepositoryGetOneContext) : Promise<ProjectRepository>;\n\n async getOne(input: string | ProjectRepositoryGetOneContext) : Promise<ProjectRepository> {\n let context : ProjectRepositoryGetOneContext;\n if (typeof input === 'string') {\n context = parseLongProjectRepositoryName(input);\n } else {\n context = input;\n }\n\n const { data } : { data: ProjectRepository } = await this.client.get(\n `projects/${context.projectName}/repositories/${context.repositoryName}`,\n );\n\n const parsed = parseLongProjectRepositoryName(data.name);\n\n return {\n ...data,\n name_short: parsed.repositoryName,\n project_name: parsed.projectName,\n };\n }\n\n async getMany(context: ProjectRepositoryGetManyContext): Promise<ResourceCollectionResponse<ProjectRepository>> {\n const result = await this.client\n .get(`projects/${context.projectName}/repositories${buildQueryString(context.query)}`);\n\n return {\n data: result.data\n .map((item: ProjectRepository) => {\n const parsed = parseLongProjectRepositoryName(item.name);\n\n return {\n ...item,\n name_short: parsed.repositoryName,\n project_name: parsed.projectName,\n };\n }),\n meta: extractResourceMetaOfResponse(result),\n };\n }\n\n async getAll(context: ProjectRepositoryGetManyContext) : Promise<ResourceCollectionResponse<ProjectRepository>> {\n context.query = context.query || {};\n\n if (!context.query.page_size) {\n context.query.page_size = 50;\n }\n\n if (!context.query.page) {\n context.query.page = 1;\n }\n\n const response = await this.getMany(context);\n if (response.data.length === context.query.page_size) {\n context.query.page++;\n\n const next = await this.getAll(context);\n\n response.data.push(...next.data);\n }\n\n return response;\n }\n\n async update(context: ProjectRepositoryUpdateContext) : Promise<void> {\n await this.client\n .put(`projects/${context.projectName}/repositories/${context.repositoryName}`, context.data);\n }\n\n async delete(projectRepositoryName: string) : Promise<void>;\n\n async delete(context: ProjectRepositoryDeleteContext) : Promise<void>;\n\n async delete(input: string | ProjectRepositoryDeleteContext) : Promise<void> {\n let context : ProjectRepositoryDeleteContext;\n if (typeof input === 'string') {\n context = parseLongProjectRepositoryName(input);\n } else {\n context = input;\n }\n\n await this.client\n .delete(`projects/${context.projectName}/repositories/${context.repositoryName}`);\n }\n}\n","/*\n * Copyright (c) 2022-2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { buildQueryString } from '../../utils';\nimport { BaseAPI } from '../base';\nimport { buildProjectRepositoryLongName } from '../project-repository';\nimport type { BaseAPIContext } from '../type';\nimport type {\n ProjectArtifact,\n ProjectArtifactCopyElement,\n ProjectArtifactDeleteContext,\n ProjectArtifactGetManyContext,\n} from './type';\n\nexport class ProjectRepositoryArtifactAPI extends BaseAPI {\n // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor\n constructor(context: BaseAPIContext) {\n super(context);\n }\n\n async getMany(context: ProjectArtifactGetManyContext) : Promise<ProjectArtifact[]> {\n const { data } = await this.client\n .get(`projects/${context.projectName}/repositories/${context.repositoryName}/artifacts${buildQueryString(context.query)}`);\n\n return data;\n }\n\n async copy(destination: ProjectArtifactCopyElement, source: string | ProjectArtifactCopyElement) : Promise<void> {\n let from : string;\n if (typeof source === 'string') {\n from = source;\n } else {\n if (!source.artifactTag && !source.artifactDigest) {\n source.artifactTag = 'latest';\n }\n\n from = buildProjectRepositoryLongName(source);\n }\n\n await this.client\n .post(\n `projects/${destination.projectName}/repositories/${destination.repositoryName}/artifacts?` +\n `from=${from}`,\n );\n }\n\n async delete(context: ProjectArtifactDeleteContext) {\n await this.client\n .delete(`projects/${context.projectName}/repositories/${context.repositoryName}/artifacts/${context.tagOrDigest || 'latest'}`);\n }\n}\n","/*\n * Copyright (c) 2022-2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BaseAPI } from '../base';\nimport type { BaseAPIContext } from '../type';\nimport type {\n ProjectArtifactLabelCreateContext,\n ProjectArtifactLabelDeleteContext,\n} from './type';\n\nexport class ProjectRepositoryArtifactLabelAPI extends BaseAPI {\n // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor\n constructor(context: BaseAPIContext) {\n super(context);\n }\n\n async create(options: ProjectArtifactLabelCreateContext) : Promise<void> {\n await this.client\n .post(\n `projects/${options.projectName}/repositories/${options.repositoryName}` +\n `/artifacts/${options.tagOrDigest || 'latest'}/labels`,\n {\n id: options.labelId,\n },\n );\n }\n\n async delete(options: ProjectArtifactLabelDeleteContext) {\n await this.client\n .delete(`projects/${options.projectName}/repositories/${options.repositoryName}` +\n `/artifacts/${options.tagOrDigest || 'latest'}/labels/${options.labelId}`);\n }\n}\n","/*\n * Copyright (c) 2022-2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { merge } from 'smob';\nimport { HeaderName } from '../../constants';\nimport { buildQueryString, extractResourceIDOfResponse, extractResourceMetaOfResponse } from '../../utils';\nimport { BaseAPI } from '../base';\nimport type { BaseAPIContext, ResourceCollectionResponse } from '../type';\nimport type {\n ProjectWebhookEventType,\n ProjectWebhookPolicy,\n ProjectWebhookPolicyCreateContext,\n ProjectWebhookPolicyCreateResponse,\n ProjectWebhookPolicyDeleteByNameContext,\n ProjectWebhookPolicyDeleteContext,\n ProjectWebhookPolicyFindOneContext,\n ProjectWebhookPolicyGetManyContext,\n ProjectWebhookPolicyGetOneContext,\n ProjectWebhookPolicyUpdateContext,\n} from './type';\n\nexport class ProjectWebhookPolicyAPI extends BaseAPI {\n // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor\n constructor(context: BaseAPIContext) {\n super(context);\n }\n\n async create(context: ProjectWebhookPolicyCreateContext) : Promise<ProjectWebhookPolicyCreateResponse> {\n const headers: Record<string, any> = {};\n\n if (context.isProjectName) {\n headers[HeaderName.IS_RESOURCE_NAME] = true;\n }\n\n const response = await this.client\n .post(\n `projects/${context.projectIdOrName}/webhook/policies`,\n this.extendPayload(context.data),\n headers,\n );\n\n return {\n id: extractResourceIDOfResponse(response),\n };\n }\n\n async getMany(context: ProjectWebhookPolicyGetManyContext) : Promise<ResourceCollectionResponse<ProjectWebhookPolicy>> {\n const headers: Record<string, any> = {};\n\n if (context.isProjectName) {\n headers[HeaderName.IS_RESOURCE_NAME] = true;\n }\n\n const response = await this.client\n .get(\n `projects/${context.projectIdOrName}/webhook/policies${buildQueryString(context.query)}`,\n headers,\n );\n\n return {\n data: response.data,\n meta: extractResourceMetaOfResponse(response),\n };\n }\n\n async getOne(\n context: ProjectWebhookPolicyGetOneContext,\n ) : Promise<ProjectWebhookPolicy> {\n const headers: Record<string, any> = {};\n\n if (context.isProjectName) {\n headers[HeaderName.IS_RESOURCE_NAME] = true;\n }\n\n const response = await this.client\n .get(\n `projects/${context.projectIdOrName}/webhook/policies/${context.id}`,\n headers,\n );\n\n return response.data;\n }\n\n async findOne(context: ProjectWebhookPolicyFindOneContext): Promise<ProjectWebhookPolicy | undefined> {\n const response = await this.getMany({\n projectIdOrName: context.projectIdOrName,\n isProjectName: context.isProjectName,\n query: {\n q: {\n name: context.name,\n },\n page_size: 1,\n },\n });\n\n return response.data.pop();\n }\n\n async update(context: ProjectWebhookPolicyUpdateContext): Promise<void> {\n const headers: Record<string, any> = {};\n\n if (context.isProjectName) {\n headers[HeaderName.IS_RESOURCE_NAME] = true;\n }\n\n await this.client.put(\n `projects/${context.projectIdOrName}/webhook/policies/${context.id}`,\n this.extendPayload({\n ...context.data,\n id: context.id,\n }),\n headers,\n );\n }\n\n async deleteByName(context: ProjectWebhookPolicyDeleteByNameContext) {\n const webhook = await this.findOne(context);\n if (webhook) {\n await this.delete({\n isProjectName: false,\n projectIdOrName: webhook.project_id as number,\n id: webhook.id,\n });\n }\n }\n\n async delete(context: ProjectWebhookPolicyDeleteContext) : Promise<any> {\n const headers: Record<string, any> = {};\n\n if (context.isProjectName) {\n headers[HeaderName.IS_RESOURCE_NAME] = true;\n }\n\n await this.client\n .delete(`projects/${context.projectIdOrName}/webhook/policies/${context.id}`, headers);\n }\n\n protected extendPayload(data: Partial<ProjectWebhookPolicy>) : Partial<ProjectWebhookPolicy> {\n data.name = data.name || (Math.random() + 1).toString(36).substring(7);\n\n if (typeof data.enabled === 'undefined') {\n data.enabled = true;\n }\n\n if (typeof data.targets === 'undefined') {\n data.targets = [];\n }\n\n if (typeof data.event_types === 'undefined') {\n data.event_types = ['PUSH_ARTIFACT'];\n } else {\n data.event_types = merge(['PUSH_ARTIFACT'] satisfies ProjectWebhookEventType[], data.event_types);\n }\n\n return data;\n }\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport enum RobotPermissionResource {\n ARTIFACT = 'artifact',\n ARTIFACT_LABEL = 'artifact-label',\n IMMUTABLE_TAG = 'immutable-tag',\n LABEL = 'label',\n LOG = 'log',\n METADATA = 'metadata',\n NOTIFICATION_POLICY = 'notification-policy',\n PREHEAT_POLICY = 'preheat-policy',\n PROJECT = 'project',\n REPOSITORY = 'repository',\n SCAN = 'scan',\n TAG = 'tag',\n}\n\nexport enum RobotPermissionAction {\n CREATE = 'create',\n DELETE = 'delete',\n READ = 'read',\n UPDATE = 'update',\n PULL = 'pull',\n PUSH = 'push',\n LIST = 'list',\n STOP = 'stop',\n}\n","/*\n * Copyright (c) 2022-2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { merge } from 'smob';\nimport { buildQueryString, extractResourceMetaOfResponse } from '../../utils';\nimport { BaseAPI } from '../base';\nimport type { BaseAPIContext, ResourceCollectionResponse } from '../type';\nimport type {\n Robot,\n RobotCreatePayload,\n RobotGetManyContext,\n RobotUpdatePayload,\n RobotUpdateSecretResponse,\n} from './type';\n\nexport class RobotAPI extends BaseAPI {\n // eslint-disable-next-line no-useless-constructor,@typescript-eslint/no-useless-constructor\n constructor(context: BaseAPIContext) {\n super(context);\n }\n\n async create(data: RobotCreatePayload) : Promise<Robot> {\n const response = await this.client\n .post('robots', this.extendPayload(data));\n\n return merge(response.data, data);\n }\n\n async getMany(context: RobotGetManyContext) : Promise<ResourceCollectionResponse<Robot>> {\n const response = await this.client.get(`robots${buildQueryString(context.query)}`);\n\n return {\n data: response.data,\n meta: extractResourceMetaOfResponse(response),\n };\n }\n\n async getOne(id: number) : Promise<Robot> {\n const response = await this.client.get(`robots/${id}`);\n\n return response.data;\n }\n\n /**\n * Update harbor project robot account.\n * If no \"secret\" provided, a new secret is generated.\n *\n * @param id\n * @param secret\n */\n async updateSecret(\n id: string | number,\n secret?: string,\n ): Promise<RobotUpdateSecretResponse> {\n const payload: Record<string, any> = {\n ...(secret ? { secret } : {}),\n };\n\n const { data }: { data: Robot } = await this.client\n .patch(`robots/${id}`, payload);\n\n if (typeof payload.secret !== 'undefined') {\n data.secret = payload.secret;\n }\n\n return data as RobotUpdateSecretResponse;\n }\n\n async update(\n id: number,\n data: RobotUpdatePayload,\n ): Promise<void> {\n await this.client\n .put(`robots/${id}`, this.extendPayload({ ...data, id }));\n }\n\n async delete(id: Robot['id']): Promise<void> {\n await this.client\n .delete(`robots/${id}`);\n }\n\n extendPayload<T extends Record<string, any>>(data: T) : T {\n return merge((data || {}), {\n description: '',\n duration: -1,\n level: 'system',\n editable: true,\n disable: false,\n permissions: [],\n } satisfies Partial<Robot>) as T;\n }\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { RobotPermissionAction, RobotPermissionResource } from './constants';\nimport type { RobotPermission } from './type';\n\n/**\n * Create robot permission to access all resources.\n *\n * @param namespace (e.g. * or project name)\n */\nexport function buildRobotPermissionForAllResources(\n namespace: string,\n) : RobotPermission {\n return {\n access: [\n { resource: RobotPermissionResource.ARTIFACT, action: RobotPermissionAction.CREATE },\n { resource: RobotPermissionResource.ARTIFACT, action: RobotPermissionAction.DELETE },\n { resource: RobotPermissionResource.ARTIFACT, action: RobotPermissionAction.LIST },\n { resource: RobotPermissionResource.ARTIFACT, action: RobotPermissionAction.READ },\n\n { resource: RobotPermissionResource.ARTIFACT_LABEL, action: RobotPermissionAction.CREATE },\n { resource: RobotPermissionResource.ARTIFACT_LABEL, action: RobotPermissionAction.DELETE },\n\n { resource: RobotPermissionResource.IMMUTABLE_TAG, action: RobotPermissionAction.CREATE },\n { resource: RobotPermissionResource.IMMUTABLE_TAG, action: RobotPermissionAction.DELETE },\n { resource: RobotPermissionResource.IMMUTABLE_TAG, action: RobotPermissionAction.LIST },\n { resource: RobotPermissionResource.IMMUTABLE_TAG, action: RobotPermissionAction.UPDATE },\n\n { resource: RobotPermissionResource.REPOSITORY, action: RobotPermissionAction.LIST },\n { resource: RobotPermissionResource.REPOSITORY, action: RobotPermissionAction.PULL },\n { resource: RobotPermissionResource.REPOSITORY, action: RobotPermissionAction.PUSH },\n { resource: RobotPermissionResource.REPOSITORY, action: RobotPermissionAction.UPDATE },\n { resource: RobotPermissionResource.REPOSITORY, action: RobotPermissionAction.DELETE },\n\n { resource: RobotPermissionResource.TAG, action: RobotPermissionAction.CREATE },\n { resource: RobotPermissionResource.TAG, action: RobotPermissionAction.DELETE },\n { resource: RobotPermissionResource.TAG, action: RobotPermissionAction.LIST },\n\n { resource: RobotPermissionResource.SCAN, action: RobotPermissionAction.READ },\n { resource: RobotPermissionResource.SCAN, action: RobotPermissionAction.STOP },\n { resource: RobotPermissionResource.SCAN, action: RobotPermissionAction.CREATE },\n\n { resource: RobotPermissionResource.LABEL, action: RobotPermissionAction.CREATE },\n { resource: RobotPermissionResource.LABEL, action: RobotPermissionAction.DELETE },\n { resource: RobotPermissionResource.LABEL, action: RobotPermissionAction.LIST },\n { resource: RobotPermissionResource.LABEL, action: RobotPermissionAction.READ },\n { resource: RobotPermissionResource.LABEL, action: RobotPermissionAction.UPDATE },\n\n { resource: RobotPermissionResource.METADATA, action: RobotPermissionAction.CREATE },\n { resource: RobotPermissionResource.METADATA, action: RobotPermissionAction.DELETE },\n { resource: RobotPermissionResource.METADATA, action: RobotPermissionAction.LIST },\n { resource: RobotPermissionResource.METADATA, action: RobotPermissionAction.READ },\n { resource: RobotPermissionResource.METADATA, action: RobotPermissionAction.UPDATE },\n\n { resource: RobotPermissionResource.LOG, action: RobotPermissionAction.LIST },\n\n { resource: RobotPermissionResource.NOTIFICATION_POLICY, action: RobotPermissionAction.CREATE },\n { resource: RobotPermissionResource.NOTIFICATION_POLICY, action: RobotPermissionAction.DELETE },\n { resource: RobotPermissionResource.NOTIFICATION_POLICY, action: RobotPermissionAction.LIST },\n { resource: RobotPermissionResource.NOTIFICATION_POLICY, action: RobotPermissionAction.READ },\n { resource: RobotPermissionResource.NOTIFICATION_POLICY, action: RobotPermissionAction.UPDATE },\n\n { resource: RobotPermissionResource.PREHEAT_POLICY, action: RobotPermissionAction.CREATE },\n { resource: RobotPermissionResource.PREHEAT_POLICY, action: RobotPermissionAction.DELETE },\n { resource: RobotPermissionResource.PREHEAT_POLICY, action: RobotPermissionAction.LIST },\n { resource: RobotPermissionResource.PREHEAT_POLICY, action: RobotPermissionAction.READ },\n { resource: RobotPermissionResource.PREHEAT_POLICY, action: RobotPermissionAction.UPDATE },\n\n { resource: RobotPermissionResource.PROJECT, action: RobotPermissionAction.DELETE },\n { resource: RobotPermissionResource.PROJECT, action: RobotPermissionAction.READ },\n { resource: RobotPermissionResource.PROJECT, action: RobotPermissionAction.UPDATE },\n ],\n kind: 'project',\n namespace,\n };\n}\n","/*\n * Copyright (c) 2021-2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { Client as BaseClient } from 'hapic';\nimport type { ConfigInput, ConnectionOptions } from './config';\nimport {\n ProjectAPI,\n ProjectRepositoryAPI,\n ProjectRepositoryArtifactAPI,\n ProjectRepositoryArtifactLabelAPI,\n ProjectWebhookPolicyAPI,\n RobotAPI,\n} from './domains';\nimport type { SearchResult } from './type';\nimport { parseConnectionString } from './utils';\n\nexport class HarborClient extends BaseClient {\n public readonly project: ProjectAPI;\n\n public readonly projectRepositoryArtifact: ProjectRepositoryArtifactAPI;\n\n public readonly projectRepositoryArtifactLabel : ProjectRepositoryArtifactLabelAPI;\n\n public readonly projectRepository: ProjectRepositoryAPI;\n\n public readonly projectWebhookPolicy: ProjectWebhookPolicyAPI;\n\n public readonly robot : RobotAPI;\n\n // -----------------------------------------------------------------------------------\n\n constructor(input?: ConfigInput) {\n input = input || {};\n\n super(input.request);\n\n this.project = new ProjectAPI({ client: this });\n this.projectRepository = new ProjectRepositoryAPI({ client: this });\n this.projectRepositoryArtifact = new ProjectRepositoryArtifactAPI({ client: this });\n this.projectRepositoryArtifactLabel = new ProjectRepositoryArtifactLabelAPI({ client: this });\n this.projectWebhookPolicy = new ProjectWebhookPolicyAPI({ client: this });\n this.robot = new RobotAPI({ client: this });\n\n this.applyConfig(input);\n }\n\n // -----------------------------------------------------------------------------------\n\n applyConfig(input?: ConfigInput) {\n input = input || {};\n\n let connectionOptions : ConnectionOptions | undefined;\n\n if (input.connectionString) {\n connectionOptions = parseConnectionString(input.connectionString);\n }\n\n if (input.connectionOptions) {\n connectionOptions = input.connectionOptions;\n }\n\n if (connectionOptions) {\n this.setBaseURL(connectionOptions.host);\n\n this.setAuthorizationHeader({\n type: 'Basic',\n username: connectionOptions.user,\n password: connectionOptions.password,\n });\n }\n }\n\n // -----------------------------------------------------------------------------------\n\n async search(q: string): Promise<SearchResult> {\n const { data } = await this\n .get(`search?q=${q}`);\n\n return data;\n }\n}\n","/*\n * Copyright (c) 2022-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n hasOwnProperty,\n verifyInstanceBySymbol,\n} from 'hapic';\nimport type { ConfigInput } from './config';\nimport { HarborClient } from './module';\n\nconst instances: Record<string, HarborClient> = {};\n\n/**\n * Verify if a harbor client singleton instance exists.\n *\n * @param key\n */\nexport function hasClient(\n key?: string,\n) : boolean {\n return hasOwnProperty(instances, key || 'default');\n}\n\n/**\n * Set the harbor client singleton instance.\n *\n * @param client\n * @param key\n */\nexport function setClient(\n client: HarborClient,\n key?: string,\n) : HarborClient {\n key = key || 'default';\n\n instances[key] = client;\n\n return client;\n}\n\n/**\n * Receive a harbor singleton instance.\n *\n * @param key\n */\nexport function useClient(\n key?: string,\n) : HarborClient {\n key = key || 'default';\n\n if (Object.prototype.hasOwnProperty.call(instances, key)) {\n return instances[key];\n }\n\n const instance = createClient();\n\n instances[key] = instance;\n\n return instance;\n}\n\n/**\n * Unset a harbor client singleton instance.\n *\n * @param key\n */\nexport function unsetClient(key?: string) {\n key = key || 'default';\n if (hasOwnProperty(instances, key)) {\n delete instances[key];\n }\n}\n\n/**\n * Create a harbor client.\n *\n * @param input\n */\nexport function createClient(input?: ConfigInput) {\n return new HarborClient(input);\n}\n\n/**\n * Check if the argument is of instance Client.\n *\n * @param input\n */\nexport function isClient(input: unknown): input is HarborClient {\n if (input instanceof HarborClient) {\n return true;\n }\n\n return verifyInstanceBySymbol(input, 'HarborClient');\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { createClient } from './instance';\n\nexport * from './constants';\nexport * from './client';\nexport * from './config';\nexport * from './instance';\nexport * from './domains';\nexport * from './module';\nexport * from './type';\nexport * from './utils';\n\nconst client = createClient();\nexport default client;\n"],"names":["HeaderName","ConnectionStringParseError","Error","connectionStringMissing","serviceName","parts","push","join","connectionStringInvalid","parseConnectionString","connectionString","split","length","host","authParts","user","password","buildQueryString","input","withQuestionMark","searchParams","URLSearchParams","keys","Object","i","value","isObject","childKeys","childSearchParams","j","append","encodeURIComponent","toString","Array","isArray","queryString","extractResourceIDOfResponse","response","headers","has","LOCATION","get","id","parseInt","substring","lastIndexOf","Number","isNaN","undefined","extractResourceMetaOfResponse","meta","TOTAL_COUNT","total","BaseAPI","setClient","isClient","client","createClient","context","ProjectAPI","create","data","post","delete","isProjectName","IS_RESOURCE_NAME","update","put","getMany","options","query","getAll","page_size","page","next","getOne","constructor","parseLongProjectRepositoryName","name","index","indexOf","projectName","repositoryName","artifactDigest","artifactTag","buildProjectRepositoryLongName","representation","str","ProjectRepositoryAPI","findOne","q","shift","parsed","name_short","project_name","result","map","item","ProjectRepositoryArtifactAPI","copy","destination","source","from","tagOrDigest","ProjectRepositoryArtifactLabelAPI","labelId","ProjectWebhookPolicyAPI","projectIdOrName","extendPayload","pop","deleteByName","webhook","project_id","Math","random","enabled","targets","event_types","merge","RobotPermissionResource","RobotPermissionAction","RobotAPI","updateSecret","secret","payload","patch","description","duration","level","editable","disable","permissions","buildRobotPermissionForAllResources","namespace","access","resource","ARTIFACT","action","CREATE","DELETE","LIST","READ","ARTIFACT_LABEL","IMMUTABLE_TAG","UPDATE","REPOSITORY","PULL","PUSH","TAG","SCAN","STOP","LABEL","METADATA","LOG","NOTIFICATION_POLICY","PREHEAT_POLICY","PROJECT","kind","HarborClient","BaseClient","applyConfig","connectionOptions","setBaseURL","setAuthorizationHeader","type","username","search","request","project","projectRepository","projectRepositoryArtifact","projectRepositoryArtifactLabel","projectWebhookPolicy","robot","instances","hasClient","key","hasOwnProperty","useClient","prototype","call","instance","unsetClient","verifyInstanceBySymbol"],"mappings":"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