New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@eclipse-che/devfile-converter

Package Overview
Dependencies
Maintainers
5
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@eclipse-che/devfile-converter - npm Package Compare versions

Comparing version 0.0.1-990aacb to 0.0.1-ad84efa

9

lib/converter/devfile-converter.d.ts

@@ -28,4 +28,13 @@ import { V220DevfileCommands, V220DevfileComponents, V220DevfileComponentsItemsContainerEndpoints, V220DevfileComponentsItemsContainerEnv, V220DevfileComponentsItemsContainerVolumeMounts, V220DevfileProjects, V220DevfileProjectsItemsGit } from '@devfile/api';

devfileV1toDevfileV2(devfileV1: che.workspace.devfile.Devfile): Promise<Devfile>;
fixProjectsZipLocations(devfileV2: Devfile): Promise<void>;
fixDuplicatedEndpoints(devfileV2: Devfile): Promise<void>;
fixInvalidVolumeName(devfileV2: Devfile): Promise<void>;
processVolumesFromDevfileV2(devfileV2: Devfile): Promise<void>;
processPluginsAndEditorsFromDevfileV2(devfileV2: Devfile, devfileV1: che.workspace.devfile.Devfile, externalContentAccess?: (filename: string) => Promise<string>): Promise<void>;
findFirstProjectPath(devfileV1: che.workspace.devfile.Devfile): string | undefined;
prunePlaceHolderComponents(devfileV1: che.workspace.devfile.Devfile): void;
fixNightlyImages(devfileV1: che.workspace.devfile.Devfile): void;
fixMemoryLimit(devfileV1: che.workspace.devfile.Devfile): void;
processDefaultWorkDirCommands(devfileV1: che.workspace.devfile.Devfile, path: string): Promise<void>;
devfileV2toDevfileV1(devfileV2: Devfile, externalContentAccess?: (filename: string) => Promise<string>): Promise<che.workspace.devfile.Devfile>;
}

393

lib/converter/devfile-converter.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {

@@ -83,2 +87,4 @@ if (k2 === undefined) k2 = k;

volume.name = volumeV1.name;
// volume names should not use _
volume.name = volume.name.replace(/_/g, '-');
}

@@ -115,3 +121,12 @@ if (volumeV1.containerPath) {

if (endpointV1.name) {
endpoint.name = endpointV1.name;
// the name can't have spaces
// replace space by dash and then remove all special characters
var endpointName = endpointV1.name
.replace(/\s+/g, '-')
// names should not use _
.replace(/_/g, '-')
// trim '-' character from start or end
.replace(/^\-+|\-+$/g, '')
.toLowerCase();
endpoint.name = endpointName;
}

@@ -194,4 +209,9 @@ if (endpointV1.port) {

if (componentV2.kubernetes) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
return JSON.parse(componentV2.kubernetes.inlined);
if (componentV2.kubernetes.inlined) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
return JSON.parse(componentV2.kubernetes.inlined);
}
else {
return undefined;
}
}

