@wocker/ws
Version:
Docker workspace for web projects
251 lines (250 loc) • 10.1 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PresetService = void 0;
const core_1 = require("@wocker/core");
const utils_1 = require("@wocker/utils");
const md5_1 = __importDefault(require("md5"));
const PresetRepository_1 = require("../repositories/PresetRepository");
const GithubClient_1 = require("../../../makes/GithubClient");
let PresetService = class PresetService {
constructor(appConfigService, fs, presetRepository) {
this.appConfigService = appConfigService;
this.fs = fs;
this.presetRepository = presetRepository;
}
async prompt(configMap, values = {}) {
for (const name in configMap) {
const config = configMap[name];
switch (config.type) {
case "boolean": {
const value = await (0, utils_1.promptConfirm)({
message: config.message,
required: config.required,
default: typeof values[name] !== "undefined" && values[name] === "true"
? true
: config.default
});
values[name] = value.toString();
break;
}
case "select": {
const options = (0, utils_1.normalizeOptions)(config.options);
const defaultValue = config.multiple ? options.reduce((defaultValue, option) => {
if (values[option.value] === "true") {
return [
...defaultValue,
option.value
];
}
return defaultValue;
}, []) : values[name];
const result = await (0, utils_1.promptSelect)({
required: config.required,
multiple: config.multiple,
message: config.message,
options: config.options,
default: defaultValue
});
if (!config.multiple) {
values[name] = result;
}
else {
for (const option of options) {
if (result.includes(option.value)) {
values[option.value] = "true";
}
else if (option.value in values) {
delete values[option.value];
}
}
}
break;
}
case "int":
case "number": {
const result = await (0, utils_1.promptInput)({
...config,
type: "number",
default: values[name] || config.default
});
values[name] = result.toString();
break;
}
case "string":
case "text":
case "password": {
values[name] = await (0, utils_1.promptInput)({
...config,
type: config.type === "string" ? "text" : config.type,
default: values[name] || config.default
});
break;
}
}
}
return values;
}
getImageNameForProject(project, preset) {
switch (project.presetMode) {
case "project":
return `project-${project.name}:develop`;
default:
return this.getImageName(preset, project.buildArgs || {});
}
}
getImageName(preset, buildArgs) {
const rawValues = [], hashValues = [];
Object.keys(preset.buildArgsOptions || {}).forEach((key) => {
const hash = (preset.buildArgsOptions[key] || {}).hash || true;
const value = buildArgs[key];
if (hash) {
hashValues.push(value);
}
else {
rawValues.push(value);
}
});
const version = [
...rawValues,
(0, md5_1.default)(hashValues.join(",")).substring(0, 6)
].filter((value) => {
return !!value;
}).join("-");
return `ws-preset-${preset.name}:${version}`;
}
get(name) {
const preset = name
? this.presetRepository.searchOne({ name })
: this.presetRepository.searchOne({ path: this.appConfigService.pwd() });
if (!preset) {
throw new Error(name ? `Preset "${name}" not found` : "Preset not found");
}
return preset;
}
async init() {
const fs = new core_1.FileSystem(this.appConfigService.pwd());
let preset = this.presetRepository.searchOne({
path: this.appConfigService.pwd()
});
if (preset) {
return;
}
if (fs.exists("config.json")) {
const config = fs.readJSON("config.json");
this.appConfigService.registerPreset(config.name, core_1.PRESET_SOURCE_EXTERNAL, fs.path());
return;
}
let config = {};
config.name = await (0, utils_1.promptInput)({
message: "Preset name",
required: true,
validate: (name) => {
if (!name || typeof name !== "string") {
return true;
}
if (this.presetRepository.searchOne({ name })) {
return "Preset name already taken";
}
return true;
}
});
config.version = await (0, utils_1.promptInput)({
message: "Preset version",
validate: (version) => {
if (!/^[0-9]+\.[0-9]+\.[0-9]+$/.test(version)) {
return "Invalid version";
}
return true;
}
});
config.type = await (0, utils_1.promptSelect)({
message: "Preset type",
options: ["dockerfile", "image"]
});
switch (config.type) {
case "dockerfile":
const files = await fs.readdirFiles();
const dockerfiles = files.filter((fileName) => {
if (new RegExp("^(.*)\\.dockerfile$").test(fileName)) {
return true;
}
return new RegExp("^Dockerfile(\\..*)?").test(fileName);
});
if (dockerfiles.length === 0) {
throw new Error("No dockerfiles found");
}
config.dockerfile = await (0, utils_1.promptSelect)({
message: "Preset dockerfile",
options: dockerfiles
});
break;
case "image":
config.image = await (0, utils_1.promptInput)({
message: "Preset image",
required: true,
validate(value) {
if (!/^[a-z0-9]+(?:[._-][a-z0-9]+)*(?::[a-z0-9]+(?:[._-][a-z0-9]+)*)?$/.test(value)) {
return "Invalid image name";
}
return true;
}
});
break;
}
console.info(JSON.stringify(config, null, 4));
const confirm = await (0, utils_1.promptConfirm)({
message: "Correct",
default: true
});
if (!confirm) {
return;
}
fs.writeJSON("config.json", config);
this.appConfigService.registerPreset(config.name, core_1.PRESET_SOURCE_EXTERNAL, fs.path());
}
async deinit() {
const preset = this.presetRepository.searchOne({
path: this.appConfigService.pwd()
});
if (!preset) {
return;
}
this.appConfigService.config.unregisterPreset(preset.name);
this.appConfigService.save();
}
async addPreset(name, repository, version) {
if (!repository) {
repository = `kearisp/wocker-${name}-preset`;
}
let preset = this.presetRepository.searchOne({
name
});
if (!preset) {
console.info("Loading...");
const [owner, repo] = repository.split("/");
const github = new GithubClient_1.GithubClient(owner, repo);
const info = await github.getInfo();
await github.download(info.default_branch, this.fs.path(`presets/${name}`));
this.appConfigService.registerPreset(name, core_1.PRESET_SOURCE_GITHUB);
}
}
};
exports.PresetService = PresetService;
exports.PresetService = PresetService = __decorate([
(0, core_1.Injectable)(),
__metadata("design:paramtypes", [core_1.AppConfigService,
core_1.AppFileSystemService,
PresetRepository_1.PresetRepository])
], PresetService);