@nocobase/plugin-backups 3.0.0-alpha.4 → 3.0.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client-v2/268.96daf48ff72f362a.js +10 -0
- package/dist/client-v2/index.js +1 -1
- package/dist/externalVersion.js +11 -11
- package/dist/locale/en-US.json +1 -0
- package/dist/locale/zh-CN.json +1 -0
- package/dist/node_modules/archiver/package.json +1 -1
- package/dist/node_modules/cron-parser/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/semver/package.json +1 -1
- package/dist/node_modules/yauzl/package.json +1 -1
- package/dist/server/collections/backup-settings.js +5 -0
- package/dist/server/managers/backup.d.ts +2 -0
- package/dist/server/managers/backup.js +19 -3
- package/dist/server/managers/restore.d.ts +1 -0
- package/dist/server/managers/restore.js +19 -0
- package/dist/server/plugin.js +2 -0
- package/package.json +2 -2
- package/dist/client-v2/268.105b4075a27d89f7.js +0 -10
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
"use strict";(self.webpackChunk_nocobase_plugin_backups_client_v2=self.webpackChunk_nocobase_plugin_backups_client_v2||[]).push([["268"],{887:function(e,t,n){n.r(t),n.d(t,{default:function(){return g}});var r=n(694),a=n(625),o=n(59),c=n(155),l=n.n(c),u=n(837);n(693);var i=n(488);function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function m(e,t,n,r,a,o,c){try{var l=e[o](c),u=l.value}catch(e){n(e);return}l.done?t(u):Promise.resolve(u).then(r,a)}function p(e){return function(){var t=this,n=arguments;return new Promise(function(r,a){var o=e.apply(t,n);function c(e){m(o,r,a,c,l,"next",e)}function l(e){m(o,r,a,c,l,"throw",e)}c(void 0)})}}function f(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){var r;r=n[t],t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r})}return e}function b(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n,r,a=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var o=[],c=!0,l=!1;try{for(a=a.call(e);!(c=(n=a.next()).done)&&(o.push(n.value),!t||o.length!==t);c=!0);}catch(e){l=!0,r=e}finally{try{c||null==a.return||a.return()}finally{if(l)throw r}}return o}}(e,t)||function(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return s(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e,t){var n,r,a,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},c=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),l=Object.defineProperty;return l(c,"next",{value:u(0)}),l(c,"throw",{value:u(1)}),l(c,"return",{value:u(2)}),"function"==typeof Symbol&&l(c,Symbol.iterator,{value:function(){return this}}),c;function u(l){return function(u){var i=[l,u];if(n)throw TypeError("Generator is already executing.");for(;c&&(c=0,i[0]&&(o=0)),o;)try{if(n=1,r&&(a=2&i[0]?r.return:i[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,i[1])).done)return a;switch(r=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,r=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!(a=(a=o.trys).length>0&&a[a.length-1])&&(6===i[0]||2===i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]<a[3])){o.label=i[1];break}if(6===i[0]&&o.label<a[1]){o.label=a[1],a=i;break}if(a&&o.label<a[2]){o.label=a[2],o.ops.push(i);break}a[2]&&o.ops.pop(),o.trys.pop();continue}i=t.call(e,o)}catch(e){i=[6,e],r=0}finally{n=a=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}}}var y={scheduled:!1,cron:"0 0 * * *",keep:100,enableFilesBackup:!1,enablePortalsBackup:!0},h=function(e){var t,n,r,a=e.onChange,o=e.value,c=function(e,t){if(null==e)return{};var n,r,a,o={};if("u">typeof Reflect&&Reflect.ownKeys){for(a=0,n=Reflect.ownKeys(Object(e));a<n.length;a++)r=n[a],!(t.indexOf(r)>=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r]);return o}if(o=function(e,t){if(null==e)return{};var n,r,a={},o=Object.getOwnPropertyNames(e);for(r=0;r<o.length;r++)n=o[r],!(t.indexOf(n)>=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n]);return a}(e,t),Object.getOwnPropertySymbols)for(a=0,n=Object.getOwnPropertySymbols(e);a<n.length;a++)r=n[a],!(t.indexOf(r)>=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r]);return o}(e,["onChange","value"]),i=window.cronLocale;return l().createElement("fieldset",{className:"nb-backup-settings-cron"},l().createElement(u.l4,(t=f({},c),n=n={clearButton:!1,locale:i,value:null!=(r=null!=o?o:y.cron)?r:"",setValue:function(e){null==a||a(e)}},Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):(function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t.push.apply(t,n)}return t})(Object(n)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}),t)))},g=function(){var e=(0,r.useFlowContext)(),t=(0,i.k)(),n=o.App.useApp(),u=n.message,s=n.notification,m=b(o.Form.useForm(),1)[0],g=b((0,c.useState)(!1),2),v=g[0],w=g[1],k=o.Form.useWatch("scheduled",m),O=(0,a.useRequest)(function(){return p(function(){var t;return d(this,function(n){switch(n.label){case 0:return[4,e.api.request({url:"backupSettings:get/1"})];case 1:return[2,null==(t=n.sent().data)?void 0:t.data]}})})()},{onSuccess:function(e){m.setFieldsValue(f({},y,e))}}),j=(0,a.useRequest)(function(){return p(function(){var t,n;return d(this,function(r){switch(r.label){case 0:return[4,e.api.request({url:"storages:list"})];case 1:return[2,(null!=(t=null==(n=r.sent().data)?void 0:n.data)?t:[]).filter(function(e){return"local"!==e.type})]}})})()}),E=(0,c.useMemo)(function(){var e;return(null!=(e=j.data)?e:[]).map(function(e){return{label:e.title,value:e.id}})},[j.data]);return l().createElement(o.Card,{bordered:!1},l().createElement("style",null,"\n .nb-backup-settings-cron {\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n }\n\n .nb-backup-settings-cron .react-js-cron {\n padding: 0.5em 0.5em 0 0.5em;\n border: 1px dashed #ccc;\n }\n\n .nb-backup-settings-cron .react-js-cron .react-js-cron-field {\n flex-shrink: 0;\n margin-bottom: 0.5em;\n }\n\n .nb-backup-settings-cron .react-js-cron .react-js-cron-field > span {\n flex-shrink: 0;\n margin: 0 0.5em 0 0;\n }\n\n .nb-backup-settings-cron .react-js-cron .react-js-cron-field > .react-js-cron-select {\n margin: 0 0.5em 0 0;\n }\n\n .nb-backup-settings-cron\n .react-js-cron\n .react-js-cron-field\n > .react-js-cron-select\n .ant-select-selection-overflow {\n align-items: center;\n flex: initial;\n }\n"),l().createElement(o.Form,{form:m,layout:"vertical",initialValues:y,disabled:O.loading,onFinish:function(n){return p(function(){var r,a,o;return d(this,function(c){switch(c.label){case 0:r=f({},O.data,n),w(!0),c.label=1;case 1:return c.trys.push([1,3,4,5]),[4,e.api.request({url:"backupSettings:update/1",method:"post",data:r,skipNotify:!0})];case 2:return c.sent(),O.mutate(r),u.success(t("Saved successfully")),[3,5];case 3:return a=c.sent(),o=e.api.toErrMessages(a),s.error({message:o.length?o.map(function(e,n){var r="string"==typeof e?e:e.message;return l().createElement("div",{key:"".concat(n,"_").concat(r)},r||t("Save failed"))}):t("Save failed"),role:"alert"}),[3,5];case 4:return w(!1),[7];case 5:return[2]}})})()}},l().createElement(o.Form.Item,{label:t("Automatic backup")},l().createElement(o.Space,{direction:"vertical",style:{width:"100%"}},l().createElement(o.Form.Item,{name:"scheduled",valuePropName:"checked",noStyle:!0},l().createElement(o.Checkbox,null,t("Run automatic backup on the cron schedule"))),l().createElement(o.Form.Item,{name:"cron",rules:[{required:!!k,message:t("The field value is required")}],style:{marginBottom:0}},l().createElement(h,{disabled:!k})))),l().createElement(o.Form.Item,{name:"keep",label:t("Maximum number of backups"),extra:t("The maximum number of backups to keep, older backups are automatically deleted."),required:!0,rules:[{required:!0,message:t("The field value is required")},{type:"integer",min:1,max:1e3,message:t("Maximum number of backups must be an integer between {{min}} and {{max}}",{min:1,max:1e3})}]},l().createElement(o.InputNumber,{min:1,max:1e3,precision:0,style:{width:"100%"}})),l().createElement(o.Form.Item,{name:"storageId",label:t("Sync backups to cloud storage")},l().createElement(o.Select,{loading:j.loading,options:E,style:{width:"100%"}})),l().createElement(o.Form.Item,{name:"enableFilesBackup",label:t("Backup local storage files"),valuePropName:"checked"},l().createElement(o.Switch,null)),l().createElement(o.Form.Item,{name:"enablePortalsBackup",label:t("Backup AI mode portals"),valuePropName:"checked"},l().createElement(o.Switch,null)),l().createElement(o.Form.Item,{name:"encryptionPassword",label:t("Restore password"),extra:t("If a restore password is set, it must be entered when restoring the backup.")},l().createElement(o.Input.Password,{autoComplete:"new-password",style:{width:"100%"}})),l().createElement(o.Form.Item,null,l().createElement(o.Button,{type:"primary",htmlType:"submit",loading:v},t("Submit")))))}},488:function(e,t,n){n.d(t,{k:function(){return o}});var r=n(694),a=n(401);function o(){var e=(0,r.useFlowEngine)();return function(t,n){return e.context.t(t,function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){var r;r=n[t],t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r})}return e}({ns:[a.C,"client"]},n))}}}}]);
|
package/dist/client-v2/index.js
CHANGED
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("ahooks"),require("@emotion/css"),require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@ant-design/icons"),require("@nocobase/flow-engine")):"function"==typeof define&&define.amd?define("@nocobase/plugin-backups/client-v2",["ahooks","@emotion/css","@nocobase/client-v2","dayjs","react","antd","@ant-design/icons","@nocobase/flow-engine"],t):"object"==typeof exports?exports["@nocobase/plugin-backups/client-v2"]=t(require("ahooks"),require("@emotion/css"),require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@ant-design/icons"),require("@nocobase/flow-engine")):e["@nocobase/plugin-backups/client-v2"]=t(e.ahooks,e["@emotion/css"],e["@nocobase/client-v2"],e.dayjs,e.react,e.antd,e["@ant-design/icons"],e["@nocobase/flow-engine"])}(self,function(e,t,n,r,o,i,c,a){return function(){"use strict";var u,s,l,p={401:function(e,t,n){n.d(t,{C:function(){return r},l:function(){return o}});var r="backups",o="backupRestoreRuntime"},375:function(e){e.exports=c},477:function(e){e.exports=t},485:function(e){e.exports=n},694:function(e){e.exports=a},625:function(t){t.exports=e},59:function(e){e.exports=i},185:function(e){e.exports=r},155:function(e){e.exports=o}},f={};function
|
|
10
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("ahooks"),require("@emotion/css"),require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@ant-design/icons"),require("@nocobase/flow-engine")):"function"==typeof define&&define.amd?define("@nocobase/plugin-backups/client-v2",["ahooks","@emotion/css","@nocobase/client-v2","dayjs","react","antd","@ant-design/icons","@nocobase/flow-engine"],t):"object"==typeof exports?exports["@nocobase/plugin-backups/client-v2"]=t(require("ahooks"),require("@emotion/css"),require("@nocobase/client-v2"),require("dayjs"),require("react"),require("antd"),require("@ant-design/icons"),require("@nocobase/flow-engine")):e["@nocobase/plugin-backups/client-v2"]=t(e.ahooks,e["@emotion/css"],e["@nocobase/client-v2"],e.dayjs,e.react,e.antd,e["@ant-design/icons"],e["@nocobase/flow-engine"])}(self,function(e,t,n,r,o,i,c,a){return function(){"use strict";var u,s,l,p={401:function(e,t,n){n.d(t,{C:function(){return r},l:function(){return o}});var r="backups",o="backupRestoreRuntime"},375:function(e){e.exports=c},477:function(e){e.exports=t},485:function(e){e.exports=n},694:function(e){e.exports=a},625:function(t){t.exports=e},59:function(e){e.exports=i},185:function(e){e.exports=r},155:function(e){e.exports=o}},f={};function b(e){var t=f[e];if(void 0!==t)return t.exports;var n=f[e]={id:e,exports:{}};return p[e].call(n.exports,n,n.exports,b),n.exports}b.m=p,b.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return b.d(t,{a:t}),t},b.d=function(e,t){for(var n in t)b.o(t,n)&&!b.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},b.f={},b.e=function(e){return Promise.all(Object.keys(b.f).reduce(function(t,n){return b.f[n](e,t),t},[]))},b.u=function(e){return""+e+"."+({268:"96daf48ff72f362a",346:"45d02ff0f75c76e4",567:"72267b98c0ce9379"})[e]+".js"},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},d={},b.l=function(e,t,n,r){if(d[e])return void d[e].push(t);if(void 0!==n)for(var o,i,c=document.getElementsByTagName("script"),a=0;a<c.length;a++){var u=c[a];if(u.getAttribute("src")==e||u.getAttribute("data-rspack")=="@nocobase/plugin-backups/client-v2:"+n){o=u;break}}o||(i=!0,(o=document.createElement("script")).timeout=120,b.nc&&o.setAttribute("nonce",b.nc),o.setAttribute("data-rspack","@nocobase/plugin-backups/client-v2:"+n),o.src=e),d[e]=[t];var s=function(t,n){o.onerror=o.onload=null,clearTimeout(l);var r=d[e];if(delete d[e],o.parentNode&&o.parentNode.removeChild(o),r&&r.forEach(function(e){return e(n)}),t)return t(n)},l=setTimeout(s.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=s.bind(null,o.onerror),o.onload=s.bind(null,o.onload),i&&document.head.appendChild(o)},b.r=function(e){"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.nc=void 0,b.g.importScripts&&(g=b.g.location+"");var d,g,h=b.g.document;if(!g&&h&&(h.currentScript&&"SCRIPT"===h.currentScript.tagName.toUpperCase()&&(g=h.currentScript.src),!g)){var v=h.getElementsByTagName("script");if(v.length)for(var y=v.length-1;y>-1&&(!g||!/^http(s?):/.test(g));)g=v[y--].src}if(!g)throw Error("Automatic publicPath is not supported in this browser");b.p=g.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),u={889:0},b.f.j=function(e,t){var n=b.o(u,e)?u[e]:void 0;if(0!==n)if(n)t.push(n[2]);else{var r=new Promise(function(t,r){n=u[e]=[t,r]});t.push(n[2]=r);var o=b.p+b.u(e),i=Error();b.l(o,function(t){if(b.o(u,e)&&(0!==(n=u[e])&&(u[e]=void 0),n)){var r=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;i.message="Loading chunk "+e+" failed.\n("+r+": "+o+")",i.name="ChunkLoadError",i.type=r,i.request=o,n[1](i)}},"chunk-"+e,e)}},s=function(e,t){var n,r,o=t[0],i=t[1],c=t[2],a=0;if(o.some(function(e){return 0!==u[e]})){for(n in i)b.o(i,n)&&(b.m[n]=i[n]);c&&c(b)}for(e&&e(t);a<o.length;a++)r=o[a],b.o(u,r)&&u[r]&&u[r][0](),u[r]=0},(l=self.webpackChunk_nocobase_plugin_backups_client_v2=self.webpackChunk_nocobase_plugin_backups_client_v2||[]).forEach(s.bind(null,0)),l.push=s.bind(null,l.push.bind(l));var m={};return!function(){var e="",t="u">typeof document?document.currentScript:null;if(t&&t.src){var n=t.src.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"");n.indexOf("/static/plugins/@nocobase/plugin-backups/dist/client-v2/")>=0&&(e=n.replace(/\/[^\/]+$/,"/"))}if(!e){var r=window.__webpack_public_path__||"";r&&("/"!==r.charAt(r.length-1)&&(r+="/"),e=r+"static/plugins/@nocobase/plugin-backups/dist/client-v2/")}if(!e){var o=window.__nocobase_modern_client_prefix__||"v",i="/"+(o=String(o).replace(/^\/+|\/+$/g,"")||"v")+"/";if(!(e=window.__nocobase_public_path__||"")&&window.location&&window.location.pathname){var c=window.location.pathname||"/",a=c.indexOf(i);e=a>=0?c.slice(0,a+1):"/"}e&&(e=e.replace(RegExp("/"+o+"/?$"),"/")),e||(e="/"),"/"!==e.charAt(e.length-1)&&(e+="/"),e+="static/plugins/@nocobase/plugin-backups/dist/client-v2/"}b.p=e}(),!function(){b.r(m),b.d(m,{default:function(){return u}});var e=b(485),t=b(401);function n(e,t,n,r,o,i,c){try{var a=e[i](c),u=a.value}catch(e){n(e);return}a.done?t(u):Promise.resolve(u).then(r,o)}function r(e,t,n){return(r=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&i(o,n.prototype),o}).apply(null,arguments)}function o(e){return(o=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function i(e,t){return(i=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function c(e){var t="function"==typeof Map?new Map:void 0;return(c=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return r(e,arguments,o(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),i(n,e)})(e)}function a(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(a=function(){return!!e})()}var u=function(e){var r;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function c(){var e,t;if(!(this instanceof c))throw TypeError("Cannot call a class as a function");return e=c,t=arguments,e=o(e),function(e,t){var n;if(t&&("object"==((n=t)&&"u">typeof Symbol&&n.constructor===Symbol?"symbol":typeof n)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,a()?Reflect.construct(e,t||[],o(this).constructor):e.apply(this,t))}return c.prototype=Object.create(e&&e.prototype,{constructor:{value:c,writable:!0,configurable:!0}}),e&&i(c,e),r=[{key:"load",value:function(){var e;return(e=function(){var e;return function(e,t){var n,r,o,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},c=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),a=Object.defineProperty;return a(c,"next",{value:u(0)}),a(c,"throw",{value:u(1)}),a(c,"return",{value:u(2)}),"function"==typeof Symbol&&a(c,Symbol.iterator,{value:function(){return this}}),c;function u(a){return function(u){var s=[a,u];if(n)throw TypeError("Generator is already executing.");for(;c&&(c=0,s[0]&&(i=0)),i;)try{if(n=1,r&&(o=2&s[0]?r.return:s[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,s[1])).done)return o;switch(r=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,r=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===s[0]||2===s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){i.label=s[1];break}if(6===s[0]&&i.label<o[1]){i.label=o[1],o=s;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(s);break}o[2]&&i.ops.pop(),i.trys.pop();continue}s=t.call(e,i)}catch(e){s=[6,e],r=0}finally{n=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}}}(this,function(n){return e=this.t("Backup manager"),this.flowEngine.context.defineProperty(t.l,{value:this.createBackupRestoreRuntime()}),this.pluginSettingsManager.addMenuItem({key:t.C,title:e,icon:"CloudServerOutlined",showTabs:!0}),this.pluginSettingsManager.addPageTabItem({menuKey:t.C,key:"list",title:this.t("Backup list"),icon:"CloudServerOutlined",aclSnippet:"pm.".concat(t.C),componentLoader:function(){return b.e("567").then(b.bind(b,258))}}),this.pluginSettingsManager.addPageTabItem({menuKey:t.C,key:"settings",title:this.t("Settings"),icon:"SettingOutlined",aclSnippet:"pm.".concat(t.C,".settings"),componentLoader:function(){return Promise.all([b.e("346"),b.e("268")]).then(b.bind(b,887))}}),[2]})},function(){var t=this,r=arguments;return new Promise(function(o,i){var c=e.apply(t,r);function a(e){n(c,o,i,a,u,"next",e)}function u(e){n(c,o,i,a,u,"throw",e)}a(void 0)})}).call(this)}},{key:"createBackupRestoreRuntime",value:function(){var e=this.app;return{showCheckBackupMessage:function(){"function"==typeof e.setMaintaining?e.setMaintaining(!0):e.maintaining=!0,e.error={command:{name:"APP Restoring"},message:"checking backup...",code:"APP_COMMANDING"}},hideCheckBackupMessage:function(){"function"==typeof e.setMaintaining?e.setMaintaining(!1):e.maintaining=!1}}}}],function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(c.prototype,r),c}(c(e.Plugin))}(),m}()});
|
package/dist/externalVersion.js
CHANGED
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
|
11
|
-
"@nocobase/client": "3.0.0-alpha.
|
|
11
|
+
"@nocobase/client": "3.0.0-alpha.5",
|
|
12
12
|
"react": "18.2.0",
|
|
13
|
-
"@nocobase/flow-engine": "3.0.0-alpha.
|
|
14
|
-
"@nocobase/client-v2": "3.0.0-alpha.
|
|
15
|
-
"@nocobase/cache": "3.0.0-alpha.
|
|
16
|
-
"@nocobase/lock-manager": "3.0.0-alpha.
|
|
17
|
-
"@nocobase/server": "3.0.0-alpha.
|
|
13
|
+
"@nocobase/flow-engine": "3.0.0-alpha.5",
|
|
14
|
+
"@nocobase/client-v2": "3.0.0-alpha.5",
|
|
15
|
+
"@nocobase/cache": "3.0.0-alpha.5",
|
|
16
|
+
"@nocobase/lock-manager": "3.0.0-alpha.5",
|
|
17
|
+
"@nocobase/server": "3.0.0-alpha.5",
|
|
18
18
|
"lodash": "4.18.1",
|
|
19
|
-
"@nocobase/database": "3.0.0-alpha.
|
|
19
|
+
"@nocobase/database": "3.0.0-alpha.5",
|
|
20
20
|
"sequelize": "6.35.2",
|
|
21
|
-
"@nocobase/test": "3.0.0-alpha.
|
|
21
|
+
"@nocobase/test": "3.0.0-alpha.5",
|
|
22
22
|
"@formily/antd-v5": "1.2.3",
|
|
23
23
|
"@formily/react": "2.3.7",
|
|
24
24
|
"@formily/reactive": "2.3.7",
|
|
@@ -28,7 +28,7 @@ module.exports = {
|
|
|
28
28
|
"ahooks": "3.7.8",
|
|
29
29
|
"@emotion/css": "11.13.0",
|
|
30
30
|
"dayjs": "1.11.13",
|
|
31
|
-
"@nocobase/plugin-file-manager": "3.0.0-alpha.
|
|
32
|
-
"@nocobase/resourcer": "3.0.0-alpha.
|
|
33
|
-
"@nocobase/utils": "3.0.0-alpha.
|
|
31
|
+
"@nocobase/plugin-file-manager": "3.0.0-alpha.5",
|
|
32
|
+
"@nocobase/resourcer": "3.0.0-alpha.5",
|
|
33
|
+
"@nocobase/utils": "3.0.0-alpha.5"
|
|
34
34
|
};
|
package/dist/locale/en-US.json
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"Backing up": "Backing up",
|
|
7
7
|
"Backup list": "Backup list",
|
|
8
8
|
"Backup local storage files": "Backup local storage files",
|
|
9
|
+
"Backup AI mode portals": "Backup AI mode portals",
|
|
9
10
|
"Backup manager": "Backup manager",
|
|
10
11
|
"Click or drag file to this area to upload": "Click or drag file to this area to upload",
|
|
11
12
|
"Confirm the application database schema": "Confirm the application database schema",
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"Backing up": "备份中",
|
|
7
7
|
"Backup list": "备份列表",
|
|
8
8
|
"Backup local storage files": "备份本地存储文件",
|
|
9
|
+
"Backup AI mode portals": "备份 AI 模式门户",
|
|
9
10
|
"Backup manager": "备份管理器",
|
|
10
11
|
"Click or drag file to this area to upload": "点击或拖拽文件到此区域上传",
|
|
11
12
|
"Confirm the application database schema": "确认应用数据库 Schema",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"archiver","version":"5.3.2","description":"a streaming interface for archive generation","homepage":"https://github.com/archiverjs/node-archiver","author":{"name":"Chris Talkington","url":"http://christalkington.com/"},"repository":{"type":"git","url":"https://github.com/archiverjs/node-archiver.git"},"bugs":{"url":"https://github.com/archiverjs/node-archiver/issues"},"license":"MIT","main":"index.js","files":["index.js","lib"],"engines":{"node":">= 10"},"scripts":{"test":"mocha --reporter dot","bench":"node benchmark/simple/pack-zip.js"},"dependencies":{"archiver-utils":"^2.1.0","async":"^3.2.4","buffer-crc32":"^0.2.1","readable-stream":"^3.6.0","readdir-glob":"^1.1.2","tar-stream":"^2.2.0","zip-stream":"^4.1.0"},"devDependencies":{"archiver-jsdoc-theme":"^1.1.3","chai":"^4.3.7","jsdoc":"^3.6.4","mkdirp":"^2.1.5","mocha":"^9.0.2","rimraf":"^4.3.1","stream-bench":"^0.1.2","tar":"^6.1.13","yauzl":"^2.9.0"},"keywords":["archive","archiver","stream","zip","tar"],"publishConfig":{"registry":"https://registry.npmjs.org/"},"_lastModified":"2026-
|
|
1
|
+
{"name":"archiver","version":"5.3.2","description":"a streaming interface for archive generation","homepage":"https://github.com/archiverjs/node-archiver","author":{"name":"Chris Talkington","url":"http://christalkington.com/"},"repository":{"type":"git","url":"https://github.com/archiverjs/node-archiver.git"},"bugs":{"url":"https://github.com/archiverjs/node-archiver/issues"},"license":"MIT","main":"index.js","files":["index.js","lib"],"engines":{"node":">= 10"},"scripts":{"test":"mocha --reporter dot","bench":"node benchmark/simple/pack-zip.js"},"dependencies":{"archiver-utils":"^2.1.0","async":"^3.2.4","buffer-crc32":"^0.2.1","readable-stream":"^3.6.0","readdir-glob":"^1.1.2","tar-stream":"^2.2.0","zip-stream":"^4.1.0"},"devDependencies":{"archiver-jsdoc-theme":"^1.1.3","chai":"^4.3.7","jsdoc":"^3.6.4","mkdirp":"^2.1.5","mocha":"^9.0.2","rimraf":"^4.3.1","stream-bench":"^0.1.2","tar":"^6.1.13","yauzl":"^2.9.0"},"keywords":["archive","archiver","stream","zip","tar"],"publishConfig":{"registry":"https://registry.npmjs.org/"},"_lastModified":"2026-08-01T20:52:58.745Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"cron-parser","version":"4.4.0","description":"Node.js library for parsing crontab instructions","main":"lib/parser.js","types":"index.d.ts","typesVersions":{"<4.1":{"*":["types/ts3/*"]}},"directories":{"test":"test"},"scripts":{"test:tsd":"tsd","test:unit":"TZ=UTC tap ./test/*.js","test:cover":"TZ=UTC tap --coverage-report=html ./test/*.js","lint":"eslint .","lint:fix":"eslint --fix .","test":"npm run lint && npm run test:unit && npm run test:tsd"},"repository":{"type":"git","url":"https://github.com/harrisiirak/cron-parser.git"},"keywords":["cron","crontab","parser"],"author":"Harri Siirak","contributors":["Nicholas Clawson","Daniel Prentis <daniel@salsitasoft.com>","Renault John Lecoultre","Richard Astbury <richard.astbury@gmail.com>","Meaglin Wasabi <Meaglin.wasabi@gmail.com>","Mike Kusold <hello@mikekusold.com>","Alex Kit <alex.kit@atmajs.com>","Santiago Gimeno <santiago.gimeno@gmail.com>","Daniel <darc.tec@gmail.com>","Christian Steininger <christian.steininger.cs@gmail.com>","Mykola Piskovyi <m.piskovyi@gmail.com>","Brian Vaughn <brian.david.vaughn@gmail.com>","Nicholas Clawson <nickclaw@gmail.com>","Yasuhiroki <yasuhiroki.duck@gmail.com>","Nicholas Clawson <nickclaw@gmail.com>","Brendan Warkentin <faazshift@gmail.com>","Charlie Fish <fishcharlie.code@gmail.com>","Ian Graves <ian+diskimage@iangrav.es>","Andy Thompson <me@andytson.com>","Regev Brody <regevbr@gmail.com>"],"license":"MIT","dependencies":{"luxon":"^1.28.0"},"devDependencies":{"eslint":"^8.2.0","sinon":"^10.0.0","tap":"^16.0.1","tsd":"^0.19.0"},"engines":{"node":">=0.8"},"browser":{"fs":false},"tap":{"check-coverage":false},"tsd":{"directory":"test","compilerOptions":{"lib":["es2017","dom"]}},"_lastModified":"2026-
|
|
1
|
+
{"name":"cron-parser","version":"4.4.0","description":"Node.js library for parsing crontab instructions","main":"lib/parser.js","types":"index.d.ts","typesVersions":{"<4.1":{"*":["types/ts3/*"]}},"directories":{"test":"test"},"scripts":{"test:tsd":"tsd","test:unit":"TZ=UTC tap ./test/*.js","test:cover":"TZ=UTC tap --coverage-report=html ./test/*.js","lint":"eslint .","lint:fix":"eslint --fix .","test":"npm run lint && npm run test:unit && npm run test:tsd"},"repository":{"type":"git","url":"https://github.com/harrisiirak/cron-parser.git"},"keywords":["cron","crontab","parser"],"author":"Harri Siirak","contributors":["Nicholas Clawson","Daniel Prentis <daniel@salsitasoft.com>","Renault John Lecoultre","Richard Astbury <richard.astbury@gmail.com>","Meaglin Wasabi <Meaglin.wasabi@gmail.com>","Mike Kusold <hello@mikekusold.com>","Alex Kit <alex.kit@atmajs.com>","Santiago Gimeno <santiago.gimeno@gmail.com>","Daniel <darc.tec@gmail.com>","Christian Steininger <christian.steininger.cs@gmail.com>","Mykola Piskovyi <m.piskovyi@gmail.com>","Brian Vaughn <brian.david.vaughn@gmail.com>","Nicholas Clawson <nickclaw@gmail.com>","Yasuhiroki <yasuhiroki.duck@gmail.com>","Nicholas Clawson <nickclaw@gmail.com>","Brendan Warkentin <faazshift@gmail.com>","Charlie Fish <fishcharlie.code@gmail.com>","Ian Graves <ian+diskimage@iangrav.es>","Andy Thompson <me@andytson.com>","Regev Brody <regevbr@gmail.com>"],"license":"MIT","dependencies":{"luxon":"^1.28.0"},"devDependencies":{"eslint":"^8.2.0","sinon":"^10.0.0","tap":"^16.0.1","tsd":"^0.19.0"},"engines":{"node":">=0.8"},"browser":{"fs":false},"tap":{"check-coverage":false},"tsd":{"directory":"test","compilerOptions":{"lib":["es2017","dom"]}},"_lastModified":"2026-08-01T20:52:57.607Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"fs-extra","version":"9.1.0","description":"fs-extra contains methods that aren't included in the vanilla Node.js fs package. Such as recursive mkdir, copy, and remove.","engines":{"node":">=10"},"homepage":"https://github.com/jprichardson/node-fs-extra","repository":{"type":"git","url":"https://github.com/jprichardson/node-fs-extra"},"keywords":["fs","file","file system","copy","directory","extra","mkdirp","mkdir","mkdirs","recursive","json","read","write","extra","delete","remove","touch","create","text","output","move","promise"],"author":"JP Richardson <jprichardson@gmail.com>","license":"MIT","dependencies":{"at-least-node":"^1.0.0","graceful-fs":"^4.2.0","jsonfile":"^6.0.1","universalify":"^2.0.0"},"devDependencies":{"coveralls":"^3.0.0","klaw":"^2.1.1","klaw-sync":"^3.0.2","minimist":"^1.1.1","mocha":"^5.0.5","nyc":"^15.0.0","proxyquire":"^2.0.1","read-dir-files":"^0.1.1","standard":"^14.1.0"},"main":"./lib/index.js","files":["lib/","!lib/**/__tests__/"],"scripts":{"full-ci":"npm run lint && npm run coverage","coverage":"nyc -r lcovonly npm run unit","coveralls":"coveralls < coverage/lcov.info","lint":"standard","test-find":"find ./lib/**/__tests__ -name *.test.js | xargs mocha","test":"npm run lint && npm run unit","unit":"node test.js"},"_lastModified":"2026-
|
|
1
|
+
{"name":"fs-extra","version":"9.1.0","description":"fs-extra contains methods that aren't included in the vanilla Node.js fs package. Such as recursive mkdir, copy, and remove.","engines":{"node":">=10"},"homepage":"https://github.com/jprichardson/node-fs-extra","repository":{"type":"git","url":"https://github.com/jprichardson/node-fs-extra"},"keywords":["fs","file","file system","copy","directory","extra","mkdirp","mkdir","mkdirs","recursive","json","read","write","extra","delete","remove","touch","create","text","output","move","promise"],"author":"JP Richardson <jprichardson@gmail.com>","license":"MIT","dependencies":{"at-least-node":"^1.0.0","graceful-fs":"^4.2.0","jsonfile":"^6.0.1","universalify":"^2.0.0"},"devDependencies":{"coveralls":"^3.0.0","klaw":"^2.1.1","klaw-sync":"^3.0.2","minimist":"^1.1.1","mocha":"^5.0.5","nyc":"^15.0.0","proxyquire":"^2.0.1","read-dir-files":"^0.1.1","standard":"^14.1.0"},"main":"./lib/index.js","files":["lib/","!lib/**/__tests__/"],"scripts":{"full-ci":"npm run lint && npm run coverage","coverage":"nyc -r lcovonly npm run unit","coveralls":"coveralls < coverage/lcov.info","lint":"standard","test-find":"find ./lib/**/__tests__ -name *.test.js | xargs mocha","test":"npm run lint && npm run unit","unit":"node test.js"},"_lastModified":"2026-08-01T20:52:59.376Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"semver","version":"7.6.0","description":"The semantic version parser used by npm.","main":"index.js","scripts":{"test":"tap","snap":"tap","lint":"eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"","postlint":"template-oss-check","lintfix":"npm run lint -- --fix","posttest":"npm run lint","template-oss-apply":"template-oss-apply --force"},"devDependencies":{"@npmcli/eslint-config":"^4.0.0","@npmcli/template-oss":"4.21.3","tap":"^16.0.0"},"license":"ISC","repository":{"type":"git","url":"https://github.com/npm/node-semver.git"},"bin":{"semver":"bin/semver.js"},"files":["bin/","lib/","classes/","functions/","internal/","ranges/","index.js","preload.js","range.bnf"],"tap":{"timeout":30,"coverage-map":"map.js","nyc-arg":["--exclude","tap-snapshots/**"]},"engines":{"node":">=10"},"dependencies":{"lru-cache":"^6.0.0"},"author":"GitHub Inc.","templateOSS":{"//@npmcli/template-oss":"This file is partially managed by @npmcli/template-oss. Edits may be overwritten.","version":"4.21.3","engines":">=10","distPaths":["classes/","functions/","internal/","ranges/","index.js","preload.js","range.bnf"],"allowPaths":["/classes/","/functions/","/internal/","/ranges/","/index.js","/preload.js","/range.bnf"],"publish":"true"},"_lastModified":"2026-
|
|
1
|
+
{"name":"semver","version":"7.6.0","description":"The semantic version parser used by npm.","main":"index.js","scripts":{"test":"tap","snap":"tap","lint":"eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"","postlint":"template-oss-check","lintfix":"npm run lint -- --fix","posttest":"npm run lint","template-oss-apply":"template-oss-apply --force"},"devDependencies":{"@npmcli/eslint-config":"^4.0.0","@npmcli/template-oss":"4.21.3","tap":"^16.0.0"},"license":"ISC","repository":{"type":"git","url":"https://github.com/npm/node-semver.git"},"bin":{"semver":"bin/semver.js"},"files":["bin/","lib/","classes/","functions/","internal/","ranges/","index.js","preload.js","range.bnf"],"tap":{"timeout":30,"coverage-map":"map.js","nyc-arg":["--exclude","tap-snapshots/**"]},"engines":{"node":">=10"},"dependencies":{"lru-cache":"^6.0.0"},"author":"GitHub Inc.","templateOSS":{"//@npmcli/template-oss":"This file is partially managed by @npmcli/template-oss. Edits may be overwritten.","version":"4.21.3","engines":">=10","distPaths":["classes/","functions/","internal/","ranges/","index.js","preload.js","range.bnf"],"allowPaths":["/classes/","/functions/","/internal/","/ranges/","/index.js","/preload.js","/range.bnf"],"publish":"true"},"_lastModified":"2026-08-01T20:52:59.716Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"yauzl","version":"3.3.0","description":"yet another unzip library for node","engines":{"node":">=12"},"main":"index.js","scripts":{"test":"node test/test.js"},"repository":{"type":"git","url":"git+https://github.com/thejoshwolfe/yauzl.git"},"keywords":["unzip","zip","stream","archive","file"],"author":"Josh Wolfe <thejoshwolfe@gmail.com>","license":"MIT","bugs":{"url":"https://github.com/thejoshwolfe/yauzl/issues"},"homepage":"https://github.com/thejoshwolfe/yauzl","dependencies":{"buffer-crc32":"~0.2.3","pend":"~1.2.0"},"devDependencies":{"bl":"^6.0.11"},"files":["fd-slicer.js","index.js"],"_lastModified":"2026-
|
|
1
|
+
{"name":"yauzl","version":"3.3.0","description":"yet another unzip library for node","engines":{"node":">=12"},"main":"index.js","scripts":{"test":"node test/test.js"},"repository":{"type":"git","url":"git+https://github.com/thejoshwolfe/yauzl.git"},"keywords":["unzip","zip","stream","archive","file"],"author":"Josh Wolfe <thejoshwolfe@gmail.com>","license":"MIT","bugs":{"url":"https://github.com/thejoshwolfe/yauzl/issues"},"homepage":"https://github.com/thejoshwolfe/yauzl","dependencies":{"buffer-crc32":"~0.2.3","pend":"~1.2.0"},"devDependencies":{"bl":"^6.0.11"},"files":["fd-slicer.js","index.js"],"_lastModified":"2026-08-01T20:52:59.173Z"}
|
|
@@ -63,6 +63,11 @@ var backup_settings_default = (0, import_database.defineCollection)({
|
|
|
63
63
|
type: "boolean",
|
|
64
64
|
name: "enableFilesBackup"
|
|
65
65
|
},
|
|
66
|
+
{
|
|
67
|
+
type: "boolean",
|
|
68
|
+
name: "enablePortalsBackup",
|
|
69
|
+
defaultValue: true
|
|
70
|
+
},
|
|
66
71
|
{
|
|
67
72
|
type: "belongsTo",
|
|
68
73
|
name: "storage",
|
|
@@ -14,6 +14,7 @@ export interface BackupSettings {
|
|
|
14
14
|
storageId?: string | number | null;
|
|
15
15
|
encryptionPassword: string;
|
|
16
16
|
enableFilesBackup: boolean;
|
|
17
|
+
enablePortalsBackup?: boolean;
|
|
17
18
|
keep?: number;
|
|
18
19
|
scheduled: boolean;
|
|
19
20
|
cron: string;
|
|
@@ -54,6 +55,7 @@ export declare class BackupManager {
|
|
|
54
55
|
protected set backupDir(backupDir: string);
|
|
55
56
|
protected set tempDir(tempDir: string);
|
|
56
57
|
protected set uploadDir(uploadDir: string);
|
|
58
|
+
protected set portalDir(portalDir: string);
|
|
57
59
|
protected set backupTasksCacheName(backupTasksCacheName: string);
|
|
58
60
|
createBackupName(): Promise<string>;
|
|
59
61
|
backup(fileBaseName: string, opts?: Partial<BackupSettings>): Promise<string>;
|
|
@@ -50,7 +50,7 @@ var import_utils = require("@nocobase/utils");
|
|
|
50
50
|
var import_util = require("util");
|
|
51
51
|
var import_database = require("../adapters/database");
|
|
52
52
|
var import_utils2 = require("../utils");
|
|
53
|
-
const BACKUP_METADATA_VERSION =
|
|
53
|
+
const BACKUP_METADATA_VERSION = 3;
|
|
54
54
|
class BackupManager {
|
|
55
55
|
app;
|
|
56
56
|
ctx;
|
|
@@ -62,6 +62,7 @@ class BackupManager {
|
|
|
62
62
|
#backupDir;
|
|
63
63
|
#tempDir;
|
|
64
64
|
#uploadDir;
|
|
65
|
+
#portalDir;
|
|
65
66
|
#aesKeyPath;
|
|
66
67
|
constructor(app, ctx, settings) {
|
|
67
68
|
this.app = app;
|
|
@@ -73,6 +74,7 @@ class BackupManager {
|
|
|
73
74
|
this.#backupDir = (0, import_utils.storagePathJoin)("backups", app.name);
|
|
74
75
|
this.#tempDir = (0, import_utils.storagePathJoin)("tmp", "backups", app.name);
|
|
75
76
|
this.#uploadDir = (0, import_utils.storagePathJoin)("uploads");
|
|
77
|
+
this.#portalDir = (0, import_utils.storagePathJoin)("portals", app.name);
|
|
76
78
|
this.#aesKeyPath = (0, import_utils.storagePathJoin)("apps", app.name, "aes_key.dat");
|
|
77
79
|
}
|
|
78
80
|
set backupPrefix(backupPrefix) {
|
|
@@ -87,14 +89,24 @@ class BackupManager {
|
|
|
87
89
|
set uploadDir(uploadDir) {
|
|
88
90
|
this.#uploadDir = uploadDir;
|
|
89
91
|
}
|
|
92
|
+
set portalDir(portalDir) {
|
|
93
|
+
this.#portalDir = portalDir;
|
|
94
|
+
}
|
|
90
95
|
set backupTasksCacheName(backupTasksCacheName) {
|
|
91
96
|
this.#backupTasksCacheName = backupTasksCacheName;
|
|
92
97
|
}
|
|
93
98
|
#normalizeBackupSettings(settings) {
|
|
94
99
|
if (typeof settings.toJSON === "function") {
|
|
95
|
-
|
|
100
|
+
const values = settings.toJSON();
|
|
101
|
+
return {
|
|
102
|
+
...values,
|
|
103
|
+
enablePortalsBackup: values.enablePortalsBackup ?? true
|
|
104
|
+
};
|
|
96
105
|
}
|
|
97
|
-
return {
|
|
106
|
+
return {
|
|
107
|
+
...settings,
|
|
108
|
+
enablePortalsBackup: settings.enablePortalsBackup ?? true
|
|
109
|
+
};
|
|
98
110
|
}
|
|
99
111
|
async createBackupName() {
|
|
100
112
|
await this.#dbAdapter.check("backup");
|
|
@@ -199,6 +211,7 @@ class BackupManager {
|
|
|
199
211
|
...opts.metadata ?? {},
|
|
200
212
|
metadataVersion: BACKUP_METADATA_VERSION,
|
|
201
213
|
enableFilesBackup: opts.enableFilesBackup,
|
|
214
|
+
enablePortalsBackup: opts.enablePortalsBackup,
|
|
202
215
|
version: await this.app.version.get(),
|
|
203
216
|
description: opts.description,
|
|
204
217
|
createdBy: opts.createdBy,
|
|
@@ -292,6 +305,9 @@ class BackupManager {
|
|
|
292
305
|
}
|
|
293
306
|
}
|
|
294
307
|
}
|
|
308
|
+
if (opts.enablePortalsBackup && fs.existsSync(this.#portalDir)) {
|
|
309
|
+
archive.directory(this.#portalDir, "portals");
|
|
310
|
+
}
|
|
295
311
|
if (fs.existsSync(this.#aesKeyPath)) {
|
|
296
312
|
archive.file(this.#aesKeyPath, { name: "aes_key.dat" });
|
|
297
313
|
}
|
|
@@ -20,6 +20,7 @@ export declare class RestoreManager {
|
|
|
20
20
|
protected set backupDir(backupDir: string);
|
|
21
21
|
protected set tempDir(tempDir: string);
|
|
22
22
|
protected set uploadDir(uploadDir: string);
|
|
23
|
+
protected set portalDir(portalDir: string);
|
|
23
24
|
protected set restoreTasksCacheName(restoreTasksCacheName: string);
|
|
24
25
|
restoreFromBackup(backupFileName: string, taskId: string, password?: string, tolerentMode?: boolean, options?: RestoreOptions): Promise<void>;
|
|
25
26
|
restoreFromUpload(backupFile: Express.Multer.File, taskId: string, password?: string, tolerentMode?: boolean, options?: RestoreOptions): Promise<void>;
|
|
@@ -61,6 +61,7 @@ class RestoreManager {
|
|
|
61
61
|
#backupDir;
|
|
62
62
|
#tempDir;
|
|
63
63
|
#uploadDir;
|
|
64
|
+
#portalDir;
|
|
64
65
|
#aesKeyPath;
|
|
65
66
|
constructor(ctx, dbOptions) {
|
|
66
67
|
this.ctx = ctx;
|
|
@@ -69,6 +70,7 @@ class RestoreManager {
|
|
|
69
70
|
this.#backupDir = (0, import_utils.storagePathJoin)("backups", ctx.app.name);
|
|
70
71
|
this.#tempDir = (0, import_utils.storagePathJoin)("tmp", "backups", ctx.app.name);
|
|
71
72
|
this.#uploadDir = (0, import_utils.storagePathJoin)("uploads");
|
|
73
|
+
this.#portalDir = (0, import_utils.storagePathJoin)("portals", ctx.app.name);
|
|
72
74
|
this.#aesKeyPath = (0, import_utils.storagePathJoin)("apps", ctx.app.name, "aes_key.dat");
|
|
73
75
|
}
|
|
74
76
|
set backupDir(backupDir) {
|
|
@@ -80,6 +82,9 @@ class RestoreManager {
|
|
|
80
82
|
set uploadDir(uploadDir) {
|
|
81
83
|
this.#uploadDir = uploadDir;
|
|
82
84
|
}
|
|
85
|
+
set portalDir(portalDir) {
|
|
86
|
+
this.#portalDir = portalDir;
|
|
87
|
+
}
|
|
83
88
|
set restoreTasksCacheName(restoreTasksCacheName) {
|
|
84
89
|
this.#restoreTasksCacheName = restoreTasksCacheName;
|
|
85
90
|
}
|
|
@@ -119,6 +124,7 @@ class RestoreManager {
|
|
|
119
124
|
this.ctx.logger.warn("Tolerent mode enabled, ignoring the error and continue the upgrade.", {
|
|
120
125
|
module: import_utils2.BACKUPS
|
|
121
126
|
});
|
|
127
|
+
await this.#restorePortals(metadata.enablePortalsBackup === true, extractedDir);
|
|
122
128
|
await this.#restoreFilesAndCleanup(uploadsExist, extractedDir);
|
|
123
129
|
await this.ctx.app.upgrade();
|
|
124
130
|
} else if (!skipRevertOnError) {
|
|
@@ -147,6 +153,7 @@ class RestoreManager {
|
|
|
147
153
|
toolchain: this.#resolveRestoreToolchain(metadata)
|
|
148
154
|
});
|
|
149
155
|
this.ctx.logger.info("Database restored successfully", { module: import_utils2.BACKUPS });
|
|
156
|
+
await this.#restorePortals(metadata.enablePortalsBackup === true, extractedDir);
|
|
150
157
|
await this.#restoreFilesAndCleanup(restoreUploads, extractedDir);
|
|
151
158
|
} catch (error) {
|
|
152
159
|
this.ctx.logger.error(`Error restoring backup: ${error.message}. Trying to revert the backup process`, {
|
|
@@ -194,6 +201,7 @@ class RestoreManager {
|
|
|
194
201
|
this.ctx.logger.warn("Tolerent mode enabled, ignoring the error and continue the upgrade.", {
|
|
195
202
|
module: import_utils2.BACKUPS
|
|
196
203
|
});
|
|
204
|
+
await this.#restorePortals(metadata.enablePortalsBackup === true, extractedDir);
|
|
197
205
|
await this.#restoreFilesAndCleanup(uploadsExist, extractedDir);
|
|
198
206
|
await this.ctx.app.runCommand("upgrade");
|
|
199
207
|
} else {
|
|
@@ -401,6 +409,7 @@ class RestoreManager {
|
|
|
401
409
|
if (restoreUploads) {
|
|
402
410
|
this.#notify(RESTORE_STEPS.UPLOADS);
|
|
403
411
|
}
|
|
412
|
+
await this.#restorePortals(metadata.enablePortalsBackup === true, extractedDir);
|
|
404
413
|
await this.#restoreFilesAndCleanup(restoreUploads, extractedDir);
|
|
405
414
|
} catch (error) {
|
|
406
415
|
await statusCache.set(taskId, {
|
|
@@ -419,6 +428,16 @@ class RestoreManager {
|
|
|
419
428
|
});
|
|
420
429
|
await this.ctx.app.runCommand("upgrade");
|
|
421
430
|
}
|
|
431
|
+
async #restorePortals(restorePortals, extractedDir) {
|
|
432
|
+
if (!restorePortals) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const portalsDir = import_path.default.join(extractedDir, "portals");
|
|
436
|
+
await import_fs_extra.default.rm(this.#portalDir, { recursive: true, force: true });
|
|
437
|
+
if (await import_fs_extra.default.pathExists(portalsDir)) {
|
|
438
|
+
await import_fs_extra.default.copy(portalsDir, this.#portalDir, { overwrite: true });
|
|
439
|
+
}
|
|
440
|
+
}
|
|
422
441
|
async #restoreFilesAndCleanup(restoreUploads, extractedDir) {
|
|
423
442
|
if (restoreUploads) {
|
|
424
443
|
const uploadsDir = import_path.default.join(extractedDir, "uploads");
|
package/dist/server/plugin.js
CHANGED
|
@@ -57,6 +57,7 @@ const DEFAULT_SETTINGS = {
|
|
|
57
57
|
cron: "0 0 * * *",
|
|
58
58
|
keep: 100,
|
|
59
59
|
enableFilesBackup: true,
|
|
60
|
+
enablePortalsBackup: true,
|
|
60
61
|
storageId: null,
|
|
61
62
|
encryptionPassword: ""
|
|
62
63
|
}
|
|
@@ -198,6 +199,7 @@ class PluginBackupsServer extends import_server.Plugin {
|
|
|
198
199
|
cron: null,
|
|
199
200
|
encryptionPassword: null,
|
|
200
201
|
enableFilesBackup: false,
|
|
202
|
+
enablePortalsBackup: false,
|
|
201
203
|
keep: 0
|
|
202
204
|
});
|
|
203
205
|
const fileBaseName = await backupManager.createBackupName();
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"displayName.zh-CN": "备份管理器",
|
|
5
5
|
"description": "Provides backup and restore functionality, supports scheduled backups, and ensures data security and quick recovery.",
|
|
6
6
|
"description.zh-CN": "提供备份与还原功能,支持定时备份,确保数据安全与快速恢复。",
|
|
7
|
-
"version": "3.0.0-alpha.
|
|
7
|
+
"version": "3.0.0-alpha.5",
|
|
8
8
|
"license": "Apache-2.0",
|
|
9
9
|
"main": "dist/server/index.js",
|
|
10
10
|
"nocobase": {
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"keywords": [
|
|
51
51
|
"System management"
|
|
52
52
|
],
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "82c7ed1cdb2f247c190582e34ee37f154cac0968"
|
|
54
54
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
"use strict";(self.webpackChunk_nocobase_plugin_backups_client_v2=self.webpackChunk_nocobase_plugin_backups_client_v2||[]).push([["268"],{887:function(e,t,n){n.r(t),n.d(t,{default:function(){return h}});var r=n(694),a=n(625),o=n(59),c=n(155),l=n.n(c),u=n(837);n(693);var i=n(488);function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function f(e,t,n,r,a,o,c){try{var l=e[o](c),u=l.value}catch(e){n(e);return}l.done?t(u):Promise.resolve(u).then(r,a)}function m(e){return function(){var t=this,n=arguments;return new Promise(function(r,a){var o=e.apply(t,n);function c(e){f(o,r,a,c,l,"next",e)}function l(e){f(o,r,a,c,l,"throw",e)}c(void 0)})}}function p(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){var r;r=n[t],t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r})}return e}function b(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n,r,a=null==e?null:"u">typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var o=[],c=!0,l=!1;try{for(a=a.call(e);!(c=(n=a.next()).done)&&(o.push(n.value),!t||o.length!==t);c=!0);}catch(e){l=!0,r=e}finally{try{c||null==a.return||a.return()}finally{if(l)throw r}}return o}}(e,t)||function(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return s(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e,t){var n,r,a,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},c=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),l=Object.defineProperty;return l(c,"next",{value:u(0)}),l(c,"throw",{value:u(1)}),l(c,"return",{value:u(2)}),"function"==typeof Symbol&&l(c,Symbol.iterator,{value:function(){return this}}),c;function u(l){return function(u){var i=[l,u];if(n)throw TypeError("Generator is already executing.");for(;c&&(c=0,i[0]&&(o=0)),o;)try{if(n=1,r&&(a=2&i[0]?r.return:i[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,i[1])).done)return a;switch(r=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,r=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!(a=(a=o.trys).length>0&&a[a.length-1])&&(6===i[0]||2===i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]<a[3])){o.label=i[1];break}if(6===i[0]&&o.label<a[1]){o.label=a[1],a=i;break}if(a&&o.label<a[2]){o.label=a[2],o.ops.push(i);break}a[2]&&o.ops.pop(),o.trys.pop();continue}i=t.call(e,o)}catch(e){i=[6,e],r=0}finally{n=a=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}}}var y={scheduled:!1,cron:"0 0 * * *",keep:100,enableFilesBackup:!1},g=function(e){var t,n,r,a=e.onChange,o=e.value,c=function(e,t){if(null==e)return{};var n,r,a,o={};if("u">typeof Reflect&&Reflect.ownKeys){for(a=0,n=Reflect.ownKeys(Object(e));a<n.length;a++)r=n[a],!(t.indexOf(r)>=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r]);return o}if(o=function(e,t){if(null==e)return{};var n,r,a={},o=Object.getOwnPropertyNames(e);for(r=0;r<o.length;r++)n=o[r],!(t.indexOf(n)>=0)&&Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n]);return a}(e,t),Object.getOwnPropertySymbols)for(a=0,n=Object.getOwnPropertySymbols(e);a<n.length;a++)r=n[a],!(t.indexOf(r)>=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r]);return o}(e,["onChange","value"]),i=window.cronLocale;return l().createElement("fieldset",{className:"nb-backup-settings-cron"},l().createElement(u.l4,(t=p({},c),n=n={clearButton:!1,locale:i,value:null!=(r=null!=o?o:y.cron)?r:"",setValue:function(e){null==a||a(e)}},Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):(function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t.push.apply(t,n)}return t})(Object(n)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}),t)))},h=function(){var e=(0,r.useFlowContext)(),t=(0,i.k)(),n=o.App.useApp(),u=n.message,s=n.notification,f=b(o.Form.useForm(),1)[0],h=b((0,c.useState)(!1),2),v=h[0],w=h[1],O=o.Form.useWatch("scheduled",f),k=(0,a.useRequest)(function(){return m(function(){var t;return d(this,function(n){switch(n.label){case 0:return[4,e.api.request({url:"backupSettings:get/1"})];case 1:return[2,null==(t=n.sent().data)?void 0:t.data]}})})()},{onSuccess:function(e){f.setFieldsValue(p({},y,e))}}),j=(0,a.useRequest)(function(){return m(function(){var t,n;return d(this,function(r){switch(r.label){case 0:return[4,e.api.request({url:"storages:list"})];case 1:return[2,(null!=(t=null==(n=r.sent().data)?void 0:n.data)?t:[]).filter(function(e){return"local"!==e.type})]}})})()}),E=(0,c.useMemo)(function(){var e;return(null!=(e=j.data)?e:[]).map(function(e){return{label:e.title,value:e.id}})},[j.data]);return l().createElement(o.Card,{bordered:!1},l().createElement("style",null,"\n .nb-backup-settings-cron {\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n }\n\n .nb-backup-settings-cron .react-js-cron {\n padding: 0.5em 0.5em 0 0.5em;\n border: 1px dashed #ccc;\n }\n\n .nb-backup-settings-cron .react-js-cron .react-js-cron-field {\n flex-shrink: 0;\n margin-bottom: 0.5em;\n }\n\n .nb-backup-settings-cron .react-js-cron .react-js-cron-field > span {\n flex-shrink: 0;\n margin: 0 0.5em 0 0;\n }\n\n .nb-backup-settings-cron .react-js-cron .react-js-cron-field > .react-js-cron-select {\n margin: 0 0.5em 0 0;\n }\n\n .nb-backup-settings-cron\n .react-js-cron\n .react-js-cron-field\n > .react-js-cron-select\n .ant-select-selection-overflow {\n align-items: center;\n flex: initial;\n }\n"),l().createElement(o.Form,{form:f,layout:"vertical",initialValues:y,disabled:k.loading,onFinish:function(n){return m(function(){var r,a,o;return d(this,function(c){switch(c.label){case 0:r=p({},k.data,n),w(!0),c.label=1;case 1:return c.trys.push([1,3,4,5]),[4,e.api.request({url:"backupSettings:update/1",method:"post",data:r,skipNotify:!0})];case 2:return c.sent(),k.mutate(r),u.success(t("Saved successfully")),[3,5];case 3:return a=c.sent(),o=e.api.toErrMessages(a),s.error({message:o.length?o.map(function(e,n){var r="string"==typeof e?e:e.message;return l().createElement("div",{key:"".concat(n,"_").concat(r)},r||t("Save failed"))}):t("Save failed"),role:"alert"}),[3,5];case 4:return w(!1),[7];case 5:return[2]}})})()}},l().createElement(o.Form.Item,{label:t("Automatic backup")},l().createElement(o.Space,{direction:"vertical",style:{width:"100%"}},l().createElement(o.Form.Item,{name:"scheduled",valuePropName:"checked",noStyle:!0},l().createElement(o.Checkbox,null,t("Run automatic backup on the cron schedule"))),l().createElement(o.Form.Item,{name:"cron",rules:[{required:!!O,message:t("The field value is required")}],style:{marginBottom:0}},l().createElement(g,{disabled:!O})))),l().createElement(o.Form.Item,{name:"keep",label:t("Maximum number of backups"),extra:t("The maximum number of backups to keep, older backups are automatically deleted."),required:!0,rules:[{required:!0,message:t("The field value is required")},{type:"integer",min:1,max:1e3,message:t("Maximum number of backups must be an integer between {{min}} and {{max}}",{min:1,max:1e3})}]},l().createElement(o.InputNumber,{min:1,max:1e3,precision:0,style:{width:"100%"}})),l().createElement(o.Form.Item,{name:"storageId",label:t("Sync backups to cloud storage")},l().createElement(o.Select,{loading:j.loading,options:E,style:{width:"100%"}})),l().createElement(o.Form.Item,{name:"enableFilesBackup",label:t("Backup local storage files"),valuePropName:"checked"},l().createElement(o.Switch,null)),l().createElement(o.Form.Item,{name:"encryptionPassword",label:t("Restore password"),extra:t("If a restore password is set, it must be entered when restoring the backup.")},l().createElement(o.Input.Password,{autoComplete:"new-password",style:{width:"100%"}})),l().createElement(o.Form.Item,null,l().createElement(o.Button,{type:"primary",htmlType:"submit",loading:v},t("Submit")))))}},488:function(e,t,n){n.d(t,{k:function(){return o}});var r=n(694),a=n(401);function o(){var e=(0,r.useFlowEngine)();return function(t,n){return e.context.t(t,function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){var r;r=n[t],t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r})}return e}({ns:[a.C,"client"]},n))}}}}]);
|