@@ -307,3 +327,14 @@ else if (componentV2.openshift) {

if (commandV1.name) {
devfileV2Command.id = commandV1.name;
// the id can't have spaces
// replace space by dash and then remove all special characters
devfileV2Command.id = commandV1.name
.replace(/\s+/g, '-')
.replace(/[^a-zA-Z-]/g, '')
.toLowerCase();
// needs to be max 63 characters
if (devfileV2Command.id.length > 63) {
devfileV2Command.id = devfileV2Command.id.substring(0, 63);
}
// trim '-' character from start or end
devfileV2Command.id = devfileV2Command.id.replace(/^\-+|\-+$/g, '');
}

@@ -313,2 +344,6 @@ if (commandV1.actions && commandV1.actions[0].type === 'exec') {

var action = commandV1.actions[0];
// label is the same as name
if (commandV1.name) {
devfileV2Command.exec.label = commandV1.name;
}
if (action.command) {

@@ -334,2 +369,5 @@ devfileV2Command.exec.commandLine = action.command;

if (commandV2.exec) {
if (commandV2.exec.label) {
devfileV1Command.name = commandV2.exec.label;
}
var devfileAction = {};

@@ -347,9 +385,21 @@ if (commandV2.exec.commandLine) {

devfileV1Command.actions = [devfileAction];
return devfileV1Command;
}
return devfileV1Command;
return undefined;
};
DevfileConverter.prototype.projectV1toProjectV2 = function (projectV1) {
// the name can't have spaces
// replace space by dash and then remove all special characters
var projectName = projectV1.name
.replace(/\s+/g, '-')
// names should not use _
.replace(/_/g, '-')
// names should not use .
.replace(/\./g, '-')
// trim '-' character from start or end
.replace(/^\-+|\-+$/g, '')
.toLowerCase();
var devfileV2Project = {
attributes: {},
name: projectV1.name
name: projectName
};

@@ -361,3 +411,3 @@ if (projectV1.clonePath) {

var source = projectV1.source;
if (source.type === 'git' || source.type === 'github') {
if (source.type === 'git' || source.type === 'github' || source.type === 'bitbucket') {
var remotes = { origin: source.location };

@@ -435,2 +485,7 @@ devfileV2Project.git = {

devfileMetadataV2.attributes['metadata-name-field'] = 'generateName';
devfileMetadataV2.attributes['metadata-name-original-value'] = metadataV1.generateName;
// remove the trailing - to make it compliant with kubernetes name
if (devfileMetadataV2.name.endsWith('-')) {
devfileMetadataV2.name = devfileMetadataV2.name.slice(0, -1);
}
}

@@ -453,4 +508,5 @@ if (metadataV1.name) {

var nameField = metaDataAttributes['metadata-name-field'];
if (nameField === 'generateName') {
devfileMetadataV1.generateName = metadataV2.name;
var originalValue = metaDataAttributes['metadata-name-original-value'];
if (nameField === 'generateName' && originalValue) {
devfileMetadataV1.generateName = originalValue;
}

@@ -465,2 +521,3 @@ else if (nameField === 'name') {

delete metadataV2.attributes['metadata-name-field'];
delete metadataV2.attributes['metadata-name-original-value'];
}

@@ -498,3 +555,5 @@ }

}
var cheTheiaPluginsContent = chePluginComponents.map(function (chePluginComponent) {
var cheTheiaPluginsContent = chePluginComponents
.filter(function (component) { return component.id; })
.map(function (chePluginComponent) {
var cheTheiaPlugin = {};

@@ -504,5 +563,2 @@ if (chePluginComponent.id) {

}
if (chePluginComponent.reference) {
cheTheiaPlugin.reference = chePluginComponent.reference;
}
cheTheiaPlugin.override = {

@@ -556,5 +612,2 @@ sidecar: {}

}
if (cheEditorComponentV1.reference) {
cheEditorYaml.reference = cheEditorComponentV1.reference;
}
if (cheEditorComponentV1.registryUrl) {

@@ -599,39 +652,187 @@ cheEditorYaml.registryUrl = cheEditorComponentV1.registryUrl;

return __generator(this, function (_b) {
devfileV2 = {
schemaVersion: '2.0.0',
metadata: this.metadataV1toMetadataV2(devfileV1.metadata),
projects: (devfileV1.projects || []).map(function (project) { return _this.projectV1toProjectV2(project); }),
components: (devfileV1.components || [])
.map(function (component) { return _this.componentV1toComponentV2(component); })
.filter(function (c) { return c; }),
commands: (devfileV1.commands || []).map(function (command) { return _this.commandV1toCommandV2(command); }).filter(function (c) { return c; })
};
devfileV2.attributes = {};
inlineCheTheiaPluginsYaml = this.inlineCheTheiaPluginsYamlFromComponentsV1(devfileV1.components);
if (inlineCheTheiaPluginsYaml) {
devfileV2.attributes[this.CHE_THEIA_PLUGINS_YAML] = inlineCheTheiaPluginsYaml;
switch (_b.label) {
case 0:
devfileV2 = {
schemaVersion: '2.1.0',
metadata: this.metadataV1toMetadataV2(devfileV1.metadata),
projects: (devfileV1.projects || []).map(function (project) { return _this.projectV1toProjectV2(project); }),
components: (devfileV1.components || [])
.map(function (component) { return _this.componentV1toComponentV2(component); })
.filter(function (c) { return c; }),
commands: (devfileV1.commands || []).map(function (command) { return _this.commandV1toCommandV2(command); }).filter(function (c) { return c; })
};
devfileV2.attributes = {};
// handle the ephemeral attribute
if (devfileV1.attributes &&
devfileV1.attributes.persistVolumes &&
devfileV1.attributes.persistVolumes === 'false') {
devfileV2.attributes['controller.devfile.io/storage-type'] = 'ephemeral';
}
inlineCheTheiaPluginsYaml = this.inlineCheTheiaPluginsYamlFromComponentsV1(devfileV1.components);
if (inlineCheTheiaPluginsYaml) {
devfileV2.attributes[this.CHE_THEIA_PLUGINS_YAML] = inlineCheTheiaPluginsYaml;
}
inlineVsCodeExtensionJson = this.inlineVsCodeExtensionFromComponentsV1(devfileV1.components);
if (inlineVsCodeExtensionJson) {
devfileV2.attributes[this.VSCODE_EXTENSIONS_JSON] = inlineVsCodeExtensionJson;
}
inlineCheEditorYaml = this.inlineCheEditorYamlFromComponentsV1(devfileV1.components);
if (inlineCheEditorYaml) {
devfileV2.attributes[this.CHE_EDITOR_YAML] = inlineCheEditorYaml;
}
if (devfileV1.attributes) {
Object.assign(devfileV2.metadata.attributes, {});
Object.keys(devfileV1.attributes).forEach(function (attributeName) {
devfileV2.metadata.attributes[attributeName] = devfileV1.attributes[attributeName];
});
}
launchCommand = (_a = devfileV1.commands) === null || _a === void 0 ? void 0 : _a.find(function (command) { return command.actions[0].type === 'vscode-launch'; });
if (launchCommand) {
devfileV2.attributes[this.VSCODE_LAUNCH_JSON] = launchCommand.actions[0].referenceContent;
}
// fix duplicated endpoints (same properties (name, port, etc..)
return [4 /*yield*/, this.fixDuplicatedEndpoints(devfileV2)];
case 1:
// fix duplicated endpoints (same properties (name, port, etc..)
_b.sent();
// process volumes
return [4 /*yield*/, this.fixInvalidVolumeName(devfileV2)];
case 2:
// process volumes
_b.sent();
return [4 /*yield*/, this.processVolumesFromDevfileV2(devfileV2)];
case 3:
_b.sent();
// fix zip project location (multi-host --> single-host)
return [4 /*yield*/, this.fixProjectsZipLocations(devfileV2)];
case 4:
// fix zip project location (multi-host --> single-host)
_b.sent();
content = JSON.stringify(devfileV2);
// update devfile v1 constants
content = content.replace(/\$\(CHE_PROJECTS_ROOT\)/g, '$(PROJECTS_ROOT)');
content = content.replace(/\$\{CHE_PROJECTS_ROOT\}/g, '${PROJECTS_ROOT}');
return [2 /*return*/, JSON.parse(content)];
}
inlineVsCodeExtensionJson = this.inlineVsCodeExtensionFromComponentsV1(devfileV1.components);
if (inlineVsCodeExtensionJson) {
devfileV2.attributes[this.VSCODE_EXTENSIONS_JSON] = inlineVsCodeExtensionJson;
}
inlineCheEditorYaml = this.inlineCheEditorYamlFromComponentsV1(devfileV1.components);
if (inlineCheEditorYaml) {
devfileV2.attributes[this.CHE_EDITOR_YAML] = inlineCheEditorYaml;
}
if (devfileV1.attributes) {
Object.assign(devfileV2.metadata.attributes, {});
Object.keys(devfileV1.attributes).forEach(function (attributeName) {
devfileV2.metadata.attributes[attributeName] = devfileV1.attributes[attributeName];
});
});
};
// if some endpoints have excactly the same value, remove duplicates
DevfileConverter.prototype.fixProjectsZipLocations = function (devfileV2) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
// get projects
devfileV2.projects.forEach(function (project) {
if (project.zip && project.zip.location) {
var location = project.zip.location;
// if matching a pattern, then update the location
var regex = /https:\/\/(devfile-registry|codeready|eclipse-che)-(?<namespace>.*?)\.(?<subdomain>.*)[\/.*]*\/resources\/(?<resourcelink>.*)/gm;
var m = regex.exec(location);
if (m !== null) {
var namespace = m.groups.namespace;
var resourcelink = m.groups.resourcelink;
var newLocation = "http://devfile-registry.".concat(namespace, ".svc:8080/resources/").concat(resourcelink);
project.zip.location = newLocation;
}
}
});
return [2 /*return*/];
});
});
};
// if some endpoints have excactly the same value, remove duplicates
DevfileConverter.prototype.fixDuplicatedEndpoints = function (devfileV2) {
return __awaiter(this, void 0, void 0, function () {
var endpoints, uniqueEndpoints, uniqueEndpointsJson, alreadyProcessedEndpoints;
return __generator(this, function (_a) {
endpoints = devfileV2.components
.filter(function (component) { return component.container; })
.map(function (component) { return component.container.endpoints; })
.flat();
uniqueEndpoints = endpoints.filter(function (value, index) {
var _value = JSON.stringify(value);
return (index ===
endpoints.findIndex(function (obj) {
return JSON.stringify(obj) === _value;
}));
});
uniqueEndpointsJson = uniqueEndpoints.map(function (endpoint) { return JSON.stringify(endpoint); });
alreadyProcessedEndpoints = [];
// ok now we'll iterate on endpoints and check if we need to replace endpoint if it's already been added
devfileV2.components
.filter(function (component) { return component.container; })
.forEach(function (component) {
var endpoints = component.container.endpoints || [];
var i = endpoints.length;
while (i--) {
var jsonEndpoint = JSON.stringify(endpoints[i]);
if (uniqueEndpointsJson.includes(jsonEndpoint)) {
// first time we see, we keep
if (!alreadyProcessedEndpoints.includes(jsonEndpoint)) {
alreadyProcessedEndpoints.push(jsonEndpoint);
}
else {
// need to remove this endpoint
endpoints.splice(i, 1);
}
}
}
});
return [2 /*return*/];
});
});
};
// if some volume component are also components, update the name of the volume component
// to be componentName-volume
DevfileConverter.prototype.fixInvalidVolumeName = function (devfileV2) {
return __awaiter(this, void 0, void 0, function () {
var mountedVolumes, mountedVolumeNames, allComponentExceptVolumeNames, invalidVolumeNames;
return __generator(this, function (_a) {
mountedVolumes = devfileV2.components
.map(function (component) { return component.container; })
.filter(function (container) { return container; })
.map(function (container) { return container.volumeMounts; })
.reduce(function (acc, volumeMounts) { return acc.concat(volumeMounts); }, [])
.filter(function (volume) { return volume; });
mountedVolumeNames = mountedVolumes.map(function (volume) { return volume.name; });
allComponentExceptVolumeNames = devfileV2.components
.filter(function (component) { return !component.volume; })
.map(function (component) { return component.name; });
invalidVolumeNames = mountedVolumeNames.filter(function (componentName) {
return allComponentExceptVolumeNames.includes(componentName);
});
// we have duplicates, need to update the volume name
mountedVolumes.forEach(function (volume) {
if (invalidVolumeNames.includes(volume.name)) {
volume.name = "".concat(volume.name, "-volume");
}
});
return [2 /*return*/];
});
});
};
// add missing volumes components when a volumeMount is defined in the devfile
DevfileConverter.prototype.processVolumesFromDevfileV2 = function (devfileV2) {
return __awaiter(this, void 0, void 0, function () {
var mountedVolumes, mountedVolumeNames, allComponentVolumeNames, missingVolumes;
return __generator(this, function (_a) {
mountedVolumes = devfileV2.components
.map(function (component) { return component.container; })
.filter(function (container) { return container; })
.map(function (container) { return container.volumeMounts; })
.reduce(function (acc, volumeMounts) { return acc.concat(volumeMounts); }, [])
.filter(function (volume) { return volume; });
mountedVolumeNames = mountedVolumes.map(function (volume) { return volume.name; });
allComponentVolumeNames = devfileV2.components
.filter(function (component) { return component.volume; })
.map(function (component) { return component.name; });
missingVolumes = Array.from(new Set(mountedVolumeNames.filter(function (volumeName) { return !allComponentVolumeNames.includes(volumeName); })));
// add missing volumes
missingVolumes.forEach(function (volumeName) {
devfileV2.components.push({
name: volumeName,
volume: {}
});
}
launchCommand = (_a = devfileV1.commands) === null || _a === void 0 ? void 0 : _a.find(function (command) { return command.actions[0].type === 'vscode-launch'; });
if (launchCommand) {
devfileV2.attributes[this.VSCODE_LAUNCH_JSON] = launchCommand.actions[0].referenceContent;
}
content = JSON.stringify(devfileV2);
// update devfile v1 constants
content = content.replace(/\$\(CHE_PROJECTS_ROOT\)/g, '$(PROJECTS_ROOT)');
content = content.replace(/\$\{CHE_PROJECTS_ROOT\}/g, '${PROJECTS_ROOT}');
return [2 /*return*/, JSON.parse(content)];
});
return [2 /*return*/];
});

@@ -699,3 +900,3 @@ });

devfileV1.components.push({
id: "".concat(recommendation.replaceAll('.', '/'), "/latest"),
id: "".concat(recommendation.replace(/\./g, '/'), "/latest"),
type: 'chePlugin'

@@ -732,5 +933,2 @@ });

}
if (component.reference) {
v1component.reference = component.reference;
}
if (component.registryUrl) {

@@ -787,5 +985,2 @@ v1component.registryUrl = component.registryUrl;

}
if (cheEditorYaml.reference) {
v1component.reference = cheEditorYaml.reference;
}
if (cheEditorYaml.registryUrl) {

@@ -802,5 +997,65 @@ v1component.registryUrl = cheEditorYaml.registryUrl;

};
DevfileConverter.prototype.findFirstProjectPath = function (devfileV1) {
var projects = devfileV1.projects;
if (!projects || projects.length === 0) {
return undefined;
}
// take first project
var project = projects[0];
var path;
if (project.clonePath) {
path = "${CHE_PROJECTS_ROOT}/".concat(project.clonePath);
}
else {
path = "${CHE_PROJECTS_ROOT}/".concat(project.name);
}
return path;
};
DevfileConverter.prototype.prunePlaceHolderComponents = function (devfileV1) {
devfileV1.components = devfileV1.components.filter(function (component) { return component.image !== 'buildguidanceimage-placeholder'; });
};
DevfileConverter.prototype.fixNightlyImages = function (devfileV1) {
devfileV1.components.forEach(function (component) {
if (component.image && component.image === 'quay.io/eclipse/che-quarkus:nightly') {
component.image = 'quay.io/eclipse/che-quarkus:next';
}
else if (component.image && component.image === 'quay.io/eclipse/che-java11-maven:nightly') {
component.image = 'quay.io/eclipse/che-java11-maven:next';
}
});
};
// Apply 1Gi on all components without memoryLimit
DevfileConverter.prototype.fixMemoryLimit = function (devfileV1) {
devfileV1.components.forEach(function (component) {
if (component.type === 'dockerimage' && !component.memoryLimit) {
component.memoryLimit = '1Gi';
}
});
};
DevfileConverter.prototype.processDefaultWorkDirCommands = function (devfileV1, path) {
return __awaiter(this, void 0, void 0, function () {
var execWithoutWorkingdir;
return __generator(this, function (_a) {
execWithoutWorkingdir = devfileV1.commands
.filter(function (command) {
return command.actions &&
command.actions.find(function (action) {
return (!action.workdir || action.workdir === '$PROJECTS_ROOT' || action.workdir === '${PROJECTS_ROOT}') &&
action.type === 'exec';
});
})
.map(function (command) { return command.actions; })
.flat();
// update working directory
if (execWithoutWorkingdir.length > 0 && path) {
// set the working directory to the project directory
execWithoutWorkingdir.forEach(function (exec) { return (exec.workdir = path); });
}
return [2 /*return*/];
});
});
};
DevfileConverter.prototype.devfileV2toDevfileV1 = function (devfileV2, externalContentAccess) {
return __awaiter(this, void 0, void 0, function () {
var devfileV1, attributeKeys, attributes_1, devfileV1Any, content;
var devfileV1, attributeKeys, attributes_1, firstProjectPath, devfileV1Any, content;
var _this = this;

@@ -836,2 +1091,14 @@ return __generator(this, function (_a) {

_a.sent();
firstProjectPath = this.findFirstProjectPath(devfileV1);
// update workDir of commands to be inside the current project if missing
return [4 /*yield*/, this.processDefaultWorkDirCommands(devfileV1, firstProjectPath)];
case 2:
// update workDir of commands to be inside the current project if missing
_a.sent();
// prune placeholder components
this.prunePlaceHolderComponents(devfileV1);
// fix nightly images of che
this.fixNightlyImages(devfileV1);
// memoryLimit is a mandatory attribute in devfile v1
this.fixMemoryLimit(devfileV1);
devfileV1Any = devfileV1;

@@ -855,2 +1122,5 @@ if (devfileV1.components && devfileV1.components.length === 0) {

}
if (devfileV1.attributes && Object.keys(devfileV1.attributes).length === 0) {
delete devfileV1Any.attributes;
}
content = JSON.stringify(devfileV1, undefined, 2);

@@ -860,2 +1130,5 @@ // update devfile v2 constants

content = content.replace(/\$\{PROJECTS_ROOT\}/g, '${CHE_PROJECTS_ROOT}');
if (firstProjectPath) {
content = content.replace(/\$\{PROJECT_SOURCE\}/g, firstProjectPath);
}
return [2 /*return*/, JSON.parse(content)];

@@ -862,0 +1135,0 @@ }

{
"name": "@eclipse-che/devfile-converter",
"version": "0.0.1-990aacb",
"version": "0.0.1-ad84efa",
"description": "Convert devfile v1 to v2 or v2 to v1",

@@ -73,2 +73,10 @@ "publishConfig": {

],
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 100,
"lines": 100,
"statements": 100
}
},
"coverageDirectory": "coverage",

@@ -75,0 +83,0 @@ "modulePathIgnorePatterns": [

@@ -18,1 +18,5 @@ # devfile-converter

```
# Trademark
"Che" is a trademark of the Eclipse Foundation.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc