UNPKG

@microsoft/compose-language-service

Version:
83 lines 4.86 kB
"use strict"; /*!-------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See LICENSE in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.ImageLinkProvider = void 0; const vscode_languageserver_1 = require("vscode-languageserver"); const yaml_1 = require("yaml"); const ActionContext_1 = require("../utils/ActionContext"); const yamlRangeToLspRange_1 = require("../utils/yamlRangeToLspRange"); const ProviderBase_1 = require("./ProviderBase"); const dockerHubImageRegex = /^(?<imageName>[.\w-]+)(?<tag>:[.\w-]+)?$/i; const dockerHubNamespacedImageRegex = /^(?<namespace>[a-z0-9]+)\/(?<imageName>[.\w-]+)(?<tag>:[.\w-]+)?$/i; const mcrImageRegex = /^mcr.microsoft.com\/(?<namespace>([a-z0-9]+\/)+)(?<imageName>[.\w-]+)(?<tag>:[.\w-]+)?$/i; class ImageLinkProvider extends ProviderBase_1.ProviderBase { on(params, token) { const ctx = (0, ActionContext_1.getCurrentContext)(); ctx.telemetry.properties.isActivationEvent = 'true'; // This happens automatically so we'll treat it as isActivationEvent === true const results = []; const imageTypes = new Set(); const serviceMap = params.document.yamlDocument.value.getIn(['services']); if ((0, yaml_1.isMap)(serviceMap)) { for (const service of serviceMap.items) { // Within each loop we'll check for cancellation (though this is expected to be very fast) if (token.isCancellationRequested) { return undefined; } if ((0, yaml_1.isMap)(service.value)) { const image = service.value.getIn(['image'], true); const hasBuild = service.value.has('build'); if (!hasBuild && (0, yaml_1.isScalar)(image) && typeof image.value === 'string') { const quoteOffset = (image.type === yaml_1.Scalar.QUOTE_SINGLE || image.type === yaml_1.Scalar.QUOTE_DOUBLE) ? 1 : 0; // Offset if the scalar is quoted const link = ImageLinkProvider.getLinkForImage(image.value, imageTypes); if (link && image.range) { results.push(vscode_languageserver_1.DocumentLink.create((0, yamlRangeToLspRange_1.yamlRangeToLspRange)(params.document.textDocument, [quoteOffset + image.range[0] + link.start, quoteOffset + image.range[0] + link.start + link.length]), link.uri)); } } } } } ctx.telemetry.properties.imageTypes = Array.from(imageTypes.values()).sort().join(','); return results; } static getLinkForImage(image, imageTypes) { var _a, _b, _c, _d, _e, _f; let match; let namespace; let imageName; if ((match = dockerHubImageRegex.exec(image)) && (imageName = (_a = match.groups) === null || _a === void 0 ? void 0 : _a['imageName'])) { imageTypes.add('dockerHub'); return { uri: `https://hub.docker.com/_/${imageName}`, start: match.index, length: imageName.length }; } else if ((match = dockerHubNamespacedImageRegex.exec(image)) && (namespace = (_b = match.groups) === null || _b === void 0 ? void 0 : _b['namespace']) && (imageName = (_c = match.groups) === null || _c === void 0 ? void 0 : _c['imageName'])) { imageTypes.add('dockerHubNamespaced'); return { uri: `https://hub.docker.com/r/${namespace}/${imageName}`, start: match.index, length: namespace.length + 1 + imageName.length // 1 is the length of the '/' after namespace }; } else if ((match = mcrImageRegex.exec(image)) && (namespace = (_e = (_d = match.groups) === null || _d === void 0 ? void 0 : _d['namespace']) === null || _e === void 0 ? void 0 : _e.replace(/\/$/, '')) && (imageName = (_f = match.groups) === null || _f === void 0 ? void 0 : _f['imageName'])) { imageTypes.add('mcr'); return { uri: `https://hub.docker.com/_/microsoft-${namespace.replace('/', '-')}-${imageName}`, start: match.index, length: 18 + namespace.length + 1 + imageName.length // 18 is the length of 'mcr.microsoft.com/', 1 is the length of the '/' after namespace }; } return undefined; } } exports.ImageLinkProvider = ImageLinkProvider; //# sourceMappingURL=ImageLinkProvider.js.map