mirror of
https://github.com/eliasrenman/gardentron.git
synced 2026-03-16 20:46:07 +01:00
fix: fixing server issues
This commit is contained in:
@@ -71,11 +71,11 @@ def get_body(request: str):
|
|||||||
for index in range(len(req)):
|
for index in range(len(req)):
|
||||||
item = req[index]
|
item = req[index]
|
||||||
|
|
||||||
if item.find("Content-Type") != -1:
|
if item.lower().find("content-type") != -1:
|
||||||
if not item.find("application/json"):
|
if not item.find("application/json"):
|
||||||
return
|
return
|
||||||
|
|
||||||
if item.find("Content-Length") != -1:
|
if item.lower().find("content-length") != -1:
|
||||||
content_length_index = index
|
content_length_index = index
|
||||||
|
|
||||||
if index > content_length_index:
|
if index > content_length_index:
|
||||||
@@ -83,6 +83,7 @@ def get_body(request: str):
|
|||||||
out = out.replace("\n", "")
|
out = out.replace("\n", "")
|
||||||
out = out.replace("\t", "")
|
out = out.replace("\t", "")
|
||||||
|
|
||||||
|
print("Output", out)
|
||||||
if out != "":
|
if out != "":
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|||||||
1027
server/package-lock.json
generated
Normal file
1027
server/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -19,10 +19,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^4.14.1",
|
"@prisma/client": "^4.14.1",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
"eventemitter2": "^6.4.9",
|
"eventemitter2": "^6.4.9",
|
||||||
"node-cron": "^3.0.2",
|
"node-cron": "^3.0.2",
|
||||||
"prisma": "^4.14.1",
|
"prisma": "^4.14.1",
|
||||||
"queue": "^7.0.0",
|
"queue": "^6.0.2",
|
||||||
"socket.io": "^4.6.1"
|
"socket.io": "^4.6.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
export const BASE_URL = process.env.IOT_BASE_URL;
|
||||||
export const iotClient = axios.create({
|
export const iotClient = axios.create({
|
||||||
baseURL: process.env.IOT_BASE_URL,
|
baseURL: BASE_URL,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,9 +10,5 @@ export type MoistureReading = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type MoistureResponse = {
|
export type MoistureResponse = {
|
||||||
data: {
|
data: MoistureReading[];
|
||||||
sensor_0: MoistureReading;
|
|
||||||
sensor_1: MoistureReading;
|
|
||||||
sensor_2: MoistureReading;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { startServer } from "./server";
|
import { startServer } from "./server";
|
||||||
import { prisma } from "./prisma";
|
import { prisma } from "./prisma";
|
||||||
|
import { config } from "dotenv";
|
||||||
|
config();
|
||||||
|
|
||||||
startServer()
|
startServer()
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
|
|||||||
@@ -1,43 +1,59 @@
|
|||||||
import Queue from "queue";
|
import Queue from "queue";
|
||||||
import { Prisma } from "@prisma/client";
|
|
||||||
import { iotClient } from "../axios/iot.axios";
|
import { iotClient } from "../axios/iot.axios";
|
||||||
import { MositureRow, readMoistureLevels } from "../cron";
|
|
||||||
import { config } from "../config";
|
import { config } from "../config";
|
||||||
|
import { MositureRow, readMoistureLevels } from "../cron";
|
||||||
import { emitter } from "../eventemitter";
|
import { emitter } from "../eventemitter";
|
||||||
|
|
||||||
const queue = new Queue({ results: [] });
|
const queue = new Queue({ results: [], concurrency: 1 });
|
||||||
|
|
||||||
queue.start().then((result) => console.log("Successfully started queue"));
|
queue.start((result) => console.log("Successfully started queue"));
|
||||||
|
|
||||||
export function checkReadingAndEnqueue(rows: MositureRow[]) {
|
export function checkReadingAndEnqueue(rows: MositureRow[]) {
|
||||||
rows.forEach((row) => {
|
rows
|
||||||
|
.sort((a, b) => +a.name)
|
||||||
|
.forEach((row) => {
|
||||||
// Read config for threshold values
|
// Read config for threshold values
|
||||||
const threshold = config.config.moisture.thresholds.lower[row.name];
|
const threshold =
|
||||||
|
config.config.moisture.thresholds.lower["sensor_" + row.name];
|
||||||
|
console.log(
|
||||||
|
row.value.toNumber() >= threshold,
|
||||||
|
row.value.toNumber(),
|
||||||
|
threshold,
|
||||||
|
config.config.moisture.thresholds.lower,
|
||||||
|
row.name
|
||||||
|
);
|
||||||
// Conclude which sensors need watering.
|
// Conclude which sensors need watering.
|
||||||
if (row.value.toNumber() >= threshold) {
|
if (row.value.toNumber() <= threshold) {
|
||||||
console.log(`Enqueing ${row.name}`);
|
console.log(`Enqueing ${row.name}`);
|
||||||
// Enqueue relevant sensors
|
// Enqueue relevant sensors
|
||||||
queue.push(() => process(row));
|
queue.push((cb) =>
|
||||||
|
process(row)
|
||||||
|
.then((val) => cb && cb(undefined, val!))
|
||||||
|
.catch((err) => cb && cb(err!))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
queue.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function process(row: MositureRow) {
|
async function process(row: MositureRow) {
|
||||||
console.log("Started processing of", row.name);
|
console.log("Started processing of", row.name);
|
||||||
const index = row.name.replace(/[^0-9]/g, "");
|
const index = row.name;
|
||||||
try {
|
try {
|
||||||
// Enable water gate
|
// Enable water gate
|
||||||
await toggleWater(index, true);
|
await toggleWater(index, true);
|
||||||
|
await sleep(10 * 1000);
|
||||||
// Check moisture level once per second for configured time
|
// Check moisture level once per second for configured time
|
||||||
await Promise.race([
|
await Promise.race([
|
||||||
sleep(config.config.timeout * 1000),
|
sleep(config.config.timeout * 1000),
|
||||||
timeoutCb(row.name, row.value.toNumber()),
|
timeoutCb(row.name, row.value.toNumber()),
|
||||||
]);
|
]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`Failed to processing of ${row.name}`, e);
|
console.log(`Failed to processing of ${row.name}`);
|
||||||
|
console.log(e);
|
||||||
} finally {
|
} finally {
|
||||||
// Finally turn of the water gate
|
// Finally turn of the water gate
|
||||||
toggleWater(index, false);
|
await toggleWater(index, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function timeoutCb(name: string, initalRead: number): Promise<void> {
|
async function timeoutCb(name: string, initalRead: number): Promise<void> {
|
||||||
@@ -46,14 +62,18 @@ async function timeoutCb(name: string, initalRead: number): Promise<void> {
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
throw Error(`Failed getting a moisture level reading for ${name}`);
|
throw Error(`Failed getting a moisture level reading for ${name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(name in data.data)) {
|
if (!(name in data.data)) {
|
||||||
throw Error(
|
throw Error(
|
||||||
`Recieved invalid response for mosisture level reading for ${name}`
|
`Recieved invalid response for mosisture level reading for ${name}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const reading = data.data[name as "sensor_0"].precentage;
|
|
||||||
|
const reading = data.data[+name].precentage;
|
||||||
const lowerThreshold = initalRead + config.config.threshold;
|
const lowerThreshold = initalRead + config.config.threshold;
|
||||||
|
console.log(lowerThreshold, reading);
|
||||||
if (lowerThreshold >= reading) {
|
if (lowerThreshold >= reading) {
|
||||||
|
console.log("Water low warning!");
|
||||||
// Trigger the low water alarm
|
// Trigger the low water alarm
|
||||||
queue.end(Error("Water level low"));
|
queue.end(Error("Water level low"));
|
||||||
// Update the configuration
|
// Update the configuration
|
||||||
@@ -66,9 +86,12 @@ async function timeoutCb(name: string, initalRead: number): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const upperThreshold =
|
const upperThreshold =
|
||||||
initalRead + config.config.moisture.thresholds.upper[name as "sensor_0"];
|
initalRead +
|
||||||
|
config.config.moisture.thresholds.upper[("sensor_" + name) as "sensor_0"];
|
||||||
if (reading >= upperThreshold) {
|
if (reading >= upperThreshold) {
|
||||||
console.log(`Successfully upped the moisture level for ${name}`);
|
console.log(
|
||||||
|
`Successfully upped the moisture level for ${"sensor_" + name}`
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If moisture level reaches upper threshold then cancel out of the checking loop
|
// If moisture level reaches upper threshold then cancel out of the checking loop
|
||||||
@@ -78,10 +101,18 @@ async function timeoutCb(name: string, initalRead: number): Promise<void> {
|
|||||||
|
|
||||||
function toggleWater(index: string, on: boolean) {
|
function toggleWater(index: string, on: boolean) {
|
||||||
return iotClient
|
return iotClient
|
||||||
.post(`relay/${on ? "activate" : "deactivate"}`, {
|
.post(`/relay/${on ? "activate" : "deactivate"}`, {
|
||||||
relay: index,
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ relay: +index }),
|
||||||
})
|
})
|
||||||
.then((item) => ({ on: true }));
|
.then(async (item) => {
|
||||||
|
console.log(`Successfully ${on ? "activate" : "deactivate"}d water gate`);
|
||||||
|
return { on };
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/node-cron/-/node-cron-3.0.7.tgz"
|
resolved "https://registry.npmjs.org/@types/node-cron/-/node-cron-3.0.7.tgz"
|
||||||
integrity sha512-9PuLtBboc/+JJ7FshmJWv769gDonTpItN0Ol5TMwclpSQNjVyB2SRxSKBcTtbSysSL5R7Oea06kTTFNciCoYwA==
|
integrity sha512-9PuLtBboc/+JJ7FshmJWv769gDonTpItN0Ol5TMwclpSQNjVyB2SRxSKBcTtbSysSL5R7Oea06kTTFNciCoYwA==
|
||||||
|
|
||||||
"@types/node@*", "@types/node@>=10.0.0", "@types/node@^20.2.1":
|
"@types/node@*", "@types/node@^20.2.1", "@types/node@>=10.0.0":
|
||||||
version "20.2.1"
|
version "20.2.1"
|
||||||
resolved "https://registry.npmjs.org/@types/node/-/node-20.2.1.tgz"
|
resolved "https://registry.npmjs.org/@types/node/-/node-20.2.1.tgz"
|
||||||
integrity sha512-DqJociPbZP1lbZ5SQPk4oag6W7AyaGMO6gSfRwq3PWl4PXTwJpRQJhDq4W0kzrg3w6tJ1SwlvGZ5uKFHY13LIg==
|
integrity sha512-DqJociPbZP1lbZ5SQPk4oag6W7AyaGMO6gSfRwq3PWl4PXTwJpRQJhDq4W0kzrg3w6tJ1SwlvGZ5uKFHY13LIg==
|
||||||
@@ -146,7 +146,7 @@ balanced-match@^1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
|
||||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
base64id@2.0.0, base64id@~2.0.0:
|
base64id@~2.0.0, base64id@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz"
|
resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz"
|
||||||
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
|
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
|
||||||
@@ -240,6 +240,11 @@ diff@^4.0.1:
|
|||||||
resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz"
|
resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz"
|
||||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||||
|
|
||||||
|
dotenv@^16.3.1:
|
||||||
|
version "16.3.1"
|
||||||
|
resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz"
|
||||||
|
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
|
||||||
|
|
||||||
engine.io-parser@~5.0.3:
|
engine.io-parser@~5.0.3:
|
||||||
version "5.0.6"
|
version "5.0.6"
|
||||||
resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz"
|
resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz"
|
||||||
@@ -287,11 +292,6 @@ form-data@^4.0.0:
|
|||||||
combined-stream "^1.0.8"
|
combined-stream "^1.0.8"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
fsevents@~2.3.2:
|
|
||||||
version "2.3.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
|
||||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
|
||||||
|
|
||||||
glob-parent@~5.1.2:
|
glob-parent@~5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
|
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
|
||||||
@@ -309,6 +309,11 @@ ignore-by-default@^1.0.1:
|
|||||||
resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz"
|
resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz"
|
||||||
integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==
|
integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==
|
||||||
|
|
||||||
|
inherits@~2.0.3:
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
||||||
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
|
|
||||||
is-binary-path@~2.1.0:
|
is-binary-path@~2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
|
resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
|
||||||
@@ -357,16 +362,16 @@ minimatch@^3.1.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
ms@2.1.2:
|
|
||||||
version "2.1.2"
|
|
||||||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
|
|
||||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
|
||||||
|
|
||||||
ms@^2.1.1:
|
ms@^2.1.1:
|
||||||
version "2.1.3"
|
version "2.1.3"
|
||||||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
|
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
|
||||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||||
|
|
||||||
|
ms@2.1.2:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
|
||||||
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
negotiator@0.6.3:
|
negotiator@0.6.3:
|
||||||
version "0.6.3"
|
version "0.6.3"
|
||||||
resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
|
resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
|
||||||
@@ -417,7 +422,7 @@ picomatch@^2.0.4, picomatch@^2.2.1:
|
|||||||
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
|
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
|
||||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||||
|
|
||||||
prisma@^4.14.1:
|
prisma@*, prisma@^4.14.1:
|
||||||
version "4.14.1"
|
version "4.14.1"
|
||||||
resolved "https://registry.npmjs.org/prisma/-/prisma-4.14.1.tgz"
|
resolved "https://registry.npmjs.org/prisma/-/prisma-4.14.1.tgz"
|
||||||
integrity sha512-z6hxzTMYqT9SIKlzD08dhzsLUpxjFKKsLpp5/kBDnSqiOjtUyyl/dC5tzxLcOa3jkEHQ8+RpB/fE3w8bgNP51g==
|
integrity sha512-z6hxzTMYqT9SIKlzD08dhzsLUpxjFKKsLpp5/kBDnSqiOjtUyyl/dC5tzxLcOa3jkEHQ8+RpB/fE3w8bgNP51g==
|
||||||
@@ -434,10 +439,12 @@ pstree.remy@^1.1.8:
|
|||||||
resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz"
|
resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz"
|
||||||
integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
|
integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
|
||||||
|
|
||||||
queue@^7.0.0:
|
queue@^6.0.2:
|
||||||
version "7.0.0"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/queue/-/queue-7.0.0.tgz#2f43841ac492a4848007089810702704f5b2c4ae"
|
resolved "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz"
|
||||||
integrity sha512-sphwS7HdfQnvrJAXUNAUgpf9H/546IE3p/5Lf2jr71O4udEYlqAhkevykumas2FYuMkX/29JMOgrRdRoYZ/X9w==
|
integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==
|
||||||
|
dependencies:
|
||||||
|
inherits "~2.0.3"
|
||||||
|
|
||||||
readdirp@~3.6.0:
|
readdirp@~3.6.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
@@ -530,7 +537,7 @@ ts-node@^10.9.1:
|
|||||||
v8-compile-cache-lib "^3.0.1"
|
v8-compile-cache-lib "^3.0.1"
|
||||||
yn "3.1.1"
|
yn "3.1.1"
|
||||||
|
|
||||||
typescript@^5.0.4:
|
typescript@^5.0.4, typescript@>=2.7:
|
||||||
version "5.0.4"
|
version "5.0.4"
|
||||||
resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz"
|
resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz"
|
||||||
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
|
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
|
||||||
|
|||||||
Reference in New Issue
Block a user