UNPKG

n8n

Version:

n8n Workflow Automation Tool

344 lines 14.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = 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) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); 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 __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; 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.SourceControlGitService = void 0; const typedi_1 = require("typedi"); const child_process_1 = require("child_process"); const path_1 = __importDefault(require("path")); const constants_1 = require("./constants"); const sourceControlHelper_ee_1 = require("./sourceControlHelper.ee"); const Logger_1 = require("../../Logger"); const n8n_workflow_1 = require("n8n-workflow"); const ownership_service_1 = require("../../services/ownership.service"); const sourceControlPreferences_service_ee_1 = require("./sourceControlPreferences.service.ee"); let SourceControlGitService = class SourceControlGitService { constructor(logger, ownershipService, sourceControlPreferencesService) { this.logger = logger; this.ownershipService = ownershipService; this.sourceControlPreferencesService = sourceControlPreferencesService; this.git = null; this.gitOptions = {}; } preInitCheck() { this.logger.debug('GitService.preCheck'); try { const gitResult = (0, child_process_1.execSync)('git --version', { stdio: ['pipe', 'pipe', 'pipe'], }); this.logger.debug(`Git binary found: ${gitResult.toString()}`); } catch (error) { throw new n8n_workflow_1.ApplicationError('Git binary not found', { cause: error }); } try { const sshResult = (0, child_process_1.execSync)('ssh -V', { stdio: ['pipe', 'pipe', 'pipe'], }); this.logger.debug(`SSH binary found: ${sshResult.toString()}`); } catch (error) { throw new n8n_workflow_1.ApplicationError('SSH binary not found', { cause: error }); } return true; } async initService(options) { const { sourceControlPreferences: sourceControlPreferences, gitFolder, sshFolder } = options; this.logger.debug('GitService.init'); if (this.git !== null) { return; } this.preInitCheck(); this.logger.debug('Git pre-check passed'); (0, sourceControlHelper_ee_1.sourceControlFoldersExistCheck)([gitFolder, sshFolder]); await this.setGitSshCommand(gitFolder, sshFolder); if (!(await this.checkRepositorySetup())) { await this.git.init(); } if (!(await this.hasRemote(sourceControlPreferences.repositoryUrl))) { if (sourceControlPreferences.connected && sourceControlPreferences.repositoryUrl) { const instanceOwner = await this.ownershipService.getInstanceOwner(); await this.initRepository(sourceControlPreferences, instanceOwner); } } } async setGitSshCommand(gitFolder = this.sourceControlPreferencesService.gitFolder, sshFolder = this.sourceControlPreferencesService.sshFolder) { const privateKeyPath = await this.sourceControlPreferencesService.getPrivateKeyPath(); const sshKnownHosts = path_1.default.join(sshFolder, 'known_hosts'); const sshCommand = `ssh -o UserKnownHostsFile=${sshKnownHosts} -o StrictHostKeyChecking=no -i ${privateKeyPath}`; this.gitOptions = { baseDir: gitFolder, binary: 'git', maxConcurrentProcesses: 6, trimmed: false, }; const { simpleGit } = await Promise.resolve().then(() => __importStar(require('simple-git'))); this.git = simpleGit(this.gitOptions) .env('GIT_SSH_COMMAND', sshCommand) .env('GIT_TERMINAL_PROMPT', '0'); } resetService() { this.git = null; } async checkRepositorySetup() { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (async)'); } if (!(await this.git.checkIsRepo())) { return false; } try { await this.git.status(); return true; } catch (error) { return false; } } async hasRemote(remote) { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (async)'); } try { const remotes = await this.git.getRemotes(true); const foundRemote = remotes.find((e) => e.name === constants_1.SOURCE_CONTROL_ORIGIN && e.refs.push === remote); if (foundRemote) { this.logger.debug(`Git remote found: ${foundRemote.name}: ${foundRemote.refs.push}`); return true; } } catch (error) { throw new n8n_workflow_1.ApplicationError('Git is not initialized', { cause: error }); } this.logger.debug(`Git remote not found: ${remote}`); return false; } async initRepository(sourceControlPreferences, user) { var _a, _b; if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (Promise)'); } if (sourceControlPreferences.initRepo) { try { await this.git.init(); } catch (error) { this.logger.debug(`Git init: ${error.message}`); } } try { await this.git.addRemote(constants_1.SOURCE_CONTROL_ORIGIN, sourceControlPreferences.repositoryUrl); this.logger.debug(`Git remote added: ${sourceControlPreferences.repositoryUrl}`); } catch (error) { if (error.message.includes('remote origin already exists')) { this.logger.debug(`Git remote already exists: ${error.message}`); } else { throw error; } } await this.setGitUserDetails(user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : constants_1.SOURCE_CONTROL_DEFAULT_NAME, (_a = user.email) !== null && _a !== void 0 ? _a : constants_1.SOURCE_CONTROL_DEFAULT_EMAIL); await this.trackRemoteIfReady(sourceControlPreferences.branchName); if (sourceControlPreferences.initRepo) { try { const branches = await this.getBranches(); if (((_b = branches.branches) === null || _b === void 0 ? void 0 : _b.length) === 0) { await this.git.raw(['branch', '-M', sourceControlPreferences.branchName]); } } catch (error) { this.logger.debug(`Git init: ${error.message}`); } } } async trackRemoteIfReady(targetBranch) { if (!this.git) return; await this.fetch(); const { currentBranch, branches: remoteBranches } = await this.getBranches(); if (!currentBranch && remoteBranches.some((b) => b === targetBranch)) { await this.git.checkout(targetBranch); const upstream = [constants_1.SOURCE_CONTROL_ORIGIN, targetBranch].join('/'); await this.git.branch([`--set-upstream-to=${upstream}`, targetBranch]); this.logger.info('Set local git repository to track remote', { upstream }); } } async setGitUserDetails(name, email) { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (setGitUserDetails)'); } await this.git.addConfig('user.email', email); await this.git.addConfig('user.name', name); } async getBranches() { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (getBranches)'); } try { const { branches } = await this.git.branch(['-r']); const remoteBranches = Object.keys(branches) .map((name) => name.split('/')[1]) .filter((name) => name !== 'HEAD'); const { current } = await this.git.branch(); return { branches: remoteBranches, currentBranch: current, }; } catch (error) { throw new n8n_workflow_1.ApplicationError('Could not get remote branches from repository', { cause: error }); } } async setBranch(branch) { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (setBranch)'); } await this.git.checkout(branch); await this.git.branch([`--set-upstream-to=${constants_1.SOURCE_CONTROL_ORIGIN}/${branch}`, branch]); return await this.getBranches(); } async getCurrentBranch() { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (getCurrentBranch)'); } const currentBranch = (await this.git.branch()).current; return { current: currentBranch, remote: 'origin/' + currentBranch, }; } async diffRemote() { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (diffRemote)'); } const currentBranch = await this.getCurrentBranch(); if (currentBranch.remote) { const target = currentBranch.remote; return await this.git.diffSummary(['...' + target, '--ignore-all-space']); } return; } async diffLocal() { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (diffLocal)'); } const currentBranch = await this.getCurrentBranch(); if (currentBranch.remote) { const target = currentBranch.current; return await this.git.diffSummary([target, '--ignore-all-space']); } return; } async fetch() { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (fetch)'); } await this.setGitSshCommand(); return await this.git.fetch(); } async pull(options = { ffOnly: true }) { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (pull)'); } await this.setGitSshCommand(); const params = {}; if (options.ffOnly) { Object.assign(params, { '--ff-only': true }); } return await this.git.pull(params); } async push(options = { force: false, branch: constants_1.SOURCE_CONTROL_DEFAULT_BRANCH, }) { const { force, branch } = options; if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized ({)'); } await this.setGitSshCommand(); if (force) { return await this.git.push(constants_1.SOURCE_CONTROL_ORIGIN, branch, ['-f']); } return await this.git.push(constants_1.SOURCE_CONTROL_ORIGIN, branch); } async stage(files, deletedFiles) { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (stage)'); } if (deletedFiles === null || deletedFiles === void 0 ? void 0 : deletedFiles.size) { try { await this.git.rm(Array.from(deletedFiles)); } catch (error) { this.logger.debug(`Git rm: ${error.message}`); } } return await this.git.add(Array.from(files)); } async resetBranch(options = { hard: true, target: 'HEAD' }) { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (Promise)'); } if (options === null || options === void 0 ? void 0 : options.hard) { return await this.git.raw(['reset', '--hard', options.target]); } return await this.git.raw(['reset', options.target]); } async commit(message) { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (commit)'); } return await this.git.commit(message); } async status() { if (!this.git) { throw new n8n_workflow_1.ApplicationError('Git is not initialized (status)'); } const statusResult = await this.git.status(); return statusResult; } }; exports.SourceControlGitService = SourceControlGitService; exports.SourceControlGitService = SourceControlGitService = __decorate([ (0, typedi_1.Service)(), __metadata("design:paramtypes", [Logger_1.Logger, ownership_service_1.OwnershipService, sourceControlPreferences_service_ee_1.SourceControlPreferencesService]) ], SourceControlGitService); //# sourceMappingURL=sourceControlGit.service.ee.js.map