mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-06-27 11:50:00 +00:00
Cleanup more callback things (#3051)
Looks quite stable on my computers, so maybe we give it a try? --------- Co-authored-by: veeck <michael@veeck.de>
This commit is contained in:
parent
b5b61246e6
commit
1b2785cc56
@ -37,10 +37,7 @@ _This release is scheduled to be released on 2023-04-01._
|
|||||||
- Update dates in Calendar widgets every minute
|
- Update dates in Calendar widgets every minute
|
||||||
- Cleanup jest coverage for patches
|
- Cleanup jest coverage for patches
|
||||||
- Update `stylelint` dependencies, switch to `stylelint-config-standard` and handle `stylelint` issues
|
- Update `stylelint` dependencies, switch to `stylelint-config-standard` and handle `stylelint` issues
|
||||||
- Convert load callbacks to async/await
|
- Convert lots of callbacks to async/await
|
||||||
- Convert module start to async/await
|
|
||||||
- Convert translator callbacks to async/await
|
|
||||||
- Convert app-start/-stop callbacks to async/awaits
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
89
js/app.js
89
js/app.js
@ -152,9 +152,8 @@ function App() {
|
|||||||
* Loads a specific module.
|
* Loads a specific module.
|
||||||
*
|
*
|
||||||
* @param {string} module The name of the module (including subpath).
|
* @param {string} module The name of the module (including subpath).
|
||||||
* @param {Function} callback Function to be called after loading
|
|
||||||
*/
|
*/
|
||||||
function loadModule(module, callback) {
|
function loadModule(module) {
|
||||||
const elements = module.split("/");
|
const elements = module.split("/");
|
||||||
const moduleName = elements[elements.length - 1];
|
const moduleName = elements[elements.length - 1];
|
||||||
let moduleFolder = `${__dirname}/../modules/${module}`;
|
let moduleFolder = `${__dirname}/../modules/${module}`;
|
||||||
@ -199,39 +198,37 @@ function App() {
|
|||||||
m.setPath(path.resolve(moduleFolder));
|
m.setPath(path.resolve(moduleFolder));
|
||||||
nodeHelpers.push(m);
|
nodeHelpers.push(m);
|
||||||
|
|
||||||
m.loaded(callback);
|
m.loaded();
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all modules.
|
* Loads all modules.
|
||||||
*
|
*
|
||||||
* @param {Module[]} modules All modules to be loaded
|
* @param {string[]} modules All modules to be loaded
|
||||||
* @param {Function} callback Function to be called after loading
|
|
||||||
*/
|
*/
|
||||||
function loadModules(modules, callback) {
|
async function loadModules(modules) {
|
||||||
Log.log("Loading module helpers ...");
|
return new Promise((resolve) => {
|
||||||
|
Log.log("Loading module helpers ...");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function loadNextModule() {
|
function loadNextModule() {
|
||||||
if (modules.length > 0) {
|
if (modules.length > 0) {
|
||||||
const nextModule = modules[0];
|
const nextModule = modules[0];
|
||||||
loadModule(nextModule, function () {
|
loadModule(nextModule);
|
||||||
modules = modules.slice(1);
|
modules = modules.slice(1);
|
||||||
loadNextModule();
|
loadNextModule();
|
||||||
});
|
} else {
|
||||||
} else {
|
// All modules are loaded
|
||||||
// All modules are loaded
|
Log.log("All module helpers loaded.");
|
||||||
Log.log("All module helpers loaded.");
|
resolve();
|
||||||
callback();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
loadNextModule();
|
loadNextModule();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -272,43 +269,41 @@ function App() {
|
|||||||
Log.setLogLevel(config.logLevel);
|
Log.setLogLevel(config.logLevel);
|
||||||
|
|
||||||
let modules = [];
|
let modules = [];
|
||||||
|
|
||||||
for (const module of config.modules) {
|
for (const module of config.modules) {
|
||||||
if (!modules.includes(module.module) && !module.disabled) {
|
if (!modules.includes(module.module) && !module.disabled) {
|
||||||
modules.push(module.module);
|
modules.push(module.module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await loadModules(modules);
|
||||||
|
|
||||||
loadModules(modules, async function () {
|
httpServer = new Server(config);
|
||||||
httpServer = new Server(config);
|
const { app, io } = await httpServer.open();
|
||||||
const { app, io } = await httpServer.open();
|
Log.log("Server started ...");
|
||||||
Log.log("Server started ...");
|
|
||||||
|
|
||||||
const nodePromises = [];
|
const nodePromises = [];
|
||||||
for (let nodeHelper of nodeHelpers) {
|
for (let nodeHelper of nodeHelpers) {
|
||||||
nodeHelper.setExpressApp(app);
|
nodeHelper.setExpressApp(app);
|
||||||
nodeHelper.setSocketIO(io);
|
nodeHelper.setSocketIO(io);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
nodePromises.push(nodeHelper.start());
|
nodePromises.push(nodeHelper.start());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`);
|
Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`);
|
||||||
Log.error(error);
|
Log.error(error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const results = await Promise.allSettled(nodePromises);
|
const results = await Promise.allSettled(nodePromises);
|
||||||
|
|
||||||
// Log errors that happened during async node_helper startup
|
// Log errors that happened during async node_helper startup
|
||||||
results.forEach((result) => {
|
results.forEach((result) => {
|
||||||
if (result.status === "rejected") {
|
if (result.status === "rejected") {
|
||||||
Log.error(result.reason);
|
Log.error(result.reason);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
Log.log("Sockets connected & modules started ...");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Log.log("Sockets connected & modules started ...");
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
141
js/loader.js
141
js/loader.js
@ -16,37 +16,9 @@ const Loader = (function () {
|
|||||||
/* Private Methods */
|
/* Private Methods */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loops thru all modules and requests load for every module.
|
* Loops through all modules and requests start for every module.
|
||||||
*/
|
*/
|
||||||
const loadModules = function () {
|
const startModules = async function () {
|
||||||
let moduleData = getModuleData();
|
|
||||||
|
|
||||||
const loadNextModule = function () {
|
|
||||||
if (moduleData.length > 0) {
|
|
||||||
const nextModule = moduleData[0];
|
|
||||||
loadModule(nextModule, function () {
|
|
||||||
moduleData = moduleData.slice(1);
|
|
||||||
loadNextModule();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// All modules loaded. Load custom.css
|
|
||||||
// This is done after all the modules so we can
|
|
||||||
// overwrite all the defined styles.
|
|
||||||
|
|
||||||
loadFile(config.customCss).then(() => {
|
|
||||||
// custom.css loaded. Start all modules.
|
|
||||||
startModules();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
loadNextModule();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loops thru all modules and requests start for every module.
|
|
||||||
*/
|
|
||||||
const startModules = function () {
|
|
||||||
const modulePromises = [];
|
const modulePromises = [];
|
||||||
for (const module of moduleObjects) {
|
for (const module of moduleObjects) {
|
||||||
try {
|
try {
|
||||||
@ -57,25 +29,25 @@ const Loader = (function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.allSettled(modulePromises).then((results) => {
|
const results = await Promise.allSettled(modulePromises);
|
||||||
// Log errors that happened during async node_helper startup
|
|
||||||
results.forEach((result) => {
|
|
||||||
if (result.status === "rejected") {
|
|
||||||
Log.error(result.reason);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Notify core of loaded modules.
|
// Log errors that happened during async node_helper startup
|
||||||
MM.modulesStarted(moduleObjects);
|
results.forEach((result) => {
|
||||||
|
if (result.status === "rejected") {
|
||||||
// Starting modules also hides any modules that have requested to be initially hidden
|
Log.error(result.reason);
|
||||||
for (const thisModule of moduleObjects) {
|
|
||||||
if (thisModule.data.hiddenOnStartup) {
|
|
||||||
Log.info("Initially hiding " + thisModule.name);
|
|
||||||
thisModule.hide();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Notify core of loaded modules.
|
||||||
|
MM.modulesStarted(moduleObjects);
|
||||||
|
|
||||||
|
// Starting modules also hides any modules that have requested to be initially hidden
|
||||||
|
for (const thisModule of moduleObjects) {
|
||||||
|
if (thisModule.data.hiddenOnStartup) {
|
||||||
|
Log.info("Initially hiding " + thisModule.name);
|
||||||
|
thisModule.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -130,32 +102,30 @@ const Loader = (function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load modules via ajax request and create module objects.s
|
* Load modules via ajax request and create module objects.
|
||||||
*
|
*
|
||||||
* @param {object} module Information about the module we want to load.
|
* @param {object} module Information about the module we want to load.
|
||||||
* @param {Function} callback Function called when done.
|
* @returns {Promise<void>} resolved when module is loaded
|
||||||
*/
|
*/
|
||||||
const loadModule = function (module, callback) {
|
const loadModule = async function (module) {
|
||||||
const url = module.path + module.file;
|
const url = module.path + module.file;
|
||||||
|
|
||||||
const afterLoad = function () {
|
/**
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
const afterLoad = async function () {
|
||||||
const moduleObject = Module.create(module.name);
|
const moduleObject = Module.create(module.name);
|
||||||
if (moduleObject) {
|
if (moduleObject) {
|
||||||
bootstrapModule(module, moduleObject, function () {
|
await bootstrapModule(module, moduleObject);
|
||||||
callback();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (loadedModuleFiles.indexOf(url) !== -1) {
|
if (loadedModuleFiles.indexOf(url) !== -1) {
|
||||||
afterLoad();
|
await afterLoad();
|
||||||
} else {
|
} else {
|
||||||
loadFile(url).then(() => {
|
await loadFile(url);
|
||||||
loadedModuleFiles.push(url);
|
loadedModuleFiles.push(url);
|
||||||
afterLoad();
|
await afterLoad();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,24 +134,21 @@ const Loader = (function () {
|
|||||||
*
|
*
|
||||||
* @param {object} module Information about the module we want to load.
|
* @param {object} module Information about the module we want to load.
|
||||||
* @param {Module} mObj Modules instance.
|
* @param {Module} mObj Modules instance.
|
||||||
* @param {Function} callback Function called when done.
|
|
||||||
*/
|
*/
|
||||||
const bootstrapModule = function (module, mObj, callback) {
|
const bootstrapModule = async function (module, mObj) {
|
||||||
Log.info("Bootstrapping module: " + module.name);
|
Log.info("Bootstrapping module: " + module.name);
|
||||||
|
|
||||||
mObj.setData(module);
|
mObj.setData(module);
|
||||||
|
|
||||||
mObj.loadScripts().then(() => {
|
await mObj.loadScripts();
|
||||||
Log.log("Scripts loaded for: " + module.name);
|
Log.log("Scripts loaded for: " + module.name);
|
||||||
mObj.loadStyles().then(() => {
|
|
||||||
Log.log("Styles loaded for: " + module.name);
|
await mObj.loadStyles();
|
||||||
mObj.loadTranslations().then(() => {
|
Log.log("Styles loaded for: " + module.name);
|
||||||
Log.log("Translations loaded for: " + module.name);
|
|
||||||
moduleObjects.push(mObj);
|
await mObj.loadTranslations();
|
||||||
callback();
|
Log.log("Translations loaded for: " + module.name);
|
||||||
});
|
|
||||||
});
|
moduleObjects.push(mObj);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,8 +202,28 @@ const Loader = (function () {
|
|||||||
/**
|
/**
|
||||||
* Load all modules as defined in the config.
|
* Load all modules as defined in the config.
|
||||||
*/
|
*/
|
||||||
loadModules: function () {
|
loadModules: async function () {
|
||||||
loadModules();
|
let moduleData = getModuleData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<void>} when all modules are loaded
|
||||||
|
*/
|
||||||
|
const loadNextModule = async function () {
|
||||||
|
if (moduleData.length > 0) {
|
||||||
|
const nextModule = moduleData[0];
|
||||||
|
await loadModule(nextModule);
|
||||||
|
moduleData = moduleData.slice(1);
|
||||||
|
await loadNextModule();
|
||||||
|
} else {
|
||||||
|
// All modules loaded. Load custom.css
|
||||||
|
// This is done after all the modules so we can
|
||||||
|
// overwrite all the defined styles.
|
||||||
|
await loadFile(config.customCss);
|
||||||
|
// custom.css loaded. Start all modules.
|
||||||
|
await startModules();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
await loadNextModule();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -250,7 +237,7 @@ const Loader = (function () {
|
|||||||
loadFileForModule: async function (fileName, module) {
|
loadFileForModule: async function (fileName, module) {
|
||||||
if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) {
|
if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) {
|
||||||
Log.log("File already loaded: " + fileName);
|
Log.log("File already loaded: " + fileName);
|
||||||
return Promise.resolve();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileName.indexOf("http://") === 0 || fileName.indexOf("https://") === 0 || fileName.indexOf("/") !== -1) {
|
if (fileName.indexOf("http://") === 0 || fileName.indexOf("https://") === 0 || fileName.indexOf("/") !== -1) {
|
||||||
|
@ -479,13 +479,14 @@ const MM = (function () {
|
|||||||
/**
|
/**
|
||||||
* Main init method.
|
* Main init method.
|
||||||
*/
|
*/
|
||||||
init: function () {
|
init: async function () {
|
||||||
Log.info("Initializing MagicMirror².");
|
Log.info("Initializing MagicMirror².");
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
|
||||||
Log.setLogLevel(config.logLevel);
|
Log.setLogLevel(config.logLevel);
|
||||||
|
|
||||||
Translator.loadCoreTranslations(config.language).then(() => Loader.loadModules());
|
await Translator.loadCoreTranslations(config.language);
|
||||||
|
await Loader.loadModules();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,7 @@ const Module = Class.extend({
|
|||||||
// visibility when hiding and showing module.
|
// visibility when hiding and showing module.
|
||||||
lockStrings: [],
|
lockStrings: [],
|
||||||
|
|
||||||
// Storage of the nunjuck Environment,
|
// Storage of the nunjucks Environment,
|
||||||
// This should not be referenced directly.
|
// This should not be referenced directly.
|
||||||
// Use the nunjucksEnvironment() to get it.
|
// Use the nunjucksEnvironment() to get it.
|
||||||
_nunjucksEnvironment: null,
|
_nunjucksEnvironment: null,
|
||||||
@ -302,7 +302,7 @@ const Module = Class.extend({
|
|||||||
/**
|
/**
|
||||||
* Load all translations.
|
* Load all translations.
|
||||||
*/
|
*/
|
||||||
async loadTranslations() {
|
loadTranslations: async function () {
|
||||||
const translations = this.getTranslations() || {};
|
const translations = this.getTranslations() || {};
|
||||||
const language = config.language.toLowerCase();
|
const language = config.language.toLowerCase();
|
||||||
|
|
||||||
|
@ -13,9 +13,8 @@ const NodeHelper = Class.extend({
|
|||||||
Log.log("Initializing new module helper ...");
|
Log.log("Initializing new module helper ...");
|
||||||
},
|
},
|
||||||
|
|
||||||
loaded(callback) {
|
loaded() {
|
||||||
Log.log(`Module helper loaded: ${this.name}`);
|
Log.log(`Module helper loaded: ${this.name}`);
|
||||||
callback();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
|
@ -9,6 +9,9 @@ const path = require("path");
|
|||||||
const ipfilter = require("express-ipfilter").IpFilter;
|
const ipfilter = require("express-ipfilter").IpFilter;
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const helmet = require("helmet");
|
const helmet = require("helmet");
|
||||||
|
const socketio = require("socket.io");
|
||||||
|
const http = require("http");
|
||||||
|
const https = require("https");
|
||||||
|
|
||||||
const Log = require("logger");
|
const Log = require("logger");
|
||||||
const Utils = require("./utils.js");
|
const Utils = require("./utils.js");
|
||||||
@ -38,11 +41,11 @@ function Server(config) {
|
|||||||
key: fs.readFileSync(config.httpsPrivateKey),
|
key: fs.readFileSync(config.httpsPrivateKey),
|
||||||
cert: fs.readFileSync(config.httpsCertificate)
|
cert: fs.readFileSync(config.httpsCertificate)
|
||||||
};
|
};
|
||||||
server = require("https").Server(options, app);
|
server = https.Server(options, app);
|
||||||
} else {
|
} else {
|
||||||
server = require("http").Server(app);
|
server = http.Server(app);
|
||||||
}
|
}
|
||||||
const io = require("socket.io")(server, {
|
const io = socketio(server, {
|
||||||
cors: {
|
cors: {
|
||||||
origin: /.*$/,
|
origin: /.*$/,
|
||||||
credentials: true
|
credentials: true
|
||||||
|
2191
package-lock.json
generated
2191
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@ -51,31 +51,31 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint-config-prettier": "^8.6.0",
|
"eslint-config-prettier": "^8.6.0",
|
||||||
"eslint-plugin-jest": "^27.2.1",
|
"eslint-plugin-jest": "^27.2.1",
|
||||||
"eslint-plugin-jsdoc": "^39.8.0",
|
"eslint-plugin-jsdoc": "^40.0.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"express-basic-auth": "^1.2.1",
|
"express-basic-auth": "^1.2.1",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"jest": "^29.4.2",
|
"jest": "^29.4.3",
|
||||||
"jsdom": "^21.1.0",
|
"jsdom": "^21.1.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"playwright": "^1.30.0",
|
"playwright": "^1.31.1",
|
||||||
"prettier": "^2.8.4",
|
"prettier": "^2.8.4",
|
||||||
"pretty-quick": "^3.1.3",
|
"pretty-quick": "^3.1.3",
|
||||||
"sinon": "^15.0.1",
|
"sinon": "^15.0.1",
|
||||||
"stylelint": "^15.1.0",
|
"stylelint": "^15.2.0",
|
||||||
"stylelint-config-standard": "^30.0.1",
|
"stylelint-config-standard": "^30.0.1",
|
||||||
"stylelint-prettier": "^2.0.0",
|
"stylelint-prettier": "^3.0.0",
|
||||||
"suncalc": "^1.9.0"
|
"suncalc": "^1.9.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"electron": "^22.2.0"
|
"electron": "^22.3.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"console-stamp": "^3.1.0",
|
"console-stamp": "^3.1.1",
|
||||||
"digest-fetch": "^2.0.1",
|
"digest-fetch": "^2.0.1",
|
||||||
"envsub": "^4.1.0",
|
"envsub": "^4.1.0",
|
||||||
"eslint": "^8.33.0",
|
"eslint": "^8.35.0",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-ipfilter": "^1.3.1",
|
"express-ipfilter": "^1.3.1",
|
||||||
"feedme": "^2.0.2",
|
"feedme": "^2.0.2",
|
||||||
@ -86,7 +86,7 @@
|
|||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"node-fetch": "^2.6.9",
|
"node-fetch": "^2.6.9",
|
||||||
"node-ical": "^0.15.3",
|
"node-ical": "^0.15.3",
|
||||||
"socket.io": "^4.6.0"
|
"socket.io": "^4.6.1"
|
||||||
},
|
},
|
||||||
"_moduleAliases": {
|
"_moduleAliases": {
|
||||||
"node_helper": "js/node_helper.js",
|
"node_helper": "js/node_helper.js",
|
||||||
|
@ -13,7 +13,7 @@ describe("Electron app environment", () => {
|
|||||||
it("should open browserwindow", async () => {
|
it("should open browserwindow", async () => {
|
||||||
const module = await helpers.getElement("#module_0_helloworld");
|
const module = await helpers.getElement("#module_0_helloworld");
|
||||||
expect(await module.textContent()).toContain("Test Display Header");
|
expect(await module.textContent()).toContain("Test Display Header");
|
||||||
expect(await global.electronApp.windows().length).toBe(1);
|
expect(global.electronApp.windows().length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
18
vendor/package-lock.json
generated
vendored
18
vendor/package-lock.json
generated
vendored
@ -9,7 +9,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.3.0",
|
"@fortawesome/fontawesome-free": "^6.3.0",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"moment-timezone": "^0.5.40",
|
"moment-timezone": "^0.5.41",
|
||||||
"nunjucks": "^3.2.3",
|
"nunjucks": "^3.2.3",
|
||||||
"suncalc": "^1.9.0",
|
"suncalc": "^1.9.0",
|
||||||
"weathericons": "^2.1.0"
|
"weathericons": "^2.1.0"
|
||||||
@ -51,11 +51,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/moment-timezone": {
|
"node_modules/moment-timezone": {
|
||||||
"version": "0.5.40",
|
"version": "0.5.41",
|
||||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.40.tgz",
|
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.41.tgz",
|
||||||
"integrity": "sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==",
|
"integrity": "sha512-e0jGNZDOHfBXJGz8vR/sIMXvBIGJJcqFjmlg9lmE+5KX1U7/RZNMswfD8nKnNCnQdKTIj50IaRKwl1fvMLyyRg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"moment": ">= 2.9.0"
|
"moment": "^2.29.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": "*"
|
||||||
@ -123,11 +123,11 @@
|
|||||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||||
},
|
},
|
||||||
"moment-timezone": {
|
"moment-timezone": {
|
||||||
"version": "0.5.40",
|
"version": "0.5.41",
|
||||||
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.40.tgz",
|
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.41.tgz",
|
||||||
"integrity": "sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==",
|
"integrity": "sha512-e0jGNZDOHfBXJGz8vR/sIMXvBIGJJcqFjmlg9lmE+5KX1U7/RZNMswfD8nKnNCnQdKTIj50IaRKwl1fvMLyyRg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"moment": ">= 2.9.0"
|
"moment": "^2.29.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nunjucks": {
|
"nunjucks": {
|
||||||
|
2
vendor/package.json
vendored
2
vendor/package.json
vendored
@ -12,7 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.3.0",
|
"@fortawesome/fontawesome-free": "^6.3.0",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"moment-timezone": "^0.5.40",
|
"moment-timezone": "^0.5.41",
|
||||||
"nunjucks": "^3.2.3",
|
"nunjucks": "^3.2.3",
|
||||||
"suncalc": "^1.9.0",
|
"suncalc": "^1.9.0",
|
||||||
"weathericons": "^2.1.0"
|
"weathericons": "^2.1.0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user