Merge branch 'mhkim-node' of http://39.117.244.52:3000/kjs/ERP-node into jskim-node
This commit is contained in:
@@ -191,18 +191,30 @@ export const getLangKeys = async (
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const { companyCode, menuCode, keyType, searchText, categoryId } = req.query;
|
||||
const userCompanyCode = req.user?.companyCode;
|
||||
logger.info("다국어 키 목록 조회 요청", {
|
||||
query: req.query,
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
// company_code 필터링: 비관리자는 자기 회사 + 공통(*) 키만 조회 가능
|
||||
let effectiveCompanyCode = companyCode as string;
|
||||
if (userCompanyCode !== "*") {
|
||||
// 비관리자가 다른 회사의 데이터를 요청하면 자기 회사로 제한
|
||||
if (companyCode && companyCode !== userCompanyCode && companyCode !== "*") {
|
||||
effectiveCompanyCode = userCompanyCode || "";
|
||||
}
|
||||
}
|
||||
|
||||
const multiLangService = new MultiLangService();
|
||||
const langKeys = await multiLangService.getLangKeys({
|
||||
companyCode: companyCode as string,
|
||||
companyCode: effectiveCompanyCode,
|
||||
menuCode: menuCode as string,
|
||||
keyType: keyType as string,
|
||||
searchText: searchText as string,
|
||||
categoryId: categoryId ? parseInt(categoryId as string, 10) : undefined,
|
||||
// 비관리자: companyCode 필터가 없으면 자기 회사 + 공통(*) 키만 반환
|
||||
userCompanyCode: userCompanyCode,
|
||||
});
|
||||
|
||||
const response: ApiResponse<any[]> = {
|
||||
@@ -235,9 +247,24 @@ export const getLangTexts = async (
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const { keyId } = req.params;
|
||||
const userCompanyCode = req.user?.companyCode;
|
||||
logger.info("다국어 텍스트 조회 요청", { keyId, user: req.user });
|
||||
|
||||
const multiLangService = new MultiLangService();
|
||||
|
||||
// 비관리자: 해당 키가 자기 회사 또는 공통(*) 키인지 검증
|
||||
if (userCompanyCode !== "*") {
|
||||
const keyOwner = await multiLangService.getKeyCompanyCode(parseInt(keyId));
|
||||
if (keyOwner && keyOwner !== "*" && keyOwner !== userCompanyCode) {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "다른 회사의 다국어 키에 접근할 권한이 없습니다.",
|
||||
error: { code: "PERMISSION_DENIED" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const langTexts = await multiLangService.getLangTexts(parseInt(keyId));
|
||||
|
||||
const response: ApiResponse<any[]> = {
|
||||
@@ -270,6 +297,7 @@ export const createLangKey = async (
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const keyData: CreateLangKeyRequest = req.body;
|
||||
const userCompanyCode = req.user?.companyCode;
|
||||
logger.info("다국어 키 생성 요청", { keyData, user: req.user });
|
||||
|
||||
// 필수 입력값 검증
|
||||
@@ -285,6 +313,26 @@ export const createLangKey = async (
|
||||
return;
|
||||
}
|
||||
|
||||
// 권한 검사: 공통 키(*)는 최고 관리자만 생성 가능
|
||||
if (keyData.companyCode === "*" && userCompanyCode !== "*") {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "공통 키는 최고 관리자만 생성할 수 있습니다.",
|
||||
error: { code: "PERMISSION_DENIED" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 비관리자: 자기 회사 키만 생성 가능
|
||||
if (userCompanyCode !== "*" && keyData.companyCode !== userCompanyCode) {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "다른 회사의 키를 생성할 권한이 없습니다.",
|
||||
error: { code: "PERMISSION_DENIED" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const multiLangService = new MultiLangService();
|
||||
const keyId = await multiLangService.createLangKey({
|
||||
...keyData,
|
||||
@@ -323,10 +371,33 @@ export const updateLangKey = async (
|
||||
try {
|
||||
const { keyId } = req.params;
|
||||
const keyData: UpdateLangKeyRequest = req.body;
|
||||
const userCompanyCode = req.user?.companyCode;
|
||||
|
||||
logger.info("다국어 키 수정 요청", { keyId, keyData, user: req.user });
|
||||
|
||||
const multiLangService = new MultiLangService();
|
||||
|
||||
// 비관리자: 해당 키가 자기 회사 키인지 검증 (공통 키는 수정 불가)
|
||||
if (userCompanyCode !== "*") {
|
||||
const keyOwner = await multiLangService.getKeyCompanyCode(parseInt(keyId));
|
||||
if (!keyOwner) {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
message: "다국어 키를 찾을 수 없습니다.",
|
||||
error: { code: "KEY_NOT_FOUND" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (keyOwner !== userCompanyCode) {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "다른 회사의 다국어 키를 수정할 권한이 없습니다.",
|
||||
error: { code: "PERMISSION_DENIED" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await multiLangService.updateLangKey(parseInt(keyId), {
|
||||
...keyData,
|
||||
updatedBy: req.user?.userId || "system",
|
||||
@@ -362,9 +433,32 @@ export const deleteLangKey = async (
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const { keyId } = req.params;
|
||||
const userCompanyCode = req.user?.companyCode;
|
||||
logger.info("다국어 키 삭제 요청", { keyId, user: req.user });
|
||||
|
||||
const multiLangService = new MultiLangService();
|
||||
|
||||
// 비관리자: 해당 키가 자기 회사 키인지 검증 (공통 키 삭제 불가)
|
||||
if (userCompanyCode !== "*") {
|
||||
const keyOwner = await multiLangService.getKeyCompanyCode(parseInt(keyId));
|
||||
if (!keyOwner) {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
message: "다국어 키를 찾을 수 없습니다.",
|
||||
error: { code: "KEY_NOT_FOUND" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (keyOwner !== userCompanyCode) {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "다른 회사의 다국어 키를 삭제할 권한이 없습니다.",
|
||||
error: { code: "PERMISSION_DENIED" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await multiLangService.deleteLangKey(parseInt(keyId));
|
||||
|
||||
const response: ApiResponse<string> = {
|
||||
@@ -397,9 +491,32 @@ export const toggleLangKey = async (
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const { keyId } = req.params;
|
||||
const userCompanyCode = req.user?.companyCode;
|
||||
logger.info("다국어 키 상태 토글 요청", { keyId, user: req.user });
|
||||
|
||||
const multiLangService = new MultiLangService();
|
||||
|
||||
// 비관리자: 해당 키가 자기 회사 키인지 검증
|
||||
if (userCompanyCode !== "*") {
|
||||
const keyOwner = await multiLangService.getKeyCompanyCode(parseInt(keyId));
|
||||
if (!keyOwner) {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
message: "다국어 키를 찾을 수 없습니다.",
|
||||
error: { code: "KEY_NOT_FOUND" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (keyOwner !== userCompanyCode) {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "다른 회사의 다국어 키를 변경할 권한이 없습니다.",
|
||||
error: { code: "PERMISSION_DENIED" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const result = await multiLangService.toggleLangKey(parseInt(keyId));
|
||||
|
||||
const response: ApiResponse<string> = {
|
||||
@@ -433,6 +550,7 @@ export const saveLangTexts = async (
|
||||
try {
|
||||
const { keyId } = req.params;
|
||||
const textData: SaveLangTextsRequest = req.body;
|
||||
const userCompanyCode = req.user?.companyCode;
|
||||
|
||||
logger.info("다국어 텍스트 저장 요청", { keyId, textData, user: req.user });
|
||||
|
||||
@@ -454,6 +572,28 @@ export const saveLangTexts = async (
|
||||
}
|
||||
|
||||
const multiLangService = new MultiLangService();
|
||||
|
||||
// 비관리자: 해당 키가 자기 회사 또는 공통(*) 키인지 검증
|
||||
if (userCompanyCode !== "*") {
|
||||
const keyOwner = await multiLangService.getKeyCompanyCode(parseInt(keyId));
|
||||
if (!keyOwner) {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
message: "다국어 키를 찾을 수 없습니다.",
|
||||
error: { code: "KEY_NOT_FOUND" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (keyOwner !== userCompanyCode) {
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
message: "다른 회사의 다국어 텍스트를 수정할 권한이 없습니다.",
|
||||
error: { code: "PERMISSION_DENIED" },
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await multiLangService.saveLangTexts(parseInt(keyId), {
|
||||
texts: textData.texts.map((text) => ({
|
||||
...text,
|
||||
|
||||
@@ -673,6 +673,22 @@ export class MultiLangService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 키의 소유 회사 코드 조회 (권한 검증용)
|
||||
*/
|
||||
async getKeyCompanyCode(keyId: number): Promise<string | null> {
|
||||
try {
|
||||
const result = await queryOne<{ company_code: string }>(
|
||||
`SELECT company_code FROM multi_lang_key_master WHERE key_id = $1`,
|
||||
[keyId]
|
||||
);
|
||||
return result?.company_code || null;
|
||||
} catch (error) {
|
||||
logger.error("키 소유 회사 코드 조회 실패:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 다국어 키 목록 조회
|
||||
*/
|
||||
@@ -688,6 +704,10 @@ export class MultiLangService {
|
||||
if (params.companyCode) {
|
||||
whereConditions.push(`company_code = $${paramIndex++}`);
|
||||
values.push(params.companyCode);
|
||||
} else if (params.userCompanyCode && params.userCompanyCode !== "*") {
|
||||
// 비관리자: companyCode 필터가 없으면 자기 회사 + 공통(*) 키만 반환
|
||||
whereConditions.push(`company_code IN ($${paramIndex++}, '*')`);
|
||||
values.push(params.userCompanyCode);
|
||||
}
|
||||
|
||||
// 메뉴 코드 필터
|
||||
|
||||
@@ -140,6 +140,7 @@ export interface GetLangKeysParams {
|
||||
includeOverrides?: boolean;
|
||||
page?: number;
|
||||
limit?: number;
|
||||
userCompanyCode?: string; // 요청 사용자의 회사 코드 (비관리자 필터링용)
|
||||
}
|
||||
|
||||
export interface GetUserTextParams {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
42
frontend/package-lock.json
generated
42
frontend/package-lock.json
generated
@@ -266,7 +266,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@@ -308,7 +307,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
@@ -342,7 +340,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
|
||||
"integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@dnd-kit/accessibility": "^3.1.1",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
@@ -3058,7 +3055,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.4.0.tgz",
|
||||
"integrity": "sha512-k4iu1R6e5D54918V4sqmISUkI5OgTw3v7/sDRKEC632Wd5g2WBtUS5gyG63X0GJO/HZUj1tsjSXfyzwrUHZl1g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.17.8",
|
||||
"@types/react-reconciler": "^0.32.0",
|
||||
@@ -3712,7 +3708,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.6.tgz",
|
||||
"integrity": "sha512-gB1sljYjcobZKxjPbKSa31FUTyr+ROaBdoH+wSSs9Dk+yDCmMs+TkTV3PybRRVLC7ax7q0erJ9LvRWnMktnRAw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@tanstack/query-core": "5.90.6"
|
||||
},
|
||||
@@ -3807,7 +3802,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.27.1.tgz",
|
||||
"integrity": "sha512-nkerkl8syHj44ZzAB7oA2GPmmZINKBKCa79FuNvmGJrJ4qyZwlkDzszud23YteFZEytbc87kVd/fP76ROS6sLg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
@@ -4121,7 +4115,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.27.1.tgz",
|
||||
"integrity": "sha512-ijKo3+kIjALthYsnBmkRXAuw2Tswd9gd7BUR5OMfIcjGp8v576vKxOxrRfuYiUM78GPt//P0sVc1WV82H5N0PQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-changeset": "^2.3.0",
|
||||
"prosemirror-collab": "^1.3.1",
|
||||
@@ -6622,7 +6615,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
|
||||
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
@@ -6633,7 +6625,6 @@
|
||||
"integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.2.0"
|
||||
}
|
||||
@@ -6676,7 +6667,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.180.0.tgz",
|
||||
"integrity": "sha512-ykFtgCqNnY0IPvDro7h+9ZeLY+qjgUWv+qEvUt84grhenO60Hqd4hScHE7VTB9nOQ/3QM8lkbNE+4vKjEpUxKg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@dimforge/rapier3d-compat": "~0.12.0",
|
||||
"@tweenjs/tween.js": "~23.1.3",
|
||||
@@ -6759,7 +6749,6 @@
|
||||
"integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.46.2",
|
||||
"@typescript-eslint/types": "8.46.2",
|
||||
@@ -7392,7 +7381,6 @@
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -8543,8 +8531,7 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/d3": {
|
||||
"version": "7.9.0",
|
||||
@@ -8866,7 +8853,6 @@
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
|
||||
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
@@ -9626,7 +9612,6 @@
|
||||
"integrity": "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -9715,7 +9700,6 @@
|
||||
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"eslint-config-prettier": "bin/cli.js"
|
||||
},
|
||||
@@ -9817,7 +9801,6 @@
|
||||
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@rtsao/scc": "^1.1.0",
|
||||
"array-includes": "^3.1.9",
|
||||
@@ -10989,7 +10972,6 @@
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz",
|
||||
"integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/immer"
|
||||
@@ -11770,8 +11752,7 @@
|
||||
"version": "1.9.4",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/levn": {
|
||||
"version": "0.4.1",
|
||||
@@ -13110,7 +13091,6 @@
|
||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
@@ -13404,7 +13384,6 @@
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz",
|
||||
"integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"orderedmap": "^2.0.0"
|
||||
}
|
||||
@@ -13434,7 +13413,6 @@
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz",
|
||||
"integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
@@ -13483,7 +13461,6 @@
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.4.tgz",
|
||||
"integrity": "sha512-WkKgnyjNncri03Gjaz3IFWvCAE94XoiEgvtr0/r2Xw7R8/IjK3sKLSiDoCHWcsXSAinVaKlGRZDvMCsF1kbzjA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.20.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
@@ -13687,7 +13664,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
|
||||
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -13757,7 +13733,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
|
||||
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.26.0"
|
||||
},
|
||||
@@ -13808,7 +13783,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz",
|
||||
"integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
@@ -13841,8 +13815,7 @@
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-leaflet": {
|
||||
"version": "5.0.0",
|
||||
@@ -14150,7 +14123,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"use-sync-external-store": "^1.4.0"
|
||||
@@ -14173,8 +14145,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/recharts/node_modules/redux-thunk": {
|
||||
"version": "3.1.0",
|
||||
@@ -15204,8 +15175,7 @@
|
||||
"version": "0.180.0",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.180.0.tgz",
|
||||
"integrity": "sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/three-mesh-bvh": {
|
||||
"version": "0.8.3",
|
||||
@@ -15293,7 +15263,6 @@
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -15642,7 +15611,6 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
||||
Reference in New Issue
Block a user