22
backend/db/schema/dockdoor.schema.ts
Normal file
22
backend/db/schema/dockdoor.schema.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { boolean, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import type { z } from "zod";
|
||||
|
||||
export const dockDoorScanners = pgTable("dock_door_scanners", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
ip: text("ip").notNull(),
|
||||
name: text("name").unique(),
|
||||
dockId: text("dock_id"),
|
||||
active: boolean("active").default(true),
|
||||
currentLoadingOrder: text("current_loading_order").default(""),
|
||||
add_date: timestamp("add_date").defaultNow(),
|
||||
add_user: text("add_user").default("lst-system"),
|
||||
upd_date: timestamp("upd_date").defaultNow(),
|
||||
upd_user: text("upd_user").default("lst-system"),
|
||||
});
|
||||
|
||||
export const dockDoorScannersSchema = createSelectSchema(dockDoorScanners);
|
||||
export const newDockDoorScannersSchema = createInsertSchema(dockDoorScanners);
|
||||
|
||||
export type DockDoorScanners = z.infer<typeof dockDoorScannersSchema>;
|
||||
export type NewDockDoorScanners = z.infer<typeof newDockDoorScannersSchema>;
|
||||
@@ -0,0 +1,35 @@
|
||||
import { addDays, subDays } from "date-fns";
|
||||
import { format } from "date-fns-tz";
|
||||
import { Router } from "express";
|
||||
import { runProdApi } from "../utils/prodEndpoint.utils.js";
|
||||
import { apiReturn } from "../utils/returnHelper.utils.js";
|
||||
|
||||
const r = Router();
|
||||
|
||||
r.get("/", async (_, res) => {
|
||||
const orders = await runProdApi({
|
||||
method: "post",
|
||||
endpoint: "/public/v1.0/OutboundDeliveries/LoadingOrders/Search",
|
||||
data: [
|
||||
{
|
||||
loadingDateFrom: format(subDays(new Date(Date.now()), 3), "yyyy-MM-dd"),
|
||||
loadingDateTo: format(addDays(new Date(Date.now()), 3), "yyyy-MM-dd"),
|
||||
states: [
|
||||
1, // planned
|
||||
],
|
||||
//isCommissioned: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
return apiReturn(res, {
|
||||
success: true,
|
||||
level: "info",
|
||||
module: "dockdoor",
|
||||
subModule: "current Active loading orders",
|
||||
message: `Current active loading loaders.`,
|
||||
data: orders?.data ?? [],
|
||||
status: 200,
|
||||
});
|
||||
});
|
||||
|
||||
export default r;
|
||||
18
backend/dockdoorScanning/dockdoor.closeLoadingOrder.route.ts
Normal file
18
backend/dockdoorScanning/dockdoor.closeLoadingOrder.route.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Router } from "express";
|
||||
import { apiReturn } from "../utils/returnHelper.utils.js";
|
||||
|
||||
const r = Router();
|
||||
|
||||
r.post("/", async (req, res) => {
|
||||
return apiReturn(res, {
|
||||
success: true,
|
||||
level: "info",
|
||||
module: "dockdoor",
|
||||
subModule: "lane check",
|
||||
message: `Release x is being closed now. the bol should come out at the default printer.`,
|
||||
data: req.body ?? [],
|
||||
status: 200,
|
||||
});
|
||||
});
|
||||
|
||||
export default r;
|
||||
89
backend/dockdoorScanning/dockdoor.loadUnits.ts
Normal file
89
backend/dockdoorScanning/dockdoor.loadUnits.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
// sends the units from the dock door scanner here.
|
||||
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/db.controller.js";
|
||||
import { dockDoorScanners } from "../db/schema/dockdoor.schema.js";
|
||||
import { runProdApi } from "../utils/prodEndpoint.utils.js";
|
||||
import { returnFunc } from "../utils/returnHelper.utils.js";
|
||||
|
||||
// validate we are active
|
||||
|
||||
type Data = {
|
||||
dockId?: string;
|
||||
sscc?: string;
|
||||
runningNr?: string;
|
||||
};
|
||||
|
||||
export const loadUnit = async (data: Data) => {
|
||||
// are we even active at this time?
|
||||
const dockDoorActive = await db.query.settings.findFirst({
|
||||
where: (u, { eq }) => eq(u.name, "dockDoorScanning"),
|
||||
});
|
||||
|
||||
if (!dockDoorActive?.active) {
|
||||
return returnFunc({
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "loadunit",
|
||||
message: "Dock door scanning feature is not active.",
|
||||
data: [],
|
||||
notify: false,
|
||||
room: "",
|
||||
});
|
||||
}
|
||||
// check if its a valids an sscc
|
||||
|
||||
if (data.sscc === "noread") {
|
||||
return returnFunc({
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "loadUnit",
|
||||
message:
|
||||
"Failed to load the unit to the truck, there was no pallet read.",
|
||||
data: [],
|
||||
notify: false,
|
||||
room: `dockDoorLoading${data.dockId}`,
|
||||
});
|
||||
}
|
||||
|
||||
// check if we currently have a loading order attached to the dock door.
|
||||
const dock = await db
|
||||
.select()
|
||||
.from(dockDoorScanners)
|
||||
.where(eq(dockDoorScanners.dockId, data.dockId as string));
|
||||
|
||||
if (dock[0]?.currentLoadingOrder === "") {
|
||||
return returnFunc({
|
||||
success: true,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "loadingOrders",
|
||||
message:
|
||||
"There are know current active loading orders please start one and try again.",
|
||||
data: [],
|
||||
notify: false,
|
||||
room: `dockDoorLoading${data.dockId}`,
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: pallet validation, check if we are on hold, then check if we have been in the staging warehouse for more than x time.
|
||||
|
||||
// if on hold stop the scan and send a bad read with the reason its on hold and what its on hold for, including coa.
|
||||
|
||||
// if precheck is active then check if we have a warehouse, then check if the pallet was in the warehouse for greater than the define min, all fails send a warning and still do the scan
|
||||
|
||||
// add the loading units
|
||||
try {
|
||||
const prod = await runProdApi({
|
||||
method: "post",
|
||||
endpoint: `/public/v1.0/OutboundDeliveries/LoadingOrders/${dock[0]?.currentLoadingOrder}/LoadUnit`,
|
||||
data: [{ sscc: data.sscc?.slice(2) }],
|
||||
});
|
||||
|
||||
console.log(prod?.data);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
43
backend/dockdoorScanning/dockdoor.routes.ts
Normal file
43
backend/dockdoorScanning/dockdoor.routes.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { Express } from "express";
|
||||
import { featureCheck } from "../middleware/featureActive.middleware.js";
|
||||
import activeLoadingOrders from "./dockdoor.activeLoadingOrders.route.js";
|
||||
import closeLoadingOrder from "./dockdoor.closeLoadingOrder.route.js";
|
||||
import startLoad from "./dockdoor.startLoad.route.js";
|
||||
import prodDocks from "./dockdoors.docks.route.js";
|
||||
import docks from "./dockdoors.route.js";
|
||||
|
||||
export const setupDockDoorRoutes = (baseUrl: string, app: Express) => {
|
||||
//stats will be like this as we dont need to change this
|
||||
|
||||
app.use(
|
||||
`${baseUrl}/api/dockDoor/scanners`,
|
||||
featureCheck("dockDoorScanning"),
|
||||
|
||||
docks,
|
||||
);
|
||||
|
||||
app.use(
|
||||
`${baseUrl}/api/dockDoor/closeLoadingOrder`,
|
||||
featureCheck("dockDoorScanning"),
|
||||
closeLoadingOrder,
|
||||
);
|
||||
app.use(
|
||||
`${baseUrl}/api/dockDoor/activeLoadingOrders`,
|
||||
featureCheck("dockDoorScanning"),
|
||||
activeLoadingOrders,
|
||||
);
|
||||
app.use(
|
||||
`${baseUrl}/api/dockDoor/startLoad`,
|
||||
featureCheck("dockDoorScanning"),
|
||||
startLoad,
|
||||
);
|
||||
app.use(
|
||||
`${baseUrl}/api/dockDoor/docks`,
|
||||
featureCheck("dockDoorScanning"),
|
||||
prodDocks,
|
||||
);
|
||||
|
||||
// TODO : add manual way to add pallets
|
||||
|
||||
// all other system should be under /api/system/*
|
||||
};
|
||||
65
backend/dockdoorScanning/dockdoor.startLoad.route.ts
Normal file
65
backend/dockdoorScanning/dockdoor.startLoad.route.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { Router } from "express";
|
||||
import z from "zod";
|
||||
import { db } from "../db/db.controller.js";
|
||||
import { dockDoorScanners } from "../db/schema/dockdoor.schema.js";
|
||||
import { apiReturn } from "../utils/returnHelper.utils.js";
|
||||
import { tryCatch } from "../utils/trycatch.utils.js";
|
||||
|
||||
const r = Router();
|
||||
|
||||
const startLoading = z.object({
|
||||
loadingOrder: z.string(),
|
||||
dockId: z.string(),
|
||||
});
|
||||
|
||||
r.post("/", async (req, res) => {
|
||||
try {
|
||||
const validated = startLoading.parse(req.body);
|
||||
|
||||
const { data, error } = await tryCatch(
|
||||
db
|
||||
.update(dockDoorScanners)
|
||||
.set({
|
||||
currentLoadingOrder: validated.loadingOrder,
|
||||
upd_date: sql`NOW()`,
|
||||
upd_user: req.user?.username,
|
||||
})
|
||||
.returning(),
|
||||
);
|
||||
|
||||
if (error) {
|
||||
return apiReturn(res, {
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "loadingOrder",
|
||||
message: `Failed to updating the dock.`,
|
||||
data: (error as any) ?? [],
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
return apiReturn(res, {
|
||||
success: true,
|
||||
level: "info",
|
||||
module: "dockdoor",
|
||||
subModule: "loadingOrder",
|
||||
message: `Loading order ${validated.loadingOrder} was just added to dockId ${validated.dockId}.`,
|
||||
data: data ?? [],
|
||||
status: 200,
|
||||
});
|
||||
} catch (error) {
|
||||
return apiReturn(res, {
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "loadingOrder",
|
||||
message: `Failed to start loading order.`,
|
||||
data: (error as any) ?? [],
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default r;
|
||||
54
backend/dockdoorScanning/dockdoors.docks.route.ts
Normal file
54
backend/dockdoorScanning/dockdoors.docks.route.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Router } from "express";
|
||||
import { prodQuery } from "../prodSql/prodSqlQuery.controller.js";
|
||||
import {
|
||||
type SqlQuery,
|
||||
sqlQuerySelector,
|
||||
} from "../prodSql/prodSqlQuerySelector.utils.js";
|
||||
import { apiReturn } from "../utils/returnHelper.utils.js";
|
||||
import { tryCatch } from "../utils/trycatch.utils.js";
|
||||
|
||||
const r = Router();
|
||||
|
||||
r.get("/", async (_, res) => {
|
||||
const activeDocks = sqlQuerySelector(`outbound.docks`) as SqlQuery;
|
||||
|
||||
if (!activeDocks.success) {
|
||||
return apiReturn(res, {
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "docks",
|
||||
message: `There was an error getting the docks query.`,
|
||||
data: [],
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
const { data, error } = await tryCatch(
|
||||
prodQuery(activeDocks.query, "Current Active Docks"),
|
||||
);
|
||||
|
||||
if (error) {
|
||||
return apiReturn(res, {
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "newDock",
|
||||
message: `There was an error getting the docks.`,
|
||||
data: (error as any) ?? ([] as any),
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
return apiReturn(res, {
|
||||
success: true,
|
||||
level: "info",
|
||||
module: "dockdoor",
|
||||
subModule: "docks",
|
||||
message: `Current active docks.`,
|
||||
data: (data.data as any) ?? ([] as any),
|
||||
status: 200,
|
||||
});
|
||||
});
|
||||
|
||||
export default r;
|
||||
76
backend/dockdoorScanning/dockdoors.route.ts
Normal file
76
backend/dockdoorScanning/dockdoors.route.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { Router } from "express";
|
||||
import z from "zod";
|
||||
import { db } from "../db/db.controller.js";
|
||||
import { dockDoorScanners } from "../db/schema/dockdoor.schema.js";
|
||||
import { requireAuth } from "../middleware/auth.middleware.js";
|
||||
import { apiReturn } from "../utils/returnHelper.utils.js";
|
||||
|
||||
const r = Router();
|
||||
|
||||
const newDockScanner = z.object({
|
||||
ip: z.string(),
|
||||
name: z.string(),
|
||||
dockId: z.string(),
|
||||
});
|
||||
|
||||
r.get("/", async (_, res) => {
|
||||
try {
|
||||
const docks = await db
|
||||
.select()
|
||||
.from(dockDoorScanners)
|
||||
.orderBy(dockDoorScanners.name);
|
||||
|
||||
return apiReturn(res, {
|
||||
success: true,
|
||||
level: "info",
|
||||
module: "dockdoor",
|
||||
subModule: "lane check",
|
||||
message: `All dock Doors.`,
|
||||
data: docks ?? [],
|
||||
status: 200,
|
||||
});
|
||||
} catch (error) {
|
||||
return apiReturn(res, {
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "newDock",
|
||||
message: `There was an error adding in the new dock.`,
|
||||
data: error ?? ([] as any),
|
||||
status: 200,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
r.post("/", requireAuth, async (req, res) => {
|
||||
try {
|
||||
const validated = newDockScanner.parse(req.body);
|
||||
|
||||
const newDock = await db
|
||||
.insert(dockDoorScanners)
|
||||
.values(validated)
|
||||
.returning();
|
||||
|
||||
return apiReturn(res, {
|
||||
success: true,
|
||||
level: "info",
|
||||
module: "dockdoor",
|
||||
subModule: "lane check",
|
||||
message: `${validated.name} was just added.`,
|
||||
data: newDock ?? [],
|
||||
status: 200,
|
||||
});
|
||||
} catch (error) {
|
||||
return apiReturn(res, {
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "dockdoor",
|
||||
subModule: "newDock",
|
||||
message: `There was an error adding in the new dock.`,
|
||||
data: error ?? ([] as any),
|
||||
status: 200,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default r;
|
||||
6
backend/prodSql/queries/outbound.docks.sql
Normal file
6
backend/prodSql/queries/outbound.docks.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
USE [test1_AlplaPROD2.0_Read]
|
||||
|
||||
SELECT *
|
||||
FROM [masterData].[Dock] (nolock)
|
||||
where active = 1
|
||||
order by Description desc
|
||||
@@ -4,6 +4,7 @@ import { setupAuthRoutes } from "./auth/auth.routes.js";
|
||||
// import the routes and route setups
|
||||
import { setupApiDocsRoutes } from "./configs/scaler.config.js";
|
||||
import { setupDatamartRoutes } from "./datamart/datamart.routes.js";
|
||||
import { setupDockDoorRoutes } from "./dockdoorScanning/dockdoor.routes.js";
|
||||
import { setupGPSqlRoutes } from "./gpSql/gpSql.routes.js";
|
||||
import { setupMobileRoutes } from "./mobile/mobile.routes.js";
|
||||
import { setupNotificationRoutes } from "./notification/notification.routes.js";
|
||||
@@ -29,4 +30,5 @@ export const setupRoutes = (baseUrl: string, app: Express) => {
|
||||
setupNotificationRoutes(baseUrl, app);
|
||||
setupOCPRoutes(baseUrl, app);
|
||||
setupTCPRoutes(baseUrl, app);
|
||||
setupDockDoorRoutes(baseUrl, app);
|
||||
};
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export type RoomId = "logs" | "labels" | "admin" | "admin:build"; //| "alerts" | "metrics";
|
||||
@@ -162,6 +162,17 @@ const servers: NewServerData[] = [
|
||||
serverLoc: "D$\\LST_V3",
|
||||
buildNumber: 1,
|
||||
},
|
||||
{
|
||||
name: "Salt Lake City",
|
||||
server: "USSLC1VMS006",
|
||||
plantToken: "usslc1",
|
||||
idAddress: "10.202.0.26",
|
||||
greatPlainsPlantCode: "70",
|
||||
contactEmail: "",
|
||||
contactPhone: "",
|
||||
serverLoc: "D$\\LST_V3",
|
||||
buildNumber: 1,
|
||||
},
|
||||
];
|
||||
|
||||
// notes here for when it comes time to pull in all the server address info [test1_AlplaPROD2.0_Read].[masterData].[Plant] has everything from every server :D
|
||||
|
||||
@@ -86,8 +86,40 @@ const newSettings: NewSetting[] = [
|
||||
roles: ["admin"],
|
||||
seedVersion: 1,
|
||||
},
|
||||
{
|
||||
name: "dockDoorScanning",
|
||||
value: "0",
|
||||
active: false,
|
||||
description: "dock door scanning",
|
||||
moduleName: "dockDoorScanning",
|
||||
settingType: "feature",
|
||||
roles: ["admin"],
|
||||
seedVersion: 1,
|
||||
},
|
||||
|
||||
// standard settings
|
||||
{
|
||||
name: "stagingWarehouse",
|
||||
value: "30218",
|
||||
active: true,
|
||||
description:
|
||||
"The warehouse we will use for staging, validation that we did our prechecks if required",
|
||||
moduleName: "dockDoorScanning",
|
||||
settingType: "standard",
|
||||
roles: ["admin"],
|
||||
seedVersion: 1,
|
||||
},
|
||||
{
|
||||
name: "precheck",
|
||||
value: "5",
|
||||
active: false,
|
||||
description:
|
||||
"Precheck is required, the value is in minute, 5 min should be 5",
|
||||
moduleName: "dockDoorScanning",
|
||||
settingType: "standard",
|
||||
roles: ["admin"],
|
||||
seedVersion: 1,
|
||||
},
|
||||
{
|
||||
name: "prolinkCheck",
|
||||
value: "1",
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import net from "node:net";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/db.controller.js";
|
||||
import { dockDoorScanners } from "../db/schema/dockdoor.schema.js";
|
||||
import { printerData } from "../db/schema/printers.schema.js";
|
||||
import { loadUnit } from "../dockdoorScanning/dockdoor.loadUnits.js";
|
||||
import { createLogger } from "../logger/logger.controller.js";
|
||||
import { delay } from "../utils/delay.utils.js";
|
||||
import { returnFunc } from "../utils/returnHelper.utils.js";
|
||||
@@ -14,6 +16,7 @@ export let isServerRunning = false;
|
||||
|
||||
const port = parseInt(process.env.TCP_PORT ?? "2222", 10);
|
||||
|
||||
// This is the parser for zebra scanners
|
||||
const parseTcpAlert = (input: string) => {
|
||||
// guard
|
||||
const colonIndex = input.indexOf(":");
|
||||
@@ -74,6 +77,24 @@ export const startTCPServer = async () => {
|
||||
|
||||
printerListen(printerData as PrinterData);
|
||||
}
|
||||
|
||||
// check if its a dock door scanner
|
||||
// TODO: move to the db and get real info lol
|
||||
const dockdoorScanners = await db.select().from(dockDoorScanners);
|
||||
|
||||
if (dockdoorScanners.some((s) => s.ip === ip.replace("::ffff:", ""))) {
|
||||
console.log("dock door logic");
|
||||
|
||||
const currentDock = dockdoorScanners.filter(
|
||||
(s) => s.ip === ip.replace("::ffff:", ""),
|
||||
);
|
||||
|
||||
// send the data + dock scan over
|
||||
loadUnit({
|
||||
dockId: currentDock[0]?.dockId ?? "0",
|
||||
sscc: data.toString(),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("end", () => {
|
||||
|
||||
@@ -16,7 +16,8 @@ export interface ReturnHelper<T = unknown[]> {
|
||||
| "tcp"
|
||||
| "logistics"
|
||||
| "admin"
|
||||
| "mobile";
|
||||
| "mobile"
|
||||
| "dockdoor";
|
||||
subModule: string;
|
||||
|
||||
level: "info" | "error" | "debug" | "fatal" | "warn";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "LST mobile",
|
||||
"slug": "lst-mobile",
|
||||
"version": "0.11.1-alpha",
|
||||
"orientation": "portrait",
|
||||
"orientation": "default",
|
||||
"icon": "./assets/icon_white.png",
|
||||
"scheme": "lstmobile",
|
||||
"userInterfaceStyle": "automatic",
|
||||
@@ -15,10 +15,14 @@
|
||||
"foregroundImage": "./assets/adaptive-icon-white.png",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"versionCode": 37,
|
||||
"versionCode": 39,
|
||||
"minSupportedVersionCode": 33,
|
||||
"predictiveBackGestureEnabled": false,
|
||||
"package": "net.alpla.lst.mobile"
|
||||
"package": "net.alpla.lst.mobile",
|
||||
"permissions": [
|
||||
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||
"android.permission.READ_EXTERNAL_STORAGE"
|
||||
]
|
||||
},
|
||||
"web": {
|
||||
"output": "static",
|
||||
|
||||
88
lstMobile/package-lock.json
generated
88
lstMobile/package-lock.json
generated
@@ -35,6 +35,7 @@
|
||||
"expo-image": "~55.0.8",
|
||||
"expo-linking": "~55.0.13",
|
||||
"expo-router": "~55.0.12",
|
||||
"expo-screen-orientation": "~55.0.16",
|
||||
"expo-splash-screen": "~55.0.18",
|
||||
"expo-status-bar": "~55.0.5",
|
||||
"expo-symbols": "~55.0.7",
|
||||
@@ -46,6 +47,7 @@
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-native": "0.83.4",
|
||||
"react-native-blob-util": "^0.24.9",
|
||||
"react-native-gesture-handler": "~2.30.0",
|
||||
"react-native-reanimated": "4.2.1",
|
||||
"react-native-safe-area-context": "~5.6.2",
|
||||
@@ -6132,6 +6134,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/base-64": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
|
||||
"integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
@@ -8171,6 +8178,16 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-screen-orientation": {
|
||||
"version": "55.0.16",
|
||||
"resolved": "https://registry.npmjs.org/expo-screen-orientation/-/expo-screen-orientation-55.0.16.tgz",
|
||||
"integrity": "sha512-I9NIqb2zAkHsK/CxdmMdmgSFP7E1v++8z/Mj2X9j1AuK6l55yOma/JHo905KU3x2zPm9/l1BTzmMA320tiBebg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-server": {
|
||||
"version": "55.0.9",
|
||||
"resolved": "https://registry.npmjs.org/expo-server/-/expo-server-55.0.9.tgz",
|
||||
@@ -12821,6 +12838,77 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-blob-util": {
|
||||
"version": "0.24.9",
|
||||
"resolved": "https://registry.npmjs.org/react-native-blob-util/-/react-native-blob-util-0.24.9.tgz",
|
||||
"integrity": "sha512-tG3+m0WhVdBGifvxSFxZDVqtr85D0fGBJU6E4UxmK3tU+RabJZTumXEn8k7jn5/NFe8OhQhPjtBEZ11ZJ6L7Vw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base-64": "0.1.0",
|
||||
"glob": "13.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ronradtke"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-blob-util/node_modules/balanced-match": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
|
||||
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-blob-util/node_modules/brace-expansion": {
|
||||
"version": "5.0.6",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
|
||||
"integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-blob-util/node_modules/glob": {
|
||||
"version": "13.0.1",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.1.tgz",
|
||||
"integrity": "sha512-B7U/vJpE3DkJ5WXTgTpTRN63uV42DseiXXKMwG14LQBXmsdeIoHAPbU/MEo6II0k5ED74uc2ZGTC6MwHFQhF6w==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"minimatch": "^10.1.2",
|
||||
"minipass": "^7.1.2",
|
||||
"path-scurry": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-blob-util/node_modules/minimatch": {
|
||||
"version": "10.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
|
||||
"integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^5.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-css-interop": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.2.3.tgz",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
"expo-image": "~55.0.8",
|
||||
"expo-linking": "~55.0.13",
|
||||
"expo-router": "~55.0.12",
|
||||
"expo-screen-orientation": "~55.0.16",
|
||||
"expo-splash-screen": "~55.0.18",
|
||||
"expo-status-bar": "~55.0.5",
|
||||
"expo-symbols": "~55.0.7",
|
||||
@@ -56,6 +57,7 @@
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-native": "0.83.4",
|
||||
"react-native-blob-util": "^0.24.9",
|
||||
"react-native-gesture-handler": "~2.30.0",
|
||||
"react-native-reanimated": "4.2.1",
|
||||
"react-native-safe-area-context": "~5.6.2",
|
||||
|
||||
Reference in New Issue
Block a user