mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Allow a project to be located below the root of repo
This commit is contained in:
		| @@ -135,7 +135,12 @@ | ||||
|             "updated": "Project '__project__' updated", | ||||
|             "pull": "Project '__project__' reloaded", | ||||
|             "revert": "Project '__project__' reverted", | ||||
|             "merge-complete": "Git merge completed" | ||||
|             "merge-complete": "Git merge completed", | ||||
|             "setupCredentials": "Setup credentials", | ||||
|             "setupProjectFiles": "Setup project files", | ||||
|             "no": "No thanks", | ||||
|             "createDefault": "Create default project files", | ||||
|             "mergeConflict": "Show merge conflicts" | ||||
|         }, | ||||
|         "label": { | ||||
|             "manage-project-dep": "Manage project dependencies", | ||||
| @@ -544,14 +549,19 @@ | ||||
|                 "removeFromProject": "remove from project", | ||||
|                 "addToProject": "add to project", | ||||
|                 "files": "Files", | ||||
|                 "package": "Package", | ||||
|                 "flow": "Flow", | ||||
|                 "credentials": "Credentials", | ||||
|                 "package":"Package", | ||||
|                 "packageCreate":"File will be created when changes are saved", | ||||
|                 "fileNotExist":"File does not exist", | ||||
|                 "selectFile": "Select File", | ||||
|                 "invalidEncryptionKey": "Invalid encryption key", | ||||
|                 "encryptionEnabled": "Encryption enabled", | ||||
|                 "encryptionDisabled": "Encryption disabled", | ||||
|                 "setTheEncryptionKey": "Set the encryption key:", | ||||
|                 "resetTheEncryptionKey": "Reset the encryption key:", | ||||
|                 "changeTheEncryptionKey": "Change the encryption key:", | ||||
|                 "setTheEncryptionKey": "Set the encryption key", | ||||
|                 "resetTheEncryptionKey": "Reset the encryption key", | ||||
|                 "changeTheEncryptionKey": "Change the encryption key", | ||||
|                 "currentKey": "Current key", | ||||
|                 "newKey": "New key", | ||||
|                 "credentialsAlert": "This will delete all existing credentials", | ||||
|   | ||||
| @@ -211,7 +211,7 @@ var RED = (function() { | ||||
|                             } | ||||
|                         ] | ||||
|                     } else if (msg.error === "missing-types") { | ||||
|                         text+="<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | ||||
|                         text+="<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>"; | ||||
|                         if (!!RED.projects.getActiveProject()) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
| @@ -239,7 +239,7 @@ var RED = (function() { | ||||
|                             if (RED.user.hasPermission("projects.write")) { | ||||
|                                 options.buttons = [ | ||||
|                                     { | ||||
|                                         text: "Setup credentials", | ||||
|                                         text: RED._("notification.project.setupCredentials"), | ||||
|                                         click: function() { | ||||
|                                             persistentNotifications[notificationId].hideNotification(); | ||||
|                                             RED.projects.showCredentialsPrompt(); | ||||
| @@ -250,7 +250,7 @@ var RED = (function() { | ||||
|                         } else { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: "Close", | ||||
|                                     text: RED._("common.label.close"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                     } | ||||
| @@ -261,7 +261,7 @@ var RED = (function() { | ||||
|                         if (RED.user.hasPermission("projects.write")) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: "Setup project files", | ||||
|                                     text: RED._("notification.project.setupProjectFiles"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.projects.showFilesPrompt(); | ||||
| @@ -273,10 +273,10 @@ var RED = (function() { | ||||
|                         if (RED.user.hasPermission("projects.write")) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: "Create default package file", | ||||
|                                     text: RED._("notification.project.setupProjectFiles"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.projects.createDefaultPackageFile(); | ||||
|                                         RED.projects.showFilesPrompt(); | ||||
|                                     } | ||||
|                                 } | ||||
|                             ] | ||||
| @@ -285,13 +285,13 @@ var RED = (function() { | ||||
|                         if (RED.user.hasPermission("projects.write")) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: "No thanks", | ||||
|                                     text: RED._("notification.project.no"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                     } | ||||
|                                 }, | ||||
|                                 { | ||||
|                                     text: "Create default project files", | ||||
|                                     text: RED._("notification.project.createDefault"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.projects.createDefaultFileSet(); | ||||
| @@ -305,7 +305,7 @@ var RED = (function() { | ||||
|                         if (RED.user.hasPermission("projects.write")) { | ||||
|                             options.buttons = [ | ||||
|                                 { | ||||
|                                     text: "Show merge conflicts", | ||||
|                                     text: RED._("notification.project.mergeConflict"), | ||||
|                                     click: function() { | ||||
|                                         persistentNotifications[notificationId].hideNotification(); | ||||
|                                         RED.sidebar.versionControl.showLocalChanges(); | ||||
|   | ||||
| @@ -526,7 +526,7 @@ RED.projects.settings = (function() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function showProjectFileListing(row,activeProject,current,filter,done) { | ||||
|     function showProjectFileListing(row,activeProject,current,selectFilter,done) { | ||||
|         var dialog; | ||||
|         var dialogBody; | ||||
|         var filesList; | ||||
| @@ -569,14 +569,15 @@ RED.projects.settings = (function() { | ||||
|                 }) | ||||
|                 return result; | ||||
|             } | ||||
|             var files = sortFiles("",files,""); | ||||
|             createFileSubList(container,files.children,current,filter,done,"height: 175px"); | ||||
|             var files = sortFiles("",files,"") | ||||
|  | ||||
|             createFileSubList(container,files.children,current,selectFilter,done,"height: 175px"); | ||||
|             spinner.remove(); | ||||
|         }); | ||||
|         return container; | ||||
|     } | ||||
|  | ||||
|     function createFileSubList(container, files, current, filter, onselect, style) { | ||||
|     function createFileSubList(container, files, current, selectFilter, onselect, style) { | ||||
|         style = style || ""; | ||||
|         var list = $('<ol>',{class:"projects-dialog-file-list", style:style}).appendTo(container).editableList({ | ||||
|             addButton: false, | ||||
| @@ -592,7 +593,7 @@ RED.projects.settings = (function() { | ||||
|                         } else { | ||||
|                             children.hide(); | ||||
|                         } | ||||
|                         createFileSubList(children,entry.children,current,filter,onselect); | ||||
|                         createFileSubList(children,entry.children,current,selectFilter,onselect); | ||||
|                         header.addClass("selectable"); | ||||
|                         header.click(function(e) { | ||||
|                             if ($(this).hasClass("expanded")) { | ||||
| @@ -618,7 +619,7 @@ RED.projects.settings = (function() { | ||||
|                         header.addClass("projects-dialog-file-list-entry-file-type-git"); | ||||
|                     } | ||||
|                     $('<span class="projects-dialog-file-list-entry-file"> <i class="fa '+fileIcon+'"></i></span>').appendTo(header); | ||||
|                     if (filter.test(entry.name)) { | ||||
|                     if (selectFilter(entry)) { | ||||
|                         header.addClass("selectable"); | ||||
|                         if (entry.path === current) { | ||||
|                             header.addClass("selected"); | ||||
| @@ -626,7 +627,7 @@ RED.projects.settings = (function() { | ||||
|                         header.click(function(e) { | ||||
|                             $(".projects-dialog-file-list-entry.selected").removeClass("selected"); | ||||
|                             $(this).addClass("selected"); | ||||
|                             onselect(entry.path); | ||||
|                             onselect(entry.path,true); | ||||
|                         }) | ||||
|                         header.dblclick(function(e) { | ||||
|                             e.preventDefault(); | ||||
| @@ -730,18 +731,27 @@ RED.projects.settings = (function() { | ||||
|         var title = $('<h3></h3>').text(RED._("sidebar.project.projectSettings.files")).appendTo(pane); | ||||
|         var filesContainer = $('<div class="user-settings-section"></div>').appendTo(pane); | ||||
|         if (RED.user.hasPermission("projects.write")) { | ||||
|             var editFilesButton = $('<button class="editor-button editor-button-small" style="float: right;">' + RED._('sidebar.project.projectSettings.edit') + '</button>') | ||||
|             var editFilesButton = $('<button type="button" id="project-settings-tab-settings-file-edit" class="editor-button editor-button-small" style="float: right;">' + RED._('sidebar.project.projectSettings.edit') + '</button>') | ||||
|                 .appendTo(title) | ||||
|                 .click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     formButtons.show(); | ||||
|                     editFilesButton.hide(); | ||||
|                     // packageFileLabelText.hide(); | ||||
|  | ||||
|                     if (!activeProject.files.package) { | ||||
|                         packageFileSubLabel.find(".projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.packageCreate")); | ||||
|                         packageFileSubLabel.show(); | ||||
|                     } | ||||
|  | ||||
|                     packageFileInputSearch.show(); | ||||
|                     // packageFileInputCreate.show(); | ||||
|                     flowFileLabelText.hide(); | ||||
|                     flowFileInput.show(); | ||||
|                     flowFileInputSearch.show(); | ||||
|                     credFileLabel.hide(); | ||||
|                     credFileInput.show(); | ||||
|                     flowFileInput.focus(); | ||||
|  | ||||
|                     flowFileInputResize(); | ||||
|  | ||||
|                     // credentialStateLabel.parent().hide(); | ||||
|                     credentialStateLabel.addClass("uneditable-input"); | ||||
|                     $(".user-settings-row-credentials").show(); | ||||
| @@ -752,14 +762,76 @@ RED.projects.settings = (function() { | ||||
|         } | ||||
|         var row; | ||||
|  | ||||
|         // Flow files | ||||
|         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); | ||||
|         $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.package")).appendTo(row); | ||||
|         var packageFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row); | ||||
|         var packageFileLabelPrefixText = $('<span style="display:inline-block; padding: 6px 0 6px 6px">').text("/").appendTo(packageFileLabel); | ||||
|         var packageFileLabelText = $('<span style="display:inline-block;  padding: 6px 6px 6px 0">').text(activeProject.files.package||"package.json").appendTo(packageFileLabel); | ||||
|         var packageFileInput = $('<input type="hidden">').val(activeProject.files.package||"package.json").appendTo(packageFileLabel); | ||||
|  | ||||
|         var packageFileInputSearch = $('<button type="button" class="editor-button toggle single" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; width: 36px; height: 34px; position: absolute; top: -1px; right: -1px;"><i class="fa fa-folder-open-o"></i></button>') | ||||
|             .hide() | ||||
|             .appendTo(packageFileLabel) | ||||
|             .click(function(e) { | ||||
|                 if ($(this).hasClass('selected')) { | ||||
|                     $(this).removeClass('selected'); | ||||
|                     packageFileLabel.find('.project-file-listing-container').slideUp(200,function() { | ||||
|                          $(this).remove(); | ||||
|                          packageFileLabel.css('height',''); | ||||
|                      }); | ||||
|                     packageFileLabel.css('color',''); | ||||
|                 } else { | ||||
|                     $(this).addClass('selected'); | ||||
|                     packageFileLabel.css('color','inherit'); | ||||
|                     var fileList = showProjectFileListing(packageFileLabel,activeProject,packageFileInput.val(), | ||||
|                                         function(entry) { return entry.children || /package\.json$/.test(entry.path); }, | ||||
|                                         function(result,close) { | ||||
|                                             if (result) { | ||||
|                                                 packageFileInput.val(result); | ||||
|                                                 packageFileLabelText.text(result); | ||||
|                                                 var rootDir = result.substring(0,result.length - 12); | ||||
|                                                 flowFileLabelPrefixText.text("/"+rootDir); | ||||
|                                                 credFileLabelPrefixText.text("/"+rootDir); | ||||
|                                                 flowFileInputResize(); | ||||
|                                                 packageFileSubLabel.hide(); | ||||
|                                             } | ||||
|                                             if (close) { | ||||
|                                                 $(packageFileInputSearch).click(); | ||||
|                                             } | ||||
|                                             checkFiles(); | ||||
|                                         }); | ||||
|                     packageFileLabel.css('height','auto'); | ||||
|                     setTimeout(function() { | ||||
|                         fileList.slideDown(200); | ||||
|                     },50); | ||||
|  | ||||
|                 } | ||||
|             }) | ||||
|         RED.popover.tooltip(packageFileInputSearch,RED._("sidebar.project.projectSettings.selectFile")); | ||||
|         var packageFileSubLabel = $('<label style="margin-left: 110px" class="projects-edit-form-sublabel"><small><span class="form-warning"><i class="fa fa-warning"></i> <span class="projects-edit-form-sublabel-text"></span></small></label>').appendTo(row).hide(); | ||||
|         if (!activeProject.files.package) { | ||||
|             packageFileSubLabel.find(".projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.fileNotExist")); | ||||
|             packageFileSubLabel.show(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         var projectPackage = "/"+(activeProject.files.package||"package.json"); | ||||
|         var projectRoot = projectPackage.substring(0,projectPackage.length - 12); | ||||
|  | ||||
|         // Flow files | ||||
|         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); | ||||
|         $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.flow")).appendTo(row); | ||||
|         var flowFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row); | ||||
|         var flowFileLabelText = $('<span style="display:inline-block; padding: 6px">').text(activeProject.files.flow).appendTo(flowFileLabel); | ||||
|  | ||||
|         var flowFileInput = $('<input id="" type="text" style="margin-bottom: 0;width: 100%; border: none;">').val(activeProject.files.flow).hide().appendTo(flowFileLabel); | ||||
|         var flowFileInputSearch = $('<button class="editor-button" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; width: 36px; height: 34px; position: absolute; top: -1px; right: -1px;"><i class="fa fa-folder-open-o"></i></button>') | ||||
|         var flowFileLabelPrefixText = $('<span style="display:inline-block; padding: 6px 0 6px 6px">').text(projectRoot).appendTo(flowFileLabel); | ||||
|         var flowFileLabelText = $('<span style="display:inline-block; padding: 6px 6px 6px 0">').text(activeProject.files.flow||"flows.json").appendTo(flowFileLabel); | ||||
|         var flowFileInputResize = function() { | ||||
|             flowFileInput.css({ | ||||
|                 "width": "calc(100% - "+(flowFileInputSearch.width() + flowFileLabelPrefixText.width())+"px)" | ||||
|             }); | ||||
|         } | ||||
|         var flowFileInput = $('<input type="text" style="padding-left:1px; margin-top: -2px; margin-bottom: 0;border: none;">').val(activeProject.files.flow||"flows.json").hide().appendTo(flowFileLabel); | ||||
|         var flowFileInputSearch = $('<button type="button" class="editor-button toggle single" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; width: 36px; height: 34px; position: absolute; top: -1px; right: -1px;"><i class="fa fa-folder-open-o"></i></button>') | ||||
|             .hide() | ||||
|             .appendTo(flowFileLabel) | ||||
|             .click(function(e) { | ||||
| @@ -773,15 +845,24 @@ RED.projects.settings = (function() { | ||||
|                 } else { | ||||
|                     $(this).addClass('selected'); | ||||
|                     flowFileLabel.css('color','inherit'); | ||||
|                     var fileList = showProjectFileListing(flowFileLabel,activeProject,flowFileInput.val(), /.*\.json$/,function(result,isDblClick) { | ||||
|                         if (result) { | ||||
|                             flowFileInput.val(result); | ||||
|                         } | ||||
|                         if (isDblClick) { | ||||
|                             $(flowFileInputSearch).click(); | ||||
|                         } | ||||
|                         checkFiles(); | ||||
|                     }); | ||||
|                     var packageFile = packageFileInput.val(); | ||||
|                     var packagePrefix = packageFile.substring(0,packageFile.length - 12); | ||||
|                     var re = new RegExp("^"+packagePrefix+".*\.json$"); | ||||
|                     var fileList = showProjectFileListing(flowFileLabel, | ||||
|                                                           activeProject, | ||||
|                                                           flowFileInput.val(), | ||||
|                                                           function(entry) { return !/package.json$/.test(entry.path) && re.test(entry.path) && !/_cred\.json$/.test(entry.path) }, | ||||
|                                                           function(result,isDblClick) { | ||||
|                                                               if (result) { | ||||
|                                                                   flowFileInput.val(result.substring(packagePrefix.length)); | ||||
|  | ||||
|                                                               } | ||||
|                                                               if (isDblClick) { | ||||
|                                                                   $(flowFileInputSearch).click(); | ||||
|                                                               } | ||||
|                                                               checkFiles(); | ||||
|                                                           } | ||||
|                                                       ); | ||||
|                     flowFileLabel.css('height','auto'); | ||||
|                     setTimeout(function() { | ||||
|                         fileList.slideDown(200); | ||||
| @@ -789,26 +870,32 @@ RED.projects.settings = (function() { | ||||
|  | ||||
|                 } | ||||
|             }) | ||||
|         RED.popover.tooltip(flowFileInputSearch,RED._("sidebar.project.projectSettings.selectFile")); | ||||
|  | ||||
|         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); | ||||
|         $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.credentials")).appendTo(row); | ||||
|         var credFileLabel = $('<div class="uneditable-input">').text(activeProject.files.credentials).appendTo(row); | ||||
|         var credFileInput = $('<div class="uneditable-input">').text(activeProject.files.credentials).hide().insertAfter(credFileLabel); | ||||
|  | ||||
|         var credFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row); | ||||
|         var credFileLabelPrefixText = $('<span style="display:inline-block;padding: 6px 0 6px 6px">').text(projectRoot).appendTo(credFileLabel); | ||||
|         var credFileLabelText = $('<span style="display:inline-block; padding: 6px 6px 6px 0">').text(activeProject.files.credentials||"flows_cred.json").appendTo(credFileLabel); | ||||
|  | ||||
|         var credFileInput = $('<input type="hidden">').val(activeProject.files.credentials||"flows_cred.json").insertAfter(credFileLabel); | ||||
|  | ||||
|         var checkFiles = function() { | ||||
|             var saveDisabled; | ||||
|             var currentFlowValue = flowFileInput.val(); | ||||
|             var m = /^(.+?)(\.[^.]*)?$/.exec(currentFlowValue); | ||||
|             if (m) { | ||||
|                 credFileInput.text(m[1]+"_cred"+(m[2]||".json")); | ||||
|                 credFileLabelText.text(m[1]+"_cred"+(m[2]||".json")); | ||||
|             } else if (currentFlowValue === "") { | ||||
|                 credFileInput.text(""); | ||||
|                 credFileLabelText.text(""); | ||||
|             } | ||||
|             credFileInput.val(credFileLabelText.text()); | ||||
|             var isFlowInvalid = currentFlowValue==="" || | ||||
|                                 /\.\./.test(currentFlowValue) || | ||||
|                                 /\/$/.test(currentFlowValue); | ||||
|  | ||||
|             saveDisabled = isFlowInvalid || credFileInput.text()===""; | ||||
|             saveDisabled = isFlowInvalid || credFileLabelText.text()===""; | ||||
|  | ||||
|             if (credentialSecretExistingInput.is(":visible")) { | ||||
|                 credentialSecretExistingInput.toggleClass("input-error", credentialSecretExistingInput.val() === ""); | ||||
| @@ -821,19 +908,22 @@ RED.projects.settings = (function() { | ||||
|  | ||||
|  | ||||
|             flowFileInput.toggleClass("input-error", isFlowInvalid); | ||||
|             credFileInput.toggleClass("input-error",credFileInput.text()===""); | ||||
|             // credFileInput.toggleClass("input-error",credFileInput.text()===""); | ||||
|             saveButton.toggleClass('disabled',saveDisabled); | ||||
|             saveButton.prop('disabled',saveDisabled); | ||||
|         } | ||||
|         flowFileInput.on("change keyup paste",checkFiles); | ||||
|  | ||||
|  | ||||
|         if (!activeProject.files.flow) { | ||||
|             $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(flowFileLabelText); | ||||
|         } | ||||
|         if (!activeProject.files.credentials) { | ||||
|             $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(credFileLabel); | ||||
|         } | ||||
|         // if (!activeProject.files.package) { | ||||
|         //     $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(packageFileLabelText); | ||||
|         // } | ||||
|         // if (!activeProject.files.flow) { | ||||
|         //     $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(flowFileLabelText); | ||||
|         // } | ||||
|         // if (!activeProject.files.credentials) { | ||||
|         //     $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(credFileLabel); | ||||
|         // } | ||||
|  | ||||
|  | ||||
|         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); | ||||
| @@ -844,7 +934,7 @@ RED.projects.settings = (function() { | ||||
|  | ||||
|         credentialStateLabel.css('color','#666'); | ||||
|         credentialSecretButtons.css('vertical-align','top'); | ||||
|         var credentialSecretResetButton = $('<button class="editor-button" style="vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-trash-o"></i></button>') | ||||
|         var credentialSecretResetButton = $('<button type="button" class="editor-button" style="vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-trash-o"></i></button>') | ||||
|             .appendTo(credentialSecretButtons) | ||||
|             .click(function(e) { | ||||
|                 e.preventDefault(); | ||||
| @@ -866,7 +956,9 @@ RED.projects.settings = (function() { | ||||
|                 } | ||||
|                 checkFiles(); | ||||
|             }); | ||||
|         var credentialSecretEditButton = $('<button class="editor-button" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-pencil"></i></button>') | ||||
|         RED.popover.tooltip(credentialSecretResetButton,RED._("sidebar.project.projectSettings.resetTheEncryptionKey")); | ||||
|  | ||||
|         var credentialSecretEditButton = $('<button type="button" class="editor-button" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-pencil"></i></button>') | ||||
|             .appendTo(credentialSecretButtons) | ||||
|             .click(function(e) { | ||||
|                 e.preventDefault(); | ||||
| @@ -896,6 +988,7 @@ RED.projects.settings = (function() { | ||||
|                 checkFiles(); | ||||
|             }) | ||||
|  | ||||
|         RED.popover.tooltip(credentialSecretEditButton,RED._("sidebar.project.projectSettings.changeTheEncryptionKey")); | ||||
|  | ||||
|         row = $('<div class="user-settings-row user-settings-row-credentials"></div>').hide().appendTo(filesContainer); | ||||
|  | ||||
| @@ -930,11 +1023,13 @@ RED.projects.settings = (function() { | ||||
|         var hideEditForm = function() { | ||||
|             editFilesButton.show(); | ||||
|             formButtons.hide(); | ||||
|             // packageFileLabelText.show(); | ||||
|             packageFileInputSearch.hide(); | ||||
|             // packageFileInputCreate.hide(); | ||||
|             flowFileLabelText.show(); | ||||
|             flowFileInput.hide(); | ||||
|             flowFileInputSearch.hide(); | ||||
|             credFileLabel.show(); | ||||
|             credFileInput.hide(); | ||||
|  | ||||
|             // credentialStateLabel.parent().show(); | ||||
|             credentialStateLabel.removeClass("uneditable-input"); | ||||
|             credentialStateLabel.css('height',''); | ||||
| @@ -954,13 +1049,26 @@ RED.projects.settings = (function() { | ||||
|         } | ||||
|  | ||||
|         var formButtons = $('<span class="button-row" style="position: relative; float: right; margin-right:0;"></span>').hide().appendTo(filesContainer); | ||||
|         $('<button class="editor-button">' + RED._("common.label.cancel") + '</button>') | ||||
|         $('<button type="button" class="editor-button">' + RED._("common.label.cancel") + '</button>') | ||||
|             .appendTo(formButtons) | ||||
|             .click(function(evt) { | ||||
|                 evt.preventDefault(); | ||||
|                 var projectPackage = "/"+(activeProject.files.package||"package.json"); | ||||
|                 var projectRoot = projectPackage.substring(0,projectPackage.length - 12); | ||||
|                 flowFileLabelPrefixText.text(projectRoot); | ||||
|                 credFileLabelPrefixText.text(projectRoot); | ||||
|                 packageFileLabelText.text(activeProject.files.package||"package.json"); | ||||
|                 if (!activeProject.files.package) { | ||||
|                     packageFileSubLabel.find(".projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.fileNotExist")); | ||||
|                     packageFileSubLabel.show(); | ||||
|                 } else { | ||||
|                     packageFileSubLabel.hide(); | ||||
|                 } | ||||
|                 flowFileInput.val(flowFileLabelText.text()); | ||||
|                 credFileLabelText.text(activeProject.files.credentials||"flows_cred.json"); | ||||
|                 hideEditForm(); | ||||
|             }); | ||||
|         var saveButton = $('<button class="editor-button">' + RED._("common.label.save") + '</button>') | ||||
|         var saveButton = $('<button type="button" class="editor-button">' + RED._("common.label.save") + '</button>') | ||||
|             .appendTo(formButtons) | ||||
|             .click(function(evt) { | ||||
|                 evt.preventDefault(); | ||||
| @@ -972,13 +1080,15 @@ RED.projects.settings = (function() { | ||||
|                         return; | ||||
|                     } | ||||
|                     flowFileLabelText.text(flowFileInput.val()); | ||||
|                     credFileLabel.text(credFileInput.text()); | ||||
|                     credFileLabelText.text(credFileInput.val()); | ||||
|                     packageFileSubLabel.hide(); | ||||
|                     hideEditForm(); | ||||
|                 } | ||||
|                 var payload = { | ||||
|                     files: { | ||||
|                         flow: flowFileInput.val(), | ||||
|                         credentials: credFileInput.text() | ||||
|                         credentials: credFileInput.val(), | ||||
|                         package: packageFileInput.val() | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
| @@ -992,7 +1102,8 @@ RED.projects.settings = (function() { | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // console.log(JSON.stringify(payload,null,4)); | ||||
|                 console.log(payload); | ||||
|                 return; | ||||
|                 RED.deploy.setDeployInflight(true); | ||||
|                 utils.sendRequest({ | ||||
|                     url: "projects/"+activeProject.name, | ||||
|   | ||||
| @@ -2061,7 +2061,6 @@ RED.projects = (function() { | ||||
|             console.log(xhr); | ||||
|             console.log(textStatus); | ||||
|             console.log(err); | ||||
|             console.log(stack); | ||||
|         }).always(function() { | ||||
|             var delta = Date.now() - start; | ||||
|             delta = Math.max(0,500-delta); | ||||
| @@ -2389,6 +2388,9 @@ RED.projects = (function() { | ||||
|                 return; | ||||
|             } | ||||
|             RED.projects.settings.show('settings'); | ||||
|             setTimeout(function() { | ||||
|                 $("#project-settings-tab-settings-file-edit").click(); | ||||
|             },200) | ||||
|         }, | ||||
|         showProjectDependencies: function() { | ||||
|             RED.projects.settings.show('deps'); | ||||
|   | ||||
| @@ -967,6 +967,7 @@ RED.utils = (function() { | ||||
|         addSpinnerOverlay: addSpinnerOverlay, | ||||
|         decodeObject: decodeObject, | ||||
|         parseContextKey: parseContextKey, | ||||
|         createIconElement: createIconElement | ||||
|         createIconElement: createIconElement, | ||||
|         sanitize: sanitize | ||||
|     } | ||||
| })(); | ||||
|   | ||||
| @@ -60,7 +60,7 @@ | ||||
| .project-settings-tab-pane { | ||||
|     & * .projects-edit-form-sublabel { | ||||
|         margin-right: 50px; | ||||
|         margin-top: -10px; | ||||
|         margin-top: -10px !important; | ||||
|         margin-bottom: 5px; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -53,6 +53,7 @@ function getGitUser(user) { | ||||
|     } | ||||
|     return null; | ||||
| } | ||||
|  | ||||
| function Project(path) { | ||||
|     this.path = path; | ||||
|     this.name = fspath.basename(path); | ||||
| @@ -72,7 +73,7 @@ Project.prototype.load = function () { | ||||
|             projectSettings = globalProjectSettings.projects[this.name] || {}; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     this.paths.root = projectSettings.rootPath || ""; | ||||
|     this.credentialSecret = projectSettings.credentialSecret; | ||||
|     this.git = projectSettings.git || { user:{} }; | ||||
|  | ||||
| @@ -83,8 +84,8 @@ Project.prototype.load = function () { | ||||
|     return checkProjectFiles(project).then(function(missingFiles) { | ||||
|         project.missingFiles = missingFiles; | ||||
|         if (missingFiles.indexOf('package.json') === -1) { | ||||
|             project.paths['package.json'] = fspath.join(project.path,"package.json"); | ||||
|             promises.push(fs.readFile(project.paths['package.json'],"utf8").then(function(content) { | ||||
|             project.paths['package.json'] = fspath.join(project.paths.root,"package.json"); | ||||
|             promises.push(fs.readFile(fspath.join(project.path,project.paths['package.json']),"utf8").then(function(content) { | ||||
|                 try { | ||||
|                     project.package = util.parseJSON(content); | ||||
|                     if (project.package.hasOwnProperty('node-red')) { | ||||
| @@ -101,17 +102,19 @@ Project.prototype.load = function () { | ||||
|                     project.package = {}; | ||||
|                 } | ||||
|             })); | ||||
|             if (missingFiles.indexOf('README.md') === -1) { | ||||
|                 project.paths['README.md'] = fspath.join(project.paths.root,"README.md"); | ||||
|                 promises.push(fs.readFile(fspath.join(project.path,project.paths['README.md']),"utf8").then(function(content) { | ||||
|                     project.description = content; | ||||
|                 })); | ||||
|             } else { | ||||
|                 project.description = ""; | ||||
|             } | ||||
|         } else { | ||||
|             project.package = {}; | ||||
|         } | ||||
|         if (missingFiles.indexOf('README.md') === -1) { | ||||
|             project.paths['README.md'] = fspath.join(project.path,"README.md"); | ||||
|             promises.push(fs.readFile(project.paths['README.md'],"utf8").then(function(content) { | ||||
|                 project.description = content; | ||||
|             })); | ||||
|         } else { | ||||
|             project.description = ""; | ||||
|         } | ||||
|  | ||||
|         // if (missingFiles.indexOf('flow.json') !== -1) { | ||||
|         //     console.log("MISSING FLOW FILE"); | ||||
|         // } else { | ||||
| @@ -131,6 +134,10 @@ Project.prototype.load = function () { | ||||
|     }); | ||||
| }; | ||||
|  | ||||
| Project.prototype.getFilePath = function(file) { | ||||
|     return fspath.join(this.path,this.paths.root,this.paths[file]) | ||||
| } | ||||
|  | ||||
| Project.prototype.initialise = function(user,data) { | ||||
|     var project = this; | ||||
|     // if (!this.empty) { | ||||
| @@ -224,6 +231,7 @@ Project.prototype.parseRemoteBranch = function (remoteBranch) { | ||||
| Project.prototype.isEmpty = function () { | ||||
|     return this.empty; | ||||
| }; | ||||
|  | ||||
| Project.prototype.isMerging = function() { | ||||
|     return this.merging; | ||||
| } | ||||
| @@ -243,6 +251,7 @@ Project.prototype.update = function (user, data) { | ||||
|     var savePackage = false; | ||||
|     var flowFilesChanged = false; | ||||
|     var credentialSecretChanged = false; | ||||
|     var reloadProject = false; | ||||
|  | ||||
|     var globalProjectSettings = settings.get("projects"); | ||||
|     if (!globalProjectSettings.projects.hasOwnProperty(this.name)) { | ||||
| @@ -250,7 +259,6 @@ Project.prototype.update = function (user, data) { | ||||
|         saveSettings = true; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     if (data.credentialSecret && data.credentialSecret !== this.credentialSecret) { | ||||
|         var existingSecret = data.currentCredentialSecret; | ||||
|         var isReset = data.resetCredentialSecret; | ||||
| @@ -278,6 +286,55 @@ Project.prototype.update = function (user, data) { | ||||
|         credentialSecretChanged = true; | ||||
|     } | ||||
|  | ||||
|     if (this.missingFiles.indexOf('package.json') !== -1) { | ||||
|         if (!data.files || !data.files.package) { | ||||
|             // Cannot update a project that doesn't have a known package.json | ||||
|             return Promise.reject("Cannot update project with missing package.json"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (data.hasOwnProperty('files')) { | ||||
|         this.package['node-red'] = this.package['node-red'] || { settings: {}}; | ||||
|         if (data.files.hasOwnProperty('package') && data.files.package !== fspath.join(this.paths.root,"package.json")) { | ||||
|             // We have a package file. It could be one that doesn't exist yet, or | ||||
|             // does exist and we need to load it. | ||||
|             if (!/package\.json$/.test(data.files.package)) { | ||||
|                 return Promise.reject("Invalid package file: "+data.files.package) | ||||
|             } | ||||
|             var root = data.files.package.substring(0,data.files.package.length-12); | ||||
|             this.paths.root = root; | ||||
|             this.paths['package.json'] = 'package.json'; | ||||
|             globalProjectSettings.projects[this.name].rootPath = root; | ||||
|             saveSettings = true; | ||||
|             // 1. check if it exists | ||||
|             if (fs.existsSync(fspath.join(this.path,this.paths.root,this.paths['package.json']))) { | ||||
|                 // Load the existing one.... | ||||
|             } else { | ||||
|                 var newPackage = defaultFileSet["package.json"](this); | ||||
|                 fs.writeFileSync(fspath.join(this.path,this.paths.root,this.paths['package.json']),newPackage); | ||||
|                 this.package = JSON.parse(newPackage); | ||||
|             } | ||||
|             reloadProject = true; | ||||
|             flowFilesChanged = true; | ||||
|         } | ||||
|  | ||||
|         if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow) { | ||||
|             this.paths.flowFile = data.files.flow; | ||||
|             this.package['node-red'].settings.flowFile = data.files.flow; | ||||
|             savePackage = true; | ||||
|             flowFilesChanged = true; | ||||
|         } | ||||
|         if (data.files.hasOwnProperty('credentials') && this.package['node-red'].settings.credentialsFile !== data.files.credentials) { | ||||
|             this.paths.credentialsFile = data.files.credentials; | ||||
|             this.package['node-red'].settings.credentialsFile = data.files.credentials; | ||||
|             // Don't know if the credSecret is invalid or not so clear the flag | ||||
|             delete this.credentialSecretInvalid; | ||||
|  | ||||
|             savePackage = true; | ||||
|             flowFilesChanged = true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (data.hasOwnProperty('description')) { | ||||
|         saveREADME = true; | ||||
|         this.description = data.description; | ||||
| @@ -333,47 +390,32 @@ Project.prototype.update = function (user, data) { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (data.hasOwnProperty('files')) { | ||||
|         this.package['node-red'] = this.package['node-red'] || { settings: {}}; | ||||
|         if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow) { | ||||
|             this.paths.flowFile = data.files.flow; | ||||
|             this.package['node-red'].settings.flowFile = data.files.flow; | ||||
|             savePackage = true; | ||||
|             flowFilesChanged = true; | ||||
|         } | ||||
|         if (data.files.hasOwnProperty('credentials') && this.package['node-red'].settings.credentialsFile !== data.files.credentials) { | ||||
|             this.paths.credentialsFile = data.files.credentials; | ||||
|             this.package['node-red'].settings.credentialsFile = data.files.credentials; | ||||
|             // Don't know if the credSecret is invalid or not so clear the flag | ||||
|             delete this.credentialSecretInvalid; | ||||
|  | ||||
|             savePackage = true; | ||||
|             flowFilesChanged = true; | ||||
|         } | ||||
|     } | ||||
|     if (saveSettings) { | ||||
|         promises.push(settings.set("projects",globalProjectSettings)); | ||||
|     } | ||||
|     if (saveREADME) { | ||||
|         promises.push(util.writeFile(this.paths['README.md'], this.description)); | ||||
|         promises.push(util.writeFile(fspath.join(this.path,this.paths['README.md']), this.description)); | ||||
|     } | ||||
|     if (savePackage) { | ||||
|         promises.push(fs.readFile(project.paths['package.json'],"utf8").then(content => { | ||||
|         promises.push(fs.readFile(fspath.join(project.path,project.paths['package.json']),"utf8").then(content => { | ||||
|             var currentPackage = {}; | ||||
|             try { | ||||
|                 currentPackage = util.parseJSON(content); | ||||
|             } catch(err) { | ||||
|             } | ||||
|             this.package = Object.assign(currentPackage,this.package); | ||||
|             return util.writeFile(this.paths['package.json'], JSON.stringify(this.package,"",4)); | ||||
|             return util.writeFile(fspath.join(project.path,this.paths['package.json']), JSON.stringify(this.package,"",4)); | ||||
|         })); | ||||
|     } | ||||
|     return when.settle(promises).then(function(res) { | ||||
|         return { | ||||
|     return when.settle(promises).then(res => { | ||||
|         if (reloadProject) { | ||||
|             return this.load() | ||||
|         } | ||||
|     }).then(() => { return { | ||||
|             flowFilesChanged: flowFilesChanged, | ||||
|             credentialSecretChanged: credentialSecretChanged | ||||
|         } | ||||
|     }) | ||||
|         }}) | ||||
| }; | ||||
|  | ||||
| Project.prototype.getFiles = function () { | ||||
| @@ -384,12 +426,15 @@ Project.prototype.getFiles = function () { | ||||
|         throw err; | ||||
|     }); | ||||
| }; | ||||
|  | ||||
| Project.prototype.stageFile = function(file) { | ||||
|     return gitTools.stageFile(this.path,file); | ||||
| }; | ||||
|  | ||||
| Project.prototype.unstageFile = function(file) { | ||||
|     return gitTools.unstageFile(this.path,file); | ||||
| } | ||||
|  | ||||
| Project.prototype.commit = function(user, options) { | ||||
|     var self = this; | ||||
|     return gitTools.commit(this.path,options.message,getGitUser(user)).then(function() { | ||||
| @@ -399,9 +444,11 @@ Project.prototype.commit = function(user, options) { | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
| Project.prototype.getFileDiff = function(file,type) { | ||||
|     return gitTools.getFileDiff(this.path,file,type); | ||||
| } | ||||
|  | ||||
| Project.prototype.getCommits = function(options) { | ||||
|     return gitTools.getCommits(this.path,options).catch(function(err) { | ||||
|         if (/bad default revision/i.test(err.message) || /ambiguous argument/i.test(err.message) || /does not have any commits yet/i.test(err.message)) { | ||||
| @@ -414,9 +461,11 @@ Project.prototype.getCommits = function(options) { | ||||
|         throw err; | ||||
|     }) | ||||
| } | ||||
|  | ||||
| Project.prototype.getCommit = function(sha) { | ||||
|     return gitTools.getCommit(this.path,sha); | ||||
| } | ||||
|  | ||||
| Project.prototype.getFile = function (filePath,treeish) { | ||||
|     if (treeish !== "_") { | ||||
|         return gitTools.getFile(this.path, filePath, treeish); | ||||
| @@ -424,6 +473,7 @@ Project.prototype.getFile = function (filePath,treeish) { | ||||
|         return fs.readFile(fspath.join(this.path,filePath),"utf8"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| Project.prototype.revertFile = function (filePath) { | ||||
|     var self = this; | ||||
|     return gitTools.revertFile(this.path, filePath).then(function() { | ||||
| @@ -431,8 +481,6 @@ Project.prototype.revertFile = function (filePath) { | ||||
|     }); | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| Project.prototype.status = function(user, includeRemote) { | ||||
|     var self = this; | ||||
|  | ||||
| @@ -615,6 +663,7 @@ Project.prototype.resolveMerge = function (file,resolutions) { | ||||
|         }) | ||||
|     }); | ||||
| }; | ||||
|  | ||||
| Project.prototype.abortMerge = function () { | ||||
|     var self = this; | ||||
|     return gitTools.abortMerge(this.path).then(function() { | ||||
| @@ -675,12 +724,11 @@ Project.prototype.setBranch = function (branchName, isCreate) { | ||||
|         return self.load(); | ||||
|     }) | ||||
| }; | ||||
|  | ||||
| Project.prototype.getBranchStatus = function (branchName) { | ||||
|     return gitTools.getBranchStatus(this.path,branchName); | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| Project.prototype.getRemotes = function (user) { | ||||
|     return gitTools.getRemotes(this.path).then(function(remotes) { | ||||
|         var result = []; | ||||
| @@ -693,12 +741,14 @@ Project.prototype.getRemotes = function (user) { | ||||
|         return {remotes:result}; | ||||
|     }) | ||||
| }; | ||||
|  | ||||
| Project.prototype.addRemote = function(user,remote,options) { | ||||
|     var project = this; | ||||
|     return gitTools.addRemote(this.path,remote,options).then(function() { | ||||
|         return project.loadRemotes() | ||||
|     }); | ||||
| } | ||||
|  | ||||
| Project.prototype.updateRemote = function(user,remote,options) { | ||||
|     var username; | ||||
|     if (!user) { | ||||
| @@ -716,6 +766,7 @@ Project.prototype.updateRemote = function(user,remote,options) { | ||||
|     } | ||||
|     return Promise.resolve(); | ||||
| } | ||||
|  | ||||
| Project.prototype.removeRemote = function(user, remote) { | ||||
|     // TODO: if this was the last remote using this url, then remove the authCache | ||||
|     // details. | ||||
| @@ -725,11 +776,10 @@ Project.prototype.removeRemote = function(user, remote) { | ||||
|     }); | ||||
| } | ||||
|  | ||||
|  | ||||
| Project.prototype.getFlowFile = function() { | ||||
|     // console.log("Project.getFlowFile = ",this.paths.flowFile); | ||||
|     if (this.paths.flowFile) { | ||||
|         return fspath.join(this.path,this.paths.flowFile); | ||||
|         return fspath.join(this.path,this.paths.root,this.paths.flowFile); | ||||
|     } else { | ||||
|         return null; | ||||
|     } | ||||
| @@ -742,14 +792,16 @@ Project.prototype.getFlowFileBackup = function() { | ||||
|     } | ||||
|     return null; | ||||
| } | ||||
|  | ||||
| Project.prototype.getCredentialsFile = function() { | ||||
|     // console.log("Project.getCredentialsFile = ",this.paths.credentialsFile); | ||||
|     if (this.paths.credentialsFile) { | ||||
|         return fspath.join(this.path,this.paths.credentialsFile); | ||||
|         return fspath.join(this.path,this.paths.root,this.paths.credentialsFile); | ||||
|     } else { | ||||
|         return this.paths.credentialsFile; | ||||
|     } | ||||
| } | ||||
|  | ||||
| Project.prototype.getCredentialsFileBackup = function() { | ||||
|     return getBackupFilename(this.getCredentialsFile()); | ||||
| } | ||||
| @@ -763,10 +815,11 @@ Project.prototype.export = function () { | ||||
|         dependencies: this.package.dependencies||{}, | ||||
|         empty: this.empty, | ||||
|         settings: { | ||||
|             credentialsEncrypted: (typeof this.credentialSecret === "string"), | ||||
|             credentialsEncrypted: (typeof this.credentialSecret === "string") && this.credentialSecret.length > 0, | ||||
|             credentialSecretInvalid: this.credentialSecretInvalid | ||||
|         }, | ||||
|         files: { | ||||
|             package: this.paths['package.json'], | ||||
|             flow: this.paths.flowFile, | ||||
|             credentials: this.paths.credentialsFile | ||||
|         }, | ||||
| @@ -777,7 +830,6 @@ Project.prototype.export = function () { | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| function getCredentialsFilename(filename) { | ||||
|     filename = filename || "undefined"; | ||||
|     // TODO: DRY - ./index.js | ||||
| @@ -793,7 +845,6 @@ function getBackupFilename(filename) { | ||||
|     var ffDir = fspath.dirname(filename); | ||||
|     return fspath.join(ffDir,"."+ffName+".backup"); | ||||
| } | ||||
|  | ||||
| function checkProjectExists(projectPath) { | ||||
|     return fs.pathExists(projectPath).then(function(exists) { | ||||
|         if (!exists) { | ||||
| @@ -805,7 +856,6 @@ function checkProjectExists(projectPath) { | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function createDefaultProject(user, project) { | ||||
|     var projectPath = fspath.join(projectsDir,project.name); | ||||
|     // Create a basic skeleton of a project | ||||
| @@ -869,15 +919,15 @@ function createDefaultProject(user, project) { | ||||
|         }) | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function checkProjectFiles(project) { | ||||
|     var projectPath = project.path; | ||||
|     var projectRoot = project.paths.root; | ||||
|     var promises = []; | ||||
|     var paths = []; | ||||
|     for (var file in defaultFileSet) { | ||||
|         if (defaultFileSet.hasOwnProperty(file)) { | ||||
|             paths.push(file); | ||||
|             promises.push(fs.stat(fspath.join(projectPath,file))); | ||||
|             promises.push(fs.stat(fspath.join(projectPath,projectRoot,file))); | ||||
|         } | ||||
|     } | ||||
|     return when.settle(promises).then(function(results) { | ||||
| @@ -900,7 +950,6 @@ function checkProjectFiles(project) { | ||||
|         // } | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function createProject(user, metadata) { | ||||
|     var username; | ||||
|     if (!user) { | ||||
| @@ -933,6 +982,9 @@ function createProject(user, metadata) { | ||||
|                 } | ||||
|                 projects.projects[project] = {}; | ||||
|                 if (metadata.hasOwnProperty('credentialSecret')) { | ||||
|                     if (metadata.credentialSecret === "") { | ||||
|                         metadata.credentialSecret = false; | ||||
|                     } | ||||
|                     projects.projects[project].credentialSecret = metadata.credentialSecret; | ||||
|                 } | ||||
|                 return settings.set('projects',projects); | ||||
| @@ -970,7 +1022,6 @@ function createProject(user, metadata) { | ||||
|         }) | ||||
|     }) | ||||
| } | ||||
|  | ||||
| function deleteProject(user, projectPath) { | ||||
|     return checkProjectExists(projectPath).then(function() { | ||||
|         return fs.remove(projectPath).then(function() { | ||||
| @@ -981,14 +1032,12 @@ function deleteProject(user, projectPath) { | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function loadProject(projectPath) { | ||||
|     return checkProjectExists(projectPath).then(function() { | ||||
|         var project = new Project(projectPath); | ||||
|         return project.load(); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function init(_settings, _runtime) { | ||||
|     settings = _settings; | ||||
|     runtime = _runtime; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user