oxidized-web 0.16.0 → 0.17.0
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.
Potentially problematic release.
This version of oxidized-web might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.rubocop.yml +22 -2
- data/CHANGELOG.md +18 -1
- data/README.md +13 -3
- data/Rakefile +9 -4
- data/docs/configuration.md +90 -0
- data/docs/development.md +42 -40
- data/lib/oxidized/web/public/scripts/oxidized.js +13 -13
- data/lib/oxidized/web/public/weblibs/bootstrap-icons.css +31 -3
- data/lib/oxidized/web/public/weblibs/bootstrap.bundle.js +20 -19
- data/lib/oxidized/web/public/weblibs/bootstrap.bundle.js.map +1 -1
- data/lib/oxidized/web/public/weblibs/bootstrap.css +110 -124
- data/lib/oxidized/web/public/weblibs/bootstrap.css.map +1 -1
- data/lib/oxidized/web/public/weblibs/bootstrap.js +20 -17
- data/lib/oxidized/web/public/weblibs/bootstrap.js.map +1 -1
- data/lib/oxidized/web/public/weblibs/buttons.bootstrap5.css +3 -3
- data/lib/oxidized/web/public/weblibs/buttons.colVis.js +14 -5
- data/lib/oxidized/web/public/weblibs/dataTables.bootstrap5.css +111 -17
- data/lib/oxidized/web/public/weblibs/dataTables.buttons.js +25 -7
- data/lib/oxidized/web/public/weblibs/dataTables.js +337 -107
- data/lib/oxidized/web/public/weblibs/dayjs-plugin-utc.min.js +1 -0
- data/lib/oxidized/web/public/weblibs/dayjs.min.js +1 -0
- data/lib/oxidized/web/public/weblibs/fonts/bootstrap-icons.woff +0 -0
- data/lib/oxidized/web/public/weblibs/fonts/bootstrap-icons.woff2 +0 -0
- data/lib/oxidized/web/version.rb +1 -1
- data/lib/oxidized/web/views/diffs.haml +6 -7
- data/lib/oxidized/web/views/head.haml +4 -0
- data/lib/oxidized/web/views/node.haml +3 -2
- data/lib/oxidized/web/views/nodes.haml +2 -2
- data/lib/oxidized/web/views/stats.haml +2 -2
- data/lib/oxidized/web/views/version.haml +1 -2
- data/lib/oxidized/web/views/versions.haml +6 -5
- data/lib/oxidized/web/webapp.rb +40 -25
- data/lib/oxidized/web.rb +71 -26
- data/oxidized-web.gemspec +22 -13
- data/package-lock.json +37 -25
- data/package.json +7 -5
- data/spec/spec_helper.rb +1 -0
- data/spec/web/node/show_spec.rb +100 -0
- data/spec/web/node/version_spec.rb +161 -0
- data/spec/{node_spec.rb → web/node_spec.rb} +1 -1
- data/spec/{nodes_spec.rb → web/nodes_spec.rb} +1 -1
- data/spec/{root_spec.rb → web/root_spec.rb} +1 -1
- data/spec/{webapp_spec.rb → web/webapp_spec.rb} +1 -1
- data/spec/web_spec.rb +98 -0
- metadata +69 -69
- data/.rubocop_todo.yml +0 -64
- data/spec/node_version_spec.rb +0 -102
@@ -0,0 +1 @@
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.dayjsPluginUTC=e():t.dayjsPluginUTC=e()}(this,function(){return function(t){var e={};function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(o,r,function(e){return t[e]}.bind(null,r));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function r(t){var e;switch(o(t)){case"string":return/Z$/.test(t)?0:(e=/([+-])(\d{2}):?(\d{2})/.exec(t))&&(+e[3]+60*e[2])*("+"===e[1]?1:-1);case"number":return Number.isNaN(t)?null:Math.abs(t)<16?60*t:t;default:return null}}n.r(e);var i=function(t,e,n){var o=String(t);return!o||o.length>=e?t:"".concat(Array(e+1-o.length).join(n)).concat(t)},s=function(t){var e=Math.abs(t),n=Math.floor(e/60),o=e%60;return"".concat(t<=0?"+":"-").concat(i(n,2,"0"),":").concat(i(o,2,"0"))};function u(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}var f=(new Date).getTimezoneOffset(),a=Date.prototype;function c(t){return 6e4*(t-(arguments.length>1&&void 0!==arguments[1]?arguments[1]:f))}var l=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new Date,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e.getTimezoneOffset();!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.$d=new Date(e.getTime()-c(n)),this.$timezoneOffset=n}var e,n,o;return e=t,(n=[{key:"getTimezoneOffset",value:function(){return this.$timezoneOffset}},{key:"setTimezoneOffset",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.$timezoneOffset;this.$d.setTime(this.$d.getTime()+c(this.$timezoneOffset,t)),this.$timezoneOffset=t}}])&&u(e.prototype,n),o&&u(e,o),t}();["toDateString","toLocaleString","toLocaleDateString","toLocaleTimeString","setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setYear","getDate","getDay","getFullYear","getHours","getMilliseconds","getMinutes","getMonth","getSeconds","getYear"].forEach(function(t){l.prototype[t]=function(){return a[t].apply(this.$d,arguments)}}),["toISOString","toUTCString","toGMTString","toJSON","getUTCDate","getUTCDay","getUTCFullYear","getUTCHours","getUTCMilliseconds","getUTCMinutes","getUTCMonth","getUTCSeconds","valueOf","getTime"].forEach(function(t){l.prototype[t]=function(){return a[t].apply(new Date(this.$d.getTime()+c(this.$timezoneOffset)),arguments)}}),["setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds"].forEach(function(t){l.prototype[t]=function(){var e=new Date(this.$d.getTime()+c(this.$timezoneOffset));a[t].apply(e,arguments),e.setTime(e.getTime()-c(this.$timezoneOffset)),this.$d=e}}),["toString","toTimeString"].forEach(function(t){l.prototype[t]=function(){return a[t].apply(this.$d,arguments).replace(/GMT(.*)$/,"GMT".concat(s(this.$timezoneOffset)))}});var d=l,p=!1,h=function(t,e){["clone","add","subtract","startOf"].forEach(function(n){t[n]=function(){var t=this.utcOffset();return e[n].apply(this,arguments).utcOffset(t)}}),t.utc=function(){return this.utcOffset(0)},t.local=function(){return this.utcOffset(-f)},t.utcOffset=function(t){if(void 0===t){var e=this.$d.getTimezoneOffset();return 0===e?0:-e}return null!==r(t)&&(this.$d.setTimezoneOffset(-r(t)),this.init()),this},t.toDate=function(){return new Date(this.$d.getTime())},t.isLocal=function(){return this.$d.getTimezoneOffset()===f},t.isUTC=function(){return 0===this.$d.getTimezoneOffset()},t.$set=function(){for(var t,n=this.$d.getTimezoneOffset(),o=arguments.length,r=new Array(o),i=0;i<o;i++)r[i]=arguments[i];return(t=e.$set).call.apply(t,[this].concat(r)),this.$d instanceof Date&&(this.$d=new d(this.$d,n)),this},t.parse=function(t){e.parse.call(this,t);var n=this.$d,o="string"==typeof t.date?r(t.date):null;this.$d=new d(n,null===o?f:-o),p&&this.local(),this.init()}};e.default=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1?arguments[1]:void 0,n=arguments.length>2?arguments[2]:void 0;p=!!t.parseToLocal;var o=e.prototype,i=function(){};i.prototype=o;var s=new i;h(s,o),s.constructor=e.constructor,e.prototype=s,n.utc=function(t){var e=this(t);return"string"==typeof t&&null===r(t)&&(e.$d.$timezoneOffset=0),e.utc()}}}])});
|
@@ -0,0 +1 @@
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).dayjs=e()}(this,(function(){"use strict";var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",c="month",f="quarter",h="year",d="date",l="Invalid Date",$=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return"["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()<n.date())return-t(n,e);var r=12*(n.year()-e.year())+(n.month()-e.month()),i=e.clone().add(r,c),s=n-i<0,u=e.clone().add(r+(s?-1:1),c);return+(-(r+(n-i)/(s?i-u:u-i))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:h,w:o,d:a,D:d,h:u,m:s,s:i,ms:r,Q:f}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},g="en",D={};D[g]=M;var p="$isDayjsObject",S=function(t){return t instanceof _||!(!t||!t[p])},w=function t(e,n,r){var i;if(!e)return g;if("string"==typeof e){var s=e.toLowerCase();D[s]&&(i=s),n&&(D[s]=n,i=s);var u=e.split("-");if(!i&&u.length>1)return t(u[0])}else{var a=e.name;D[a]=e,i=a}return!r&&i&&(g=i),i||!r&&g},O=function(t,e){if(S(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},b=v;b.l=w,b.i=S,b.w=function(t,e){return O(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=w(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[p]=!0}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(b.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match($);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return b},m.isValid=function(){return!(this.$d.toString()===l)},m.isSame=function(t,e){var n=O(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return O(t)<this.startOf(e)},m.isBefore=function(t,e){return this.endOf(e)<O(t)},m.$g=function(t,e,n){return b.u(t)?this[e]:this.set(n,t)},m.unix=function(){return Math.floor(this.valueOf()/1e3)},m.valueOf=function(){return this.$d.getTime()},m.startOf=function(t,e){var n=this,r=!!b.u(e)||e,f=b.p(t),l=function(t,e){var i=b.w(n.$u?Date.UTC(n.$y,e,t):new Date(n.$y,e,t),n);return r?i:i.endOf(a)},$=function(t,e){return b.w(n.toDate()[t].apply(n.toDate("s"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),n)},y=this.$W,M=this.$M,m=this.$D,v="set"+(this.$u?"UTC":"");switch(f){case h:return r?l(1,0):l(31,11);case c:return r?l(1,M):l(0,M+1);case o:var g=this.$locale().weekStart||0,D=(y<g?y+7:y)-g;return l(r?m-D:m+(6-D),M);case a:case d:return $(v+"Hours",0);case u:return $(v+"Minutes",1);case s:return $(v+"Seconds",2);case i:return $(v+"Milliseconds",3);default:return this.clone()}},m.endOf=function(t){return this.startOf(t,!1)},m.$set=function(t,e){var n,o=b.p(t),f="set"+(this.$u?"UTC":""),l=(n={},n[a]=f+"Date",n[d]=f+"Date",n[c]=f+"Month",n[h]=f+"FullYear",n[u]=f+"Hours",n[s]=f+"Minutes",n[i]=f+"Seconds",n[r]=f+"Milliseconds",n)[o],$=o===a?this.$D+(e-this.$W):e;if(o===c||o===h){var y=this.clone().set(d,1);y.$d[l]($),y.init(),this.$d=y.set(d,Math.min(this.$D,y.daysInMonth())).$d}else l&&this.$d[l]($);return this.init(),this},m.set=function(t,e){return this.clone().$set(t,e)},m.get=function(t){return this[b.p(t)]()},m.add=function(r,f){var d,l=this;r=Number(r);var $=b.p(f),y=function(t){var e=O(l);return b.w(e.date(e.date()+Math.round(t*r)),l)};if($===c)return this.set(c,this.$M+r);if($===h)return this.set(h,this.$y+r);if($===a)return y(1);if($===o)return y(7);var M=(d={},d[s]=e,d[u]=n,d[i]=t,d)[$]||1,m=this.$d.getTime()+r*M;return b.w(m,this)},m.subtract=function(t,e){return this.add(-1*t,e)},m.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return n.invalidDate||l;var r=t||"YYYY-MM-DDTHH:mm:ssZ",i=b.z(this),s=this.$H,u=this.$m,a=this.$M,o=n.weekdays,c=n.months,f=n.meridiem,h=function(t,n,i,s){return t&&(t[n]||t(e,r))||i[n].slice(0,s)},d=function(t){return b.s(s%12||12,t,"0")},$=f||function(t,e,n){var r=t<12?"AM":"PM";return n?r.toLowerCase():r};return r.replace(y,(function(t,r){return r||function(t){switch(t){case"YY":return String(e.$y).slice(-2);case"YYYY":return b.s(e.$y,4,"0");case"M":return a+1;case"MM":return b.s(a+1,2,"0");case"MMM":return h(n.monthsShort,a,c,3);case"MMMM":return h(c,a);case"D":return e.$D;case"DD":return b.s(e.$D,2,"0");case"d":return String(e.$W);case"dd":return h(n.weekdaysMin,e.$W,o,2);case"ddd":return h(n.weekdaysShort,e.$W,o,3);case"dddd":return o[e.$W];case"H":return String(s);case"HH":return b.s(s,2,"0");case"h":return d(1);case"hh":return d(2);case"a":return $(s,u,!0);case"A":return $(s,u,!1);case"m":return String(u);case"mm":return b.s(u,2,"0");case"s":return String(e.$s);case"ss":return b.s(e.$s,2,"0");case"SSS":return b.s(e.$ms,3,"0");case"Z":return i}return null}(t)||i.replace(":","")}))},m.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},m.diff=function(r,d,l){var $,y=this,M=b.p(d),m=O(r),v=(m.utcOffset()-this.utcOffset())*e,g=this-m,D=function(){return b.m(y,m)};switch(M){case h:$=D()/12;break;case c:$=D();break;case f:$=D()/3;break;case o:$=(g-v)/6048e5;break;case a:$=(g-v)/864e5;break;case u:$=g/n;break;case s:$=g/e;break;case i:$=g/t;break;default:$=g}return l?$:b.a($)},m.daysInMonth=function(){return this.endOf(c).$D},m.$locale=function(){return D[this.$L]},m.locale=function(t,e){if(!t)return this.$L;var n=this.clone(),r=w(t,e,!0);return r&&(n.$L=r),n},m.clone=function(){return b.w(this.$d,this)},m.toDate=function(){return new Date(this.valueOf())},m.toJSON=function(){return this.isValid()?this.toISOString():null},m.toISOString=function(){return this.$d.toISOString()},m.toString=function(){return this.$d.toUTCString()},M}(),k=_.prototype;return O.prototype=k,[["$ms",r],["$s",i],["$m",s],["$H",u],["$W",a],["$M",c],["$y",h],["$D",d]].forEach((function(t){k[t[1]]=function(e){return this.$g(e,t[0],t[1])}})),O.extend=function(t,e){return t.$i||(t(e,_,O),t.$i=!0),O},O.locale=w,O.isDayjs=S,O.unix=function(t){return O(1e3*t)},O.en=D[g],O.Ls=D,O.p={},O}));
|
Binary file
|
Binary file
|
data/lib/oxidized/web/version.rb
CHANGED
@@ -10,9 +10,8 @@
|
|
10
10
|
%b #{@info[:node]}
|
11
11
|
.row
|
12
12
|
.col-sm-12
|
13
|
-
- date_version = Time.parse @info[:date]
|
14
13
|
Date of version:
|
15
|
-
%span.time
|
14
|
+
%span.time{ epoch: @info[:time].to_i }= @info[:time]
|
16
15
|
.row
|
17
16
|
.col-sm-12
|
18
17
|
Number of lines changed:
|
@@ -22,7 +21,7 @@
|
|
22
21
|
.row
|
23
22
|
.col-sm-6
|
24
23
|
- params = "node=#{@info[:node]}&group=#{@info[:group]}&oid=#{@info[:oid]}"
|
25
|
-
- params = "#{params}&
|
24
|
+
- params = "#{params}&epoch=#{@info[:time].to_i}&num=#{@info[:num]}"
|
26
25
|
%form{action: url_for("/node/version/diffs?#{params}"), method: 'post', role: 'form'}
|
27
26
|
.form-group
|
28
27
|
%select.form-select#oid2{name: 'oid2'}
|
@@ -30,9 +29,9 @@
|
|
30
29
|
- num = @oids_dates.count + 1
|
31
30
|
- next_id = false
|
32
31
|
- @oids_dates.each do |x|
|
33
|
-
%option{value: x[:oid]} Version #{num -= 1} (#{time_from_now x[:
|
32
|
+
%option{value: x[:oid]} Version #{num -= 1} (#{time_from_now x[:time]})
|
34
33
|
- if (x[:oid].to_s == @info[:oid2]) || (next_id)
|
35
|
-
- diff2 = {num: num,
|
34
|
+
- diff2 = {num: num, time: x[:time]}
|
36
35
|
- next_id = false
|
37
36
|
- elsif (x[:oid].to_s == @info[:oid]) && !(@info[:oid2])
|
38
37
|
- next_id = true
|
@@ -41,8 +40,8 @@
|
|
41
40
|
|
42
41
|
.row
|
43
42
|
.col-sm-12
|
44
|
-
.old_version_title Version #{diff2[:num]} (#{time_from_now diff2[:
|
45
|
-
.new_version_title Version #{@info[:num]} (#{time_from_now @info[:
|
43
|
+
.old_version_title Version #{diff2[:num]} (#{time_from_now diff2[:time]})
|
44
|
+
.new_version_title Version #{@info[:num]} (#{time_from_now @info[:time]})
|
46
45
|
|
47
46
|
.row
|
48
47
|
.col-sm-12
|
@@ -25,5 +25,9 @@
|
|
25
25
|
%script{src: url_for('/weblibs/dataTables.buttons.js')}
|
26
26
|
%script{src: url_for('/weblibs/buttons.bootstrap5.js')}
|
27
27
|
%script{src: url_for('/weblibs/buttons.colVis.js')}
|
28
|
+
-# Day.js
|
29
|
+
%script{src: url_for('/weblibs/dayjs.min.js')}
|
30
|
+
%script{src: url_for('/weblibs/dayjs-plugin-utc.min.js')}
|
31
|
+
%script dayjs.extend(dayjsPluginUTC.default)
|
28
32
|
-# Oxidized customisation
|
29
33
|
%script{src: url_for('/scripts/oxidized.js')}
|
@@ -14,7 +14,8 @@
|
|
14
14
|
%a.link-dark.link-underline-opacity-0{title: 'update',
|
15
15
|
href: url_for("/node/next/#{@data[:full_name]}")}
|
16
16
|
%i.bi.bi-repeat
|
17
|
-
- out = '';PP.pp(@data,out)
|
18
17
|
%pre.bg-body-tertiary.border.border-secondary-subtle.rounded
|
19
|
-
|
18
|
+
%code
|
19
|
+
=escape_once(JSON.pretty_generate(@data))
|
20
|
+
|
20
21
|
|
@@ -42,8 +42,8 @@
|
|
42
42
|
%td
|
43
43
|
%div{title: node[:status], class: node[:status]}
|
44
44
|
%span{style: 'visibility: hidden'}#{node[:status]}
|
45
|
-
%td.time= node[:time]
|
46
|
-
%td.time= node[:mtime]
|
45
|
+
%td.time{ epoch: node[:time].to_i }= node[:time]
|
46
|
+
%td.time{ epoch: node[:mtime].to_i }= node[:mtime]
|
47
47
|
%td
|
48
48
|
%a.link-dark.link-underline-opacity-0{title: 'Configuration',
|
49
49
|
href: url_for("/node/fetch/#{node[:full_name]}")}
|
@@ -79,8 +79,8 @@
|
|
79
79
|
%td
|
80
80
|
%div{title: status, class: status}
|
81
81
|
%span{style: 'visibility: hidden'}#{status}
|
82
|
-
%td.time= last_success
|
83
|
-
%td.time= last_failure
|
82
|
+
%td.time{ epoch: last_success.to_i }= last_success
|
83
|
+
%td.time{ epoch: last_failure.to_i }= last_failure
|
84
84
|
|
85
85
|
:javascript
|
86
86
|
$(function() {
|
@@ -13,9 +13,8 @@
|
|
13
13
|
%a.btn.btn-primary{:href => "#{request.path}?#{request.query_string}&format=text"} raw
|
14
14
|
.row
|
15
15
|
.col-sm-12
|
16
|
-
- date_version = Time.parse @info[:date]
|
17
16
|
Date of version:
|
18
|
-
%span.time
|
17
|
+
%span.time{ epoch: @info[:time].to_i }= @info[:time]
|
19
18
|
|
20
19
|
.row
|
21
20
|
.col-sm-12
|
@@ -25,17 +25,18 @@
|
|
25
25
|
- @data.each do |x|
|
26
26
|
%tr
|
27
27
|
%td #{nb -= 1}
|
28
|
-
%td
|
29
|
-
%td #{time_from_now x[:
|
28
|
+
%td.time{ epoch: x[:time].to_i }= x[:time]
|
29
|
+
%td #{time_from_now x[:time]}
|
30
30
|
%td
|
31
31
|
- params = "node=#{@node}&group=#{@group}&oid=#{x[:oid]}"
|
32
|
-
- params = "#{params}&
|
32
|
+
- params = "#{params}&epoch=#{x[:time].to_i}&num=#{nb}"
|
33
33
|
%a.link-dark.link-underline-opacity-0{title: 'configuration',
|
34
34
|
href: url_for("/node/version/view?#{params}")}
|
35
35
|
%i.bi.bi-cloud-download
|
36
36
|
|
37
|
-
|
38
|
-
%
|
37
|
+
- if nb > 1
|
38
|
+
%a.link-dark.link-underline-opacity-0{title: 'Compare with previous version', href: url_for("/node/version/diffs?#{params}")}
|
39
|
+
%i.bi.bi-file-earmark-diff
|
39
40
|
|
40
41
|
:javascript
|
41
42
|
$(function() {
|
data/lib/oxidized/web/webapp.rb
CHANGED
@@ -2,7 +2,6 @@ require 'sinatra/base'
|
|
2
2
|
require 'sinatra/json'
|
3
3
|
require 'sinatra/url_for'
|
4
4
|
require 'tilt/haml'
|
5
|
-
require 'pp'
|
6
5
|
require 'htmlentities'
|
7
6
|
require 'charlock_holmes'
|
8
7
|
module Oxidized
|
@@ -119,7 +118,7 @@ module Oxidized
|
|
119
118
|
# use this to attach author/email/message to commit
|
120
119
|
put '/node/next/?*?/:node' do
|
121
120
|
node, @json = route_parse :node
|
122
|
-
opt = JSON.
|
121
|
+
opt = JSON.parse request.body.read
|
123
122
|
nodes.next node, opt
|
124
123
|
redirect url_for('/nodes') unless @json
|
125
124
|
@data = 'ok'
|
@@ -128,7 +127,7 @@ module Oxidized
|
|
128
127
|
|
129
128
|
get '/node/show/:node' do
|
130
129
|
node, @json = route_parse :node
|
131
|
-
@data = nodes.show
|
130
|
+
@data = filter_node_vars(nodes.show(node))
|
132
131
|
out :node
|
133
132
|
end
|
134
133
|
|
@@ -158,7 +157,7 @@ module Oxidized
|
|
158
157
|
node: node,
|
159
158
|
group: params[:group],
|
160
159
|
oid: params[:oid],
|
161
|
-
|
160
|
+
time: Time.at(params[:epoch].to_i),
|
162
161
|
num: params[:num]
|
163
162
|
}
|
164
163
|
|
@@ -176,7 +175,12 @@ module Oxidized
|
|
176
175
|
get '/node/version/diffs' do
|
177
176
|
node, @json = route_parse :node
|
178
177
|
@data = nil
|
179
|
-
@info = { node: node,
|
178
|
+
@info = { node: node,
|
179
|
+
group: params[:group],
|
180
|
+
oid: params[:oid],
|
181
|
+
time: Time.at(params[:epoch].to_i),
|
182
|
+
num: params[:num],
|
183
|
+
num2: (params[:num].to_i - 1) }
|
180
184
|
group = nil
|
181
185
|
group = @info[:group] if @info[:group] != ''
|
182
186
|
@oids_dates = nodes.version node, group
|
@@ -201,7 +205,7 @@ module Oxidized
|
|
201
205
|
@stat = @data[:stat]
|
202
206
|
@data = @data[:patch]
|
203
207
|
else
|
204
|
-
@data = '
|
208
|
+
@data = 'No diff available'
|
205
209
|
end
|
206
210
|
@diff = diff_view @data
|
207
211
|
out :diffs
|
@@ -209,7 +213,7 @@ module Oxidized
|
|
209
213
|
|
210
214
|
# used for diff between 2 distant commit
|
211
215
|
post '/node/version/diffs' do
|
212
|
-
redirect url_for("/node/version/diffs?node=#{params[:node]}&group=#{params[:group]}&oid=#{params[:oid]}&
|
216
|
+
redirect url_for("/node/version/diffs?node=#{params[:node]}&group=#{params[:group]}&oid=#{params[:oid]}&epoch=#{params[:epoch]}&num=#{params[:num]}&oid2=#{params[:oid2]}")
|
213
217
|
end
|
214
218
|
|
215
219
|
# Taken von Haml 5.0, so it still works in 6.0
|
@@ -254,26 +258,23 @@ module Oxidized
|
|
254
258
|
[e.join('.'), json]
|
255
259
|
end
|
256
260
|
|
257
|
-
# give the time
|
261
|
+
# give the time elapsed between now and a date (Time object)
|
258
262
|
def time_from_now(date)
|
259
|
-
if date
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
"#{mm} min #{ss} sec ago"
|
274
|
-
end
|
263
|
+
return "no time specified" if date.nil?
|
264
|
+
|
265
|
+
raise "time_from_now needs a Time object" unless date.instance_of? Time
|
266
|
+
|
267
|
+
t = (Time.now - date).to_i
|
268
|
+
mm, ss = t.divmod(60)
|
269
|
+
hh, mm = mm.divmod(60)
|
270
|
+
dd, hh = hh.divmod(24)
|
271
|
+
if dd.positive?
|
272
|
+
"#{dd} days #{hh} hours ago"
|
273
|
+
elsif hh.positive?
|
274
|
+
"#{hh} hours #{mm} min ago"
|
275
|
+
else
|
276
|
+
"#{mm} min #{ss} sec ago"
|
275
277
|
end
|
276
|
-
date
|
277
278
|
end
|
278
279
|
|
279
280
|
# method the give diffs in separate view (the old and the new) as in github
|
@@ -326,6 +327,20 @@ module Oxidized
|
|
326
327
|
'The text contains binary values - cannot display'
|
327
328
|
end
|
328
329
|
end
|
330
|
+
|
331
|
+
def filter_node_vars(serialized_node)
|
332
|
+
# Make a deep copy of the data, so we do not impact oxidized
|
333
|
+
data = Marshal.load(Marshal.dump(serialized_node))
|
334
|
+
|
335
|
+
hide_node_vars = settings.configuration[:hide_node_vars]
|
336
|
+
if data[:vars].is_a?(Hash) && hide_node_vars&.any?
|
337
|
+
hide_node_vars.each do |key|
|
338
|
+
data[:vars][key] = '<hidden>' if data[:vars].has_key?(key)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
data
|
343
|
+
end
|
329
344
|
end
|
330
345
|
end
|
331
346
|
end
|
data/lib/oxidized/web.rb
CHANGED
@@ -1,38 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
4
|
+
require 'puma'
|
2
5
|
|
3
6
|
module Oxidized
|
4
7
|
module API
|
5
8
|
class Web
|
6
|
-
|
9
|
+
include SemanticLogger::Loggable
|
10
|
+
|
7
11
|
attr_reader :thread
|
8
12
|
|
13
|
+
DEFAULT_HOST = '127.0.0.1'
|
14
|
+
DEFAULT_PORT = 8888
|
15
|
+
DEFAULT_URI_PREFIX = ''
|
16
|
+
|
9
17
|
def initialize(nodes, configuration)
|
10
18
|
require 'oxidized/web/webapp'
|
11
|
-
|
12
|
-
# New configuration syle: extensions.oxidized-web
|
13
|
-
addr = configuration.listen? || '127.0.0.1'
|
14
|
-
port = configuration.port? || 8888
|
15
|
-
uri = configuration.url_prefix? || ''
|
16
|
-
vhosts = configuration.vhosts? || []
|
17
|
-
else
|
18
|
-
# Old configuration stlyle: "rest: 127.0.0.1:8888/prefix"
|
19
|
-
listen, uri = configuration.split '/'
|
20
|
-
addr, _, port = listen.rpartition ':'
|
21
|
-
unless port
|
22
|
-
port = addr
|
23
|
-
addr = nil
|
24
|
-
end
|
25
|
-
vhosts = []
|
26
|
-
end
|
27
|
-
uri = "/#{uri}"
|
28
|
-
@opts = {
|
29
|
-
Host: addr,
|
30
|
-
Port: port
|
31
|
-
}
|
19
|
+
@configuration = self.class.parse_configuration(configuration)
|
32
20
|
WebApp.set :nodes, nodes
|
33
|
-
WebApp.set :
|
21
|
+
WebApp.set :configuration, @configuration
|
22
|
+
WebApp.set :host_authorization, {
|
23
|
+
permitted_hosts: @configuration[:vhosts]
|
24
|
+
}
|
25
|
+
uri_prefix = @configuration[:uri_prefix]
|
34
26
|
@app = Rack::Builder.new do
|
35
|
-
map
|
27
|
+
map uri_prefix do
|
36
28
|
run WebApp
|
37
29
|
end
|
38
30
|
end
|
@@ -40,10 +32,63 @@ module Oxidized
|
|
40
32
|
|
41
33
|
def run
|
42
34
|
@thread = Thread.new do
|
43
|
-
|
44
|
-
|
35
|
+
@server = Puma::Server.new @app
|
36
|
+
addr = @configuration[:addr]
|
37
|
+
port = @configuration[:port]
|
38
|
+
@server.add_tcp_listener addr, port
|
39
|
+
logger.info "Oxidized-web server listening on #{addr}:#{port}"
|
40
|
+
@server.run.join
|
45
41
|
end
|
46
42
|
end
|
43
|
+
|
44
|
+
def self.parse_configuration(configuration)
|
45
|
+
if configuration.instance_of? Asetus::ConfigStruct
|
46
|
+
parse_new_configuration(configuration)
|
47
|
+
else
|
48
|
+
parse_legacy_configuration(configuration)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# New configuration style: extensions.oxidized-web
|
53
|
+
def self.parse_new_configuration(configuration)
|
54
|
+
hide_node_vars = configuration.hide_node_vars? || []
|
55
|
+
unless hide_node_vars.is_a?(Array)
|
56
|
+
logger.error "hide_node_vars must be a list of strings"
|
57
|
+
hide_node_vars = []
|
58
|
+
end
|
59
|
+
hide_node_vars = hide_node_vars.map(&:to_sym)
|
60
|
+
{
|
61
|
+
addr: configuration.listen? || DEFAULT_HOST,
|
62
|
+
port: configuration.port? || DEFAULT_PORT,
|
63
|
+
uri_prefix: normalize_uri(configuration.url_prefix? ||
|
64
|
+
DEFAULT_URI_PREFIX),
|
65
|
+
vhosts: configuration.vhosts? || [],
|
66
|
+
hide_node_vars: hide_node_vars
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
# Legacy configuration style: "rest: 127.0.0.1:8888/prefix"
|
71
|
+
def self.parse_legacy_configuration(configuration)
|
72
|
+
listen, uri_prefix = configuration.split('/', 2)
|
73
|
+
addr, _, port = listen.rpartition ':'
|
74
|
+
unless port
|
75
|
+
port = addr
|
76
|
+
addr = nil
|
77
|
+
end
|
78
|
+
{
|
79
|
+
addr: addr,
|
80
|
+
port: port.to_i,
|
81
|
+
uri_prefix: normalize_uri(uri_prefix || DEFAULT_URI_PREFIX),
|
82
|
+
vhosts: [],
|
83
|
+
hide_node_vars: []
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.normalize_uri(uri_prefix)
|
88
|
+
return '/' if uri_prefix.empty?
|
89
|
+
|
90
|
+
uri_prefix.start_with?('/') ? uri_prefix : "/#{uri_prefix}"
|
91
|
+
end
|
47
92
|
end
|
48
93
|
end
|
49
94
|
end
|
data/oxidized-web.gemspec
CHANGED
@@ -20,16 +20,26 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.required_ruby_version = '>= 3.1'
|
22
22
|
|
23
|
-
|
23
|
+
# Gemspec strategy
|
24
|
+
#
|
25
|
+
# For dependency and optional dependencies, we try to set the minimal
|
26
|
+
# dependency lower than the Ubuntu Noble or Debian Bookworm package version,
|
27
|
+
# so that native packages can be used.
|
28
|
+
# We limit the maximal version so that dependabot can warn about new versions
|
29
|
+
# and we can test them before activating them in Oxidized.
|
30
|
+
#
|
31
|
+
# development dependencies are set to the latest minor version of a library
|
32
|
+
# and updated after having tested them
|
33
|
+
|
34
|
+
s.add_dependency 'charlock_holmes', '>= 0.7.5', '< 0.8.0'
|
24
35
|
s.add_dependency 'emk-sinatra-url-for', '~> 0.2'
|
25
|
-
s.add_dependency 'haml', '
|
26
|
-
s.add_dependency 'htmlentities', '
|
27
|
-
s.add_dependency 'json', '
|
28
|
-
s.add_dependency '
|
29
|
-
s.add_dependency '
|
30
|
-
s.add_dependency '
|
31
|
-
s.add_dependency 'sinatra',
|
32
|
-
s.add_dependency 'sinatra-contrib', '>= 1.4.6'
|
36
|
+
s.add_dependency 'haml', '>= 6.0.0', '< 6.4.0'
|
37
|
+
s.add_dependency 'htmlentities', '>= 4.3.0', '< 4.4.0'
|
38
|
+
s.add_dependency 'json', '>= 2.3.0', '< 2.14.0'
|
39
|
+
s.add_dependency 'oxidized', '~> 0.34.0'
|
40
|
+
s.add_dependency 'puma', '~> 6.6.0'
|
41
|
+
s.add_dependency 'sinatra', '~> 4.1.1'
|
42
|
+
s.add_dependency 'sinatra-contrib', '~> 4.1.1'
|
33
43
|
|
34
44
|
s.add_development_dependency 'bundler', '~> 2.2'
|
35
45
|
s.add_development_dependency 'minitest', '~> 5.18'
|
@@ -37,11 +47,10 @@ Gem::Specification.new do |s|
|
|
37
47
|
s.add_development_dependency 'rack-test', '~> 2.1'
|
38
48
|
s.add_development_dependency 'rails_best_practices', '~> 1.19'
|
39
49
|
s.add_development_dependency 'rake', '~> 13.0'
|
40
|
-
s.add_development_dependency 'rubocop', '~> 1.
|
41
|
-
s.add_development_dependency 'rubocop-minitest', '~> 0.
|
42
|
-
s.add_development_dependency 'rubocop-rails', '~> 2.
|
50
|
+
s.add_development_dependency 'rubocop', '~> 1.78.0'
|
51
|
+
s.add_development_dependency 'rubocop-minitest', '~> 0.38.0'
|
52
|
+
s.add_development_dependency 'rubocop-rails', '~> 2.32.0'
|
43
53
|
s.add_development_dependency 'rubocop-rake', '~> 0.7.1'
|
44
54
|
s.add_development_dependency 'simplecov', '~> 0.22.0'
|
45
|
-
s.add_development_dependency 'simplecov-cobertura', '~> 2.1.0'
|
46
55
|
s.add_development_dependency 'simplecov-html', '~> 0.13.1'
|
47
56
|
end
|
data/package-lock.json
CHANGED
@@ -9,11 +9,13 @@
|
|
9
9
|
"version": "1.0.0",
|
10
10
|
"license": "Apache 2.0",
|
11
11
|
"dependencies": {
|
12
|
-
"bootstrap": "
|
13
|
-
"bootstrap-icons": "
|
14
|
-
"datatables.net-bs5": "
|
15
|
-
"datatables.net-buttons-bs5": "
|
16
|
-
"
|
12
|
+
"bootstrap": "~5.3.3",
|
13
|
+
"bootstrap-icons": "~1.13.1",
|
14
|
+
"datatables.net-bs5": "~2.3.2",
|
15
|
+
"datatables.net-buttons-bs5": "~3.2.4",
|
16
|
+
"dayjs": "~1.11.13",
|
17
|
+
"dayjs-plugin-utc": "~0.1.2",
|
18
|
+
"jquery": "~3.7.1"
|
17
19
|
}
|
18
20
|
},
|
19
21
|
"node_modules/@popperjs/core": {
|
@@ -27,9 +29,9 @@
|
|
27
29
|
}
|
28
30
|
},
|
29
31
|
"node_modules/bootstrap": {
|
30
|
-
"version": "5.3.
|
31
|
-
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.
|
32
|
-
"integrity": "sha512-
|
32
|
+
"version": "5.3.7",
|
33
|
+
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.7.tgz",
|
34
|
+
"integrity": "sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw==",
|
33
35
|
"funding": [
|
34
36
|
{
|
35
37
|
"type": "github",
|
@@ -45,9 +47,9 @@
|
|
45
47
|
}
|
46
48
|
},
|
47
49
|
"node_modules/bootstrap-icons": {
|
48
|
-
"version": "1.
|
49
|
-
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.
|
50
|
-
"integrity": "sha512
|
50
|
+
"version": "1.13.1",
|
51
|
+
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz",
|
52
|
+
"integrity": "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==",
|
51
53
|
"funding": [
|
52
54
|
{
|
53
55
|
"type": "github",
|
@@ -60,41 +62,51 @@
|
|
60
62
|
]
|
61
63
|
},
|
62
64
|
"node_modules/datatables.net": {
|
63
|
-
"version": "2.
|
64
|
-
"resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-2.
|
65
|
-
"integrity": "sha512-
|
65
|
+
"version": "2.3.2",
|
66
|
+
"resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-2.3.2.tgz",
|
67
|
+
"integrity": "sha512-31TzwIQM0+pr2ZOEOEH6dsHd/WSAl5GDDGPezOHPI3mM2NK4lcDyOoG8xXeWmSbVfbi852LNK5C84fpp4Q+qxg==",
|
66
68
|
"dependencies": {
|
67
69
|
"jquery": ">=1.7"
|
68
70
|
}
|
69
71
|
},
|
70
72
|
"node_modules/datatables.net-bs5": {
|
71
|
-
"version": "2.
|
72
|
-
"resolved": "https://registry.npmjs.org/datatables.net-bs5/-/datatables.net-bs5-2.
|
73
|
-
"integrity": "sha512-
|
73
|
+
"version": "2.3.2",
|
74
|
+
"resolved": "https://registry.npmjs.org/datatables.net-bs5/-/datatables.net-bs5-2.3.2.tgz",
|
75
|
+
"integrity": "sha512-1rh0ZTLoiziIQ4oAtgr+IOYVgJfAIceDnbDe535u8kv191pBAdTrKF6ovQO98Xy9mDXLdLNB7QCrLiV/sgPoQw==",
|
74
76
|
"dependencies": {
|
75
|
-
"datatables.net": "2.
|
77
|
+
"datatables.net": "2.3.2",
|
76
78
|
"jquery": ">=1.7"
|
77
79
|
}
|
78
80
|
},
|
79
81
|
"node_modules/datatables.net-buttons": {
|
80
|
-
"version": "3.2.
|
81
|
-
"resolved": "https://registry.npmjs.org/datatables.net-buttons/-/datatables.net-buttons-3.2.
|
82
|
-
"integrity": "sha512
|
82
|
+
"version": "3.2.4",
|
83
|
+
"resolved": "https://registry.npmjs.org/datatables.net-buttons/-/datatables.net-buttons-3.2.4.tgz",
|
84
|
+
"integrity": "sha512-anA39/R0kpHA2DOwqEHy/ZMXD5vf4tWmyNO0BnO0kJG7AFNvGTUCWBnBifXYg3G64U6JYpYY+MuTFKIB1/ZMTQ==",
|
83
85
|
"dependencies": {
|
84
86
|
"datatables.net": "^2",
|
85
87
|
"jquery": ">=1.7"
|
86
88
|
}
|
87
89
|
},
|
88
90
|
"node_modules/datatables.net-buttons-bs5": {
|
89
|
-
"version": "3.2.
|
90
|
-
"resolved": "https://registry.npmjs.org/datatables.net-buttons-bs5/-/datatables.net-buttons-bs5-3.2.
|
91
|
-
"integrity": "sha512-
|
91
|
+
"version": "3.2.4",
|
92
|
+
"resolved": "https://registry.npmjs.org/datatables.net-buttons-bs5/-/datatables.net-buttons-bs5-3.2.4.tgz",
|
93
|
+
"integrity": "sha512-yX8Ia32P1D9L02XWjisA6a9fFp0LgmzpIcvf/4ty+QG5/qj1tOOqWgsXsxxIY2Uj918WmLJS6VaJabRAMoAqHA==",
|
92
94
|
"dependencies": {
|
93
95
|
"datatables.net-bs5": "^2",
|
94
|
-
"datatables.net-buttons": "3.2.
|
96
|
+
"datatables.net-buttons": "3.2.4",
|
95
97
|
"jquery": ">=1.7"
|
96
98
|
}
|
97
99
|
},
|
100
|
+
"node_modules/dayjs": {
|
101
|
+
"version": "1.11.13",
|
102
|
+
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
|
103
|
+
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
|
104
|
+
},
|
105
|
+
"node_modules/dayjs-plugin-utc": {
|
106
|
+
"version": "0.1.2",
|
107
|
+
"resolved": "https://registry.npmjs.org/dayjs-plugin-utc/-/dayjs-plugin-utc-0.1.2.tgz",
|
108
|
+
"integrity": "sha512-ExERH5o3oo6jFOdkvMP3gytTCQ9Ksi5PtylclJWghr7k7m3o2U5QrwtdiJkOxLOH4ghr0EKhpqGefzGz1VvVJg=="
|
109
|
+
},
|
98
110
|
"node_modules/jquery": {
|
99
111
|
"version": "3.7.1",
|
100
112
|
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
|
data/package.json
CHANGED
@@ -12,10 +12,12 @@
|
|
12
12
|
"author": "The oxidized project",
|
13
13
|
"license": "Apache 2.0",
|
14
14
|
"dependencies": {
|
15
|
-
"bootstrap": "
|
16
|
-
"bootstrap-icons": "
|
17
|
-
"datatables.net-bs5": "
|
18
|
-
"datatables.net-buttons-bs5": "
|
19
|
-
"
|
15
|
+
"bootstrap": "~5.3.3",
|
16
|
+
"bootstrap-icons": "~1.13.1",
|
17
|
+
"datatables.net-bs5": "~2.3.2",
|
18
|
+
"datatables.net-buttons-bs5": "~3.2.4",
|
19
|
+
"dayjs": "~1.11.13",
|
20
|
+
"dayjs-plugin-utc": "~0.1.2",
|
21
|
+
"jquery": "~3.7.1"
|
20
22
|
}
|
21
23
|
}
|