From 12d168d14c47c7c37299abfcd18d34f6c7692941 Mon Sep 17 00:00:00 2001 From: masaaki Date: Wed, 21 Feb 2024 01:41:21 +0000 Subject: [PATCH 01/10] =?UTF-8?q?Merged=20PR=20754:=20=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E7=99=BB=E9=8C=B2=E3=83=84=E3=83=BC=E3=83=AB=E4=BD=9C?= =?UTF-8?q?=E6=88=90=EF=BC=8B=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3571: データ登録ツール作成+動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3571) - 移行データの登録ツールを作成しました - 入力用jsonファイルの読み込み - アカウント・ユーザの登録 - 既存サービスを移植・微修正し呼び出し - rate_limit用のsleep実施 - ワークタイプ・ライセンス・カードライセンスの登録 - 実行についてはpostmanでの実行を考えており、clientは作成しておりません ## レビューポイント - 既存サービスからの流用が多いですが、メインの処理はfeatures/registerになるため、こちらをメインに見ていただければと思います。 ## UIの変更 - 無し ## 動作確認状況 - ローカルで動作確認 ## 補足 - 相談、参考資料などがあれば --- .../server/.env.local.example | 36 ++ data_migration_tools/server/package-lock.json | 548 +++++++++++++++++- data_migration_tools/server/package.json | 5 +- data_migration_tools/server/src/app.module.ts | 40 +- .../server/src/common/error/code.ts | 70 +++ .../src/common/error/makeErrorResponse.ts | 10 + .../server/src/common/error/message.ts | 59 ++ .../server/src/common/error/types/types.ts | 15 + .../server/src/common/log/context.ts | 32 + .../server/src/common/log/index.ts | 4 + .../server/src/common/log/types.ts | 34 ++ .../server/src/common/password/index.ts | 3 + .../server/src/common/password/password.ts | 35 ++ .../server/src/common/repository/index.ts | 143 +++++ .../server/src/common/types/role/index.ts | 10 + .../server/src/common/types/sort/index.ts | 27 + .../server/src/common/types/sort/util.ts | 11 + .../server/src/common/types/types.ts | 155 +++++ .../server/src/constants/index.ts | 268 +++++++++ .../features/accounts/accounts.controller.ts | 12 + .../src/features/accounts/accounts.module.ts | 19 + .../src/features/accounts/accounts.service.ts | 227 ++++++++ .../features/register/register.controller.ts | 209 +++++++ .../src/features/register/register.module.ts | 25 + .../src/features/register/register.service.ts | 68 +++ .../src/features/register/types/types.ts | 10 + .../src/features/users/users.controller.ts | 10 + .../server/src/features/users/users.module.ts | 12 + .../src/features/users/users.service.ts | 306 ++++++++++ .../src/gateways/adb2c/adb2c.service.ts | 102 ++++ .../blobstorage/blobstorage.service.ts | 74 ++- .../accounts/accounts.repository.module.ts | 11 + .../accounts/accounts.repository.service.ts | 164 ++++++ .../accounts/entity/account.entity.ts | 70 +++ .../src/repositories/accounts/errors/types.ts | 28 + .../licenses/entity/license.entity.ts | 137 +++++ .../src/repositories/licenses/errors/types.ts | 108 ++++ .../licenses/licenses.repository.module.ts | 17 + .../licenses/licenses.repository.service.ts | 130 +++++ .../entity/sort_criteria.entity.ts | 16 + .../sort_criteria.repository.module.ts | 8 + .../repositories/users/entity/user.entity.ts | 97 ++++ .../src/repositories/users/errors/types.ts | 56 ++ .../users/users.repository.module.ts | 11 + .../users/users.repository.service.ts | 141 +++++ .../worktypes/entity/option_item.entity.ts | 42 ++ .../worktypes/entity/worktype.entity.ts | 44 ++ .../repositories/worktypes/errors/types.ts | 28 + .../worktypes/worktypes.repository.module.ts | 12 + .../worktypes/worktypes.repository.service.ts | 104 ++++ 50 files changed, 3785 insertions(+), 18 deletions(-) create mode 100644 data_migration_tools/server/src/common/error/code.ts create mode 100644 data_migration_tools/server/src/common/error/makeErrorResponse.ts create mode 100644 data_migration_tools/server/src/common/error/message.ts create mode 100644 data_migration_tools/server/src/common/error/types/types.ts create mode 100644 data_migration_tools/server/src/common/log/context.ts create mode 100644 data_migration_tools/server/src/common/log/index.ts create mode 100644 data_migration_tools/server/src/common/log/types.ts create mode 100644 data_migration_tools/server/src/common/password/index.ts create mode 100644 data_migration_tools/server/src/common/password/password.ts create mode 100644 data_migration_tools/server/src/common/repository/index.ts create mode 100644 data_migration_tools/server/src/common/types/role/index.ts create mode 100644 data_migration_tools/server/src/common/types/sort/index.ts create mode 100644 data_migration_tools/server/src/common/types/sort/util.ts create mode 100644 data_migration_tools/server/src/common/types/types.ts create mode 100644 data_migration_tools/server/src/features/accounts/accounts.controller.ts create mode 100644 data_migration_tools/server/src/features/accounts/accounts.module.ts create mode 100644 data_migration_tools/server/src/features/accounts/accounts.service.ts create mode 100644 data_migration_tools/server/src/features/register/register.controller.ts create mode 100644 data_migration_tools/server/src/features/register/register.module.ts create mode 100644 data_migration_tools/server/src/features/register/register.service.ts create mode 100644 data_migration_tools/server/src/features/register/types/types.ts create mode 100644 data_migration_tools/server/src/features/users/users.controller.ts create mode 100644 data_migration_tools/server/src/features/users/users.module.ts create mode 100644 data_migration_tools/server/src/features/users/users.service.ts create mode 100644 data_migration_tools/server/src/repositories/accounts/accounts.repository.module.ts create mode 100644 data_migration_tools/server/src/repositories/accounts/accounts.repository.service.ts create mode 100644 data_migration_tools/server/src/repositories/accounts/entity/account.entity.ts create mode 100644 data_migration_tools/server/src/repositories/accounts/errors/types.ts create mode 100644 data_migration_tools/server/src/repositories/licenses/entity/license.entity.ts create mode 100644 data_migration_tools/server/src/repositories/licenses/errors/types.ts create mode 100644 data_migration_tools/server/src/repositories/licenses/licenses.repository.module.ts create mode 100644 data_migration_tools/server/src/repositories/licenses/licenses.repository.service.ts create mode 100644 data_migration_tools/server/src/repositories/sort_criteria/entity/sort_criteria.entity.ts create mode 100644 data_migration_tools/server/src/repositories/sort_criteria/sort_criteria.repository.module.ts create mode 100644 data_migration_tools/server/src/repositories/users/entity/user.entity.ts create mode 100644 data_migration_tools/server/src/repositories/users/errors/types.ts create mode 100644 data_migration_tools/server/src/repositories/users/users.repository.module.ts create mode 100644 data_migration_tools/server/src/repositories/users/users.repository.service.ts create mode 100644 data_migration_tools/server/src/repositories/worktypes/entity/option_item.entity.ts create mode 100644 data_migration_tools/server/src/repositories/worktypes/entity/worktype.entity.ts create mode 100644 data_migration_tools/server/src/repositories/worktypes/errors/types.ts create mode 100644 data_migration_tools/server/src/repositories/worktypes/worktypes.repository.module.ts create mode 100644 data_migration_tools/server/src/repositories/worktypes/worktypes.repository.service.ts diff --git a/data_migration_tools/server/.env.local.example b/data_migration_tools/server/.env.local.example index e69de29..0cee3f5 100644 --- a/data_migration_tools/server/.env.local.example +++ b/data_migration_tools/server/.env.local.example @@ -0,0 +1,36 @@ +STAGE=local +NO_COLOR=TRUE +CORS=TRUE +PORT=8280 +# 開発環境ではADB2Cが別テナントになる都合上、環境変数を分けている +TENANT_NAME=adb2codmsdev +SIGNIN_FLOW_NAME=b2c_1_signin_dev +ADB2C_TENANT_ID=xxxxxxxx +ADB2C_CLIENT_ID=xxxxxxxx +ADB2C_CLIENT_SECRET=xxxxxxxx +ADB2C_ORIGIN=https://zzzzzzzzzz +JWT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA5IZZNgDew9eGmuFTezwdHYLSaJvUPPIKYoiOeVLD1paWNI51\n7Vkaoh0ngprcKOdv6T1N07V4igK7mOim2zY3yCTR6wcWR3PfFJrl9vh5SOo79koZ\noJb27YiM4jtxfx2dezzp0T2GoNR5rRolPUbWFJXnDe0DVXYXpJLb4LAlF2XAyYX0\nSYKUVUsJnzm5k4xbXtnwPwVbpm0EdswBE6qSfiL9zWk9dvHoKzSnfSDzDFoFcEoV\nchawzYXf/MM1YR4wo5XyzECc6Q5Ah4z522//mBNNaDHv83Yuw3mGShT73iJ0JQdk\nTturshv2Ecma38r6ftrIwNYXw4VVatJM8+GOOQIDAQABAoIBADrwp7u097+dK/tw\nWD61n3DIGAqg/lmFt8X4IH8MKLSE/FKr16CS1bqwOEuIM3ZdUtDeXd9Xs7IsyEPE\n5ZwuXK7DSF0M4+Mj8Ip49Q0Aww9aUoLQU9HGfgN/r4599GTrt31clZXA/6Mlighq\ncOZgCcEfdItz8OMu5SQuOIW4CKkCuaWnPOP26UqZocaXNZfpZH0iFLATMMH/TT8x\nay9ToHTQYE17ijdQ/EOLSwoeDV1CU1CIE3P4YfLJjvpKptly5dTevriHEzBi70Jx\n/KEPUn9Jj2gZafrUxRVhmMbm1zkeYxL3gsqRuTzRjEeeILuZhSJyCkQZyUNARxsg\nQY4DZfECgYEA+YLKUtmYTx60FS6DJ4s31TAsXY8kwhq/lB9E3GBZKDd0DPayXEeK\n4UWRQDTT6MI6fedW69FOZJ5sFLp8HQpcssb4Weq9PCpDhNTx8MCbdH3Um5QR3vfW\naKq/1XM8MDUnx5XcNYd87Aw3azvJAvOPr69as8IPnj6sKaRR9uQjbYUCgYEA6nfV\n5j0qmn0EJXZJblk4mvvjLLoWSs17j9YlrZJlJxXMDFRYtgnelv73xMxOMvcGoxn5\nifs7dpaM2x5EmA6jVU5sYaB/beZGEPWqPYGyjIwXPvUGAAv8Gbnvpp+xlSco/Dum\nIq0w+43ry5/xWh6CjfrvKV0J2bDOiJwPEdu/8iUCgYEAnBBSvL+dpN9vhFAzeOh7\nY71eAqcmNsLEUcG9MJqTKbSFwhYMOewF0iHRWHeylEPokhfBJn8kqYrtz4lVWFTC\n5o/Nh3BsLNXCpbMMIapXkeWiti1HgE9ErPMgSkJpwz18RDpYIqM8X+jEQS6D7HSr\nyxfDg+w+GJza0rEVE3hfMIECgYBw+KZ2VfhmEWBjEHhXE+QjQMR3s320MwebCUqE\nNCpKx8TWF/naVC0MwfLtvqbbBY0MHyLN6d//xpA9r3rLbRojqzKrY2KiuDYAS+3n\nzssRzxoQOozWju+8EYu30/ADdqfXyIHG6X3VZs87AGiQzGyJLmP3oR1y5y7MQa09\nJI16hQKBgHK5uwJhGa281Oo5/FwQ3uYLymbNwSGrsOJXiEu2XwJEXwVi2ELOKh4/\n03pBk3Kva3fIwEK+vCzDNnxShIQqBE76/2I1K1whOfoUehhYvKHGaXl2j70Zz9Ks\nrkGW1cx7p+yDqATDrwHBHTHFh5bUTTn8dN40n0e0W/llurpbBkJM\n-----END RSA PRIVATE KEY-----\n" +JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5IZZNgDew9eGmuFTezwd\nHYLSaJvUPPIKYoiOeVLD1paWNI517Vkaoh0ngprcKOdv6T1N07V4igK7mOim2zY3\nyCTR6wcWR3PfFJrl9vh5SOo79koZoJb27YiM4jtxfx2dezzp0T2GoNR5rRolPUbW\nFJXnDe0DVXYXpJLb4LAlF2XAyYX0SYKUVUsJnzm5k4xbXtnwPwVbpm0EdswBE6qS\nfiL9zWk9dvHoKzSnfSDzDFoFcEoVchawzYXf/MM1YR4wo5XyzECc6Q5Ah4z522//\nmBNNaDHv83Yuw3mGShT73iJ0JQdkTturshv2Ecma38r6ftrIwNYXw4VVatJM8+GO\nOQIDAQAB\n-----END PUBLIC KEY-----\n" +SENDGRID_API_KEY=xxxxxxxxxxxxxxxx +MAIL_FROM=xxxxx@xxxxx.xxxx +NOTIFICATION_HUB_NAME=ntf-odms-dev +NOTIFICATION_HUB_CONNECT_STRING=XXXXXXXXXXXXXXXXXX +APP_DOMAIN=http://localhost:8081/ +STORAGE_TOKEN_EXPIRE_TIME=2 +STORAGE_ACCOUNT_NAME_US=saodmsusdev +STORAGE_ACCOUNT_NAME_AU=saodmsaudev +STORAGE_ACCOUNT_NAME_EU=saodmseudev +STORAGE_ACCOUNT_KEY_US=XXXXXXXXXXXXXXXXXXXXXXX +STORAGE_ACCOUNT_KEY_AU=XXXXXXXXXXXXXXXXXXXXXXX +STORAGE_ACCOUNT_KEY_EU=XXXXXXXXXXXXXXXXXXXXXXX +STORAGE_ACCOUNT_ENDPOINT_US=https://AAAAAAAAAAAAA +STORAGE_ACCOUNT_ENDPOINT_AU=https://AAAAAAAAAAAAA +STORAGE_ACCOUNT_ENDPOINT_EU=https://AAAAAAAAAAAAA +ACCESS_TOKEN_LIFETIME_WEB=7200 +REFRESH_TOKEN_LIFETIME_WEB=86400 +REFRESH_TOKEN_LIFETIME_DEFAULT=2592000 +EMAIL_CONFIRM_LIFETIME=86400 +REDIS_HOST=redis-cache +REDIS_PORT=6379 +REDIS_PASSWORD=omdsredispass +ADB2C_CACHE_TTL=86400 \ No newline at end of file diff --git a/data_migration_tools/server/package-lock.json b/data_migration_tools/server/package-lock.json index 50d9f33..1c2990f 100644 --- a/data_migration_tools/server/package-lock.json +++ b/data_migration_tools/server/package-lock.json @@ -30,7 +30,8 @@ "mysql2": "^3.9.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.0", - "swagger-cli": "^4.0.4" + "swagger-cli": "^4.0.4", + "typeorm": "^0.3.10" }, "devDependencies": { "@types/express": "^4.17.17", @@ -424,17 +425,54 @@ } }, "node_modules/@azure/core-util": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.3.2.tgz", - "integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.7.0.tgz", + "integrity": "sha512-Zq2i3QO6k9DA8vnm29mYM4G8IE9u1mhF1GUabVEqPNX8Lj833gdxQ2NAFxt2BZsfAL+e9cT8SyVN7dFVJ/Hf0g==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz", + "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.4.2.tgz", + "integrity": "sha512-0q5DL4uyR0EZ4RXQKD8MadGH6zTIcloUoS/RVbCpNpej4pwte0xpqYxk8K97Py2RiuUvI7F4GXpoT4046VfufA==", "dependencies": { "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.5.0", + "@azure/core-client": "^1.4.0", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^3.5.0", + "@azure/msal-node": "^2.5.1", + "events": "^3.0.0", + "jws": "^4.0.0", + "open": "^8.0.0", + "stoppable": "^1.1.0", "tslib": "^2.2.0" }, "engines": { "node": ">=14.0.0" } }, +<<<<<<< HEAD +======= "node_modules/@azure/identity": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.0.1.tgz", @@ -459,6 +497,7 @@ "node": ">=18.0.0" } }, +>>>>>>> develop "node_modules/@azure/identity/node_modules/@azure/core-tracing": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", @@ -1356,7 +1395,10 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -1373,7 +1415,10 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "engines": { "node": ">=12" }, @@ -1385,7 +1430,10 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "engines": { "node": ">=12" }, @@ -1396,14 +1444,21 @@ "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", +<<<<<<< HEAD + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" +======= "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "peer": true +>>>>>>> develop }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1420,7 +1475,10 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1435,7 +1493,10 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -2270,6 +2331,18 @@ } }, "node_modules/@nestjs/typeorm": { +<<<<<<< HEAD + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-9.0.1.tgz", + "integrity": "sha512-A2BgLIPsMtmMI0bPKEf4bmzgFPsnvHqNBx3KkvaJ7hJrBQy0OqYOb+Rr06ifblKWDWS2tUPNrAFQbZjtk3PI+g==", + "dependencies": { + "uuid": "8.3.2" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0", + "@nestjs/core": "^8.0.0 || ^9.0.0", + "reflect-metadata": "^0.1.13", +======= "version": "10.0.2", "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-10.0.2.tgz", "integrity": "sha512-H738bJyydK4SQkRCTeh1aFBxoO1E9xdL/HaLGThwrqN95os5mEyAtK7BLADOS+vldP4jDZ2VQPLj4epWwRqCeQ==", @@ -2280,11 +2353,17 @@ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0", "reflect-metadata": "^0.1.13 || ^0.2.0", +>>>>>>> develop "rxjs": "^7.2.0", "typeorm": "^0.3.0" } }, "node_modules/@nestjs/typeorm/node_modules/uuid": { +<<<<<<< HEAD + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", +======= "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", @@ -2292,6 +2371,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], +>>>>>>> develop "bin": { "uuid": "dist/bin/uuid" } @@ -2576,7 +2656,10 @@ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "optional": true, +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "engines": { "node": ">=14" } @@ -2608,8 +2691,12 @@ "node_modules/@sqltools/formatter": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", +<<<<<<< HEAD + "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==" +======= "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", "peer": true +>>>>>>> develop }, "node_modules/@tootallnate/once": { "version": "2.0.0", @@ -3130,9 +3217,15 @@ } }, "node_modules/acorn": { +<<<<<<< HEAD + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", +======= "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", +>>>>>>> develop "devOptional": true, "bin": { "acorn": "bin/acorn" @@ -3258,8 +3351,12 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", +<<<<<<< HEAD + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" +======= "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "peer": true +>>>>>>> develop }, "node_modules/anymatch": { "version": "3.1.3", @@ -3278,7 +3375,10 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "engines": { "node": ">= 6.0.0" } @@ -3773,7 +3873,10 @@ "version": "2.1.11", "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", @@ -4093,8 +4196,12 @@ "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", +<<<<<<< HEAD + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" +======= "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", "peer": true +>>>>>>> develop }, "node_modules/debug": { "version": "4.3.4", @@ -4272,8 +4379,12 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", +<<<<<<< HEAD + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" +======= "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "peer": true +>>>>>>> develop }, "node_modules/easy-table": { "version": "1.1.0", @@ -5050,6 +5161,8 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", +<<<<<<< HEAD +======= "peer": true, "dependencies": { "cross-spawn": "^7.0.0", @@ -5078,6 +5191,33 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", +>>>>>>> develop + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5310,7 +5450,10 @@ "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "engines": { "node": "*" } @@ -5760,7 +5903,10 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -7097,9 +7243,15 @@ } }, "node_modules/long": { +<<<<<<< HEAD + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" +======= "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" +>>>>>>> develop }, "node_modules/lru-cache": { "version": "5.1.1", @@ -7247,7 +7399,10 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "engines": { "node": ">=16 || 14 >=14.17" } @@ -7291,6 +7446,18 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "node_modules/mysql2": { +<<<<<<< HEAD + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "dependencies": { + "denque": "^2.0.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^4.0.0", + "lru-cache": "^6.0.0", + "named-placeholders": "^1.1.2", +======= "version": "3.9.1", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", @@ -7301,6 +7468,7 @@ "long": "^5.2.1", "lru-cache": "^8.0.0", "named-placeholders": "^1.1.3", +>>>>>>> develop "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" }, @@ -7320,6 +7488,23 @@ } }, "node_modules/mysql2/node_modules/lru-cache": { +<<<<<<< HEAD + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mysql2/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, +======= "version": "8.0.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", @@ -7327,11 +7512,15 @@ "node": ">=16.14" } }, +>>>>>>> develop "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -7678,14 +7867,21 @@ "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" +======= "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", "peer": true +>>>>>>> develop }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "parse5": "^6.0.1" } @@ -7693,8 +7889,12 @@ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" +======= "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "peer": true +>>>>>>> develop }, "node_modules/parseurl": { "version": "1.3.3", @@ -7738,7 +7938,10 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -7754,7 +7957,10 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "engines": { "node": "14 || >=16.14" } @@ -8475,7 +8681,10 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -8732,7 +8941,10 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8758,7 +8970,10 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9069,7 +9284,10 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "any-promise": "^1.0.0" } @@ -9078,7 +9296,10 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -9351,7 +9572,10 @@ "version": "0.3.20", "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz", "integrity": "sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", @@ -9457,7 +9681,10 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "balanced-match": "^1.0.0" } @@ -9480,7 +9707,10 @@ "url": "https://feross.org/support" } ], +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -9490,7 +9720,10 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -9504,7 +9737,10 @@ "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -9526,7 +9762,10 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9541,7 +9780,10 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "bin": { "mkdirp": "dist/cjs/src/bin.js" }, @@ -9555,14 +9797,21 @@ "node_modules/typeorm/node_modules/reflect-metadata": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" +======= "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", "peer": true +>>>>>>> develop }, "node_modules/typeorm/node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -9580,7 +9829,10 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "engines": { "node": ">=12" } @@ -9888,6 +10140,23 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -10159,6 +10428,8 @@ "requires": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.1.0", +<<<<<<< HEAD +======= "tslib": "^2.2.0" }, "dependencies": { @@ -10183,6 +10454,7 @@ "@azure/core-tracing": "^1.0.0", "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", +>>>>>>> develop "tslib": "^2.2.0" }, "dependencies": { @@ -10193,6 +10465,33 @@ "requires": { "tslib": "^2.2.0" } +<<<<<<< HEAD + } + } + }, + "@azure/core-client": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.8.0.tgz", + "integrity": "sha512-+gHS3gEzPlhyQBMoqVPOTeNH031R5DM/xpCvz72y38C09rg4Hui/1sJS/ujoisDZbbSHyuRLVWdFlwL0pIFwbg==", + "requires": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.0.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/abort-controller": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz", + "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==", + "requires": { + "tslib": "^2.2.0" + } +======= +>>>>>>> develop }, "@azure/core-tracing": { "version": "1.0.1", @@ -10294,12 +10593,53 @@ } }, "@azure/core-util": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.3.2.tgz", - "integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.7.0.tgz", + "integrity": "sha512-Zq2i3QO6k9DA8vnm29mYM4G8IE9u1mhF1GUabVEqPNX8Lj833gdxQ2NAFxt2BZsfAL+e9cT8SyVN7dFVJ/Hf0g==", + "requires": { + "@azure/abort-controller": "^2.0.0", + "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/abort-controller": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz", + "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==", + "requires": { + "tslib": "^2.2.0" + } + } + } + }, + "@azure/identity": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.4.2.tgz", + "integrity": "sha512-0q5DL4uyR0EZ4RXQKD8MadGH6zTIcloUoS/RVbCpNpej4pwte0xpqYxk8K97Py2RiuUvI7F4GXpoT4046VfufA==", "requires": { "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.5.0", + "@azure/core-client": "^1.4.0", + "@azure/core-rest-pipeline": "^1.1.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^3.5.0", + "@azure/msal-node": "^2.5.1", + "events": "^3.0.0", + "jws": "^4.0.0", + "open": "^8.0.0", + "stoppable": "^1.1.0", "tslib": "^2.2.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", + "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", + "requires": { + "tslib": "^2.2.0" + } + } } }, "@azure/identity": { @@ -11015,7 +11355,10 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -11028,26 +11371,41 @@ "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" +======= "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "peer": true +>>>>>>> develop }, "ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" +======= "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "peer": true +>>>>>>> develop }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", +<<<<<<< HEAD + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" +======= "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "peer": true +>>>>>>> develop }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -11058,7 +11416,10 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "ansi-regex": "^6.0.1" } @@ -11067,7 +11428,10 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -11642,6 +12006,19 @@ } }, "@nestjs/typeorm": { +<<<<<<< HEAD + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-9.0.1.tgz", + "integrity": "sha512-A2BgLIPsMtmMI0bPKEf4bmzgFPsnvHqNBx3KkvaJ7hJrBQy0OqYOb+Rr06ifblKWDWS2tUPNrAFQbZjtk3PI+g==", + "requires": { + "uuid": "8.3.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" +======= "version": "10.0.2", "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-10.0.2.tgz", "integrity": "sha512-H738bJyydK4SQkRCTeh1aFBxoO1E9xdL/HaLGThwrqN95os5mEyAtK7BLADOS+vldP4jDZ2VQPLj4epWwRqCeQ==", @@ -11653,6 +12030,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" +>>>>>>> develop } } }, @@ -11844,8 +12222,12 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", +<<<<<<< HEAD + "optional": true +======= "optional": true, "peer": true +>>>>>>> develop }, "@sinclair/typebox": { "version": "0.24.51", @@ -11874,8 +12256,12 @@ "@sqltools/formatter": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", +<<<<<<< HEAD + "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==" +======= "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", "peer": true +>>>>>>> develop }, "@tootallnate/once": { "version": "2.0.0", @@ -12386,9 +12772,15 @@ } }, "acorn": { +<<<<<<< HEAD + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", +======= "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", +>>>>>>> develop "devOptional": true }, "acorn-import-assertions": { @@ -12468,8 +12860,12 @@ "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", +<<<<<<< HEAD + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" +======= "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "peer": true +>>>>>>> develop }, "anymatch": { "version": "3.1.3", @@ -12484,8 +12880,12 @@ "app-root-path": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", +<<<<<<< HEAD + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==" +======= "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", "peer": true +>>>>>>> develop }, "append-field": { "version": "1.0.0", @@ -12851,7 +13251,10 @@ "version": "2.1.11", "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", @@ -13094,8 +13497,12 @@ "dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", +<<<<<<< HEAD + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" +======= "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", "peer": true +>>>>>>> develop }, "debug": { "version": "4.3.4", @@ -13219,8 +13626,12 @@ "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", +<<<<<<< HEAD + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" +======= "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "peer": true +>>>>>>> develop }, "easy-table": { "version": "1.1.0", @@ -13822,7 +14233,10 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -13831,8 +14245,12 @@ "signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", +<<<<<<< HEAD + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" +======= "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "peer": true +>>>>>>> develop } } }, @@ -14007,8 +14425,12 @@ "highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", +<<<<<<< HEAD + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" +======= "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "peer": true +>>>>>>> develop }, "hosted-git-info": { "version": "2.8.9", @@ -14330,7 +14752,10 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "@isaacs/cliui": "^8.0.2", "@pkgjs/parseargs": "^0.11.0" @@ -15389,9 +15814,15 @@ } }, "long": { +<<<<<<< HEAD + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" +======= "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" +>>>>>>> develop }, "lru-cache": { "version": "5.1.1", @@ -15504,8 +15935,12 @@ "minipass": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", +<<<<<<< HEAD + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" +======= "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "peer": true +>>>>>>> develop }, "mkdirp": { "version": "0.5.6", @@ -15540,6 +15975,18 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "mysql2": { +<<<<<<< HEAD + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "requires": { + "denque": "^2.0.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^4.0.0", + "lru-cache": "^6.0.0", + "named-placeholders": "^1.1.2", +======= "version": "3.9.1", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", @@ -15550,6 +15997,7 @@ "long": "^5.2.1", "lru-cache": "^8.0.0", "named-placeholders": "^1.1.3", +>>>>>>> develop "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" }, @@ -15563,9 +16011,23 @@ } }, "lru-cache": { +<<<<<<< HEAD + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" +======= "version": "8.0.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==" +>>>>>>> develop } } }, @@ -15573,7 +16035,10 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -15832,14 +16297,21 @@ "parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" +======= "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", "peer": true +>>>>>>> develop }, "parse5-htmlparser2-tree-adapter": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "parse5": "^6.0.1" }, @@ -15847,8 +16319,12 @@ "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" +======= "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "peer": true +>>>>>>> develop } } }, @@ -15882,7 +16358,10 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -15891,8 +16370,12 @@ "lru-cache": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", +<<<<<<< HEAD + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==" +======= "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", "peer": true +>>>>>>> develop } } }, @@ -16439,7 +16922,10 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -16655,7 +17141,10 @@ "version": "npm:string-width@4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -16674,7 +17163,10 @@ "version": "npm:strip-ansi@6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "ansi-regex": "^5.0.1" } @@ -16886,7 +17378,10 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "any-promise": "^1.0.0" } @@ -16895,7 +17390,10 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "thenify": ">= 3.1.0 < 4" } @@ -17072,7 +17570,10 @@ "version": "0.3.20", "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz", "integrity": "sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", @@ -17095,7 +17596,10 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "balanced-match": "^1.0.0" } @@ -17104,7 +17608,10 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -17114,7 +17621,10 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -17125,7 +17635,10 @@ "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -17138,7 +17651,10 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "brace-expansion": "^2.0.1" } @@ -17146,20 +17662,31 @@ "mkdirp": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", +<<<<<<< HEAD + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==" +======= "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", "peer": true +>>>>>>> develop }, "reflect-metadata": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" +======= "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", "peer": true +>>>>>>> develop }, "yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -17173,8 +17700,12 @@ "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", +<<<<<<< HEAD + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" +======= "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "peer": true +>>>>>>> develop } } }, @@ -17387,7 +17918,10 @@ "version": "npm:wrap-ansi@7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", +<<<<<<< HEAD +======= "peer": true, +>>>>>>> develop "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", diff --git a/data_migration_tools/server/package.json b/data_migration_tools/server/package.json index fee15e8..2b445ea 100644 --- a/data_migration_tools/server/package.json +++ b/data_migration_tools/server/package.json @@ -31,6 +31,7 @@ "@nestjs/core": "^9.3.9", "@nestjs/platform-express": "^9.4.1", "@nestjs/serve-static": "^3.0.1", + "@nestjs/typeorm": "^9.0.1", "@nestjs/swagger": "^6.2.1", "@nestjs/testing": "^9.3.9", "@nestjs/typeorm": "^10.0.2", @@ -44,7 +45,9 @@ "mysql2": "^3.9.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.0", - "swagger-cli": "^4.0.4" + "swagger-cli": "^4.0.4", + "typeorm": "^0.3.10", + "mysql2": "^2.3.3" }, "devDependencies": { "@types/express": "^4.17.17", diff --git a/data_migration_tools/server/src/app.module.ts b/data_migration_tools/server/src/app.module.ts index 23a4c76..8089b78 100644 --- a/data_migration_tools/server/src/app.module.ts +++ b/data_migration_tools/server/src/app.module.ts @@ -1,15 +1,29 @@ import { MiddlewareConsumer, Module } from "@nestjs/common"; import { ServeStaticModule } from "@nestjs/serve-static"; import { ConfigModule, ConfigService } from "@nestjs/config"; +import { TypeOrmModule } from "@nestjs/typeorm"; import { join } from "path"; import { LoggerMiddleware } from "./common/loggerMiddleware"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import { DeleteModule } from "./features/delete/delete.module"; import { AdB2cModule } from "./gateways/adb2c/adb2c.module"; +import { BlobstorageModule } from "./gateways/blobstorage/blobstorage.module"; +import { RegisterController } from "./features/register/register.controller"; +import { RegisterService } from "./features/register/register.service"; +import { RegisterModule } from "./features/register/register.module"; +import { AccountsRepositoryModule } from "./repositories/accounts/accounts.repository.module"; +import { UsersRepositoryModule } from "./repositories/users/users.repository.module"; +import { SortCriteriaRepositoryModule } from "./repositories/sort_criteria/sort_criteria.repository.module"; +import { LicensesRepositoryModule } from "./repositories/licenses/licenses.repository.module"; +import { WorktypesRepositoryModule } from "./repositories/worktypes/worktypes.repository.module"; +import { AccountsController } from "./features/accounts/accounts.controller"; +import { AccountsService } from "./features/accounts/accounts.service"; +import { AccountsModule } from "./features/accounts/accounts.module"; +import { UsersController } from "./features/users/users.controller"; +import { UsersService } from "./features/users/users.service"; +import { UsersModule } from "./features/users/users.module"; +import { DeleteModule } from "./features/delete/delete.module"; import { DeleteRepositoryModule } from "./repositories/delete/delete.repository.module"; import { DeleteController } from "./features/delete/delete.controller"; import { DeleteService } from "./features/delete/delete.service"; -import { BlobstorageModule } from "./gateways/blobstorage/blobstorage.module"; @Module({ imports: [ @@ -20,6 +34,18 @@ import { BlobstorageModule } from "./gateways/blobstorage/blobstorage.module"; envFilePath: [".env.local", ".env"], isGlobal: true, }), + AdB2cModule, + AccountsModule, + UsersModule, + RegisterModule, + AccountsRepositoryModule, + UsersRepositoryModule, + SortCriteriaRepositoryModule, + LicensesRepositoryModule, + WorktypesRepositoryModule, + BlobstorageModule, + DeleteModule, + DeleteRepositoryModule, TypeOrmModule.forRootAsync({ imports: [ConfigModule], useFactory: async (configService: ConfigService) => ({ @@ -34,13 +60,9 @@ import { BlobstorageModule } from "./gateways/blobstorage/blobstorage.module"; }), inject: [ConfigService], }), - DeleteModule, - AdB2cModule, - BlobstorageModule, - DeleteRepositoryModule, ], - controllers: [DeleteController], - providers: [DeleteService], + controllers: [RegisterController, AccountsController, UsersController, DeleteController], + providers: [RegisterService, AccountsService, UsersService, DeleteService], }) export class AppModule { configure(consumer: MiddlewareConsumer) { diff --git a/data_migration_tools/server/src/common/error/code.ts b/data_migration_tools/server/src/common/error/code.ts new file mode 100644 index 0000000..3c488da --- /dev/null +++ b/data_migration_tools/server/src/common/error/code.ts @@ -0,0 +1,70 @@ +/* +エラーコード作成方針 +E+6桁(数字)で構成する。 +- 1~2桁目の値は種類(業務エラー、システムエラー...) +- 3~4桁目の値は原因箇所(トークン、DB、...) +- 5~6桁目の値は任意の重複しない値 +ex) +E00XXXX : システムエラー(通信エラーやDB接続失敗など) +E01XXXX : 業務エラー +EXX00XX : 内部エラー(内部プログラムのエラー) +EXX01XX : トークンエラー(トークン認証関連) +EXX02XX : DBエラー(DB関連) +EXX03XX : ADB2Cエラー(DB関連) +*/ +export const ErrorCodes = [ + 'E009999', // 汎用エラー + 'E000101', // トークン形式不正エラー + 'E000102', // トークン有効期限切れエラー + 'E000103', // トークン非アクティブエラー + 'E000104', // トークン署名エラー + 'E000105', // トークン発行元エラー + 'E000106', // トークンアルゴリズムエラー + 'E000107', // トークン不足エラー + 'E000108', // トークン権限エラー + 'E000301', // ADB2Cへのリクエスト上限超過エラー + 'E000401', // IPアドレス未設定エラー + 'E000501', // リクエストID未設定エラー + 'E010001', // パラメータ形式不正エラー + 'E010201', // 未認証ユーザエラー + 'E010202', // 認証済ユーザエラー + 'E010203', // 管理ユーザ権限エラー + 'E010204', // ユーザ不在エラー + 'E010205', // DBのRoleが想定外の値エラー + 'E010206', // DBのTierが想定外の値エラー + 'E010207', // ユーザーのRole変更不可エラー + 'E010208', // ユーザーの暗号化パスワード不足エラー + 'E010209', // ユーザーの同意済み利用規約バージョンが最新でないエラー + 'E010301', // メールアドレス登録済みエラー + 'E010302', // authorId重複エラー + 'E010401', // PONumber重複エラー + 'E010501', // アカウント不在エラー + 'E010502', // アカウント情報変更不可エラー + 'E010503', // 代行操作不許可エラー + 'E010504', // アカウントロックエラー + 'E010601', // タスク変更不可エラー(タスクが変更できる状態でない、またはタスクが存在しない) + 'E010602', // タスク変更権限不足エラー + 'E010603', // タスク不在エラー + 'E010701', // Blobファイル不在エラー + 'E010801', // ライセンス不在エラー + 'E010802', // ライセンス取り込み済みエラー + 'E010803', // ライセンス発行済みエラー + 'E010804', // ライセンス不足エラー + 'E010805', // ライセンス有効期限切れエラー + 'E010806', // ライセンス割り当て不可エラー + 'E010807', // ライセンス割り当て解除済みエラー + 'E010808', // ライセンス注文キャンセル不可エラー + 'E010809', // ライセンス発行キャンセル不可エラー(ステータスが変えられている場合) + 'E010810', // ライセンス発行キャンセル不可エラー(発行から一定期間経過した場合) + 'E010811', // ライセンス発行キャンセル不可エラー(発行したライセンスが割り当てされている場合) + 'E010812', // ライセンス未割当エラー + 'E010908', // タイピストグループ不在エラー + 'E010909', // タイピストグループ名重複エラー + 'E011001', // ワークタイプ重複エラー + 'E011002', // ワークタイプ登録上限超過エラー + 'E011003', // ワークタイプ不在エラー + 'E011004', // ワークタイプ使用中エラー + 'E012001', // テンプレートファイル不在エラー + 'E013001', // ワークフローのAuthorIDとWorktypeIDのペア重複エラー + 'E013002', // ワークフロー不在エラー +] as const; diff --git a/data_migration_tools/server/src/common/error/makeErrorResponse.ts b/data_migration_tools/server/src/common/error/makeErrorResponse.ts new file mode 100644 index 0000000..0a677b4 --- /dev/null +++ b/data_migration_tools/server/src/common/error/makeErrorResponse.ts @@ -0,0 +1,10 @@ +import { errors } from './message'; +import { ErrorCodeType, ErrorResponse } from './types/types'; + +export const makeErrorResponse = (errorcode: ErrorCodeType): ErrorResponse => { + const msg = errors[errorcode]; + return { + code: errorcode, + message: msg, + }; +}; diff --git a/data_migration_tools/server/src/common/error/message.ts b/data_migration_tools/server/src/common/error/message.ts new file mode 100644 index 0000000..9383694 --- /dev/null +++ b/data_migration_tools/server/src/common/error/message.ts @@ -0,0 +1,59 @@ +import { Errors } from './types/types'; + +// エラーコードとメッセージ対応表 +export const errors: Errors = { + E009999: 'Internal Server Error.', + E000101: 'Token invalid format Error.', + E000102: 'Token expired Error.', + E000103: 'Token not before Error', + E000104: 'Token invalid signature Error.', + E000105: 'Token invalid issuer Error.', + E000106: 'Token invalid algorithm Error.', + E000107: 'Token is not exist Error.', + E000108: 'Token authority failed Error.', + E000301: 'ADB2C request limit exceeded Error', + E000401: 'IP address not found Error.', + E000501: 'Request ID not found Error.', + E010001: 'Param invalid format Error.', + E010201: 'Email not verified user Error.', + E010202: 'Email already verified user Error.', + E010203: 'Administrator Permissions Error.', + E010204: 'User not Found Error.', + E010205: 'Role from DB is unexpected value Error.', + E010206: 'Tier from DB is unexpected value Error.', + E010207: 'User role change not allowed Error.', + E010208: 'User encryption password not found Error.', + E010209: 'Accepted term not latest Error.', + E010301: 'This email user already created Error', + E010302: 'This AuthorId already used Error', + E010401: 'This PoNumber already used Error', + E010501: 'Account not Found Error.', + E010502: 'Account information cannot be changed Error.', + E010503: 'Delegation not allowed Error.', + E010504: 'Account is locked Error.', + E010601: 'Task is not Editable Error', + E010602: 'No task edit permissions Error', + E010603: 'Task not found Error.', + E010701: 'File not found in Blob Storage Error.', + E010801: 'License not exist Error', + E010802: 'License already activated Error', + E010803: 'License already issued Error', + E010804: 'License shortage Error', + E010805: 'License is expired Error', + E010806: 'License is unavailable Error', + E010807: 'License is already deallocated Error', + E010808: 'Order cancel failed Error', + E010809: 'Already license order status changed Error', + E010810: 'Cancellation period expired error', + E010811: 'Already license allocated Error', + E010812: 'License not allocated Error', + E010908: 'Typist Group not exist Error', + E010909: 'Typist Group name already exist Error', + E011001: 'This WorkTypeID already used Error', + E011002: 'WorkTypeID create limit exceeded Error', + E011003: 'WorkTypeID not found Error', + E011004: 'WorkTypeID is in use Error', + E012001: 'Template file not found Error', + E013001: 'AuthorId and WorktypeId pair already exists Error', + E013002: 'Workflow not found Error', +}; diff --git a/data_migration_tools/server/src/common/error/types/types.ts b/data_migration_tools/server/src/common/error/types/types.ts new file mode 100644 index 0000000..8746924 --- /dev/null +++ b/data_migration_tools/server/src/common/error/types/types.ts @@ -0,0 +1,15 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { ErrorCodes } from '../code'; + +export class ErrorResponse { + @ApiProperty() + message: string; + @ApiProperty() + code: string; +} + +export type ErrorCodeType = (typeof ErrorCodes)[number]; + +export type Errors = { + [P in ErrorCodeType]: string; +}; diff --git a/data_migration_tools/server/src/common/log/context.ts b/data_migration_tools/server/src/common/log/context.ts new file mode 100644 index 0000000..1b887c6 --- /dev/null +++ b/data_migration_tools/server/src/common/log/context.ts @@ -0,0 +1,32 @@ +import { Request } from 'express'; +import { Context } from './types'; + +export const makeContext = ( + externalId: string, + requestId: string, + delegationId?: string, +): Context => { + return new Context(externalId, requestId, delegationId); +}; + +// リクエストヘッダーからrequestIdを取得する +export const retrieveRequestId = (req: Request): string | undefined => { + return req.header('x-request-id'); +}; + +/** + * リクエストのIPアドレスを取得します + * @param {Request} + * @return {string | undefined} + */ +export const retrieveIp = (req: Request): string | undefined => { + // ローカル環境では直近の送信元IPを取得する + if (process.env.STAGE === 'local') { + return req.ip; + } + const ip = req.header('x-forwarded-for'); + if (typeof ip === 'string') { + return ip; + } + return undefined; +}; diff --git a/data_migration_tools/server/src/common/log/index.ts b/data_migration_tools/server/src/common/log/index.ts new file mode 100644 index 0000000..7b0bf35 --- /dev/null +++ b/data_migration_tools/server/src/common/log/index.ts @@ -0,0 +1,4 @@ +import { Context } from './types'; +import { makeContext, retrieveRequestId, retrieveIp } from './context'; + +export { Context, makeContext, retrieveRequestId, retrieveIp }; diff --git a/data_migration_tools/server/src/common/log/types.ts b/data_migration_tools/server/src/common/log/types.ts new file mode 100644 index 0000000..6f56bc1 --- /dev/null +++ b/data_migration_tools/server/src/common/log/types.ts @@ -0,0 +1,34 @@ +export class Context { + /** + * APIの操作ユーザーを追跡するためのID + */ + trackingId: string; + /** + * APIの操作ユーザーのIPアドレス + */ + ip: string; + /** + * ユーザーの操作を一意に識別するためのID + */ + requestId: string; + /** + * APIの代行操作ユーザーを追跡するためのID + */ + delegationId?: string | undefined; + + constructor(externalId: string, requestId: string, delegationId?: string) { + this.trackingId = externalId; + this.delegationId = delegationId; + this.requestId = requestId; + } + /** + * ログにユーザーを特定する情報を出力する + */ + getTrackingId(): string { + if (this.delegationId) { + return `${this.requestId}_${this.trackingId} by ${this.delegationId}`; + } else { + return `${this.requestId}_${this.trackingId}`; + } + } +} diff --git a/data_migration_tools/server/src/common/password/index.ts b/data_migration_tools/server/src/common/password/index.ts new file mode 100644 index 0000000..8960a26 --- /dev/null +++ b/data_migration_tools/server/src/common/password/index.ts @@ -0,0 +1,3 @@ +import { makePassword } from './password'; + +export { makePassword }; diff --git a/data_migration_tools/server/src/common/password/password.ts b/data_migration_tools/server/src/common/password/password.ts new file mode 100644 index 0000000..f68bb3c --- /dev/null +++ b/data_migration_tools/server/src/common/password/password.ts @@ -0,0 +1,35 @@ +export const makePassword = (): string => { + // パスワードの文字数を決定 + const passLength = 8; + + // パスワードに使用可能な文字を決定(今回はアルファベットの大文字と小文字 + 数字 + symbolsの記号) + const lowerCase = 'abcdefghijklmnopqrstuvwxyz'; + const upperCase = lowerCase.toLocaleUpperCase(); + const numbers = '0123456789'; + const symbols = '@#$%^&*\\-_+=[]{}|:\',.?/`~"();!'; + const chars = lowerCase + upperCase + numbers + symbols; + + // 英字の大文字、英字の小文字、アラビア数字、記号(@#$%^&*\-_+=[]{}|\:',.?/`~"();!)から2種類以上組み合わせ + const charaTypePattern = + /^((?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*[\d])|(?=.*[a-z])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!])|(?=.*[A-Z])(?=.*[\d])|(?=.*[A-Z])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!])|(?=.*[\d])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!]))[a-zA-Z\d@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!]/; + + // autoGeneratedPasswordが以上の条件を満たせばvalidがtrueになる + let valid = false; + let autoGeneratedPassword: string = ''; + + while (!valid) { + // パスワードをランダムに決定 + while (autoGeneratedPassword.length < passLength) { + // 上で決定したcharsの中からランダムに1文字ずつ追加 + const index = Math.floor(Math.random() * chars.length); + autoGeneratedPassword += chars[index]; + } + + // パスワードが上で決定した条件をすべて満たしているかチェック + // 条件を満たすまでループ + valid = + autoGeneratedPassword.length == passLength && + charaTypePattern.test(autoGeneratedPassword); + } + return autoGeneratedPassword; +}; diff --git a/data_migration_tools/server/src/common/repository/index.ts b/data_migration_tools/server/src/common/repository/index.ts new file mode 100644 index 0000000..b3e21fa --- /dev/null +++ b/data_migration_tools/server/src/common/repository/index.ts @@ -0,0 +1,143 @@ +import { + ObjectLiteral, + Repository, + EntityTarget, + UpdateResult, + DeleteResult, + UpdateQueryBuilder, + Brackets, + FindOptionsWhere, +} from 'typeorm'; +import { Context } from '../log'; + +/** + * VS Code上で型解析エラーが発生するため、typeorm内の型定義と同一の型定義をここに記述する + */ +type QueryDeepPartialEntity = _QueryDeepPartialEntity< + ObjectLiteral extends T ? unknown : T +>; +type _QueryDeepPartialEntity = { + [P in keyof T]?: + | (T[P] extends Array + ? Array<_QueryDeepPartialEntity> + : T[P] extends ReadonlyArray + ? ReadonlyArray<_QueryDeepPartialEntity> + : _QueryDeepPartialEntity) + | (() => string); +}; + +interface InsertEntityOptions { + id: number; +} + +const insertEntity = async ( + entity: EntityTarget, + repository: Repository, + value: QueryDeepPartialEntity, + isCommentOut: boolean, + context: Context, +): Promise => { + let query = repository.createQueryBuilder().insert().into(entity); + if (isCommentOut) { + query = query.comment( + `${context.getTrackingId()}_${new Date().toUTCString()}`, + ); + } + const result = await query.values(value).execute(); + // result.identifiers[0].idがnumber型でない場合はエラー + if (typeof result.identifiers[0].id !== 'number') { + throw new Error('Failed to insert entity'); + } + const where: FindOptionsWhere = { id: result.identifiers[0].id } as T; + + // 結果をもとにセレクトする + const inserted = await repository.findOne({ + where, + comment: `${context.getTrackingId()}_${new Date().toUTCString()}`, + }); + if (!inserted) { + throw new Error('Failed to insert entity'); + } + return inserted; +}; + +const insertEntities = async ( + entity: EntityTarget, + repository: Repository, + values: QueryDeepPartialEntity[], + isCommentOut: boolean, + context: Context, +): Promise => { + let query = repository.createQueryBuilder().insert().into(entity); + if (isCommentOut) { + query = query.comment( + `${context.getTrackingId()}_${new Date().toUTCString()}`, + ); + } + const result = await query.values(values).execute(); + + // 挿入するレコードが0で、結果も0であれば、からの配列を返す + if (values.length === 0 && result.identifiers.length === 0) { + return []; + } + + // 挿入するレコード数と挿入されたレコード数が一致しない場合はエラー + if (result.identifiers.length !== values.length) { + throw new Error('Failed to insert entities'); + } + const where: FindOptionsWhere[] = result.identifiers.map((i) => { + // idがnumber型でない場合はエラー + if (typeof i.id !== 'number') { + throw new Error('Failed to insert entities'); + } + return { id: i.id } as T; + }); + + // 結果をもとにセレクトする + const inserted = await repository.find({ + where, + comment: `${context.getTrackingId()}_${new Date().toUTCString()}`, + }); + if (!inserted) { + throw new Error('Failed to insert entity'); + } + return inserted; +}; + +const updateEntity = async ( + repository: Repository, + criteria: + | string + | ((qb: UpdateQueryBuilder) => string) + | Brackets + | ObjectLiteral + | ObjectLiteral[], + values: QueryDeepPartialEntity, + isCommentOut: boolean, + context: Context, +): Promise => { + let query = repository.createQueryBuilder().update(); + if (isCommentOut) { + query = query.comment( + `${context.getTrackingId()}_${new Date().toUTCString()}`, + ); + } + return await query.set(values).where(criteria).execute(); +}; + +const deleteEntity = async ( + repository: Repository, + criteria: string | Brackets | ObjectLiteral | ObjectLiteral[], + isCommentOut: boolean, + context: Context, +): Promise => { + let query = repository.createQueryBuilder().delete(); + if (isCommentOut) { + query = query.comment( + `${context.getTrackingId()}_${new Date().toUTCString()}`, + ); + } + return await query.where(criteria).execute(); +}; + +export { insertEntity, insertEntities, updateEntity, deleteEntity }; diff --git a/data_migration_tools/server/src/common/types/role/index.ts b/data_migration_tools/server/src/common/types/role/index.ts new file mode 100644 index 0000000..d29201f --- /dev/null +++ b/data_migration_tools/server/src/common/types/role/index.ts @@ -0,0 +1,10 @@ +import { ADMIN_ROLES, USER_ROLES } from '../../../constants'; + +/** + * Token.roleに配置されうる文字列リテラル型 + */ +export type Roles = + | (typeof ADMIN_ROLES)[keyof typeof ADMIN_ROLES] + | (typeof USER_ROLES)[keyof typeof USER_ROLES]; + +export type UserRoles = (typeof USER_ROLES)[keyof typeof USER_ROLES]; diff --git a/data_migration_tools/server/src/common/types/sort/index.ts b/data_migration_tools/server/src/common/types/sort/index.ts new file mode 100644 index 0000000..b505e50 --- /dev/null +++ b/data_migration_tools/server/src/common/types/sort/index.ts @@ -0,0 +1,27 @@ +import { + TASK_LIST_SORTABLE_ATTRIBUTES, + SORT_DIRECTIONS, +} from '../../../constants'; + +export type TaskListSortableAttribute = + (typeof TASK_LIST_SORTABLE_ATTRIBUTES)[number]; + +export type SortDirection = (typeof SORT_DIRECTIONS)[number]; + +export const isTaskListSortableAttribute = ( + arg: string, +): arg is TaskListSortableAttribute => { + const param = arg as TaskListSortableAttribute; + if (TASK_LIST_SORTABLE_ATTRIBUTES.includes(param)) { + return true; + } + return false; +}; + +export const isSortDirection = (arg: string): arg is SortDirection => { + const param = arg as SortDirection; + if (SORT_DIRECTIONS.includes(param)) { + return true; + } + return false; +}; diff --git a/data_migration_tools/server/src/common/types/sort/util.ts b/data_migration_tools/server/src/common/types/sort/util.ts new file mode 100644 index 0000000..2ccf33d --- /dev/null +++ b/data_migration_tools/server/src/common/types/sort/util.ts @@ -0,0 +1,11 @@ +import { SortDirection, TaskListSortableAttribute } from '.'; + +export const getDirection = (direction: SortDirection): SortDirection => { + return direction; +}; + +export const getTaskListSortableAttribute = ( + TaskListSortableAttribute: TaskListSortableAttribute, +): TaskListSortableAttribute => { + return TaskListSortableAttribute; +}; diff --git a/data_migration_tools/server/src/common/types/types.ts b/data_migration_tools/server/src/common/types/types.ts new file mode 100644 index 0000000..7a7854e --- /dev/null +++ b/data_migration_tools/server/src/common/types/types.ts @@ -0,0 +1,155 @@ +export class AccountsInputFile { + accountId: number; + type: number; + companyName: string; + country: string; + dealerAccountId?: number; + adminName: string; + adminMail: string; + userId: number; +} + +export class UsersInputFile { + accountId: number; + userId: number; + name: string; + role: string; + authorId: string; + email: string; +} + +export class LicensesInputFile { + expiry_date: string; + account_id: number; + type: string; + status: string; + allocated_user_id?: number; +} + +export class WorktypesInputFile { + account_id: number; + custom_worktype_id: string; +} + +export class CardLicensesInputFile { + license_id: number; + issue_id: number; + card_license_key: string; + activated_at?: string; + created_at?: string; + created_by?: string; + updated_at?: string; + updated_by?: string; +} + +export function isAccountsInputFileArray(obj: any): obj is AccountsInputFile[] { + return Array.isArray(obj) && obj.every((item) => isAccountsInputFile(item)); +} +export function isAccountsInputFile(obj: any): obj is AccountsInputFile { + return ( + typeof obj === "object" && + obj !== null && + "accountId" in obj && + typeof obj.accountId === "number" && + "type" in obj && + typeof obj.type === "number" && + "companyName" in obj && + typeof obj.companyName === "string" && + "country" in obj && + typeof obj.country === "string" && + ("dealerAccountId" in obj + ? typeof obj.dealerAccountId === "number" + : true) && + "adminName" in obj && + typeof obj.adminName === "string" && + "adminMail" in obj && + typeof obj.adminMail === "string" && + "userId" in obj && + typeof obj.userId === "number" + ); +} + +export function isUsersInputFileArray(obj: any): obj is UsersInputFile[] { + return Array.isArray(obj) && obj.every((item) => isUsersInputFile(item)); +} +export function isUsersInputFile(obj: any): obj is UsersInputFile { + return ( + typeof obj === "object" && + obj !== null && + "accountId" in obj && + "userId" in obj && + "name" in obj && + "role" in obj && + "authorId" in obj && + "email" in obj && + typeof obj.accountId === "number" && + typeof obj.userId === "number" && + typeof obj.name === "string" && + typeof obj.role === "string" && + typeof obj.authorId === "string" && + typeof obj.email === "string" + ); +} + +export function isLicensesInputFileArray(obj: any): obj is LicensesInputFile[] { + return Array.isArray(obj) && obj.every((item) => isLicensesInputFile(item)); +} +export function isLicensesInputFile(obj: any): obj is LicensesInputFile { + return ( + typeof obj === "object" && + obj !== null && + "expiry_date" in obj && + "account_id" in obj && + "type" in obj && + "status" in obj && + typeof obj.expiry_date === "string" && + typeof obj.account_id === "number" && + typeof obj.type === "string" && + typeof obj.status === "string" && + (obj.allocated_user_id === null || + typeof obj.allocated_user_id === "number") + ); +} + +export function isWorktypesInputFileArray( + obj: any +): obj is WorktypesInputFile[] { + return Array.isArray(obj) && obj.every((item) => isWorktypesInputFile(item)); +} +export function isWorktypesInputFile(obj: any): obj is WorktypesInputFile { + return ( + typeof obj === "object" && + obj !== null && + "account_id" in obj && + "custom_worktype_id" in obj && + typeof obj.account_id === "number" && + typeof obj.custom_worktype_id === "string" + ); +} + +export function isCardLicensesInputFileArray( + obj: any +): obj is CardLicensesInputFile[] { + return ( + Array.isArray(obj) && obj.every((item) => isCardLicensesInputFile(item)) + ); +} +export function isCardLicensesInputFile( + obj: any +): obj is CardLicensesInputFile { + return ( + typeof obj === "object" && + obj !== null && + "license_id" in obj && + "issue_id" in obj && + "card_license_key" in obj && + typeof obj.license_id === "number" && + typeof obj.issue_id === "number" && + typeof obj.card_license_key === "string" && + (obj.activated_at === null || typeof obj.activated_at === "string") && + (obj.created_at === null || typeof obj.created_at === "string") && + (obj.created_by === null || typeof obj.created_by === "string") && + (obj.updated_at === null || typeof obj.updated_at === "string") && + (obj.updated_by === null || typeof obj.updated_by === "string") + ); +} diff --git a/data_migration_tools/server/src/constants/index.ts b/data_migration_tools/server/src/constants/index.ts index e363afc..4acb160 100644 --- a/data_migration_tools/server/src/constants/index.ts +++ b/data_migration_tools/server/src/constants/index.ts @@ -1,3 +1,20 @@ +/** + * 階層 + * @const {number} + */ +export const TIERS = { + //OMDS東京 + TIER1: 1, + //OMDS現地法人 + TIER2: 2, + //代理店 + TIER3: 3, + //販売店 + TIER4: 4, + //エンドユーザー + TIER5: 5, +} as const; + /** * 音声ファイルをEast USに保存する国リスト * @const {number} @@ -52,6 +69,213 @@ export const BLOB_STORAGE_REGION_EU = [ "GB", ]; +/** + * 管理ロール + * @const {string[]} + */ +export const ADMIN_ROLES = { + ADMIN: "admin", + STANDARD: "standard", +} as const; + +/** + * ロール + * @const {string[]} + */ +export const USER_ROLES = { + NONE: "none", + AUTHOR: "author", + TYPIST: "typist", +} as const; + +/** + * ロールのソート順 + * @const {string[]} + */ +export const USER_ROLE_ORDERS = [ + USER_ROLES.AUTHOR, + USER_ROLES.TYPIST, + USER_ROLES.NONE, +] as string[]; + +/** + * ライセンス注文状態 + * @const {string[]} + */ +export const LICENSE_ISSUE_STATUS = { + ISSUE_REQUESTING: "Issue Requesting", + ISSUED: "Issued", + CANCELED: "Order Canceled", +}; + +/** + * ライセンス種別 + * @const {string[]} + */ +export const LICENSE_TYPE = { + TRIAL: "TRIAL", + NORMAL: "NORMAL", + CARD: "CARD", +} as const; +/** + * ライセンス状態 + * @const {string[]} + */ +export const LICENSE_ALLOCATED_STATUS = { + UNALLOCATED: "Unallocated", + ALLOCATED: "Allocated", + REUSABLE: "Reusable", + DELETED: "Deleted", +} as const; +/** + * 切り替え元種別 + * @const {string[]} + */ +export const SWITCH_FROM_TYPE = { + NONE: "NONE", + CARD: "CARD", + TRIAL: "TRIAL", +} as const; + +/** + * ライセンスの期限切れが近いと見なす日数のしきい値 + * @const {number} + */ +export const LICENSE_EXPIRATION_THRESHOLD_DAYS = 14; + +/** + * ライセンスの有効期間 + * @const {number} + */ +export const LICENSE_EXPIRATION_DAYS = 365; + +/** + * タイムゾーンを加味したライセンスの有効期間(8時間) + * @const {number} + */ +export const LICENSE_EXPIRATION_TIME_WITH_TIMEZONE = 8; + +/** + * カードライセンスの桁数 + * @const {number} + */ +export const CARD_LICENSE_LENGTH = 20; + +/** + * 音声ファイルに紐づくオプションアイテムの数 + * @const {string} + */ +export const OPTION_ITEM_NUM = 10; + +/** + * 文字起こしタスクのステータス + * @const {string[]} + */ +export const TASK_STATUS = { + UPLOADED: "Uploaded", + PENDING: "Pending", + IN_PROGRESS: "InProgress", + FINISHED: "Finished", + BACKUP: "Backup", +} as const; + +/** + * タスク一覧でソート可能な属性の一覧 + */ +export const TASK_LIST_SORTABLE_ATTRIBUTES = [ + "JOB_NUMBER", + "STATUS", + "ENCRYPTION", + "AUTHOR_ID", + "WORK_TYPE", + "FILE_NAME", + "FILE_LENGTH", + "FILE_SIZE", + "RECORDING_STARTED_DATE", + "RECORDING_FINISHED_DATE", + "UPLOAD_DATE", + "TRANSCRIPTION_STARTED_DATE", + "TRANSCRIPTION_FINISHED_DATE", +] as const; + +/** + * タスク一覧のソート条件(昇順・降順) + */ +export const SORT_DIRECTIONS = ["ASC", "DESC"] as const; + +/** + * 通知タグの最大個数 + * NotificationHubの仕様上タグ式のOR条件で使えるタグは20個まで + * https://learn.microsoft.com/ja-jp/azure/notification-hubs/notification-hubs-tags-segment-push-message#tag-expressions + */ +export const TAG_MAX_COUNT = 20; + +/** + * 通知のプラットフォーム種別文字列 + */ +export const PNS = { + WNS: "wns", + APNS: "apns", +}; + +/** + * ユーザーのライセンスの有効期限の状態 + */ +export const USER_LICENSE_EXPIRY_STATUS = { + NORMAL: "Normal", + NO_LICENSE: "NoLicense", + ALERT: "Alert", + RENEW: "Renew", +}; + +/** + *トライアルライセンスの有効期限(日数) + * @const {number} + */ +export const TRIAL_LICENSE_EXPIRATION_DAYS = 30; + +/** + * ライセンスの発行数 + * @const {number} + */ +export const TRIAL_LICENSE_ISSUE_NUM = 100; + +/** + * worktypeの最大登録数 + * @const {number} + */ +export const WORKTYPE_MAX_COUNT = 20; + +/** + * worktypeのDefault値の取りうる値 + **/ +export const OPTION_ITEM_VALUE_TYPE = { + DEFAULT: "Default", + BLANK: "Blank", + LAST_INPUT: "LastInput", +} as const; + +/** + * オプションアイテムのタイプ文字列と数値の対応 + **/ +export const OPTION_ITEM_VALUE_TYPE_NUMBER: { + type: string; + value: number; +}[] = [ + { + type: OPTION_ITEM_VALUE_TYPE.BLANK, + value: 1, + }, + { + type: OPTION_ITEM_VALUE_TYPE.DEFAULT, + value: 2, + }, + { + type: OPTION_ITEM_VALUE_TYPE.LAST_INPUT, + value: 3, + }, +]; + /** * ADB2Cユーザのidentity.signInType * @const {string[]} @@ -60,8 +284,52 @@ export const ADB2C_SIGN_IN_TYPE = { EMAILADDRESS: "emailAddress", } as const; +/** + * MANUAL_RECOVERY_REQUIRED + * @const {string} + */ +export const MANUAL_RECOVERY_REQUIRED = "[MANUAL_RECOVERY_REQUIRED]"; + +/** + * 利用規約種別 + * @const {string[]} + */ +export const TERM_TYPE = { + EULA: "EULA", + DPA: "DPA", + PRIVACY_NOTICE: "PrivacyNotice", +} as const; + +/** + * 音声ファイルのフォーマット + * @const {string} + */ +export const USER_AUDIO_FORMAT = "DS2(QP)"; + +/** + * ユニットテスト実行をしている場合のNODE_ENVの値 + * @const {string[]} + */ +export const NODE_ENV_TEST = "test"; + +/** + * ユーザに対するライセンスの状態 + * @const {string[]} + */ +export const USER_LICENSE_STATUS = { + UNALLOCATED: "unallocated", + ALLOCATED: "allocated", + EXPIRED: "expired", +} as const; + /** * AutoIncrementの初期値 * @const {number} */ export const AUTO_INCREMENT_START = 853211; + +/** + * 移行データ登録時のsleep間隔 + * @const {number} + */ +export const MIGRATION_DATA_REGISTER_INTERVAL_MILLISEC = 13; diff --git a/data_migration_tools/server/src/features/accounts/accounts.controller.ts b/data_migration_tools/server/src/features/accounts/accounts.controller.ts new file mode 100644 index 0000000..97ae0b9 --- /dev/null +++ b/data_migration_tools/server/src/features/accounts/accounts.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Logger } from "@nestjs/common"; +import { ApiTags } from "@nestjs/swagger"; +import { AccountsService } from "./accounts.service"; + +@ApiTags("accounts") +@Controller("accounts") +export class AccountsController { + private readonly logger = new Logger(AccountsController.name); + constructor( + private readonly accountService: AccountsService //private readonly cryptoService: CryptoService, + ) {} +} diff --git a/data_migration_tools/server/src/features/accounts/accounts.module.ts b/data_migration_tools/server/src/features/accounts/accounts.module.ts new file mode 100644 index 0000000..cb6db2b --- /dev/null +++ b/data_migration_tools/server/src/features/accounts/accounts.module.ts @@ -0,0 +1,19 @@ +import { Module } from "@nestjs/common"; +import { UsersRepositoryModule } from "../../repositories/users/users.repository.module"; +import { AccountsRepositoryModule } from "../../repositories/accounts/accounts.repository.module"; +import { AccountsController } from "./accounts.controller"; +import { AccountsService } from "./accounts.service"; +import { AdB2cModule } from "../../gateways/adb2c/adb2c.module"; +import { BlobstorageModule } from "../../gateways/blobstorage/blobstorage.module"; + +@Module({ + imports: [ + AccountsRepositoryModule, + UsersRepositoryModule, + AdB2cModule, + BlobstorageModule, + ], + controllers: [AccountsController], + providers: [AccountsService], +}) +export class AccountsModule {} diff --git a/data_migration_tools/server/src/features/accounts/accounts.service.ts b/data_migration_tools/server/src/features/accounts/accounts.service.ts new file mode 100644 index 0000000..4a7dd65 --- /dev/null +++ b/data_migration_tools/server/src/features/accounts/accounts.service.ts @@ -0,0 +1,227 @@ +import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; +import { AccountsRepositoryService } from "../../repositories/accounts/accounts.repository.service"; +import { + AdB2cService, + ConflictError, + isConflictError, +} from "../../gateways/adb2c/adb2c.service"; +import { Account } from "../../repositories/accounts/entity/account.entity"; +import { User } from "../../repositories/users/entity/user.entity"; +import { MANUAL_RECOVERY_REQUIRED } from "../../constants"; +import { makeErrorResponse } from "../../common/error/makeErrorResponse"; +import { Context } from "../../common/log"; +import { BlobstorageService } from "../../gateways/blobstorage/blobstorage.service"; + +@Injectable() +export class AccountsService { + constructor( + private readonly accountRepository: AccountsRepositoryService, + private readonly adB2cService: AdB2cService, + private readonly blobStorageService: BlobstorageService + ) {} + private readonly logger = new Logger(AccountsService.name); + + /** + * アカウント情報をDBに作成する + * @param companyName + * @param country + * @param [dealerAccountId] + * @returns account + */ + async createAccount( + context: Context, + companyName: string, + country: string, + dealerAccountId: number | undefined, + email: string, + password: string, + username: string, + role: string, + acceptedEulaVersion: string, + acceptedPrivacyNoticeVersion: string, + acceptedDpaVersion: string, + type: number, + accountId: number, + userId: number + ): Promise<{ accountId: number; userId: number; externalUserId: string }> { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.createAccount.name + } | params: { ` + + `dealerAccountId: ${dealerAccountId}, ` + + `role: ${role}, ` + + `acceptedEulaVersion: ${acceptedEulaVersion}, ` + + `acceptedPrivacyNoticeVersion: ${acceptedPrivacyNoticeVersion}, ` + + `acceptedDpaVersion: ${acceptedDpaVersion}, ` + + `type: ${type}, ` + + `accountId: ${accountId}, ` + + `userId: ${userId} };` + ); + try { + let externalUser: { sub: string } | ConflictError; + try { + // idpにユーザーを作成 + externalUser = await this.adB2cService.createUser( + context, + email, + password, + username + ); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + this.logger.error( + `[${context.getTrackingId()}] create externalUser failed` + ); + + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + // メールアドレス重複エラー + if (isConflictError(externalUser)) { + this.logger.error( + `[${context.getTrackingId()}] email conflict. externalUser: ${externalUser}` + ); + throw new HttpException( + makeErrorResponse("E010301"), + HttpStatus.BAD_REQUEST + ); + } + + let account: Account; + let user: User; + try { + // アカウントと管理者をセットで作成 + const { newAccount, adminUser } = + await this.accountRepository.createAccount( + context, + companyName, + country, + dealerAccountId, + type, + externalUser.sub, + role, + accountId, + userId, + acceptedEulaVersion, + acceptedPrivacyNoticeVersion, + acceptedDpaVersion + ); + account = newAccount; + user = adminUser; + this.logger.log( + `[${context.getTrackingId()}] adminUser.external_id: ${ + user.external_id + }` + ); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + this.logger.error(`[${context.getTrackingId()}] create account failed`); + //リカバリ処理 + // idpのユーザーを削除 + await this.deleteAdB2cUser(externalUser.sub, context); + + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + // 新規作成アカウント用のBlobコンテナを作成 + try { + await this.blobStorageService.createContainer( + context, + account.id, + country + ); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + this.logger.error( + `[${context.getTrackingId()}] create container failed` + ); + //リカバリ処理 + // idpのユーザーを削除 + await this.deleteAdB2cUser(externalUser.sub, context); + + // DBのアカウントを削除 + await this.deleteAccount(account.id, user.id, context); + + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + return { + accountId: account.id, + userId: user.id, + externalUserId: user.external_id, + }; + } catch (e) { + throw e; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.createAccount.name}` + ); + } + } + + // AdB2cのユーザーを削除 + // TODO「タスク 2452: リトライ処理を入れる箇所を検討し、実装する」の候補 + private async deleteAdB2cUser( + externalUserId: string, + context: Context + ): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.createAccount.name + } | params: { ` + `externalUserId: ${externalUserId}};` + ); + try { + await this.adB2cService.deleteUser(externalUserId, context); + this.logger.log( + `[${context.getTrackingId()}] delete externalUser: ${externalUserId} | params: { ` + + `externalUserId: ${externalUserId}, };` + ); + } catch (error) { + this.logger.error(`[${context.getTrackingId()}] error=${error}`); + this.logger.error( + `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete externalUser: ${externalUserId}` + ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteAdB2cUser.name}` + ); + } + } + + // DBのアカウントを削除 + private async deleteAccount( + accountId: number, + userId: number, + context: Context + ): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.deleteAccount.name + } | params: { accountId: ${accountId}, userId: ${userId} };` + ); + try { + await this.accountRepository.deleteAccount(context, accountId, userId); + this.logger.log( + `[${context.getTrackingId()}] delete account: ${accountId}, user: ${userId}` + ); + } catch (error) { + this.logger.error(`[${context.getTrackingId()}] error=${error}`); + this.logger.error( + `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete account: ${accountId}, user: ${userId}` + ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteAccount.name}` + ); + } + } +} diff --git a/data_migration_tools/server/src/features/register/register.controller.ts b/data_migration_tools/server/src/features/register/register.controller.ts new file mode 100644 index 0000000..c55d548 --- /dev/null +++ b/data_migration_tools/server/src/features/register/register.controller.ts @@ -0,0 +1,209 @@ +import { + Body, + Controller, + HttpStatus, + Post, + Req, + Logger, + HttpException, +} from "@nestjs/common"; +import { makeErrorResponse } from "../../common/error/makeErrorResponse"; +import fs from "fs"; +import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; +import { Request } from "express"; +import { RegisterRequest, RegisterResponse } from "./types/types"; +import { RegisterService } from "./register.service"; +import { AccountsService } from "../accounts/accounts.service"; +import { UsersService } from "../users/users.service"; +import { makeContext } from "../../common/log"; +import { + isAccountsInputFileArray, + isUsersInputFileArray, + isLicensesInputFileArray, + isWorktypesInputFileArray, + isCardLicensesInputFileArray, +} from "../../common/types/types"; +import { makePassword } from "../../common/password/password"; +import { + USER_ROLES, + MIGRATION_DATA_REGISTER_INTERVAL_MILLISEC, +} from "../../constants"; + +@ApiTags("register") +@Controller("register") +export class RegisterController { + private readonly logger = new Logger(RegisterController.name); + constructor( + private readonly registerService: RegisterService, + private readonly accountsService: AccountsService, + private readonly usersService: UsersService + ) {} + + @Post() + @ApiResponse({ + status: HttpStatus.OK, + type: RegisterResponse, + description: "成功時のレスポンス", + }) + @ApiResponse({ + status: HttpStatus.INTERNAL_SERVER_ERROR, + description: "想定外のサーバーエラー", + }) + @ApiOperation({ operationId: "dataRegist" }) + async dataRegist( + @Body() body: RegisterRequest, + @Req() req: Request + ): Promise { + const context = makeContext("iko", "register"); + + const inputFilePath = body.inputFilePath; + + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.dataRegist.name + } | params: { inputFilePath: ${inputFilePath}};` + ); + + try { + // 読み込みファイルのフルパス + const accouncsFileFullPath = inputFilePath + "accounts.json"; + const usersFileFullPath = inputFilePath + "users.json"; + const licensesFileFullPath = inputFilePath + "licenses.json"; + const worktypesFileFullPath = inputFilePath + "worktypes.json"; + const cardLicensesFileFullPath = inputFilePath + "cardLicenses.json"; + + // ファイル存在チェックと読み込み + if ( + !fs.existsSync(accouncsFileFullPath) || + !fs.existsSync(usersFileFullPath) || + !fs.existsSync(licensesFileFullPath) || + !fs.existsSync(worktypesFileFullPath) || + !fs.existsSync(cardLicensesFileFullPath) + ) { + this.logger.error(`file not exists from ${inputFilePath}`); + throw new Error(`file not exists from ${inputFilePath}`); + } + + // アカウントの登録用ファイル読み込み + const accountsObject = JSON.parse( + fs.readFileSync(accouncsFileFullPath, "utf8") + ); + + // 型ガード(account) + if (!isAccountsInputFileArray(accountsObject)) { + throw new Error("input file is not accountsInputFiles"); + } + + for (const accountsInputFile of accountsObject) { + // ランダムなパスワードを生成する + const ramdomPassword = makePassword(); + await this.accountsService.createAccount( + context, + accountsInputFile.companyName, + accountsInputFile.country, + accountsInputFile.dealerAccountId, + accountsInputFile.adminMail, + ramdomPassword, + accountsInputFile.adminName, + "none", + null, + null, + null, + accountsInputFile.type, + accountsInputFile.accountId, + accountsInputFile.userId + ); + + // ratelimit対応のためsleepを行う + await sleep(MIGRATION_DATA_REGISTER_INTERVAL_MILLISEC); + } + // const accountsInputFiles = accountsObject as AccountsInputFile[]; + + // ユーザの登録用ファイル読み込み + const usersObject = JSON.parse( + fs.readFileSync(usersFileFullPath, "utf8") + ); + + // 型ガード(user) + if (!isUsersInputFileArray(usersObject)) { + throw new Error("input file is not usersInputFiles"); + } + + for (const usersInputFile of usersObject) { + this.logger.log(usersInputFile.name); + await this.usersService.createUser( + context, + usersInputFile.name, + usersInputFile.role === USER_ROLES.AUTHOR + ? USER_ROLES.AUTHOR + : USER_ROLES.NONE, + usersInputFile.email, + true, + true, + usersInputFile.accountId, + usersInputFile.userId, + usersInputFile.authorId, + false, + null, + true + ); + // ratelimit対応のためsleepを行う + await sleep(MIGRATION_DATA_REGISTER_INTERVAL_MILLISEC); + } + + // ライセンスの登録用ファイル読み込み + const licensesObject = JSON.parse( + fs.readFileSync(licensesFileFullPath, "utf8") + ); + + // 型ガード(license) + if (!isLicensesInputFileArray(licensesObject)) { + throw new Error("input file is not licensesInputFiles"); + } + + // ワークタイプの登録用ファイル読み込み + const worktypesObject = JSON.parse( + fs.readFileSync(worktypesFileFullPath, "utf8") + ); + + // 型ガード(Worktypes) + if (!isWorktypesInputFileArray(worktypesObject)) { + throw new Error("input file is not WorktypesInputFiles"); + } + + // カードライセンスの登録用ファイル読み込み + const cardLicensesObject = JSON.parse( + fs.readFileSync(cardLicensesFileFullPath, "utf8") + ); + + // 型ガード(cardLicenses) + if (!isCardLicensesInputFileArray(cardLicensesObject)) { + throw new Error("input file is not cardLicensesInputFiles"); + } + + // ライセンス・ワークタイプ・カードライセンスの登録 + await this.registerService.registLicenseAndWorktypeData( + context, + licensesObject, + worktypesObject, + cardLicensesObject + ); + + return {}; + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.dataRegist.name}` + ); + } + } +} + +function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/data_migration_tools/server/src/features/register/register.module.ts b/data_migration_tools/server/src/features/register/register.module.ts new file mode 100644 index 0000000..10015dd --- /dev/null +++ b/data_migration_tools/server/src/features/register/register.module.ts @@ -0,0 +1,25 @@ +import { Module } from "@nestjs/common"; +import { RegisterController } from "./register.controller"; +import { RegisterService } from "./register.service"; +import { AccountsService } from "../accounts/accounts.service"; +import { UsersService } from "../users/users.service"; +import { LicensesRepositoryModule } from "../../repositories/licenses/licenses.repository.module"; +import { WorktypesRepositoryModule } from "../../repositories/worktypes/worktypes.repository.module"; +import { UsersRepositoryModule } from "../../repositories/users/users.repository.module"; +import { AccountsRepositoryModule } from "../../repositories/accounts/accounts.repository.module"; +import { AdB2cModule } from "../../gateways/adb2c/adb2c.module"; +import { BlobstorageModule } from "../../gateways/blobstorage/blobstorage.module"; + +@Module({ + imports: [ + LicensesRepositoryModule, + WorktypesRepositoryModule, + AccountsRepositoryModule, + UsersRepositoryModule, + AdB2cModule, + BlobstorageModule, + ], + controllers: [RegisterController], + providers: [RegisterService, AccountsService, UsersService], +}) +export class RegisterModule {} diff --git a/data_migration_tools/server/src/features/register/register.service.ts b/data_migration_tools/server/src/features/register/register.service.ts new file mode 100644 index 0000000..6e42dc1 --- /dev/null +++ b/data_migration_tools/server/src/features/register/register.service.ts @@ -0,0 +1,68 @@ +import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; +import { Context } from "../../common/log"; +import { + LicensesInputFile, + WorktypesInputFile, + CardLicensesInputFile, +} from "../../common/types/types"; +import { LicensesRepositoryService } from "../../repositories/licenses/licenses.repository.service"; +import { WorktypesRepositoryService } from "../../repositories/worktypes/worktypes.repository.service"; +import { makeErrorResponse } from "../../common/error/makeErrorResponse"; +@Injectable() +export class RegisterService { + constructor( + private readonly licensesRepository: LicensesRepositoryService, + private readonly worktypesRepository: WorktypesRepositoryService + ) {} + private readonly logger = new Logger(RegisterService.name); + + /** + * Regist Data + * @param inputFilePath: string + */ + async registLicenseAndWorktypeData( + context: Context, + licensesInputFiles: LicensesInputFile[], + worktypesInputFiles: WorktypesInputFile[], + cardlicensesInputFiles: CardLicensesInputFile[] + ): Promise { + // パラメータ内容が長大なのでログには出さない + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.registLicenseAndWorktypeData.name + }` + ); + + try { + this.logger.log("Licenses register start"); + await this.licensesRepository.insertLicenses(context, licensesInputFiles); + this.logger.log("Licenses register end"); + + this.logger.log("Worktypes register start"); + await this.worktypesRepository.createWorktype( + context, + worktypesInputFiles + ); + this.logger.log("Worktypes register end"); + + this.logger.log("CardLicenses register start"); + await this.licensesRepository.insertCardLicenses( + context, + cardlicensesInputFiles + ); + this.logger.log("CardLicenses register end"); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${ + this.registLicenseAndWorktypeData.name + }` + ); + } + } +} diff --git a/data_migration_tools/server/src/features/register/types/types.ts b/data_migration_tools/server/src/features/register/types/types.ts new file mode 100644 index 0000000..30fe678 --- /dev/null +++ b/data_migration_tools/server/src/features/register/types/types.ts @@ -0,0 +1,10 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class RegisterRequest { + @ApiProperty() + inputFilePath: string; + +} + +export class RegisterResponse {} + diff --git a/data_migration_tools/server/src/features/users/users.controller.ts b/data_migration_tools/server/src/features/users/users.controller.ts new file mode 100644 index 0000000..14c5cad --- /dev/null +++ b/data_migration_tools/server/src/features/users/users.controller.ts @@ -0,0 +1,10 @@ +import { Controller, Logger } from "@nestjs/common"; +import { ApiTags } from "@nestjs/swagger"; +import { UsersService } from "./users.service"; + +@ApiTags("users") +@Controller("users") +export class UsersController { + private readonly logger = new Logger(UsersController.name); + constructor(private readonly usersService: UsersService) {} +} diff --git a/data_migration_tools/server/src/features/users/users.module.ts b/data_migration_tools/server/src/features/users/users.module.ts new file mode 100644 index 0000000..3f0da57 --- /dev/null +++ b/data_migration_tools/server/src/features/users/users.module.ts @@ -0,0 +1,12 @@ +import { Module } from "@nestjs/common"; +import { AdB2cModule } from "../../gateways/adb2c/adb2c.module"; +import { UsersRepositoryModule } from "../../repositories/users/users.repository.module"; +import { UsersController } from "./users.controller"; +import { UsersService } from "./users.service"; + +@Module({ + imports: [UsersRepositoryModule, AdB2cModule], + controllers: [UsersController], + providers: [UsersService], +}) +export class UsersModule {} diff --git a/data_migration_tools/server/src/features/users/users.service.ts b/data_migration_tools/server/src/features/users/users.service.ts new file mode 100644 index 0000000..cb639cd --- /dev/null +++ b/data_migration_tools/server/src/features/users/users.service.ts @@ -0,0 +1,306 @@ +import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; +import { makeErrorResponse } from "../../common/error/makeErrorResponse"; +import { makePassword } from "../../common/password/password"; +import { + AdB2cService, + ConflictError, + isConflictError, +} from "../../gateways/adb2c/adb2c.service"; +import { + User as EntityUser, + newUser, +} from "../../repositories/users/entity/user.entity"; +import { UsersRepositoryService } from "../../repositories/users/users.repository.service"; +import { MANUAL_RECOVERY_REQUIRED, USER_ROLES } from "../../constants"; +import { Context } from "../../common/log"; +import { UserRoles } from "../../common/types/role"; + +@Injectable() +export class UsersService { + private readonly logger = new Logger(UsersService.name); + constructor( + private readonly usersRepository: UsersRepositoryService, + private readonly adB2cService: AdB2cService + ) {} + + /** + * Creates user + * @param context + * @param name + * @param role + * @param email + * @param autoRenew + * @param notification + * @param accountId + * @param userid + * @param [authorId] + * @param [encryption] + * @param [encryptionPassword] + * @param [prompt] + * @returns user + */ + async createUser( + context: Context, + name: string, + role: UserRoles, + email: string, + autoRenew: boolean, + notification: boolean, + accountId: number, + userid: number, + authorId?: string | undefined, + encryption?: boolean | undefined, + encryptionPassword?: string | undefined, + prompt?: boolean | undefined + ): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.createUser.name} | params: { ` + + `role: ${role}, ` + + `autoRenew: ${autoRenew}, ` + + `notification: ${notification}, ` + + `accountId: ${accountId}, ` + + `userid: ${userid}, ` + + `authorId: ${authorId}, ` + + `encryption: ${encryption}, ` + + `prompt: ${prompt} };` + ); + + //authorIdが重複していないかチェックする + if (authorId) { + let isAuthorIdDuplicated = false; + try { + isAuthorIdDuplicated = await this.usersRepository.existsAuthorId( + context, + accountId, + authorId + ); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + if (isAuthorIdDuplicated) { + throw new HttpException( + makeErrorResponse("E010302"), + HttpStatus.BAD_REQUEST + ); + } + } + + // ランダムなパスワードを生成する + const ramdomPassword = makePassword(); + + //Azure AD B2Cにユーザーを新規登録する + let externalUser: { sub: string } | ConflictError; + try { + this.logger.log(`name=${name}`); + // idpにユーザーを作成 + externalUser = await this.adB2cService.createUser( + context, + email, + ramdomPassword, + name + ); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + this.logger.error( + `[${context.getTrackingId()}] create externalUser failed` + ); + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + // メールアドレス重複エラー + if (isConflictError(externalUser)) { + throw new HttpException( + makeErrorResponse("E010301"), + HttpStatus.BAD_REQUEST + ); + } + + //Azure AD B2Cに登録したユーザー情報のID(sub)と受け取った情報を使ってDBにユーザーを登録する + let newUser: EntityUser; + + try { + //roleに応じてユーザー情報を作成する + const newUserInfo = this.createNewUserInfo( + context, + userid, + role, + accountId, + externalUser.sub, + autoRenew, + notification, + authorId, + encryption, + encryptionPassword, + prompt + ); + // ユーザ作成 + newUser = await this.usersRepository.createNormalUser( + context, + newUserInfo + ); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + this.logger.error(`[${context.getTrackingId()}]create user failed`); + //リカバリー処理 + //Azure AD B2Cに登録したユーザー情報を削除する + await this.deleteB2cUser(externalUser.sub, context); + + switch (e.code) { + case "ER_DUP_ENTRY": + //AuthorID重複エラー + throw new HttpException( + makeErrorResponse("E010302"), + HttpStatus.BAD_REQUEST + ); + default: + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + } + + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.createUser.name}` + ); + return; + } + + // Azure AD B2Cに登録したユーザー情報を削除する + // TODO 「タスク 2452: リトライ処理を入れる箇所を検討し、実装する」の候補 + private async deleteB2cUser(externalUserId: string, context: Context) { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.deleteB2cUser.name + } | params: { externalUserId: ${externalUserId} }` + ); + try { + await this.adB2cService.deleteUser(externalUserId, context); + this.logger.log( + `[${context.getTrackingId()}] delete externalUser: ${externalUserId}` + ); + } catch (error) { + this.logger.error(`[${context.getTrackingId()}] error=${error}`); + this.logger.error( + `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete externalUser: ${externalUserId}` + ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteB2cUser.name}` + ); + } + } + + // DBに登録したユーザー情報を削除する + private async deleteUser(userId: number, context: Context) { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.deleteUser.name + } | params: { userId: ${userId} }` + ); + try { + await this.usersRepository.deleteNormalUser(context, userId); + this.logger.log(`[${context.getTrackingId()}] delete user: ${userId}`); + } catch (error) { + this.logger.error(`[${context.getTrackingId()}] error=${error}`); + this.logger.error( + `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete user: ${userId}` + ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteUser.name}` + ); + } + } + + // roleを受け取って、roleに応じたnewUserを作成して返却する + private createNewUserInfo( + context: Context, + id: number, + role: UserRoles, + accountId: number, + externalId: string, + autoRenew: boolean, + notification: boolean, + authorId?: string | undefined, + encryption?: boolean | undefined, + encryptionPassword?: string | undefined, + prompt?: boolean | undefined + ): newUser { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.createNewUserInfo.name + } | params: { ` + + `id: ${id}, ` + + `role: ${role}, ` + + `accountId: ${accountId}, ` + + `authorId: ${authorId}, ` + + `externalId: ${externalId}, ` + + `autoRenew: ${autoRenew}, ` + + `notification: ${notification}, ` + + `authorId: ${authorId}, ` + + `encryption: ${encryption}, ` + + `prompt: ${prompt} };` + ); + try { + switch (role) { + case USER_ROLES.NONE: + case USER_ROLES.TYPIST: + return { + id, + account_id: accountId, + external_id: externalId, + auto_renew: autoRenew, + notification, + role, + accepted_dpa_version: null, + accepted_eula_version: null, + accepted_privacy_notice_version: null, + encryption: false, + encryption_password: null, + prompt: false, + author_id: null, + }; + case USER_ROLES.AUTHOR: + return { + id, + account_id: accountId, + external_id: externalId, + auto_renew: autoRenew, + notification, + role, + author_id: authorId ?? null, + encryption: encryption ?? false, + encryption_password: encryptionPassword ?? null, + prompt: prompt ?? false, + accepted_dpa_version: null, + accepted_eula_version: null, + accepted_privacy_notice_version: null, + }; + default: + //不正なroleが指定された場合はログを出力してエラーを返す + this.logger.error( + `[${context.getTrackingId()}] [NOT IMPLEMENT] [RECOVER] role: ${role}` + ); + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + return e; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.createNewUserInfo.name}` + ); + } + } +} diff --git a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts index 743fbf8..b561f42 100644 --- a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts +++ b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts @@ -5,6 +5,8 @@ import { Injectable, Logger } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; import { AdB2cResponse, AdB2cUser } from "./types/types"; import { isPromiseRejectedResult } from "./utils/utils"; +import { Context } from "../../common/log"; +import { ADB2C_SIGN_IN_TYPE } from "../../constants"; export type ConflictError = { reason: "email"; @@ -27,9 +29,16 @@ export const isConflictError = (arg: unknown): arg is ConflictError => { @Injectable() export class AdB2cService { private readonly logger = new Logger(AdB2cService.name); + private readonly tenantName: string; + private readonly flowName: string; + private readonly ttl: number; private graphClient: Client; constructor(private readonly configService: ConfigService) { + this.tenantName = this.configService.getOrThrow("TENANT_NAME"); + this.flowName = this.configService.getOrThrow("SIGNIN_FLOW_NAME"); + this.ttl = this.configService.getOrThrow("ADB2C_CACHE_TTL"); + // ADB2Cへの認証情報 const credential = new ClientSecretCredential( this.configService.getOrThrow("ADB2C_TENANT_ID"), @@ -42,6 +51,61 @@ export class AdB2cService { this.graphClient = Client.initWithMiddleware({ authProvider }); } + + /** + * Creates user AzureADB2Cにユーザーを追加する + * @param email 管理ユーザーのメールアドレス + * @param password 管理ユーザーのパスワード + * @param username 管理ユーザーの名前 + * @returns user + */ + async createUser( + context: Context, + email: string, + password: string, + username: string + ): Promise<{ sub: string } | ConflictError> { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.createUser.name}` + ); + try { + // ユーザをADB2Cに登録 + const newUser = await this.graphClient.api("users/").post({ + accountEnabled: true, + displayName: username, + passwordPolicies: "DisableStrongPassword", + passwordProfile: { + forceChangePasswordNextSignIn: false, + password: password, + }, + identities: [ + { + signinType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: `${this.tenantName}.onmicrosoft.com`, + issuerAssignedId: email, + }, + ], + }); + return { sub: newUser.id }; + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + if (e?.statusCode === 400 && e?.body) { + const error = JSON.parse(e.body); + + // エラーが競合エラーである場合は、メールアドレス重複としてエラーを返す + if (error?.details?.find((x) => x.code === "ObjectConflict")) { + return { reason: "email", message: "ObjectConflict" }; + } + } + + throw e; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.createUser.name}` + ); + } + } + /** * Gets users * @param externalIds @@ -71,6 +135,44 @@ export class AdB2cService { } } + /** + * Azure AD B2Cからユーザ情報を削除する + * @param externalId 外部ユーザーID + * @param context コンテキスト + */ + async deleteUser(externalId: string, context: Context): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.deleteUser.name + } | params: { externalId: ${externalId} };` + ); + + try { + // https://learn.microsoft.com/en-us/graph/api/user-delete?view=graph-rest-1.0&tabs=javascript#example + await this.graphClient.api(`users/${externalId}`).delete(); + this.logger.log( + `[${context.getTrackingId()}] [ADB2C DELETE] externalId: ${externalId}` + ); + + // キャッシュからも削除する + // 移行ツール特別対応:キャッシュ登録は行わないので削除も不要 + /* + try { + await this.redisService.del(context, makeADB2CKey(externalId)); + } catch (e) { + // キャッシュからの削除に失敗しても、ADB2Cからの削除は成功しているため例外はスローしない + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + } + */ + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + throw e; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteUser.name}` + ); + } + } /** * Azure AD B2Cからユーザ情報を削除する(複数) * @param externalIds 外部ユーザーID diff --git a/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts b/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts index 68e5a80..7c26388 100644 --- a/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts +++ b/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts @@ -1,10 +1,16 @@ import { Injectable, Logger } from "@nestjs/common"; import { + ContainerClient, BlobServiceClient, StorageSharedKeyCredential, } from "@azure/storage-blob"; +import { + BLOB_STORAGE_REGION_AU, + BLOB_STORAGE_REGION_EU, + BLOB_STORAGE_REGION_US, +} from "../../constants"; import { ConfigService } from "@nestjs/config"; - +import { Context } from "../../common/log"; @Injectable() export class BlobstorageService { private readonly logger = new Logger(BlobstorageService.name); @@ -41,6 +47,44 @@ export class BlobstorageService { ); } + /** + * Creates container + * @param context + * @param accountId + * @param country + * @returns container + */ + async createContainer( + context: Context, + accountId: number, + country: string + ): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.createContainer.name + } | params: { ` + `accountId: ${accountId} };` + ); + + // 国に応じたリージョンでコンテナ名を指定してClientを取得 + const containerClient = this.getContainerClient( + context, + accountId, + country + ); + + try { + // コンテナ作成 + await containerClient.create(); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + throw e; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.createContainer.name}` + ); + } + } + /** * すべてのコンテナを削除します。 * @returns containers @@ -80,4 +124,32 @@ export class BlobstorageService { this.logger.log(`[OUT] ${this.deleteContainers.name}`); } } + + /** + * Gets container client + * @param companyName + * @returns container client + */ + private getContainerClient( + context: Context, + accountId: number, + country: string + ): ContainerClient { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.getContainerClient.name + } | params: { ` + `accountId: ${accountId} };` + ); + + const containerName = `account-${accountId}`; + if (BLOB_STORAGE_REGION_US.includes(country)) { + return this.blobServiceClientUS.getContainerClient(containerName); + } else if (BLOB_STORAGE_REGION_AU.includes(country)) { + return this.blobServiceClientAU.getContainerClient(containerName); + } else if (BLOB_STORAGE_REGION_EU.includes(country)) { + return this.blobServiceClientEU.getContainerClient(containerName); + } else { + throw new Error("invalid country"); + } + } } diff --git a/data_migration_tools/server/src/repositories/accounts/accounts.repository.module.ts b/data_migration_tools/server/src/repositories/accounts/accounts.repository.module.ts new file mode 100644 index 0000000..ddd0efd --- /dev/null +++ b/data_migration_tools/server/src/repositories/accounts/accounts.repository.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Account } from './entity/account.entity'; +import { AccountsRepositoryService } from './accounts.repository.service'; + +@Module({ + imports: [TypeOrmModule.forFeature([Account])], + providers: [AccountsRepositoryService], + exports: [AccountsRepositoryService], +}) +export class AccountsRepositoryModule {} diff --git a/data_migration_tools/server/src/repositories/accounts/accounts.repository.service.ts b/data_migration_tools/server/src/repositories/accounts/accounts.repository.service.ts new file mode 100644 index 0000000..ec24808 --- /dev/null +++ b/data_migration_tools/server/src/repositories/accounts/accounts.repository.service.ts @@ -0,0 +1,164 @@ +import { Injectable } from '@nestjs/common'; +import { + DataSource, +} from 'typeorm'; +import { User } from '../users/entity/user.entity'; +import { Account } from './entity/account.entity'; +import { + getDirection, + getTaskListSortableAttribute, +} from '../../common/types/sort/util'; +import { SortCriteria } from "../sort_criteria/entity/sort_criteria.entity"; +import { + insertEntity, + updateEntity, + deleteEntity, +} from '../../common/repository'; +import { Context } from '../../common/log'; + +@Injectable() +export class AccountsRepositoryService { + // クエリログにコメントを出力するかどうか + private readonly isCommentOut = process.env.STAGE !== "local"; + constructor(private dataSource: DataSource) {} + + /** + * プライマリ管理者とアカウント、ソート条件を同時に作成する + * @param companyName + * @param country + * @param dealerAccountId + * @param tier + * @param adminExternalUserId + * @param adminUserRole + * @param accountId + * @param userId + * @param adminUserAcceptedEulaVersion + * @param adminUserAcceptedPrivacyNoticeVersion + * @param adminUserAcceptedDpaVersion + * @returns account/admin user + */ + async createAccount( + context: Context, + companyName: string, + country: string, + dealerAccountId: number | undefined, + tier: number, + adminExternalUserId: string, + adminUserRole: string, + accountId: number, + userId: number, + adminUserAcceptedEulaVersion?: string, + adminUserAcceptedPrivacyNoticeVersion?: string, + adminUserAcceptedDpaVersion?: string + ): Promise<{ newAccount: Account; adminUser: User }> { + return await this.dataSource.transaction(async (entityManager) => { + const account = new Account(); + { + account.id = accountId; + account.parent_account_id = dealerAccountId ?? null; + account.company_name = companyName; + account.country = country; + account.tier = tier; + } + const accountsRepo = entityManager.getRepository(Account); + const newAccount = accountsRepo.create(account); + const persistedAccount = await insertEntity( + Account, + accountsRepo, + newAccount, + this.isCommentOut, + context + ); + + // 作成されたAccountのIDを使用してユーザーを作成 + const user = new User(); + { + user.id = userId; + user.account_id = persistedAccount.id; + user.external_id = adminExternalUserId; + user.role = adminUserRole; + user.accepted_eula_version = adminUserAcceptedEulaVersion ?? null; + user.accepted_privacy_notice_version = + adminUserAcceptedPrivacyNoticeVersion ?? null; + user.accepted_dpa_version = adminUserAcceptedDpaVersion ?? null; + } + const usersRepo = entityManager.getRepository(User); + const newUser = usersRepo.create(user); + const persistedUser = await insertEntity( + User, + usersRepo, + newUser, + this.isCommentOut, + context + ); + + // アカウントに管理者を設定して更新 + persistedAccount.primary_admin_user_id = persistedUser.id; + + const result = await updateEntity( + accountsRepo, + { id: persistedAccount.id }, + persistedAccount, + this.isCommentOut, + context + ); + + // 想定外の更新が行われた場合はロールバックを行った上でエラー送出 + if (result.affected !== 1) { + throw new Error(`invalid update. result.affected=${result.affected}`); + } + + // ユーザーのタスクソート条件を作成 + const sortCriteria = new SortCriteria(); + { + sortCriteria.parameter = getTaskListSortableAttribute("JOB_NUMBER"); + sortCriteria.direction = getDirection("ASC"); + sortCriteria.user_id = persistedUser.id; + } + const sortCriteriaRepo = entityManager.getRepository(SortCriteria); + const newSortCriteria = sortCriteriaRepo.create(sortCriteria); + await insertEntity( + SortCriteria, + sortCriteriaRepo, + newSortCriteria, + this.isCommentOut, + context + ); + + return { newAccount: persistedAccount, adminUser: persistedUser }; + }); + } + + /** + * プライマリ管理者とアカウント、ソート条件を同時に削除する + * @param accountId + * @returns delete + */ + async deleteAccount( + context: Context, + accountId: number, + userId: number + ): Promise { + await this.dataSource.transaction(async (entityManager) => { + const accountsRepo = entityManager.getRepository(Account); + const usersRepo = entityManager.getRepository(User); + const sortCriteriaRepo = entityManager.getRepository(SortCriteria); + // ソート条件を削除 + await deleteEntity( + sortCriteriaRepo, + { user_id: userId }, + this.isCommentOut, + context + ); + // プライマリ管理者を削除 + await deleteEntity(usersRepo, { id: userId }, this.isCommentOut, context); + // アカウントを削除 + await deleteEntity( + accountsRepo, + { id: accountId }, + this.isCommentOut, + context + ); + }); + } +} diff --git a/data_migration_tools/server/src/repositories/accounts/entity/account.entity.ts b/data_migration_tools/server/src/repositories/accounts/entity/account.entity.ts new file mode 100644 index 0000000..3c40a03 --- /dev/null +++ b/data_migration_tools/server/src/repositories/accounts/entity/account.entity.ts @@ -0,0 +1,70 @@ +import { bigintTransformer } from '../../../common/entity'; +import { User } from '../../../repositories/users/entity/user.entity'; +import { + Entity, + Column, + PrimaryGeneratedColumn, + CreateDateColumn, + UpdateDateColumn, + OneToMany, +} from 'typeorm'; + +@Entity({ name: 'accounts' }) +export class Account { + @PrimaryGeneratedColumn() + id: number; + + @Column({ nullable: true, type: 'bigint', transformer: bigintTransformer }) + parent_account_id: number | null; + + @Column() + tier: number; + + @Column() + country: string; + + @Column({ default: false }) + delegation_permission: boolean; + + @Column({ default: false }) + locked: boolean; + + @Column() + company_name: string; + + @Column({ default: false }) + verified: boolean; + + @Column({ nullable: true, type: 'bigint', transformer: bigintTransformer }) + primary_admin_user_id: number | null; + + @Column({ nullable: true, type: 'bigint', transformer: bigintTransformer }) + secondary_admin_user_id: number | null; + + @Column({ nullable: true, type: 'bigint', transformer: bigintTransformer }) + active_worktype_id: number | null; + + @Column({ nullable: true, type: 'datetime' }) + deleted_at: Date | null; + + @Column({ nullable: true, type: 'datetime' }) + created_by: string | null; + + @CreateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) // defaultはSQLite用設定値.本番用は別途migrationで設定 + created_at: Date; + + @Column({ nullable: true, type: 'datetime' }) + updated_by: string | null; + + @UpdateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) // defaultはSQLite用設定値.本番用は別途migrationで設定 + updated_at: Date; + + @OneToMany(() => User, (user) => user.id) + user: User[] | null; +} diff --git a/data_migration_tools/server/src/repositories/accounts/errors/types.ts b/data_migration_tools/server/src/repositories/accounts/errors/types.ts new file mode 100644 index 0000000..826700c --- /dev/null +++ b/data_migration_tools/server/src/repositories/accounts/errors/types.ts @@ -0,0 +1,28 @@ +// アカウント未発見エラー +export class AccountNotFoundError extends Error { + constructor(message: string) { + super(message); + this.name = 'AccountNotFoundError'; + } +} +// ディーラーアカウント未存在エラー +export class DealerAccountNotFoundError extends Error { + constructor(message: string) { + super(message); + this.name = 'DealerAccountNotFoundError'; + } +} +// 管理者ユーザ未存在エラー +export class AdminUserNotFoundError extends Error { + constructor(message: string) { + super(message); + this.name = 'AdminUserNotFoundError'; + } +} +// アカウントロックエラー +export class AccountLockedError extends Error { + constructor(message: string) { + super(message); + this.name = 'AccountLockedError'; + } +} diff --git a/data_migration_tools/server/src/repositories/licenses/entity/license.entity.ts b/data_migration_tools/server/src/repositories/licenses/entity/license.entity.ts new file mode 100644 index 0000000..90715ae --- /dev/null +++ b/data_migration_tools/server/src/repositories/licenses/entity/license.entity.ts @@ -0,0 +1,137 @@ +import { + Entity, + Column, + PrimaryGeneratedColumn, + CreateDateColumn, + UpdateDateColumn, +} from 'typeorm'; +import { bigintTransformer } from '../../../common/entity'; + + +@Entity({ name: 'licenses' }) +export class License { + @PrimaryGeneratedColumn() + id: number; + + @Column({ nullable: true, type: 'datetime' }) + expiry_date: Date | null; + + @Column() + account_id: number; + + @Column() + type: string; + + @Column() + status: string; + + @Column({ nullable: true, type: 'bigint', transformer: bigintTransformer }) + allocated_user_id: number | null; + + @Column({ nullable: true, type: 'bigint', transformer: bigintTransformer }) + order_id: number | null; + + @Column({ nullable: true, type: 'datetime' }) + deleted_at: Date | null; + + @Column({ nullable: true, type: 'bigint', transformer: bigintTransformer }) + delete_order_id: number | null; + + @Column({ nullable: true, type: 'datetime' }) + created_by: string | null; + + @CreateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) + created_at: Date; + + @Column({ nullable: true, type: 'datetime' }) + updated_by: string | null; + + @UpdateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) + updated_at: Date; +} + +@Entity({ name: 'license_allocation_history' }) +export class LicenseAllocationHistory { + @PrimaryGeneratedColumn() + id: number; + + @Column() + user_id: number; + + @Column() + license_id: number; + + @Column() + is_allocated: boolean; + + @Column() + account_id: number; + + @Column() + executed_at: Date; + + @Column() + switch_from_type: string; + + @Column({ nullable: true, type: 'datetime' }) + deleted_at: Date | null; + + @Column({ nullable: true, type: 'datetime' }) + created_by: string | null; + + @CreateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) + created_at: Date; + + @Column({ nullable: true, type: 'datetime' }) + updated_by: string | null; + + @UpdateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) + updated_at: Date; + +} + + +@Entity({ name: "card_licenses" }) +export class CardLicense { + @PrimaryGeneratedColumn() + license_id: number; + + @Column() + issue_id: number; + + @Column() + card_license_key: string; + + @Column({ nullable: true, type: "datetime" }) + activated_at: Date | null; + + @Column({ nullable: true, type: "datetime" }) + created_by: string | null; + + @CreateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: "datetime", + }) + created_at: Date; + + @Column({ nullable: true, type: "datetime" }) + updated_by: string | null; + + @UpdateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: "datetime", + }) + updated_at: Date; +} \ No newline at end of file diff --git a/data_migration_tools/server/src/repositories/licenses/errors/types.ts b/data_migration_tools/server/src/repositories/licenses/errors/types.ts new file mode 100644 index 0000000..12b34d1 --- /dev/null +++ b/data_migration_tools/server/src/repositories/licenses/errors/types.ts @@ -0,0 +1,108 @@ +// POナンバーがすでに存在するエラー +export class PoNumberAlreadyExistError extends Error { + constructor(message: string) { + super(message); + this.name = 'PoNumberAlreadyExistError'; + } +} + +// 取り込むカードライセンスが存在しないエラー +export class LicenseNotExistError extends Error { + constructor(message: string) { + super(message); + this.name = 'LicenseNotExistError'; + } +} + +// 取り込むライセンスが既に取り込み済みのエラー +export class LicenseKeyAlreadyActivatedError extends Error { + constructor(message: string) { + super(message); + this.name = 'LicenseKeyAlreadyActivatedError'; + } +} + +// 注文不在エラー +export class OrderNotFoundError extends Error { + constructor(message: string) { + super(message); + this.name = 'OrderNotFoundError'; + } +} +// 注文発行済エラー +export class AlreadyIssuedError extends Error { + constructor(message: string) { + super(message); + this.name = 'AlreadyIssuedError'; + } +} +// ライセンス不足エラー +export class LicensesShortageError extends Error { + constructor(message: string) { + super(message); + this.name = 'LicensesShortageError'; + } +} + +// ライセンス有効期限切れエラー +export class LicenseExpiredError extends Error { + constructor(message: string) { + super(message); + this.name = 'LicenseExpiredError'; + } +} +// ライセンス割り当て不可エラー +export class LicenseUnavailableError extends Error { + constructor(message: string) { + super(message); + this.name = 'LicenseUnavailableError'; + } +} + +// ライセンス割り当て解除済みエラー +export class LicenseAlreadyDeallocatedError extends Error { + constructor(message: string) { + super(message); + this.name = 'LicenseAlreadyDeallocatedError'; + } +} + +// 注文キャンセル失敗エラー +export class CancelOrderFailedError extends Error { + constructor(message: string) { + super(message); + this.name = 'CancelOrderFailedError'; + } +} + +// ライセンス発行キャンセル不可エラー(ステータスが変えられている場合) +export class AlreadyLicenseStatusChangedError extends Error { + constructor(message: string) { + super(message); + this.name = 'AlreadyLicenseStatusChangedError'; + } +} + +// ライセンス発行キャンセル不可エラー(発行から一定期間経過した場合) +export class CancellationPeriodExpiredError extends Error { + constructor(message: string) { + super(message); + this.name = 'CancellationPeriodExpiredError'; + } +} + +// ライセンス発行キャンセル不可エラー(発行したライセンスが割り当てされている場合) +export class AlreadyLicenseAllocatedError extends Error { + constructor(message: string) { + super(message); + this.name = 'AlreadyLicenseAllocatedError'; + } +} + +// ライセンス未割当エラー +export class LicenseNotAllocatedError extends Error { + constructor(message: string) { + super(message); + this.name = 'LicenseNotAllocatedError'; + } +} diff --git a/data_migration_tools/server/src/repositories/licenses/licenses.repository.module.ts b/data_migration_tools/server/src/repositories/licenses/licenses.repository.module.ts new file mode 100644 index 0000000..e3e3d0c --- /dev/null +++ b/data_migration_tools/server/src/repositories/licenses/licenses.repository.module.ts @@ -0,0 +1,17 @@ +import { Module } from "@nestjs/common"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { + CardLicense, + License, + LicenseAllocationHistory, +} from "./entity/license.entity"; +import { LicensesRepositoryService } from "./licenses.repository.service"; + +@Module({ + imports: [ + TypeOrmModule.forFeature([License, CardLicense, LicenseAllocationHistory]), + ], + providers: [LicensesRepositoryService], + exports: [LicensesRepositoryService], +}) +export class LicensesRepositoryModule {} diff --git a/data_migration_tools/server/src/repositories/licenses/licenses.repository.service.ts b/data_migration_tools/server/src/repositories/licenses/licenses.repository.service.ts new file mode 100644 index 0000000..52e13b5 --- /dev/null +++ b/data_migration_tools/server/src/repositories/licenses/licenses.repository.service.ts @@ -0,0 +1,130 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { DataSource, In } from "typeorm"; +import { + License, + LicenseAllocationHistory, + CardLicense, +} from "./entity/license.entity"; +import { insertEntities } from "../../common/repository"; +import { Context } from "../../common/log"; +import { + LicensesInputFile, + CardLicensesInputFile, +} from "../../common/types/types"; + +@Injectable() +export class LicensesRepositoryService { + //クエリログにコメントを出力するかどうか + private readonly isCommentOut = process.env.STAGE !== "local"; + constructor(private dataSource: DataSource) {} + private readonly logger = new Logger(LicensesRepositoryService.name); + + /** + * ライセンスを登録する + * @context Context + * @param licensesInputFiles + */ + async insertLicenses( + context: Context, + licensesInputFiles: LicensesInputFile[] + ): Promise<{}> { + const nowDate = new Date(); + return await this.dataSource.transaction(async (entityManager) => { + const licenseRepo = entityManager.getRepository(License); + + let newLicenses: License[] = []; + licensesInputFiles.forEach((licensesInputFile) => { + const license = new License(); + license.account_id = licensesInputFile.account_id; + license.status = licensesInputFile.status; + license.type = licensesInputFile.type; + license.expiry_date = (licensesInputFile.expiry_date) ? new Date(licensesInputFile.expiry_date) : null; + if (licensesInputFile.allocated_user_id) { + license.allocated_user_id = licensesInputFile.allocated_user_id; + } + newLicenses.push(license); + }); + + // ライセンステーブルを登録 + const insertedlicenses = await insertEntities( + License, + licenseRepo, + newLicenses, + this.isCommentOut, + context + ); + + const licenseAllocationHistoryRepo = entityManager.getRepository( + LicenseAllocationHistory + ); + // ユーザに割り当てた場合はライセンス割り当て履歴にも登録 + let newLicenseAllocationHistories: LicenseAllocationHistory[] = []; + insertedlicenses.forEach((insertedlicense) => { + if (insertedlicense.allocated_user_id) { + const licenseAllocationHistory = new LicenseAllocationHistory(); + licenseAllocationHistory.user_id = insertedlicense.allocated_user_id; + licenseAllocationHistory.license_id = insertedlicense.id; + licenseAllocationHistory.is_allocated = true; + licenseAllocationHistory.account_id = insertedlicense.account_id; + licenseAllocationHistory.switch_from_type = "NONE"; + licenseAllocationHistory.executed_at = insertedlicense.created_at; + + newLicenseAllocationHistories.push(licenseAllocationHistory); + } + }); + + // ライセンス割り当てテーブルを登録 + await insertEntities( + LicenseAllocationHistory, + licenseAllocationHistoryRepo, + newLicenseAllocationHistories, + this.isCommentOut, + context + ); + + return {}; + }); + } + + /** + * カードライセンスを登録する + * @context Context + * @param cardLicensesInputFiles + */ + async insertCardLicenses( + context: Context, + cardLicensesInputFiles: CardLicensesInputFile[] + ): Promise<{}> { + return await this.dataSource.transaction(async (entityManager) => { + const cardLicenseRepo = entityManager.getRepository(CardLicense); + + + let newCardLicenses: CardLicense[] = []; + cardLicensesInputFiles.forEach((cardLicensesInputFile) => { + const cardLicense = new CardLicense(); + cardLicense.license_id = cardLicensesInputFile.license_id; + cardLicense.issue_id = cardLicensesInputFile.issue_id; + cardLicense.card_license_key = cardLicensesInputFile.card_license_key; + cardLicense.activated_at = (cardLicensesInputFile.activated_at) ? new Date(cardLicensesInputFile.activated_at) : null; + cardLicense.created_at = (cardLicensesInputFile.created_at) ? new Date(cardLicensesInputFile.created_at) : null; + cardLicense.created_by = cardLicensesInputFile.created_by; + cardLicense.updated_at = (cardLicensesInputFile.updated_at) ? new Date(cardLicensesInputFile.updated_at) : null; + cardLicense.updated_by = cardLicensesInputFile.updated_by; + + newCardLicenses.push(cardLicense); + }); + + const query = cardLicenseRepo + .createQueryBuilder() + .insert() + .into(CardLicense); + if (this.isCommentOut) { + query.comment(`${context.getTrackingId()}_${new Date().toUTCString()}`); + } + query.values(newCardLicenses).execute(); + + return {}; + }); + } + +} diff --git a/data_migration_tools/server/src/repositories/sort_criteria/entity/sort_criteria.entity.ts b/data_migration_tools/server/src/repositories/sort_criteria/entity/sort_criteria.entity.ts new file mode 100644 index 0000000..260c9a9 --- /dev/null +++ b/data_migration_tools/server/src/repositories/sort_criteria/entity/sort_criteria.entity.ts @@ -0,0 +1,16 @@ +import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity({ name: 'sort_criteria' }) +export class SortCriteria { + @PrimaryGeneratedColumn() + id: number; + + @Column() + user_id: number; + + @Column() + parameter: string; + + @Column() + direction: string; +} diff --git a/data_migration_tools/server/src/repositories/sort_criteria/sort_criteria.repository.module.ts b/data_migration_tools/server/src/repositories/sort_criteria/sort_criteria.repository.module.ts new file mode 100644 index 0000000..8a46b37 --- /dev/null +++ b/data_migration_tools/server/src/repositories/sort_criteria/sort_criteria.repository.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { SortCriteria } from './entity/sort_criteria.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([SortCriteria])], +}) +export class SortCriteriaRepositoryModule {} diff --git a/data_migration_tools/server/src/repositories/users/entity/user.entity.ts b/data_migration_tools/server/src/repositories/users/entity/user.entity.ts new file mode 100644 index 0000000..9ae5eb6 --- /dev/null +++ b/data_migration_tools/server/src/repositories/users/entity/user.entity.ts @@ -0,0 +1,97 @@ +import { Account } from '../../../repositories/accounts/entity/account.entity'; +import { + Entity, + Column, + PrimaryGeneratedColumn, + CreateDateColumn, + UpdateDateColumn, + ManyToOne, + JoinColumn, +} from 'typeorm'; + +@Entity({ name: 'users' }) +export class User { + @PrimaryGeneratedColumn() + id: number; + + @Column() + external_id: string; + + @Column() + account_id: number; + + @Column() + role: string; + + @Column({ nullable: true, type: 'varchar' }) + author_id: string | null; + + @Column({ nullable: true, type: 'varchar' }) + accepted_eula_version: string | null; + + @Column({ nullable: true, type: 'varchar' }) + accepted_privacy_notice_version: string | null; + + @Column({ nullable: true, type: 'varchar' }) + accepted_dpa_version: string | null; + + @Column({ default: false }) + email_verified: boolean; + + @Column({ default: true }) + auto_renew: boolean; + + @Column({ default: true }) + notification: boolean; + + @Column({ default: false }) + encryption: boolean; + + @Column({ nullable: true, type: 'varchar' }) + encryption_password: string | null; + + @Column({ default: false }) + prompt: boolean; + + @Column({ nullable: true, type: 'datetime' }) + deleted_at: Date | null; + + @Column({ nullable: true, type: 'datetime' }) + created_by: string | null; + + @CreateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) // defaultはSQLite用設定値.本番用は別途migrationで設定 + created_at: Date; + + @Column({ nullable: true, type: 'datetime' }) + updated_by: string | null; + + @UpdateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) // defaultはSQLite用設定値.本番用は別途migrationで設定 + updated_at: Date; + + @ManyToOne(() => Account, (account) => account.user, { + createForeignKeyConstraints: false, + }) // createForeignKeyConstraintsはSQLite用設定値.本番用は別途migrationで設定 + @JoinColumn({ name: 'account_id' }) + account: Account | null; + +} + + +export type newUser = Omit< + User, + | 'deleted_at' + | 'created_at' + | 'updated_at' + | 'updated_by' + | 'created_by' + | 'account' + | 'license' + | 'userGroupMembers' + | 'email_verified' +>; diff --git a/data_migration_tools/server/src/repositories/users/errors/types.ts b/data_migration_tools/server/src/repositories/users/errors/types.ts new file mode 100644 index 0000000..6f90ede --- /dev/null +++ b/data_migration_tools/server/src/repositories/users/errors/types.ts @@ -0,0 +1,56 @@ +// Email検証済みエラー +export class EmailAlreadyVerifiedError extends Error { + constructor(message: string) { + super(message); + this.name = 'EmailAlreadyVerifiedError'; + } +} +// ユーザー未発見エラー +export class UserNotFoundError extends Error { + constructor(message: string) { + super(message); + this.name = 'UserNotFoundError'; + } +} +// AuthorID重複エラー +export class AuthorIdAlreadyExistsError extends Error { + constructor(message: string) { + super(message); + this.name = 'AuthorIdAlreadyExistsError'; + } +} +// 不正なRole変更エラー +export class InvalidRoleChangeError extends Error { + constructor(message: string) { + super(message); + this.name = 'InvalidRoleChangeError'; + } +} +// 暗号化パスワード不足エラー +export class EncryptionPasswordNeedError extends Error { + constructor(message: string) { + super(message); + this.name = 'EncryptionPasswordNeedError'; + } +} +// 利用規約バージョン情報不在エラー +export class TermInfoNotFoundError extends Error { + constructor(message: string) { + super(message); + this.name = 'TermInfoNotFoundError'; + } +} +// 利用規約バージョンパラメータ不在エラー +export class UpdateTermsVersionNotSetError extends Error { + constructor(message: string) { + super(message); + this.name = 'UpdateTermsVersionNotSetError'; + } +} +// 代行操作不許可エラー +export class DelegationNotAllowedError extends Error { + constructor(message: string) { + super(message); + this.name = 'DelegationNotAllowedError'; + } +} diff --git a/data_migration_tools/server/src/repositories/users/users.repository.module.ts b/data_migration_tools/server/src/repositories/users/users.repository.module.ts new file mode 100644 index 0000000..79be43a --- /dev/null +++ b/data_migration_tools/server/src/repositories/users/users.repository.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { User } from './entity/user.entity'; +import { UsersRepositoryService } from './users.repository.service'; + +@Module({ + imports: [TypeOrmModule.forFeature([User])], + providers: [UsersRepositoryService], + exports: [UsersRepositoryService], +}) +export class UsersRepositoryModule {} diff --git a/data_migration_tools/server/src/repositories/users/users.repository.service.ts b/data_migration_tools/server/src/repositories/users/users.repository.service.ts new file mode 100644 index 0000000..ebb4dc3 --- /dev/null +++ b/data_migration_tools/server/src/repositories/users/users.repository.service.ts @@ -0,0 +1,141 @@ +import { Injectable } from '@nestjs/common'; +import { User, newUser } from './entity/user.entity'; +import { + DataSource, +} from 'typeorm'; +import { SortCriteria } from '../sort_criteria/entity/sort_criteria.entity'; +import { + getDirection, + getTaskListSortableAttribute, +} from '../../common/types/sort/util'; +import { Context } from '../../common/log'; +import { + insertEntity, + deleteEntity, +} from '../../common/repository'; + +@Injectable() +export class UsersRepositoryService { + // クエリログにコメントを出力するかどうか + private readonly isCommentOut = process.env.STAGE !== "local"; + + constructor(private dataSource: DataSource) {} + + /** + * 一般ユーザーを作成する + * @param user + * @returns User + */ + async createNormalUser(context: Context, user: newUser): Promise { + const { + id, + account_id: accountId, + external_id: externalUserId, + role, + auto_renew, + notification, + author_id, + accepted_eula_version, + accepted_dpa_version, + encryption, + encryption_password: encryptionPassword, + prompt, + } = user; + const userEntity = new User(); + + userEntity.id = id; + userEntity.role = role; + userEntity.account_id = accountId; + userEntity.external_id = externalUserId; + userEntity.auto_renew = auto_renew; + userEntity.notification = notification; + userEntity.author_id = author_id; + userEntity.accepted_eula_version = accepted_eula_version; + userEntity.accepted_dpa_version = accepted_dpa_version; + userEntity.encryption = encryption; + userEntity.encryption_password = encryptionPassword; + userEntity.prompt = prompt; + userEntity.email_verified = true; + + const createdEntity = await this.dataSource.transaction( + async (entityManager) => { + const repo = entityManager.getRepository(User); + const newUser = repo.create(userEntity); + const persisted = await insertEntity( + User, + repo, + newUser, + this.isCommentOut, + context + ); + + // ユーザーのタスクソート条件を作成 + const sortCriteria = new SortCriteria(); + { + sortCriteria.parameter = getTaskListSortableAttribute("JOB_NUMBER"); + sortCriteria.direction = getDirection("ASC"); + sortCriteria.user_id = persisted.id; + } + const sortCriteriaRepo = entityManager.getRepository(SortCriteria); + const newSortCriteria = sortCriteriaRepo.create(sortCriteria); + await insertEntity( + SortCriteria, + sortCriteriaRepo, + newSortCriteria, + this.isCommentOut, + context + ); + + return persisted; + } + ); + return createdEntity; + } + + /** + * AuthorIdが既に存在するか確認する + * @param user + * @returns 存在する:true 存在しない:false + */ + async existsAuthorId( + context: Context, + accountId: number, + authorId: string + ): Promise { + const user = await this.dataSource.getRepository(User).findOne({ + where: [ + { + account_id: accountId, + author_id: authorId, + }, + ], + comment: `${context.getTrackingId()}_${new Date().toUTCString()}`, + }); + + if (user) { + return true; + } + return false; + } + + /** + * UserID指定のユーザーとソート条件を同時に削除する + * @param userId + * @returns delete + */ + async deleteNormalUser(context: Context, userId: number): Promise { + await this.dataSource.transaction(async (entityManager) => { + const usersRepo = entityManager.getRepository(User); + const sortCriteriaRepo = entityManager.getRepository(SortCriteria); + // ソート条件を削除 + await deleteEntity( + sortCriteriaRepo, + { user_id: userId }, + this.isCommentOut, + context + ); + // プライマリ管理者を削除 + await deleteEntity(usersRepo, { id: userId }, this.isCommentOut, context); + }); + } +} diff --git a/data_migration_tools/server/src/repositories/worktypes/entity/option_item.entity.ts b/data_migration_tools/server/src/repositories/worktypes/entity/option_item.entity.ts new file mode 100644 index 0000000..f9e7ac4 --- /dev/null +++ b/data_migration_tools/server/src/repositories/worktypes/entity/option_item.entity.ts @@ -0,0 +1,42 @@ +import { + Entity, + Column, + PrimaryGeneratedColumn, + UpdateDateColumn, + CreateDateColumn, + ManyToOne, + JoinColumn, +} from 'typeorm'; +import { Worktype } from './worktype.entity'; + +@Entity({ name: 'option_items' }) +export class OptionItem { + @PrimaryGeneratedColumn() + id: number; + @Column() + worktype_id: number; + @Column() + item_label: string; + @Column() + default_value_type: string; + @Column() + initial_value: string; + @Column({ nullable: true, type: 'datetime' }) + created_by: string | null; + @CreateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) // defaultはSQLite用設定値.本番用は別途migrationで設定 + created_at: Date | null; + @Column({ nullable: true, type: 'datetime' }) + updated_by: string | null; + @UpdateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) // defaultはSQLite用設定値.本番用は別途migrationで設定 + updated_at: Date | null; + + @ManyToOne(() => Worktype, (worktype) => worktype.id) + @JoinColumn({ name: 'worktype_id' }) + worktype: Worktype; +} diff --git a/data_migration_tools/server/src/repositories/worktypes/entity/worktype.entity.ts b/data_migration_tools/server/src/repositories/worktypes/entity/worktype.entity.ts new file mode 100644 index 0000000..6419cbd --- /dev/null +++ b/data_migration_tools/server/src/repositories/worktypes/entity/worktype.entity.ts @@ -0,0 +1,44 @@ +import { + Entity, + Column, + PrimaryGeneratedColumn, + CreateDateColumn, + UpdateDateColumn, +} from 'typeorm'; + +@Entity({ name: 'worktypes' }) +export class Worktype { + @PrimaryGeneratedColumn() + id: number; + + @Column() + account_id: number; + + @Column() + custom_worktype_id: string; + + @Column({ nullable: true, type: 'varchar' }) + description: string | null; + + @Column({ nullable: true, type: 'datetime' }) + deleted_at: Date | null; + + @Column({ nullable: true, type: 'datetime' }) + created_by: string | null; + + @CreateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) // defaultはSQLite用設定値.本番用は別途migrationで設定 + created_at: Date; + + @Column({ nullable: true, type: 'datetime' }) + updated_by: string | null; + + @UpdateDateColumn({ + default: () => "datetime('now', 'localtime')", + type: 'datetime', + }) // defaultはSQLite用設定値.本番用は別途migrationで設定 + updated_at: Date; + +} diff --git a/data_migration_tools/server/src/repositories/worktypes/errors/types.ts b/data_migration_tools/server/src/repositories/worktypes/errors/types.ts new file mode 100644 index 0000000..fb5db2d --- /dev/null +++ b/data_migration_tools/server/src/repositories/worktypes/errors/types.ts @@ -0,0 +1,28 @@ +// WorktypeID重複エラー +export class WorktypeIdAlreadyExistsError extends Error { + constructor(message: string) { + super(message); + this.name = 'WorktypeIdAlreadyExistsError'; + } +} +// WorktypeID登録上限エラー +export class WorktypeIdMaxCountError extends Error { + constructor(message: string) { + super(message); + this.name = 'WorktypeIdMaxCountError'; + } +} +// WorktypeID不在エラー +export class WorktypeIdNotFoundError extends Error { + constructor(message: string) { + super(message); + this.name = 'WorktypeIdNotFoundError'; + } +} +// WorktypeID使用中エラー +export class WorktypeIdInUseError extends Error { + constructor(message: string) { + super(message); + this.name = 'WorktypeIdInUseError'; + } +} diff --git a/data_migration_tools/server/src/repositories/worktypes/worktypes.repository.module.ts b/data_migration_tools/server/src/repositories/worktypes/worktypes.repository.module.ts new file mode 100644 index 0000000..1ae34d1 --- /dev/null +++ b/data_migration_tools/server/src/repositories/worktypes/worktypes.repository.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Worktype } from './entity/worktype.entity'; +import { WorktypesRepositoryService } from './worktypes.repository.service'; +import { OptionItem } from "./entity/option_item.entity"; + +@Module({ + imports: [TypeOrmModule.forFeature([Worktype, OptionItem])], + providers: [WorktypesRepositoryService], + exports: [WorktypesRepositoryService], +}) +export class WorktypesRepositoryModule {} diff --git a/data_migration_tools/server/src/repositories/worktypes/worktypes.repository.service.ts b/data_migration_tools/server/src/repositories/worktypes/worktypes.repository.service.ts new file mode 100644 index 0000000..9f7f2ff --- /dev/null +++ b/data_migration_tools/server/src/repositories/worktypes/worktypes.repository.service.ts @@ -0,0 +1,104 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource, Not } from "typeorm"; +import { Worktype } from "./entity/worktype.entity"; +import { + OPTION_ITEM_NUM, + OPTION_ITEM_VALUE_TYPE, + WORKTYPE_MAX_COUNT, +} from "../../constants"; +import { + WorktypeIdAlreadyExistsError, + WorktypeIdMaxCountError, +} from "./errors/types"; +import { OptionItem } from "./entity/option_item.entity"; +import { insertEntities, insertEntity } from "../../common/repository"; +import { Context } from "../../common/log"; +import { WorktypesInputFile } from "../../common/types/types"; + +@Injectable() +export class WorktypesRepositoryService { + // クエリログにコメントを出力するかどうか + private readonly isCommentOut = process.env.STAGE !== "local"; + + constructor(private dataSource: DataSource) {} + + /** + * ワークタイプを作成する + * @param accountId + * @param worktypeId + * @param [description] + */ + async createWorktype( + context: Context, + worktypesInputFiles: WorktypesInputFile[] + ): Promise { + await this.dataSource.transaction(async (entityManager) => { + const worktypeRepo = entityManager.getRepository(Worktype); + const optionItemRepo = entityManager.getRepository(OptionItem); + + for (const worktypesInputFile of worktypesInputFiles) { + const accountId = worktypesInputFile.account_id; + const worktypeId = worktypesInputFile.custom_worktype_id; + const description = null; + + const duplicatedWorktype = await worktypeRepo.findOne({ + where: { account_id: accountId, custom_worktype_id: worktypeId }, + comment: `${context.getTrackingId()}_${new Date().toUTCString()}`, + lock: { mode: "pessimistic_write" }, + }); + + // ワークタイプIDが重複している場合はエラー + if (duplicatedWorktype) { + throw new WorktypeIdAlreadyExistsError( + `WorktypeID is already exists. WorktypeID: ${worktypeId}` + ); + } + + const worktypeCount = await worktypeRepo.count({ + where: { account_id: accountId }, + comment: `${context.getTrackingId()}_${new Date().toUTCString()}`, + lock: { mode: "pessimistic_write" }, + }); + + // ワークタイプの登録数が上限に達している場合はエラー + if (worktypeCount >= WORKTYPE_MAX_COUNT) { + throw new WorktypeIdMaxCountError( + `Number of worktype is exceeded the limit. MAX_COUNT: ${WORKTYPE_MAX_COUNT}, currentCount: ${worktypeCount}` + ); + } + + // ワークタイプを作成 + const worktype = await insertEntity( + Worktype, + worktypeRepo, + { + account_id: accountId, + custom_worktype_id: worktypeId, + description: description ?? null, + }, + this.isCommentOut, + context + ); + + // ワークタイプに紐づくオプションアイテムを10件作成 + const newOptionItems = Array.from({ length: OPTION_ITEM_NUM }, () => { + const optionItem = new OptionItem(); + optionItem.worktype_id = worktype.id; + optionItem.item_label = ""; + optionItem.default_value_type = OPTION_ITEM_VALUE_TYPE.DEFAULT; + optionItem.initial_value = ""; + + return optionItem; + }); + + await insertEntities( + OptionItem, + optionItemRepo, + newOptionItems, + this.isCommentOut, + context + ); + } + }); + } +} From ebbf957419ef298fb20024addc0995953cff9679 Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Thu, 22 Feb 2024 02:38:05 +0000 Subject: [PATCH 02/10] =?UTF-8?q?Merged=20PR=20770:=20AuthorID=E3=82=92?= =?UTF-8?q?=E5=A4=A7=E6=96=87=E5=AD=97=E3=81=A8=E3=82=A2=E3=83=B3=E3=83=80?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E3=82=B3=E3=82=A2=E3=81=AE=E3=81=BF=E3=81=A8?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=83=90=E3=83=AA=E3=83=87=E3=83=BC=E3=82=B7?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=82=92=E5=85=A5=E3=82=8C=E3=81=9F=E3=81=93?= =?UTF-8?q?=E3=81=A8=E3=81=AB=E3=82=88=E3=82=8B=E3=83=87=E3=82=B0=E3=83=AC?= =?UTF-8?q?=E3=81=AE=E8=A7=A3=E6=B6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3784: AuthorIDを大文字とアンダースコアのみとするバリデーションを入れたことによるデグレの解消](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3784) - タイトルの通り - ロールがAuthorの時のみチェックするように修正 ## レビューポイント - 特になし ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認、develop環境で確認など ## 補足 - 相談、参考資料などがあれば --- .../src/common/validators/authorId.validator.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dictation_server/src/common/validators/authorId.validator.ts b/dictation_server/src/common/validators/authorId.validator.ts index 02ad278..23afafb 100644 --- a/dictation_server/src/common/validators/authorId.validator.ts +++ b/dictation_server/src/common/validators/authorId.validator.ts @@ -5,11 +5,26 @@ import { ValidationOptions, registerDecorator, } from 'class-validator'; +import { + PostUpdateUserRequest, + SignupRequest, +} from '../../features/users/types/types'; +import { USER_ROLES } from '../../constants'; // 大文字英数字とアンダースコアのみを許可するバリデータ @ValidatorConstraint({ name: 'IsAuthorId', async: false }) export class IsAuthorId implements ValidatorConstraintInterface { validate(value: any, args: ValidationArguments) { + const request = args.object as SignupRequest | PostUpdateUserRequest; + // requestの存在チェック + if (!request) { + return false; + } + const { role } = request; + // roleがauthor以外の場合はスキップする + if (role !== USER_ROLES.AUTHOR) { + return true; + } return /^[A-Z0-9_]*$/.test(value); } defaultMessage(args: ValidationArguments) { From 8110b9cccc3f49b48fd2464fe79890d349c3118b Mon Sep 17 00:00:00 2001 From: "maruyama.t" Date: Thu, 22 Feb 2024 05:04:48 +0000 Subject: [PATCH 03/10] =?UTF-8?q?Merged=20PR=20753:=20=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E5=A4=89=E6=8F=9B=E3=83=84=E3=83=BC=E3=83=AB=E4=BD=9C?= =?UTF-8?q?=E6=88=90=EF=BC=8B=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3570: データ変換ツール作成+動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3570) ## レビューポイント - 特にtransfer配下の処理を見ていただきたいです。 データのバリデーションは十分か。 アカウントIDとユーザーIDのインクリメント(採番)の場所は正しいか。 ユーザー名は正しく設定できているか。 worktypeの重複を除外する処理は正しいか。 COUNTRY_LIST(既存のクライアントから流用)した変換処理には問題ないか。 出力ファイル名は登録ツール側の想定通りか。 ## 動作確認状況 動作確認は、以下で行う。 [タスク 3575: [1回目実行]実施後の動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_sprints/taskboard/OMDSDictation%20%E3%83%81%E3%83%BC%E3%83%A0/OMDSDictation/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%2028-2?workitem=3575) ## 補足 - 相談、参考資料などがあれば --- .../client/src/common/error/code.ts | 70 ++ .../src/common/error/makeErrorResponse.ts | 10 + .../client/src/common/error/message.ts | 59 ++ .../client/src/common/error/types/types.ts | 15 + data_migration_tools/package-lock.json | 63 ++ data_migration_tools/server/package-lock.json | 927 ++++-------------- data_migration_tools/server/package.json | 6 +- .../server/src/common/errors/types/types.ts | 4 +- .../server/src/common/log/index.ts | 4 +- .../server/src/common/password/index.ts | 2 +- .../server/src/common/password/password.ts | 8 +- .../server/src/common/types/types.ts | 76 ++ .../src/common/validators/admin.validator.ts | 39 + .../server/src/constants/index.ts | 71 ++ .../transfer /transfer.controller.ts | 174 ++++ .../features/transfer /transfer.module.ts | 9 + .../features/transfer /transfer.service.ts | 357 +++++++ .../src/features/transfer /types/types.ts | 25 + 18 files changed, 1144 insertions(+), 775 deletions(-) create mode 100644 data_migration_tools/client/src/common/error/code.ts create mode 100644 data_migration_tools/client/src/common/error/makeErrorResponse.ts create mode 100644 data_migration_tools/client/src/common/error/message.ts create mode 100644 data_migration_tools/client/src/common/error/types/types.ts create mode 100644 data_migration_tools/package-lock.json create mode 100644 data_migration_tools/server/src/common/validators/admin.validator.ts create mode 100644 data_migration_tools/server/src/features/transfer /transfer.controller.ts create mode 100644 data_migration_tools/server/src/features/transfer /transfer.module.ts create mode 100644 data_migration_tools/server/src/features/transfer /transfer.service.ts create mode 100644 data_migration_tools/server/src/features/transfer /types/types.ts diff --git a/data_migration_tools/client/src/common/error/code.ts b/data_migration_tools/client/src/common/error/code.ts new file mode 100644 index 0000000..3c488da --- /dev/null +++ b/data_migration_tools/client/src/common/error/code.ts @@ -0,0 +1,70 @@ +/* +エラーコード作成方針 +E+6桁(数字)で構成する。 +- 1~2桁目の値は種類(業務エラー、システムエラー...) +- 3~4桁目の値は原因箇所(トークン、DB、...) +- 5~6桁目の値は任意の重複しない値 +ex) +E00XXXX : システムエラー(通信エラーやDB接続失敗など) +E01XXXX : 業務エラー +EXX00XX : 内部エラー(内部プログラムのエラー) +EXX01XX : トークンエラー(トークン認証関連) +EXX02XX : DBエラー(DB関連) +EXX03XX : ADB2Cエラー(DB関連) +*/ +export const ErrorCodes = [ + 'E009999', // 汎用エラー + 'E000101', // トークン形式不正エラー + 'E000102', // トークン有効期限切れエラー + 'E000103', // トークン非アクティブエラー + 'E000104', // トークン署名エラー + 'E000105', // トークン発行元エラー + 'E000106', // トークンアルゴリズムエラー + 'E000107', // トークン不足エラー + 'E000108', // トークン権限エラー + 'E000301', // ADB2Cへのリクエスト上限超過エラー + 'E000401', // IPアドレス未設定エラー + 'E000501', // リクエストID未設定エラー + 'E010001', // パラメータ形式不正エラー + 'E010201', // 未認証ユーザエラー + 'E010202', // 認証済ユーザエラー + 'E010203', // 管理ユーザ権限エラー + 'E010204', // ユーザ不在エラー + 'E010205', // DBのRoleが想定外の値エラー + 'E010206', // DBのTierが想定外の値エラー + 'E010207', // ユーザーのRole変更不可エラー + 'E010208', // ユーザーの暗号化パスワード不足エラー + 'E010209', // ユーザーの同意済み利用規約バージョンが最新でないエラー + 'E010301', // メールアドレス登録済みエラー + 'E010302', // authorId重複エラー + 'E010401', // PONumber重複エラー + 'E010501', // アカウント不在エラー + 'E010502', // アカウント情報変更不可エラー + 'E010503', // 代行操作不許可エラー + 'E010504', // アカウントロックエラー + 'E010601', // タスク変更不可エラー(タスクが変更できる状態でない、またはタスクが存在しない) + 'E010602', // タスク変更権限不足エラー + 'E010603', // タスク不在エラー + 'E010701', // Blobファイル不在エラー + 'E010801', // ライセンス不在エラー + 'E010802', // ライセンス取り込み済みエラー + 'E010803', // ライセンス発行済みエラー + 'E010804', // ライセンス不足エラー + 'E010805', // ライセンス有効期限切れエラー + 'E010806', // ライセンス割り当て不可エラー + 'E010807', // ライセンス割り当て解除済みエラー + 'E010808', // ライセンス注文キャンセル不可エラー + 'E010809', // ライセンス発行キャンセル不可エラー(ステータスが変えられている場合) + 'E010810', // ライセンス発行キャンセル不可エラー(発行から一定期間経過した場合) + 'E010811', // ライセンス発行キャンセル不可エラー(発行したライセンスが割り当てされている場合) + 'E010812', // ライセンス未割当エラー + 'E010908', // タイピストグループ不在エラー + 'E010909', // タイピストグループ名重複エラー + 'E011001', // ワークタイプ重複エラー + 'E011002', // ワークタイプ登録上限超過エラー + 'E011003', // ワークタイプ不在エラー + 'E011004', // ワークタイプ使用中エラー + 'E012001', // テンプレートファイル不在エラー + 'E013001', // ワークフローのAuthorIDとWorktypeIDのペア重複エラー + 'E013002', // ワークフロー不在エラー +] as const; diff --git a/data_migration_tools/client/src/common/error/makeErrorResponse.ts b/data_migration_tools/client/src/common/error/makeErrorResponse.ts new file mode 100644 index 0000000..0a677b4 --- /dev/null +++ b/data_migration_tools/client/src/common/error/makeErrorResponse.ts @@ -0,0 +1,10 @@ +import { errors } from './message'; +import { ErrorCodeType, ErrorResponse } from './types/types'; + +export const makeErrorResponse = (errorcode: ErrorCodeType): ErrorResponse => { + const msg = errors[errorcode]; + return { + code: errorcode, + message: msg, + }; +}; diff --git a/data_migration_tools/client/src/common/error/message.ts b/data_migration_tools/client/src/common/error/message.ts new file mode 100644 index 0000000..9383694 --- /dev/null +++ b/data_migration_tools/client/src/common/error/message.ts @@ -0,0 +1,59 @@ +import { Errors } from './types/types'; + +// エラーコードとメッセージ対応表 +export const errors: Errors = { + E009999: 'Internal Server Error.', + E000101: 'Token invalid format Error.', + E000102: 'Token expired Error.', + E000103: 'Token not before Error', + E000104: 'Token invalid signature Error.', + E000105: 'Token invalid issuer Error.', + E000106: 'Token invalid algorithm Error.', + E000107: 'Token is not exist Error.', + E000108: 'Token authority failed Error.', + E000301: 'ADB2C request limit exceeded Error', + E000401: 'IP address not found Error.', + E000501: 'Request ID not found Error.', + E010001: 'Param invalid format Error.', + E010201: 'Email not verified user Error.', + E010202: 'Email already verified user Error.', + E010203: 'Administrator Permissions Error.', + E010204: 'User not Found Error.', + E010205: 'Role from DB is unexpected value Error.', + E010206: 'Tier from DB is unexpected value Error.', + E010207: 'User role change not allowed Error.', + E010208: 'User encryption password not found Error.', + E010209: 'Accepted term not latest Error.', + E010301: 'This email user already created Error', + E010302: 'This AuthorId already used Error', + E010401: 'This PoNumber already used Error', + E010501: 'Account not Found Error.', + E010502: 'Account information cannot be changed Error.', + E010503: 'Delegation not allowed Error.', + E010504: 'Account is locked Error.', + E010601: 'Task is not Editable Error', + E010602: 'No task edit permissions Error', + E010603: 'Task not found Error.', + E010701: 'File not found in Blob Storage Error.', + E010801: 'License not exist Error', + E010802: 'License already activated Error', + E010803: 'License already issued Error', + E010804: 'License shortage Error', + E010805: 'License is expired Error', + E010806: 'License is unavailable Error', + E010807: 'License is already deallocated Error', + E010808: 'Order cancel failed Error', + E010809: 'Already license order status changed Error', + E010810: 'Cancellation period expired error', + E010811: 'Already license allocated Error', + E010812: 'License not allocated Error', + E010908: 'Typist Group not exist Error', + E010909: 'Typist Group name already exist Error', + E011001: 'This WorkTypeID already used Error', + E011002: 'WorkTypeID create limit exceeded Error', + E011003: 'WorkTypeID not found Error', + E011004: 'WorkTypeID is in use Error', + E012001: 'Template file not found Error', + E013001: 'AuthorId and WorktypeId pair already exists Error', + E013002: 'Workflow not found Error', +}; diff --git a/data_migration_tools/client/src/common/error/types/types.ts b/data_migration_tools/client/src/common/error/types/types.ts new file mode 100644 index 0000000..8746924 --- /dev/null +++ b/data_migration_tools/client/src/common/error/types/types.ts @@ -0,0 +1,15 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { ErrorCodes } from '../code'; + +export class ErrorResponse { + @ApiProperty() + message: string; + @ApiProperty() + code: string; +} + +export type ErrorCodeType = (typeof ErrorCodes)[number]; + +export type Errors = { + [P in ErrorCodeType]: string; +}; diff --git a/data_migration_tools/package-lock.json b/data_migration_tools/package-lock.json new file mode 100644 index 0000000..343f405 --- /dev/null +++ b/data_migration_tools/package-lock.json @@ -0,0 +1,63 @@ +{ + "name": "data_migration_tools", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "author": "", + "description": "", + "license": "UNLICENSED", + "private": true, + "packages": {}, + "devDependencies": { + "@types/express": "^4.17.17", + "@types/multer": "^1.4.7", + "@types/node": "^20.2.3", + "eslint": "^8.0.1", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^4.0.0", + "jest": "28.0.3", + "license-checker": "^25.0.1", + "prettier": "^2.3.2", + "source-map-support": "^0.5.20", + "supertest": "^6.1.3", + "swagger-ui-express": "^4.5.0", + "ts-jest": "28.0.1", + "ts-loader": "^9.2.3", + "ts-node": "^10.0.0", + "tsconfig-paths": "4.0.0", + "typescript": "^4.3.5" + }, + "jest": { + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "../coverage", + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": "src", + "testEnvironment": "node", + "testRegex": ".*\\.spec\\.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } + }, + "scripts": { + "build": "nest build && cp -r build dist", + "build:exe": "nest build && cp -r build dist && sh ./buildTool.sh", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"", + "lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "prebuild": "rimraf dist", + "start": "nest start", + "start:debug": "nest start --debug --watch", + "start:dev": "nest start --watch", + "start:prod": "node dist/main", + "test": "jest", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:watch": "jest --watch" + } +} diff --git a/data_migration_tools/server/package-lock.json b/data_migration_tools/server/package-lock.json index 1c2990f..5987ef1 100644 --- a/data_migration_tools/server/package-lock.json +++ b/data_migration_tools/server/package-lock.json @@ -27,11 +27,11 @@ "class-validator": "^0.14.0", "cookie-parser": "^1.4.6", "multer": "^1.4.5-lts.1", - "mysql2": "^3.9.1", + "mysql2": "^2.3.3", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.0", "swagger-cli": "^4.0.4", - "typeorm": "^0.3.10" + "typeorm": "^0.3.20" }, "devDependencies": { "@types/express": "^4.17.17", @@ -53,15 +53,6 @@ "typescript": "^4.3.5" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -425,54 +416,17 @@ } }, "node_modules/@azure/core-util": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.7.0.tgz", - "integrity": "sha512-Zq2i3QO6k9DA8vnm29mYM4G8IE9u1mhF1GUabVEqPNX8Lj833gdxQ2NAFxt2BZsfAL+e9cT8SyVN7dFVJ/Hf0g==", - "dependencies": { - "@azure/abort-controller": "^2.0.0", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz", - "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@azure/identity": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.4.2.tgz", - "integrity": "sha512-0q5DL4uyR0EZ4RXQKD8MadGH6zTIcloUoS/RVbCpNpej4pwte0xpqYxk8K97Py2RiuUvI7F4GXpoT4046VfufA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.3.2.tgz", + "integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==", "dependencies": { "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.5.0", - "@azure/core-client": "^1.4.0", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.6.1", - "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^3.5.0", - "@azure/msal-node": "^2.5.1", - "events": "^3.0.0", - "jws": "^4.0.0", - "open": "^8.0.0", - "stoppable": "^1.1.0", "tslib": "^2.2.0" }, "engines": { "node": ">=14.0.0" } }, -<<<<<<< HEAD -======= "node_modules/@azure/identity": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.0.1.tgz", @@ -497,7 +451,6 @@ "node": ">=18.0.0" } }, ->>>>>>> develop "node_modules/@azure/identity/node_modules/@azure/core-tracing": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", @@ -1263,9 +1216,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz", + "integrity": "sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" @@ -1278,23 +1231,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", + "espree": "^9.5.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -1350,22 +1303,22 @@ "dev": true }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", "minimatch": "^3.0.5" }, "engines": { @@ -1386,19 +1339,15 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -1415,10 +1364,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "engines": { "node": ">=12" }, @@ -1430,10 +1375,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "engines": { "node": ">=12" }, @@ -1444,21 +1385,12 @@ "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", -<<<<<<< HEAD "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" -======= - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "peer": true ->>>>>>> develop }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1475,10 +1407,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1493,10 +1421,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -2331,18 +2255,6 @@ } }, "node_modules/@nestjs/typeorm": { -<<<<<<< HEAD - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-9.0.1.tgz", - "integrity": "sha512-A2BgLIPsMtmMI0bPKEf4bmzgFPsnvHqNBx3KkvaJ7hJrBQy0OqYOb+Rr06ifblKWDWS2tUPNrAFQbZjtk3PI+g==", - "dependencies": { - "uuid": "8.3.2" - }, - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0", - "@nestjs/core": "^8.0.0 || ^9.0.0", - "reflect-metadata": "^0.1.13", -======= "version": "10.0.2", "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-10.0.2.tgz", "integrity": "sha512-H738bJyydK4SQkRCTeh1aFBxoO1E9xdL/HaLGThwrqN95os5mEyAtK7BLADOS+vldP4jDZ2VQPLj4epWwRqCeQ==", @@ -2353,17 +2265,11 @@ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0", "reflect-metadata": "^0.1.13 || ^0.2.0", ->>>>>>> develop "rxjs": "^7.2.0", "typeorm": "^0.3.0" } }, "node_modules/@nestjs/typeorm/node_modules/uuid": { -<<<<<<< HEAD - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", -======= "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", @@ -2371,7 +2277,6 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], ->>>>>>> develop "bin": { "uuid": "dist/bin/uuid" } @@ -2656,10 +2561,6 @@ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "optional": true, -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "engines": { "node": ">=14" } @@ -2691,12 +2592,7 @@ "node_modules/@sqltools/formatter": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", -<<<<<<< HEAD "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==" -======= - "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", - "peer": true ->>>>>>> develop }, "node_modules/@tootallnate/once": { "version": "2.0.0", @@ -2889,9 +2785,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true, "peer": true }, @@ -3009,12 +2905,6 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/@vercel/ncc": { "version": "0.36.1", "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.1.tgz", @@ -3217,15 +3107,9 @@ } }, "node_modules/acorn": { -<<<<<<< HEAD "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", -======= - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", ->>>>>>> develop "devOptional": true, "bin": { "acorn": "bin/acorn" @@ -3351,12 +3235,7 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", -<<<<<<< HEAD "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" -======= - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "peer": true ->>>>>>> develop }, "node_modules/anymatch": { "version": "3.1.3", @@ -3375,10 +3254,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "engines": { "node": ">= 6.0.0" } @@ -3873,10 +3748,6 @@ "version": "2.1.11", "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", @@ -4196,12 +4067,7 @@ "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", -<<<<<<< HEAD "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" -======= - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", - "peer": true ->>>>>>> develop }, "node_modules/debug": { "version": "4.3.4", @@ -4379,12 +4245,7 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", -<<<<<<< HEAD "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" -======= - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "peer": true ->>>>>>> develop }, "node_modules/easy-table": { "version": "1.1.0", @@ -4493,28 +4354,27 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", + "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.5.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4522,19 +4382,22 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "graphemer": "^1.4.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", + "optionator": "^0.9.1", "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -4595,15 +4458,12 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/ajv": { @@ -4629,9 +4489,9 @@ "dev": true }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -4639,9 +4499,6 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/estraverse": { @@ -4684,14 +4541,14 @@ "dev": true }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5161,37 +5018,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", -<<<<<<< HEAD -======= - "peer": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "peer": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", ->>>>>>> develop "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -5382,9 +5208,9 @@ "peer": true }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5401,10 +5227,10 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, "node_modules/has": { @@ -5450,10 +5276,6 @@ "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "engines": { "node": "*" } @@ -5903,10 +5725,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -6869,6 +6687,16 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7243,15 +7071,9 @@ } }, "node_modules/long": { -<<<<<<< HEAD "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" -======= - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" ->>>>>>> develop }, "node_modules/lru-cache": { "version": "5.1.1", @@ -7399,10 +7221,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "engines": { "node": ">=16 || 14 >=14.17" } @@ -7446,7 +7264,6 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "node_modules/mysql2": { -<<<<<<< HEAD "version": "2.3.3", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", @@ -7457,18 +7274,6 @@ "long": "^4.0.0", "lru-cache": "^6.0.0", "named-placeholders": "^1.1.2", -======= - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", - "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", - "dependencies": { - "denque": "^2.1.0", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", - "long": "^5.2.1", - "lru-cache": "^8.0.0", - "named-placeholders": "^1.1.3", ->>>>>>> develop "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" }, @@ -7488,7 +7293,6 @@ } }, "node_modules/mysql2/node_modules/lru-cache": { -<<<<<<< HEAD "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", @@ -7504,23 +7308,10 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, -======= - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", - "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", - "engines": { - "node": ">=16.14" - } - }, ->>>>>>> develop "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -7731,17 +7522,17 @@ "peer": true }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { "node": ">= 0.8.0" @@ -7867,21 +7658,12 @@ "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", -<<<<<<< HEAD "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" -======= - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "peer": true ->>>>>>> develop }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "parse5": "^6.0.1" } @@ -7889,12 +7671,7 @@ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", -<<<<<<< HEAD "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" -======= - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "peer": true ->>>>>>> develop }, "node_modules/parseurl": { "version": "1.3.3", @@ -7938,10 +7715,6 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -7957,10 +7730,6 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "engines": { "node": "14 || >=16.14" } @@ -8681,10 +8450,6 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -8941,10 +8706,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8970,10 +8731,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9284,10 +9041,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "any-promise": "^1.0.0" } @@ -9296,10 +9049,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -9572,10 +9321,6 @@ "version": "0.3.20", "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz", "integrity": "sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", @@ -9681,10 +9426,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "balanced-match": "^1.0.0" } @@ -9707,10 +9448,6 @@ "url": "https://feross.org/support" } ], -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -9720,10 +9457,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -9737,10 +9470,6 @@ "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -9762,10 +9491,6 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9780,10 +9505,6 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "bin": { "mkdirp": "dist/cjs/src/bin.js" }, @@ -9797,21 +9518,12 @@ "node_modules/typeorm/node_modules/reflect-metadata": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", -<<<<<<< HEAD "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" -======= - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", - "peer": true ->>>>>>> develop }, "node_modules/typeorm/node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -9829,10 +9541,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "engines": { "node": ">=12" } @@ -10106,6 +9814,15 @@ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -10122,24 +9839,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", @@ -10265,12 +9964,6 @@ } }, "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -10428,8 +10121,6 @@ "requires": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.1.0", -<<<<<<< HEAD -======= "tslib": "^2.2.0" }, "dependencies": { @@ -10454,7 +10145,6 @@ "@azure/core-tracing": "^1.0.0", "@azure/core-util": "^1.0.0", "@azure/logger": "^1.0.0", ->>>>>>> develop "tslib": "^2.2.0" }, "dependencies": { @@ -10465,33 +10155,6 @@ "requires": { "tslib": "^2.2.0" } -<<<<<<< HEAD - } - } - }, - "@azure/core-client": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.8.0.tgz", - "integrity": "sha512-+gHS3gEzPlhyQBMoqVPOTeNH031R5DM/xpCvz72y38C09rg4Hui/1sJS/ujoisDZbbSHyuRLVWdFlwL0pIFwbg==", - "requires": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-auth": "^1.4.0", - "@azure/core-rest-pipeline": "^1.9.1", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/abort-controller": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz", - "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==", - "requires": { - "tslib": "^2.2.0" - } -======= ->>>>>>> develop }, "@azure/core-tracing": { "version": "1.0.1", @@ -10593,53 +10256,12 @@ } }, "@azure/core-util": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.7.0.tgz", - "integrity": "sha512-Zq2i3QO6k9DA8vnm29mYM4G8IE9u1mhF1GUabVEqPNX8Lj833gdxQ2NAFxt2BZsfAL+e9cT8SyVN7dFVJ/Hf0g==", - "requires": { - "@azure/abort-controller": "^2.0.0", - "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/abort-controller": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.0.0.tgz", - "integrity": "sha512-RP/mR/WJchR+g+nQFJGOec+nzeN/VvjlwbinccoqfhTsTHbb8X5+mLDp48kHT0ueyum0BNSwGm0kX0UZuIqTGg==", - "requires": { - "tslib": "^2.2.0" - } - } - } - }, - "@azure/identity": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-3.4.2.tgz", - "integrity": "sha512-0q5DL4uyR0EZ4RXQKD8MadGH6zTIcloUoS/RVbCpNpej4pwte0xpqYxk8K97Py2RiuUvI7F4GXpoT4046VfufA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.3.2.tgz", + "integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==", "requires": { "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.5.0", - "@azure/core-client": "^1.4.0", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.6.1", - "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^3.5.0", - "@azure/msal-node": "^2.5.1", - "events": "^3.0.0", - "jws": "^4.0.0", - "open": "^8.0.0", - "stoppable": "^1.1.0", "tslib": "^2.2.0" - }, - "dependencies": { - "@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "requires": { - "tslib": "^2.2.0" - } - } } }, "@azure/identity": { @@ -11256,29 +10878,29 @@ } }, "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz", + "integrity": "sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==", "dev": true, "requires": { "eslint-visitor-keys": "^3.3.0" } }, "@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", "dev": true }, "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", + "espree": "^9.5.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -11323,19 +10945,19 @@ } }, "@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", "minimatch": "^3.0.5" } }, @@ -11346,19 +10968,15 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -11371,41 +10989,22 @@ "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", -<<<<<<< HEAD "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" -======= - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "peer": true ->>>>>>> develop }, "ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", -<<<<<<< HEAD "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" -======= - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "peer": true ->>>>>>> develop }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", -<<<<<<< HEAD "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" -======= - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "peer": true ->>>>>>> develop }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -11416,10 +11015,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "ansi-regex": "^6.0.1" } @@ -11428,10 +11023,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -12006,19 +11597,6 @@ } }, "@nestjs/typeorm": { -<<<<<<< HEAD - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-9.0.1.tgz", - "integrity": "sha512-A2BgLIPsMtmMI0bPKEf4bmzgFPsnvHqNBx3KkvaJ7hJrBQy0OqYOb+Rr06ifblKWDWS2tUPNrAFQbZjtk3PI+g==", - "requires": { - "uuid": "8.3.2" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" -======= "version": "10.0.2", "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-10.0.2.tgz", "integrity": "sha512-H738bJyydK4SQkRCTeh1aFBxoO1E9xdL/HaLGThwrqN95os5mEyAtK7BLADOS+vldP4jDZ2VQPLj4epWwRqCeQ==", @@ -12030,7 +11608,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" ->>>>>>> develop } } }, @@ -12222,12 +11799,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", -<<<<<<< HEAD "optional": true -======= - "optional": true, - "peer": true ->>>>>>> develop }, "@sinclair/typebox": { "version": "0.24.51", @@ -12256,12 +11828,7 @@ "@sqltools/formatter": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", -<<<<<<< HEAD "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==" -======= - "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", - "peer": true ->>>>>>> develop }, "@tootallnate/once": { "version": "2.0.0", @@ -12451,9 +12018,9 @@ } }, "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true, "peer": true }, @@ -12570,12 +12137,6 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "@vercel/ncc": { "version": "0.36.1", "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.1.tgz", @@ -12772,15 +12333,9 @@ } }, "acorn": { -<<<<<<< HEAD "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", -======= - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", ->>>>>>> develop "devOptional": true }, "acorn-import-assertions": { @@ -12860,12 +12415,7 @@ "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", -<<<<<<< HEAD "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" -======= - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "peer": true ->>>>>>> develop }, "anymatch": { "version": "3.1.3", @@ -12880,12 +12430,7 @@ "app-root-path": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", -<<<<<<< HEAD "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==" -======= - "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", - "peer": true ->>>>>>> develop }, "append-field": { "version": "1.0.0", @@ -13251,10 +12796,6 @@ "version": "2.1.11", "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", @@ -13497,12 +13038,7 @@ "dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", -<<<<<<< HEAD "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" -======= - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", - "peer": true ->>>>>>> develop }, "debug": { "version": "4.3.4", @@ -13626,12 +13162,7 @@ "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", -<<<<<<< HEAD "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" -======= - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "peer": true ->>>>>>> develop }, "easy-table": { "version": "1.1.0", @@ -13719,28 +13250,27 @@ "dev": true }, "eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", + "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.5.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -13748,19 +13278,22 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "graphemer": "^1.4.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", + "optionator": "^0.9.1", "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { @@ -13783,9 +13316,9 @@ "dev": true }, "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -13852,20 +13385,20 @@ } }, "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, "requires": { - "acorn": "^8.9.0", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^3.3.0" } }, "esprima": { @@ -14233,10 +13766,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -14245,12 +13774,7 @@ "signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", -<<<<<<< HEAD "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" -======= - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "peer": true ->>>>>>> develop } } }, @@ -14379,9 +13903,9 @@ "peer": true }, "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -14392,10 +13916,10 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, "has": { @@ -14425,12 +13949,7 @@ "highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", -<<<<<<< HEAD "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" -======= - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "peer": true ->>>>>>> develop }, "hosted-git-info": { "version": "2.8.9", @@ -14752,10 +14271,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "@isaacs/cliui": "^8.0.2", "@pkgjs/parseargs": "^0.11.0" @@ -15502,6 +15017,12 @@ } } }, + "js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -15814,15 +15335,9 @@ } }, "long": { -<<<<<<< HEAD "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" -======= - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" ->>>>>>> develop }, "lru-cache": { "version": "5.1.1", @@ -15935,12 +15450,7 @@ "minipass": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", -<<<<<<< HEAD "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" -======= - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "peer": true ->>>>>>> develop }, "mkdirp": { "version": "0.5.6", @@ -15975,7 +15485,6 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "mysql2": { -<<<<<<< HEAD "version": "2.3.3", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", @@ -15986,18 +15495,6 @@ "long": "^4.0.0", "lru-cache": "^6.0.0", "named-placeholders": "^1.1.2", -======= - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", - "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", - "requires": { - "denque": "^2.1.0", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", - "long": "^5.2.1", - "lru-cache": "^8.0.0", - "named-placeholders": "^1.1.3", ->>>>>>> develop "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" }, @@ -16011,7 +15508,6 @@ } }, "lru-cache": { -<<<<<<< HEAD "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", @@ -16023,11 +15519,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" -======= - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", - "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==" ->>>>>>> develop } } }, @@ -16035,10 +15526,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -16200,17 +15687,17 @@ "peer": true }, "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "ora": { @@ -16297,21 +15784,12 @@ "parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", -<<<<<<< HEAD "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" -======= - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "peer": true ->>>>>>> develop }, "parse5-htmlparser2-tree-adapter": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "parse5": "^6.0.1" }, @@ -16319,12 +15797,7 @@ "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", -<<<<<<< HEAD "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" -======= - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "peer": true ->>>>>>> develop } } }, @@ -16358,10 +15831,6 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -16370,12 +15839,7 @@ "lru-cache": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", -<<<<<<< HEAD "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==" -======= - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "peer": true ->>>>>>> develop } } }, @@ -16922,10 +16386,6 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -17141,10 +16601,6 @@ "version": "npm:string-width@4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -17163,10 +16619,6 @@ "version": "npm:strip-ansi@6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "ansi-regex": "^5.0.1" } @@ -17378,10 +16830,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "any-promise": "^1.0.0" } @@ -17390,10 +16838,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "thenify": ">= 3.1.0 < 4" } @@ -17570,10 +17014,6 @@ "version": "0.3.20", "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz", "integrity": "sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", @@ -17596,10 +17036,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "balanced-match": "^1.0.0" } @@ -17608,10 +17044,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -17621,10 +17053,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -17635,10 +17063,6 @@ "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -17651,10 +17075,6 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "brace-expansion": "^2.0.1" } @@ -17662,31 +17082,17 @@ "mkdirp": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", -<<<<<<< HEAD "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==" -======= - "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", - "peer": true ->>>>>>> develop }, "reflect-metadata": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", -<<<<<<< HEAD "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" -======= - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", - "peer": true ->>>>>>> develop }, "yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -17700,12 +17106,7 @@ "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", -<<<<<<< HEAD "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" -======= - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "peer": true ->>>>>>> develop } } }, @@ -17904,6 +17305,12 @@ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -17918,10 +17325,6 @@ "version": "npm:wrap-ansi@7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", -<<<<<<< HEAD -======= - "peer": true, ->>>>>>> develop "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", diff --git a/data_migration_tools/server/package.json b/data_migration_tools/server/package.json index 2b445ea..a2299cb 100644 --- a/data_migration_tools/server/package.json +++ b/data_migration_tools/server/package.json @@ -31,7 +31,6 @@ "@nestjs/core": "^9.3.9", "@nestjs/platform-express": "^9.4.1", "@nestjs/serve-static": "^3.0.1", - "@nestjs/typeorm": "^9.0.1", "@nestjs/swagger": "^6.2.1", "@nestjs/testing": "^9.3.9", "@nestjs/typeorm": "^10.0.2", @@ -42,12 +41,11 @@ "class-validator": "^0.14.0", "cookie-parser": "^1.4.6", "multer": "^1.4.5-lts.1", - "mysql2": "^3.9.1", + "mysql2": "^2.3.3", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.0", "swagger-cli": "^4.0.4", - "typeorm": "^0.3.10", - "mysql2": "^2.3.3" + "typeorm": "^0.3.20" }, "devDependencies": { "@types/express": "^4.17.17", diff --git a/data_migration_tools/server/src/common/errors/types/types.ts b/data_migration_tools/server/src/common/errors/types/types.ts index 8746924..f68eda7 100644 --- a/data_migration_tools/server/src/common/errors/types/types.ts +++ b/data_migration_tools/server/src/common/errors/types/types.ts @@ -1,5 +1,5 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { ErrorCodes } from '../code'; +import { ApiProperty } from "@nestjs/swagger"; +import { ErrorCodes } from "../code"; export class ErrorResponse { @ApiProperty() diff --git a/data_migration_tools/server/src/common/log/index.ts b/data_migration_tools/server/src/common/log/index.ts index 7b0bf35..386f9cd 100644 --- a/data_migration_tools/server/src/common/log/index.ts +++ b/data_migration_tools/server/src/common/log/index.ts @@ -1,4 +1,4 @@ -import { Context } from './types'; -import { makeContext, retrieveRequestId, retrieveIp } from './context'; +import { Context } from "./types"; +import { makeContext, retrieveRequestId, retrieveIp } from "./context"; export { Context, makeContext, retrieveRequestId, retrieveIp }; diff --git a/data_migration_tools/server/src/common/password/index.ts b/data_migration_tools/server/src/common/password/index.ts index 8960a26..1ba44a2 100644 --- a/data_migration_tools/server/src/common/password/index.ts +++ b/data_migration_tools/server/src/common/password/index.ts @@ -1,3 +1,3 @@ -import { makePassword } from './password'; +import { makePassword } from "./password"; export { makePassword }; diff --git a/data_migration_tools/server/src/common/password/password.ts b/data_migration_tools/server/src/common/password/password.ts index f68bb3c..6fbe071 100644 --- a/data_migration_tools/server/src/common/password/password.ts +++ b/data_migration_tools/server/src/common/password/password.ts @@ -3,10 +3,10 @@ export const makePassword = (): string => { const passLength = 8; // パスワードに使用可能な文字を決定(今回はアルファベットの大文字と小文字 + 数字 + symbolsの記号) - const lowerCase = 'abcdefghijklmnopqrstuvwxyz'; + const lowerCase = "abcdefghijklmnopqrstuvwxyz"; const upperCase = lowerCase.toLocaleUpperCase(); - const numbers = '0123456789'; - const symbols = '@#$%^&*\\-_+=[]{}|:\',.?/`~"();!'; + const numbers = "0123456789"; + const symbols = "@#$%^&*\\-_+=[]{}|:',.?/`~\"();!"; const chars = lowerCase + upperCase + numbers + symbols; // 英字の大文字、英字の小文字、アラビア数字、記号(@#$%^&*\-_+=[]{}|\:',.?/`~"();!)から2種類以上組み合わせ @@ -15,7 +15,7 @@ export const makePassword = (): string => { // autoGeneratedPasswordが以上の条件を満たせばvalidがtrueになる let valid = false; - let autoGeneratedPassword: string = ''; + let autoGeneratedPassword: string = ""; while (!valid) { // パスワードをランダムに決定 diff --git a/data_migration_tools/server/src/common/types/types.ts b/data_migration_tools/server/src/common/types/types.ts index 7a7854e..660b942 100644 --- a/data_migration_tools/server/src/common/types/types.ts +++ b/data_migration_tools/server/src/common/types/types.ts @@ -1,3 +1,60 @@ +export class csvInputFile { + type: string; + account_id: string; + parent_id: string; + email: string; + company_name: string; + first_name: string; + last_name: string; + country: string; + state: string; + start_date: Date; + expired_date: Date; + user_email: string; + author_id: string; + recording_mode: string; + wt1: string; + wt2: string; + wt3: string; + wt4: string; + wt5: string; + wt6: string; + wt7: string; + wt8: string; + wt9: string; + wt10: string; + wt11: string; + wt12: string; + wt13: string; + wt14: string; + wt15: string; + wt16: string; + wt17: string; + wt18: string; + wt19: string; + wt20: string; +} +export class AccountsOutputFileStep1 { + accountId: number; + type: string; + companyName: string; + country: string; + dealerAccountId?: number; + adminName: string; + adminMail: string; + userId: number; +} + +export class AccountsOutputFile { + accountId: number; + type: number; + companyName: string; + country: string; + dealerAccountId?: number; + adminName: string; + adminMail: string; + userId: number; +} export class AccountsInputFile { accountId: number; type: number; @@ -8,6 +65,14 @@ export class AccountsInputFile { adminMail: string; userId: number; } +export class UsersOutputFile { + accountId: number; + userId: number; + name: string; + role: string; + authorId: string; + email: string; +} export class UsersInputFile { accountId: number; @@ -18,6 +83,13 @@ export class UsersInputFile { email: string; } +export class LicensesOutputFile { + expiry_date: string; + account_id: number; + type: string; + status: string; + allocated_user_id?: number; +} export class LicensesInputFile { expiry_date: string; account_id: number; @@ -26,6 +98,10 @@ export class LicensesInputFile { allocated_user_id?: number; } +export class WorktypesOutputFile { + account_id: number; + custom_worktype_id: string; +} export class WorktypesInputFile { account_id: number; custom_worktype_id: string; diff --git a/data_migration_tools/server/src/common/validators/admin.validator.ts b/data_migration_tools/server/src/common/validators/admin.validator.ts new file mode 100644 index 0000000..d904154 --- /dev/null +++ b/data_migration_tools/server/src/common/validators/admin.validator.ts @@ -0,0 +1,39 @@ +import { + registerDecorator, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, +} from "class-validator"; + +@ValidatorConstraint() +export class IsAdminPassword implements ValidatorConstraintInterface { + validate(value: string): boolean { + // 8文字~64文字でなければ早期に不合格 + const minLength = 8; + const maxLength = 64; + if (value.length < minLength || value.length > maxLength) { + return false; + } + + // 英字の大文字、英字の小文字、アラビア数字、記号(@#$%^&*\-_+=[]{}|\:',.?/`~"();!)から2種類以上組み合わせ + const charaTypePattern = + /^((?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*[\d])|(?=.*[a-z])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!])|(?=.*[A-Z])(?=.*[\d])|(?=.*[A-Z])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!])|(?=.*[\d])(?=.*[@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!]))[a-zA-Z\d@#$%^&*\\\-_+=\[\]{}|:',.?\/`~"();!]/; + return new RegExp(charaTypePattern).test(value); + } + defaultMessage(): string { + return "Admin password rule not satisfied"; + } +} + +export const IsAdminPasswordvalid = (validationOptions?: ValidationOptions) => { + return (object: any, propertyName: string) => { + registerDecorator({ + name: "IsAdminPasswordvalid", + target: object.constructor, + propertyName: propertyName, + constraints: [], + options: validationOptions, + validator: IsAdminPassword, + }); + }; +}; diff --git a/data_migration_tools/server/src/constants/index.ts b/data_migration_tools/server/src/constants/index.ts index 4acb160..4330bb6 100644 --- a/data_migration_tools/server/src/constants/index.ts +++ b/data_migration_tools/server/src/constants/index.ts @@ -322,6 +322,77 @@ export const USER_LICENSE_STATUS = { EXPIRED: "expired", } as const; +/** + * typeの取りうる値(移行元CSV) + * @const {string[]} + */ +export const MIGRATION_TYPE = { + ADMINISTRATOR: "Administrator", + BC: "BC", + COUNTRY: "Country", + CUSTOMER: "Customer", + DEALER: "Dealer", + DISTRIBUTOR: "Distributor", + USER: "USER", +} as const; + +/** + * 移行先の名称と移行元の値 + * @const {string[]} + */ +export const COUNTRY_LIST = [ + { value: "CA", label: "Canada" }, + { value: "KY", label: "Cayman Islands" }, + { value: "US", label: "U.S.A." }, + { value: "AU", label: "Australia" }, + { value: "NZ", label: "New Zealand" }, + { value: "AT", label: "Austria" }, + { value: "BE", label: "Belgium" }, + { value: "BG", label: "Bulgaria" }, + { value: "HR", label: "Croatia" }, + { value: "CY", label: "Cyprus" }, + { value: "CZ", label: "Czech Republic" }, + { value: "DK", label: "Denmark" }, + { value: "EE", label: "Estonia" }, + { value: "FI", label: "Finland" }, + { value: "FR", label: "France" }, + { value: "DE", label: "Germany" }, + { value: "GR", label: "Greece" }, + { value: "HU", label: "Hungary" }, + { value: "IS", label: "Iceland" }, + { value: "IE", label: "Ireland" }, + { value: "IT", label: "Italy" }, + { value: "LV", label: "Latvia" }, + { value: "LI", label: "Liechtenstein" }, + { value: "LT", label: "Lithuania" }, + { value: "LU", label: "Luxembourg" }, + { value: "MT", label: "Malta" }, + { value: "NL", label: "Netherlands" }, + { value: "NO", label: "Norway" }, + { value: "PL", label: "Poland" }, + { value: "PT", label: "Portugal" }, + { value: "RO", label: "Romania" }, + { value: "RS", label: "Serbia" }, + { value: "SK", label: "Slovakia" }, + { value: "SI", label: "Slovenia" }, + { value: "ZA", label: "South Africa" }, + { value: "ES", label: "Spain" }, + { value: "SE", label: "Sweden" }, + { value: "CH", label: "Switzerland" }, + { value: "TR", label: "Turkey" }, + { value: "GB", label: "United Kingdom" }, +]; + +/** + * recording_modeの取りうる値(移行元CSV) + * @const {string[]} + */ +export const RECORDING_MODE = { + DS2_QP: "DS2 (QP)", + DS2_SP: "DS2 (SP)", + DSS: "DSS", +} as const; + /** * AutoIncrementの初期値 * @const {number} diff --git a/data_migration_tools/server/src/features/transfer /transfer.controller.ts b/data_migration_tools/server/src/features/transfer /transfer.controller.ts new file mode 100644 index 0000000..8ac9923 --- /dev/null +++ b/data_migration_tools/server/src/features/transfer /transfer.controller.ts @@ -0,0 +1,174 @@ +import { + Body, + Controller, + HttpStatus, + Post, + Req, + HttpException, + Logger, +} from "@nestjs/common"; +import fs from "fs"; +import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; +import { Request } from "express"; +import { transferRequest, transferResponse } from "./types/types"; +import { transferService } from "./transfer.service"; +import { makeContext } from "../../common/log"; +import { csvInputFile } from "../../common/types/types"; +import { makeErrorResponse } from "src/common/errors/makeErrorResponse"; +import { + COUNTRY_LIST, + MIGRATION_TYPE, + TIERS, + WORKTYPE_MAX_COUNT, + RECORDING_MODE, + LICENSE_ALLOCATED_STATUS, + USER_ROLES, + AUTO_INCREMENT_START, +} from "../../../src/constants"; +@ApiTags("transfer") +@Controller("transfer") +export class transferController { + private readonly logger = new Logger(transferController.name); + constructor(private readonly transferService: transferService) {} + + @Post() + @ApiResponse({ + status: HttpStatus.OK, + type: transferResponse, + description: "成功時のレスポンス", + }) + @ApiResponse({ + status: HttpStatus.INTERNAL_SERVER_ERROR, + description: "想定外のサーバーエラー", + }) + @ApiOperation({ operationId: "dataRegist" }) + async dataRegist( + @Body() body: transferRequest, + @Req() req: Request + ): Promise { + const context = makeContext("iko", "transfer"); + + const inputFilePath = body.inputFilePath; + + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.dataRegist.name + } | params: { inputFilePath: ${inputFilePath}};` + ); + try { + // 読み込みファイルのフルパス + const csvFileFullPath = inputFilePath + ".csv"; + + // ファイル存在チェックと読み込み + if (!fs.existsSync(csvFileFullPath)) { + this.logger.error(`file not exists from ${inputFilePath}`); + throw new Error(`file not exists from ${inputFilePath}`); + } + + // CSVファイルを全行読み込む + const inputFile = fs.readFileSync(csvFileFullPath, "utf-8"); + + // レコードごとに分割 + const csvInputFileLines = inputFile.split("\n"); + + // ヘッダー行を削除 + csvInputFileLines.shift(); + + // 項目ごとに切り分ける + let csvInputFile: csvInputFile[] = []; + csvInputFileLines.forEach((line) => { + const data = line.split(","); + csvInputFile.push({ + type: data[0], + account_id: data[1], + parent_id: data[2], + email: data[3], + company_name: data[4], + first_name: data[5], + last_name: data[6], + country: data[7], + state: data[8], + start_date: new Date(data[9]), + expired_date: new Date(data[10]), + user_email: data[11], + author_id: data[12], + recording_mode: data[13], + wt1: data[14], + wt2: data[15], + wt3: data[16], + wt4: data[17], + wt5: data[18], + wt6: data[19], + wt7: data[20], + wt8: data[21], + wt9: data[22], + wt10: data[23], + wt11: data[24], + wt12: data[25], + wt13: data[26], + wt14: data[27], + wt15: data[28], + wt16: data[29], + wt17: data[30], + wt18: data[31], + wt19: data[32], + wt20: data[33], + }); + }); + + // 各データのバリデーションチェック + await this.transferService.validateInputData(context, csvInputFile); + + // account_idを通番に変換し、変換前account_id: 変換後accountId配列を作成する。 + const accountIdList = csvInputFile.map((line) => line.account_id); + const accountIdListSet = new Set(accountIdList); + const accountIdListArray = Array.from(accountIdListSet); + const accountIdMap = new Map(); + accountIdListArray.forEach((accountId, index) => { + accountIdMap.set(accountId, index + AUTO_INCREMENT_START); + }); + // CSVファイルの変換 + const transferResponse = await this.transferService.registInputData( + context, + csvInputFile, + accountIdMap + ); + + // countryを除いた階層の再配置 + const accountsOutputFileStep1Lines = + transferResponse.accountsOutputFileStep1Lines; + const accountsOutputFile = await this.transferService.relocateHierarchy( + context, + accountsOutputFileStep1Lines + ); + // メールアドレスの重複を削除 + // デモライセンスの削除 + // いったんこのままコミットしてテストを実施する + + // transferResponseを4つのJSONファイルの出力する(出力先はinputと同じにする) + const outputFilePath = body.inputFilePath; + const usersOutputFile = transferResponse.usersOutputFileLines; + const licensesOutputFile = transferResponse.licensesOutputFileLines; + const worktypesOutputFile = transferResponse.worktypesOutputFileLines; + this.transferService.outputJsonFile( + context, + outputFilePath, + accountsOutputFile, + usersOutputFile, + licensesOutputFile, + worktypesOutputFile + ); + return {}; + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + throw new HttpException( + makeErrorResponse("E009999"), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.dataRegist.name}` + ); + } + } +} diff --git a/data_migration_tools/server/src/features/transfer /transfer.module.ts b/data_migration_tools/server/src/features/transfer /transfer.module.ts new file mode 100644 index 0000000..b2a7893 --- /dev/null +++ b/data_migration_tools/server/src/features/transfer /transfer.module.ts @@ -0,0 +1,9 @@ +import { Module } from "@nestjs/common"; +import { transferController } from "./transfer.controller"; +import { transferService } from "./transfer.service"; +@Module({ + imports: [], + controllers: [transferController], + providers: [transferService], +}) +export class transferModule {} diff --git a/data_migration_tools/server/src/features/transfer /transfer.service.ts b/data_migration_tools/server/src/features/transfer /transfer.service.ts new file mode 100644 index 0000000..70b5d26 --- /dev/null +++ b/data_migration_tools/server/src/features/transfer /transfer.service.ts @@ -0,0 +1,357 @@ +import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; +import { Context } from "../../common/log"; +import { + AccountsOutputFileStep1, + UsersOutputFile, + LicensesOutputFile, + WorktypesOutputFile, + csvInputFile, + AccountsOutputFile, +} from "../../common/types/types"; +import { + COUNTRY_LIST, + MIGRATION_TYPE, + TIERS, + WORKTYPE_MAX_COUNT, + RECORDING_MODE, + LICENSE_ALLOCATED_STATUS, + USER_ROLES, + SWITCH_FROM_TYPE, +} from "src/constants"; +import { registInputDataResponse } from "./types/types"; +import fs from "fs"; + +@Injectable() +export class transferService { + constructor() {} + private readonly logger = new Logger(transferService.name); + + /** + * Regist Data + * @param OutputFilePath: string + * @param csvInputFile: csvInputFile[] + */ + async registInputData( + context: Context, + csvInputFile: csvInputFile[], + accountIdMap: Map + ): Promise { + // パラメータ内容が長大なのでログには出さない + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.registInputData.name}` + ); + + try { + let accountsOutputFileStep1Lines: AccountsOutputFileStep1[] = []; + let usersOutputFileLines: UsersOutputFile[] = []; + let licensesOutputFileLines: LicensesOutputFile[] = []; + let worktypesOutputFileLines: WorktypesOutputFile[] = []; + + let userIdIndex = 0; + // csvInputFileを一行読み込みする + csvInputFile.forEach((line) => { + // typeが"USER"以外の場合、アカウントデータの作成を行う + if (line.type !== MIGRATION_TYPE.USER) { + // userIdのインクリメント + userIdIndex = userIdIndex + 1; + // line.countryの値を読み込みCOUNTRY_LISTのlabelからvalueに変換する + const country = COUNTRY_LIST.find( + (country) => country.label === line.country + )?.value; + // adminNameの変換(last_name + " "+ first_name) + const adminName = `${line.last_name} ${line.first_name}`; + + // ランダムパスワードの生成(データ登録ツール側で行うのでやらない) + // common/password/password.tsのmakePasswordを使用 + // const autoGeneratedPassword = makePassword(); + + // parentAccountIdの設定 + // parent_idが存在する場合、accountIdMapを参照し、accountIdに変換する + let parentAccountId: number | null = null; + if (line.parent_id) { + parentAccountId = accountIdMap.get(line.parent_id); + } + // AccountsOutputFile配列にPush + accountsOutputFileStep1Lines.push({ + // accountIdはaccountIdMapから取得する + accountId: accountIdMap.get(line.account_id), + type: line.type, + companyName: line.company_name, + country: country, + dealerAccountId: parentAccountId, + adminName: adminName, + adminMail: line.email, + userId: userIdIndex, + }); + } else { + // typeが"USER"の場合、ユーザデータの作成を行う + // userIdのインクリメント + userIdIndex = userIdIndex + 1; + // nameの変換 + // もしline.last_nameとline.first_nameが存在しない場合、line.emailをnameにする + // 存在する場合は、last_name + " " + first_name + let name = line.email; + if (line.last_name && line.first_name) { + name = `${line.last_name} ${line.first_name}`; + } + // roleの変換 + // authorIdが設定されてる場合はauthor、されていない場合は移行しないので次の行に進む + if (line.author_id) { + usersOutputFileLines.push({ + accountId: accountIdMap.get(line.account_id), + userId: userIdIndex, + name: name, + role: USER_ROLES.AUTHOR, + authorId: line.author_id, + email: line.user_email, + }); + } else { + return; + } + // ライセンスのデータの作成を行う + // authorIdが設定されてる場合、statusは"allocated"、allocated_user_idは対象のユーザID + // されていない場合、statusは"reusable"、allocated_user_idはnull + licensesOutputFileLines.push({ + expiry_date: line.expired_date.toISOString(), + account_id: accountIdMap.get(line.account_id), + type: SWITCH_FROM_TYPE.NONE, + status: line.author_id + ? LICENSE_ALLOCATED_STATUS.ALLOCATED + : LICENSE_ALLOCATED_STATUS.REUSABLE, + allocated_user_id: line.author_id ? userIdIndex : null, + }); + // WorktypesOutputFileの作成 + // wt1~wt20まで読み込み、account単位で作成する + // 作成したWorktypesOutputFileを配列にPush + for (let i = 1; i <= WORKTYPE_MAX_COUNT; i++) { + const wt = `wt${i}`; + if (line[wt]) { + // 既に存在する場合は、作成しない + if ( + worktypesOutputFileLines.find( + (worktype) => + worktype.account_id === accountIdMap.get(line.account_id) && + worktype.custom_worktype_id === line[wt].toString() + ) + ) { + continue; + } + } + } + } + // つぎの行に進む + }); + return { + accountsOutputFileStep1Lines, + usersOutputFileLines, + licensesOutputFileLines, + worktypesOutputFileLines, + }; + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.registInputData.name}` + ); + } + } + + /** + * 階層の付け替えを行う + * @param accountsOutputFileStep1: AccountsOutputFileStep1[] + * @returns AccountsOutputFile[] + */ + async relocateHierarchy( + context: Context, + accountsOutputFileStep1: AccountsOutputFileStep1[] + ): Promise { + // パラメータ内容が長大なのでログには出さない + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.relocateHierarchy.name}` + ); + + try { + // dealerAccountIdを検索し、typeがCountryの場合 + accountsOutputFileStep1.forEach((account) => { + if (account.type === MIGRATION_TYPE.COUNTRY) { + // そのacccountIdをdealerAccountIdにもつアカウント(Distributor)を検索する + const distributor = accountsOutputFileStep1.find( + (distributor) => + account.type === MIGRATION_TYPE.DISTRIBUTOR && + distributor.dealerAccountId === account.accountId + ); + // DistributorのdealerAccountIdをBC(Countryの親)に付け替える + distributor.dealerAccountId = account.dealerAccountId; + } + }); + // typeがCountryのアカウントを取り除く + accountsOutputFileStep1 = accountsOutputFileStep1.filter( + (account) => account.type !== MIGRATION_TYPE.COUNTRY + ); + + // typeをtierに変換し、AccountsOutputFileに変換する + let accountsOutputFile: AccountsOutputFile[] = []; + accountsOutputFileStep1.forEach((account) => { + let tier = 0; + switch (account.type) { + case MIGRATION_TYPE.ADMINISTRATOR: + tier = TIERS.TIER1; + break; + case MIGRATION_TYPE.BC: + tier = TIERS.TIER2; + break; + case MIGRATION_TYPE.DISTRIBUTOR: + tier = TIERS.TIER3; + break; + case MIGRATION_TYPE.DEALER: + tier = TIERS.TIER4; + break; + case MIGRATION_TYPE.CUSTOMER: + tier = TIERS.TIER5; + break; + } + accountsOutputFile.push({ + accountId: account.accountId, + type: tier, + companyName: account.companyName, + country: account.country, + dealerAccountId: account.dealerAccountId, + adminName: account.adminName, + adminMail: account.adminMail, + userId: account.userId, + }); + }); + return accountsOutputFile; + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.relocateHierarchy.name}` + ); + } + } + + /** + * JSONファイルの出力 + * @param outputFilePath: string + * @param accountsOutputFile: AccountsOutputFile[] + * @param usersOutputFile: UsersOutputFile[] + * @param licensesOutputFile: LicensesOutputFile[] + * @param worktypesOutputFile: WorktypesOutputFile[] + */ + async outputJsonFile( + context: Context, + outputFilePath: string, + accountsOutputFile: AccountsOutputFile[], + usersOutputFile: UsersOutputFile[], + licensesOutputFile: LicensesOutputFile[], + worktypesOutputFile: WorktypesOutputFile[] + ): Promise { + // パラメータ内容が長大なのでログには出さない + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.outputJsonFile.name}` + ); + + try { + // JSONファイルの出力を行う + // accountsOutputFile配列の出力 + const accountsOutputFileJson = JSON.stringify(accountsOutputFile); + fs.writeFileSync( + `${outputFilePath}_accounts.json`, + accountsOutputFileJson + ); + // usersOutputFile + const usersOutputFileJson = JSON.stringify(usersOutputFile); + fs.writeFileSync(`${outputFilePath}_users.json`, usersOutputFileJson); + // licensesOutputFile + const licensesOutputFileJson = JSON.stringify(licensesOutputFile); + fs.writeFileSync( + `${outputFilePath}_licenses.json`, + licensesOutputFileJson + ); + // worktypesOutputFile + const worktypesOutputFileJson = JSON.stringify(worktypesOutputFile); + fs.writeFileSync( + `${outputFilePath}_worktypes.json`, + worktypesOutputFileJson + ); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.outputJsonFile.name}` + ); + } + } + + /** + * データのバリデーションチェック + * @param csvInputFile: csvInputFile[] + */ + async validateInputData( + context: Context, + csvInputFile: csvInputFile[] + ): Promise { + // パラメータ内容が長大なのでログには出さない + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.validateInputData.name}` + ); + + try { + // csvInputFileのバリデーションチェックを行う + csvInputFile.forEach((line, index) => { + // typeのバリデーションチェック + if ( + line.type !== MIGRATION_TYPE.ADMINISTRATOR && + line.type !== MIGRATION_TYPE.BC && + line.type !== MIGRATION_TYPE.DISTRIBUTOR && + line.type !== MIGRATION_TYPE.DEALER && + line.type !== MIGRATION_TYPE.CUSTOMER && + line.type !== MIGRATION_TYPE.USER + ) { + throw new HttpException( + `type is invalid. index=${index} type=${line.type}`, + HttpStatus.BAD_REQUEST + ); + } + // countryのバリデーションチェック + if (!COUNTRY_LIST.find((country) => country.label === line.country)) { + throw new HttpException( + `country is invalid. index=${index} country=${line.country}`, + HttpStatus.BAD_REQUEST + ); + } + // mailのバリデーションチェック + // メールアドレスの形式が正しいかどうかのチェック + const mailRegExp = new RegExp( + /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$/ + ); + if (!mailRegExp.test(line.email)) { + throw new HttpException( + `email is invalid. index=${index} email=${line.email}`, + HttpStatus.BAD_REQUEST + ); + } + // recording_modeのバリデーションチェック + // RECORDING_MODEに存在するかどうかのチェック + if ( + line.recording_mode !== RECORDING_MODE.DS2_QP && + line.recording_mode !== RECORDING_MODE.DS2_SP && + line.recording_mode !== RECORDING_MODE.DSS && + line.recording_mode !== null + ) { + throw new HttpException( + `recording_mode is invalid. index=${index} recording_mode=${line.recording_mode}`, + HttpStatus.BAD_REQUEST + ); + } + }); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.validateInputData.name}` + ); + } + } +} diff --git a/data_migration_tools/server/src/features/transfer /types/types.ts b/data_migration_tools/server/src/features/transfer /types/types.ts new file mode 100644 index 0000000..63eb3ab --- /dev/null +++ b/data_migration_tools/server/src/features/transfer /types/types.ts @@ -0,0 +1,25 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { + AccountsOutputFileStep1, + LicensesOutputFile, + UsersOutputFile, + WorktypesOutputFile, +} from "src/common/types/types"; + +export class transferRequest { + @ApiProperty() + inputFilePath: string; +} + +export class transferResponse {} + +export class registInputDataResponse { + @ApiProperty() + accountsOutputFileStep1Lines: AccountsOutputFileStep1[]; + @ApiProperty() + usersOutputFileLines: UsersOutputFile[]; + @ApiProperty() + licensesOutputFileLines: LicensesOutputFile[]; + @ApiProperty() + worktypesOutputFileLines: WorktypesOutputFile[]; +} From e3ee9412c9939a7ddebcd259f1b860443ffecfd8 Mon Sep 17 00:00:00 2001 From: "maruyama.t" Date: Thu, 22 Feb 2024 06:40:52 +0000 Subject: [PATCH 04/10] =?UTF-8?q?Merged=20PR=20772:=20=E3=83=95=E3=82=A9?= =?UTF-8?q?=E3=83=AB=E3=83=80=E3=83=AA=E3=83=8D=E3=83=BC=E3=83=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3570: データ変換ツール(きれいなデータ版)作成+動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3570) - 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず) - 何をどう変更したか、追加したライブラリなど - このPull Requestでの対象/対象外 - 影響範囲(他の機能にも影響があるか) ## レビューポイント - 特にレビューしてほしい箇所 - 軽微なものや自明なものは記載不要 - 修正範囲が大きい場合などに記載 - 全体的にや仕様を満たしているか等は本当に必要な時のみ記載 ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認、develop環境で確認など ## 補足 - 相談、参考資料などがあれば --- .../src/features/{transfer => transfer}/transfer.controller.ts | 0 .../src/features/{transfer => transfer}/transfer.module.ts | 0 .../src/features/{transfer => transfer}/transfer.service.ts | 0 .../server/src/features/{transfer => transfer}/types/types.ts | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename data_migration_tools/server/src/features/{transfer => transfer}/transfer.controller.ts (100%) rename data_migration_tools/server/src/features/{transfer => transfer}/transfer.module.ts (100%) rename data_migration_tools/server/src/features/{transfer => transfer}/transfer.service.ts (100%) rename data_migration_tools/server/src/features/{transfer => transfer}/types/types.ts (100%) diff --git a/data_migration_tools/server/src/features/transfer /transfer.controller.ts b/data_migration_tools/server/src/features/transfer/transfer.controller.ts similarity index 100% rename from data_migration_tools/server/src/features/transfer /transfer.controller.ts rename to data_migration_tools/server/src/features/transfer/transfer.controller.ts diff --git a/data_migration_tools/server/src/features/transfer /transfer.module.ts b/data_migration_tools/server/src/features/transfer/transfer.module.ts similarity index 100% rename from data_migration_tools/server/src/features/transfer /transfer.module.ts rename to data_migration_tools/server/src/features/transfer/transfer.module.ts diff --git a/data_migration_tools/server/src/features/transfer /transfer.service.ts b/data_migration_tools/server/src/features/transfer/transfer.service.ts similarity index 100% rename from data_migration_tools/server/src/features/transfer /transfer.service.ts rename to data_migration_tools/server/src/features/transfer/transfer.service.ts diff --git a/data_migration_tools/server/src/features/transfer /types/types.ts b/data_migration_tools/server/src/features/transfer/types/types.ts similarity index 100% rename from data_migration_tools/server/src/features/transfer /types/types.ts rename to data_migration_tools/server/src/features/transfer/types/types.ts From dc52ec2022cf73827166c861278a83a6b2d42bd1 Mon Sep 17 00:00:00 2001 From: "makabe.t" Date: Thu, 22 Feb 2024 07:33:55 +0000 Subject: [PATCH 05/10] =?UTF-8?q?Merged=20PR=20765:=20=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E5=89=8A=E9=99=A4=E3=83=84=E3=83=BC=E3=83=AB=E4=BD=9C?= =?UTF-8?q?=E6=88=90=EF=BC=8B=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3569: データ削除ツール作成+動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3569) - ADB2Cからのユーザー削除が100件ごとにしか削除できていなかったので、修正しました。 - 取得が100件まででそのユーザーに対して削除処理をしていたので100件までの削除になっていました。 - 対応として、100件づつの削除をユーザーが全削除されるまで実行するようにしました。 ## レビューポイント - 対応方法として適切でしょうか? - ループで制限を設けていますが、MAX値として適切でしょうか? ## UIの変更 - なし ## 動作確認状況 - ローカルで順に実行できることを確認 - 実際の削除は別途develop環境で実施します。 --- data_migration_tools/server/package-lock.json | 12 +++--- .../src/features/delete/delete.controller.ts | 5 ++- .../src/features/delete/delete.service.ts | 28 ++++++++++---- .../src/gateways/adb2c/adb2c.service.ts | 18 ++++----- .../blobstorage/blobstorage.service.ts | 6 ++- .../delete/delete.repository.service.ts | 37 ++++++++++++++++++- 6 files changed, 80 insertions(+), 26 deletions(-) diff --git a/data_migration_tools/server/package-lock.json b/data_migration_tools/server/package-lock.json index 5987ef1..c1c2143 100644 --- a/data_migration_tools/server/package-lock.json +++ b/data_migration_tools/server/package-lock.json @@ -3107,9 +3107,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "devOptional": true, "bin": { "acorn": "bin/acorn" @@ -12333,9 +12333,9 @@ } }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "devOptional": true }, "acorn-import-assertions": { diff --git a/data_migration_tools/server/src/features/delete/delete.controller.ts b/data_migration_tools/server/src/features/delete/delete.controller.ts index 94567ca..ed81c5a 100644 --- a/data_migration_tools/server/src/features/delete/delete.controller.ts +++ b/data_migration_tools/server/src/features/delete/delete.controller.ts @@ -11,6 +11,7 @@ import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; import { Request } from "express"; import { DeleteService } from "./delete.service"; import { DeleteResponse } from "./types/types"; +import { makeContext } from "src/common/log"; @ApiTags("delete") @Controller("delete") @@ -33,7 +34,9 @@ export class DeleteController { }) @Post() async deleteData(): Promise<{}> { - await this.deleteService.deleteData(); + const context = makeContext("tool", "delete"); + + await this.deleteService.deleteData(context); return {}; } } diff --git a/data_migration_tools/server/src/features/delete/delete.service.ts b/data_migration_tools/server/src/features/delete/delete.service.ts index 9ade573..3055d5b 100644 --- a/data_migration_tools/server/src/features/delete/delete.service.ts +++ b/data_migration_tools/server/src/features/delete/delete.service.ts @@ -3,6 +3,7 @@ import { DeleteRepositoryService } from "../../repositories/delete/delete.reposi import { makeErrorResponse } from "../../common/errors/makeErrorResponse"; import { AdB2cService } from "../../gateways/adb2c/adb2c.service"; import { BlobstorageService } from "../../gateways/blobstorage/blobstorage.service"; +import { Context } from "../../common/log"; @Injectable() export class DeleteService { @@ -17,21 +18,34 @@ export class DeleteService { * データを削除する * @returns data */ - async deleteData(): Promise { - this.logger.log(`[IN] ${this.deleteData.name}`); + async deleteData(context: Context): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.deleteData.name}` + ); try { // BlobStorageからデータを削除する - await this.blobstorageService.deleteContainers(); + await this.blobstorageService.deleteContainers(context); - // ADB2Cからユーザ情報を取得する - const users = await this.adB2cService.getUsers(); - const externalIds = users.map((user) => user.id); - await this.adB2cService.deleteUsers(externalIds); + // 100件ずつのユーザー取得なのですべて削除するまでループする + for (let i = 0; i < 500; i++) { + // ADB2Cからユーザ情報を取得する + const { users, hasNext } = await this.adB2cService.getUsers(context); + + // ユーザーがいない場合はループを抜ける + if (!hasNext) { + break; + } + + const externalIds = users.map((user) => user.id); + await this.adB2cService.deleteUsers(context, externalIds); + } // データベースからデータを削除する await this.deleteRepositoryService.deleteData(); // AutoIncrementの値をリセットする await this.deleteRepositoryService.resetAutoIncrement(); + // 初期データを挿入する + await this.deleteRepositoryService.insertInitData(context); } catch (e) { this.logger.error(`error=${e}`); if (e instanceof Error) { diff --git a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts index b561f42..5ba0f0e 100644 --- a/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts +++ b/data_migration_tools/server/src/gateways/adb2c/adb2c.service.ts @@ -30,14 +30,10 @@ export const isConflictError = (arg: unknown): arg is ConflictError => { export class AdB2cService { private readonly logger = new Logger(AdB2cService.name); private readonly tenantName: string; - private readonly flowName: string; - private readonly ttl: number; private graphClient: Client; constructor(private readonly configService: ConfigService) { this.tenantName = this.configService.getOrThrow("TENANT_NAME"); - this.flowName = this.configService.getOrThrow("SIGNIN_FLOW_NAME"); - this.ttl = this.configService.getOrThrow("ADB2C_CACHE_TTL"); // ADB2Cへの認証情報 const credential = new ClientSecretCredential( @@ -111,8 +107,10 @@ export class AdB2cService { * @param externalIds * @returns users */ - async getUsers(): Promise { - this.logger.log(`[IN] ${this.getUsers.name}`); + async getUsers( + context: Context + ): Promise<{ users: AdB2cUser[]; hasNext: boolean }> { + this.logger.log(`[IN] [${context.getTrackingId()}] ${this.getUsers.name}`); try { const res: AdB2cResponse = await this.graphClient @@ -121,7 +119,7 @@ export class AdB2cService { .filter(`creationType eq 'LocalAccount'`) .get(); - return res.value; + return { users: res.value, hasNext: !!res["@odata.nextLink"] }; } catch (e) { this.logger.error(`error=${e}`); const { statusCode } = e; @@ -177,9 +175,11 @@ export class AdB2cService { * Azure AD B2Cからユーザ情報を削除する(複数) * @param externalIds 外部ユーザーID */ - async deleteUsers(externalIds: string[]): Promise { + async deleteUsers(context: Context, externalIds: string[]): Promise { this.logger.log( - `[IN]${this.deleteUsers.name} | params: { externalIds: ${externalIds} };` + `[IN] [${context.getTrackingId()}] ${ + this.deleteUsers.name + } | params: { externalIds: ${externalIds} };` ); try { diff --git a/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts b/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts index 7c26388..ee603c6 100644 --- a/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts +++ b/data_migration_tools/server/src/gateways/blobstorage/blobstorage.service.ts @@ -89,8 +89,10 @@ export class BlobstorageService { * すべてのコンテナを削除します。 * @returns containers */ - async deleteContainers(): Promise { - this.logger.log(`[IN] ${this.deleteContainers.name}`); + async deleteContainers(context: Context): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.deleteContainers.name}` + ); try { for await (const container of this.blobServiceClientAU.listContainers({ diff --git a/data_migration_tools/server/src/repositories/delete/delete.repository.service.ts b/data_migration_tools/server/src/repositories/delete/delete.repository.service.ts index 52539c0..f436207 100644 --- a/data_migration_tools/server/src/repositories/delete/delete.repository.service.ts +++ b/data_migration_tools/server/src/repositories/delete/delete.repository.service.ts @@ -1,11 +1,15 @@ import { Injectable } from "@nestjs/common"; import { DataSource } from "typeorm"; import { logger } from "@azure/identity"; -import { Account } from "./entity/account.entity"; import { AUTO_INCREMENT_START } from "../../constants"; +import { Term } from "./entity/term.entity"; +import { insertEntities } from "../../common/repository"; +import { Context } from "../../common/log"; @Injectable() export class DeleteRepositoryService { + // クエリログにコメントを出力するかどうか + private readonly isCommentOut = process.env.STAGE !== "local"; constructor(private dataSource: DataSource) {} /** @@ -54,4 +58,35 @@ export class DeleteRepositoryService { await queryRunner.release(); } } + + /** + * 初期データを挿入する + * @returns data + */ + async insertInitData(context: Context): Promise { + await this.dataSource.transaction(async (entityManager) => { + const termRepo = entityManager.getRepository(Term); + + // ワークフローのデータ作成 + const newTarmDpa = new Term(); + newTarmDpa.document_type = "DPA"; + newTarmDpa.version = "V0.1"; + const newTarmEula = new Term(); + newTarmEula.document_type = "EULA"; + newTarmEula.version = "V0.1"; + const newTarmPrivacyNotice = new Term(); + newTarmPrivacyNotice.document_type = "PrivacyNotice"; + newTarmPrivacyNotice.version = "V0.1"; + + const initTerms = [newTarmDpa, newTarmEula, newTarmPrivacyNotice]; + + await insertEntities( + Term, + termRepo, + initTerms, + this.isCommentOut, + context + ); + }); + } } From c31bb47bb8a18b12ff234a9f4aba5381a832d83a Mon Sep 17 00:00:00 2001 From: "maruyama.t" Date: Thu, 22 Feb 2024 07:52:16 +0000 Subject: [PATCH 06/10] =?UTF-8?q?Merged=20PR=20773:=20api=E3=81=ABtransfer?= =?UTF-8?q?=E3=81=8C=E5=AD=98=E5=9C=A8=E3=81=97=E3=81=AA=E3=81=8B=E3=81=A3?= =?UTF-8?q?=E3=81=9F=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3570: データ変換ツール(きれいなデータ版)作成+動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3570) - 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず) - 何をどう変更したか、追加したライブラリなど - このPull Requestでの対象/対象外 - 影響範囲(他の機能にも影響があるか) ## レビューポイント - 特にレビューしてほしい箇所 - 軽微なものや自明なものは記載不要 - 修正範囲が大きい場合などに記載 - 全体的にや仕様を満たしているか等は本当に必要な時のみ記載 ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認、develop環境で確認など ## 補足 - 相談、参考資料などがあれば --- data_migration_tools/server/src/app.module.ts | 21 ++++++++++++++++--- .../features/transfer/transfer.controller.ts | 10 ++++----- .../src/features/transfer/transfer.module.ts | 10 ++++----- .../src/features/transfer/transfer.service.ts | 4 ++-- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/data_migration_tools/server/src/app.module.ts b/data_migration_tools/server/src/app.module.ts index 8089b78..6935bba 100644 --- a/data_migration_tools/server/src/app.module.ts +++ b/data_migration_tools/server/src/app.module.ts @@ -24,7 +24,9 @@ import { DeleteModule } from "./features/delete/delete.module"; import { DeleteRepositoryModule } from "./repositories/delete/delete.repository.module"; import { DeleteController } from "./features/delete/delete.controller"; import { DeleteService } from "./features/delete/delete.service"; - +import { TransferModule } from "./features/transfer/transfer.module"; +import { TransferController } from "./features/transfer/transfer.controller"; +import { TransferService } from "./features/transfer/transfer.service"; @Module({ imports: [ ServeStaticModule.forRoot({ @@ -37,6 +39,7 @@ import { DeleteService } from "./features/delete/delete.service"; AdB2cModule, AccountsModule, UsersModule, + TransferModule, RegisterModule, AccountsRepositoryModule, UsersRepositoryModule, @@ -61,8 +64,20 @@ import { DeleteService } from "./features/delete/delete.service"; inject: [ConfigService], }), ], - controllers: [RegisterController, AccountsController, UsersController, DeleteController], - providers: [RegisterService, AccountsService, UsersService, DeleteService], + controllers: [ + RegisterController, + AccountsController, + UsersController, + DeleteController, + TransferController, + ], + providers: [ + RegisterService, + AccountsService, + UsersService, + DeleteService, + TransferService, + ], }) export class AppModule { configure(consumer: MiddlewareConsumer) { diff --git a/data_migration_tools/server/src/features/transfer/transfer.controller.ts b/data_migration_tools/server/src/features/transfer/transfer.controller.ts index 8ac9923..59f90fc 100644 --- a/data_migration_tools/server/src/features/transfer/transfer.controller.ts +++ b/data_migration_tools/server/src/features/transfer/transfer.controller.ts @@ -11,7 +11,7 @@ import fs from "fs"; import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; import { Request } from "express"; import { transferRequest, transferResponse } from "./types/types"; -import { transferService } from "./transfer.service"; +import { TransferService } from "./transfer.service"; import { makeContext } from "../../common/log"; import { csvInputFile } from "../../common/types/types"; import { makeErrorResponse } from "src/common/errors/makeErrorResponse"; @@ -24,12 +24,12 @@ import { LICENSE_ALLOCATED_STATUS, USER_ROLES, AUTO_INCREMENT_START, -} from "../../../src/constants"; +} from "../../constants"; @ApiTags("transfer") @Controller("transfer") -export class transferController { - private readonly logger = new Logger(transferController.name); - constructor(private readonly transferService: transferService) {} +export class TransferController { + private readonly logger = new Logger(TransferController.name); + constructor(private readonly transferService: TransferService) {} @Post() @ApiResponse({ diff --git a/data_migration_tools/server/src/features/transfer/transfer.module.ts b/data_migration_tools/server/src/features/transfer/transfer.module.ts index b2a7893..d2d9695 100644 --- a/data_migration_tools/server/src/features/transfer/transfer.module.ts +++ b/data_migration_tools/server/src/features/transfer/transfer.module.ts @@ -1,9 +1,9 @@ import { Module } from "@nestjs/common"; -import { transferController } from "./transfer.controller"; -import { transferService } from "./transfer.service"; +import { TransferController } from "./transfer.controller"; +import { TransferService } from "./transfer.service"; @Module({ imports: [], - controllers: [transferController], - providers: [transferService], + controllers: [TransferController], + providers: [TransferService], }) -export class transferModule {} +export class TransferModule {} diff --git a/data_migration_tools/server/src/features/transfer/transfer.service.ts b/data_migration_tools/server/src/features/transfer/transfer.service.ts index 70b5d26..24f93de 100644 --- a/data_migration_tools/server/src/features/transfer/transfer.service.ts +++ b/data_migration_tools/server/src/features/transfer/transfer.service.ts @@ -22,9 +22,9 @@ import { registInputDataResponse } from "./types/types"; import fs from "fs"; @Injectable() -export class transferService { +export class TransferService { constructor() {} - private readonly logger = new Logger(transferService.name); + private readonly logger = new Logger(TransferService.name); /** * Regist Data From cb68c16eb89fd13d690cd1065ba089333609dd33 Mon Sep 17 00:00:00 2001 From: "maruyama.t" Date: Thu, 22 Feb 2024 08:23:31 +0000 Subject: [PATCH 07/10] =?UTF-8?q?Merged=20PR=20775:=20=E5=A4=89=E6=8F=9B?= =?UTF-8?q?=E3=83=84=E3=83=BC=E3=83=AB=E3=81=AE=E3=83=90=E3=83=AA=E3=83=87?= =?UTF-8?q?=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=83=81=E3=82=A7=E3=83=83?= =?UTF-8?q?=E3=82=AF=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3570: データ変換ツール(きれいなデータ版)作成+動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3570) - 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず) - 何をどう変更したか、追加したライブラリなど - このPull Requestでの対象/対象外 - 影響範囲(他の機能にも影響があるか) ## レビューポイント - 特にレビューしてほしい箇所 - 軽微なものや自明なものは記載不要 - 修正範囲が大きい場合などに記載 - 全体的にや仕様を満たしているか等は本当に必要な時のみ記載 ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認、develop環境で確認など ## 補足 - 相談、参考資料などがあれば --- .../server/src/constants/index.ts | 2 +- .../features/transfer/transfer.controller.ts | 4 ++ .../src/features/transfer/transfer.service.ts | 64 +++++++++++-------- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/data_migration_tools/server/src/constants/index.ts b/data_migration_tools/server/src/constants/index.ts index 4330bb6..71bd022 100644 --- a/data_migration_tools/server/src/constants/index.ts +++ b/data_migration_tools/server/src/constants/index.ts @@ -343,7 +343,7 @@ export const MIGRATION_TYPE = { export const COUNTRY_LIST = [ { value: "CA", label: "Canada" }, { value: "KY", label: "Cayman Islands" }, - { value: "US", label: "U.S.A." }, + { value: "US", label: "United States" }, { value: "AU", label: "Australia" }, { value: "NZ", label: "New Zealand" }, { value: "AT", label: "Austria" }, diff --git a/data_migration_tools/server/src/features/transfer/transfer.controller.ts b/data_migration_tools/server/src/features/transfer/transfer.controller.ts index 59f90fc..8725a4c 100644 --- a/data_migration_tools/server/src/features/transfer/transfer.controller.ts +++ b/data_migration_tools/server/src/features/transfer/transfer.controller.ts @@ -78,6 +78,10 @@ export class TransferController { let csvInputFile: csvInputFile[] = []; csvInputFileLines.forEach((line) => { const data = line.split(","); + // ダブルクォーテーションは削除 + data.forEach((value, index) => { + data[index] = value.replace(/"/g, ""); + }); csvInputFile.push({ type: data[0], account_id: data[1], diff --git a/data_migration_tools/server/src/features/transfer/transfer.service.ts b/data_migration_tools/server/src/features/transfer/transfer.service.ts index 24f93de..5a7a58a 100644 --- a/data_migration_tools/server/src/features/transfer/transfer.service.ts +++ b/data_migration_tools/server/src/features/transfer/transfer.service.ts @@ -173,6 +173,7 @@ export class TransferService { try { // dealerAccountIdを検索し、typeがCountryの場合 accountsOutputFileStep1.forEach((account) => { + console.log(account); if (account.type === MIGRATION_TYPE.COUNTRY) { // そのacccountIdをdealerAccountIdにもつアカウント(Distributor)を検索する const distributor = accountsOutputFileStep1.find( @@ -304,6 +305,7 @@ export class TransferService { if ( line.type !== MIGRATION_TYPE.ADMINISTRATOR && line.type !== MIGRATION_TYPE.BC && + line.type !== MIGRATION_TYPE.COUNTRY && line.type !== MIGRATION_TYPE.DISTRIBUTOR && line.type !== MIGRATION_TYPE.DEALER && line.type !== MIGRATION_TYPE.CUSTOMER && @@ -315,35 +317,47 @@ export class TransferService { ); } // countryのバリデーションチェック - if (!COUNTRY_LIST.find((country) => country.label === line.country)) { - throw new HttpException( - `country is invalid. index=${index} country=${line.country}`, - HttpStatus.BAD_REQUEST - ); + if (line.country) { + if (!COUNTRY_LIST.find((country) => country.label === line.country)) { + console.log(line.country); + throw new HttpException( + `country is invalid. index=${index} country=${line.country}`, + HttpStatus.BAD_REQUEST + ); + } } // mailのバリデーションチェック // メールアドレスの形式が正しいかどうかのチェック - const mailRegExp = new RegExp( - /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$/ - ); - if (!mailRegExp.test(line.email)) { - throw new HttpException( - `email is invalid. index=${index} email=${line.email}`, - HttpStatus.BAD_REQUEST - ); + const mailRegExp = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; + if (line.email) { + if (!mailRegExp.test(line.email)) { + throw new HttpException( + `email is invalid. index=${index} email=${line.email}`, + HttpStatus.BAD_REQUEST + ); + } } - // recording_modeのバリデーションチェック - // RECORDING_MODEに存在するかどうかのチェック - if ( - line.recording_mode !== RECORDING_MODE.DS2_QP && - line.recording_mode !== RECORDING_MODE.DS2_SP && - line.recording_mode !== RECORDING_MODE.DSS && - line.recording_mode !== null - ) { - throw new HttpException( - `recording_mode is invalid. index=${index} recording_mode=${line.recording_mode}`, - HttpStatus.BAD_REQUEST - ); + if (line.user_email) { + if (!mailRegExp.test(line.user_email)) { + throw new HttpException( + `user_email is invalid. index=${index} user_email=${line.email}`, + HttpStatus.BAD_REQUEST + ); + } + } + // recording_modeの値が存在する場合 + if (line.recording_mode) { + // recording_modeのバリデーションチェック + if ( + line.recording_mode !== RECORDING_MODE.DS2_QP && + line.recording_mode !== RECORDING_MODE.DS2_SP && + line.recording_mode !== RECORDING_MODE.DSS + ) { + throw new HttpException( + `recording_mode is invalid. index=${index} recording_mode=${line.recording_mode}`, + HttpStatus.BAD_REQUEST + ); + } } }); } catch (e) { From a65d6a277466beff9a2e92bc2b27dc9542bf02dc Mon Sep 17 00:00:00 2001 From: "maruyama.t" Date: Thu, 22 Feb 2024 08:40:57 +0000 Subject: [PATCH 08/10] =?UTF-8?q?Merged=20PR=20776:=20=E9=9A=8E=E5=B1=A4?= =?UTF-8?q?=E3=81=AE=E4=BB=98=E3=81=91=E6=9B=BF=E3=81=88=E3=82=92=E8=AA=A4?= =?UTF-8?q?=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3570: データ変換ツール(きれいなデータ版)作成+動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3570) - 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず) - 何をどう変更したか、追加したライブラリなど - このPull Requestでの対象/対象外 - 影響範囲(他の機能にも影響があるか) ## レビューポイント - 特にレビューしてほしい箇所 - 軽微なものや自明なものは記載不要 - 修正範囲が大きい場合などに記載 - 全体的にや仕様を満たしているか等は本当に必要な時のみ記載 ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認、develop環境で確認など ## 補足 - 相談、参考資料などがあれば --- .../src/features/transfer/transfer.service.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/data_migration_tools/server/src/features/transfer/transfer.service.ts b/data_migration_tools/server/src/features/transfer/transfer.service.ts index 5a7a58a..31b75ed 100644 --- a/data_migration_tools/server/src/features/transfer/transfer.service.ts +++ b/data_migration_tools/server/src/features/transfer/transfer.service.ts @@ -173,16 +173,17 @@ export class TransferService { try { // dealerAccountIdを検索し、typeがCountryの場合 accountsOutputFileStep1.forEach((account) => { - console.log(account); if (account.type === MIGRATION_TYPE.COUNTRY) { + console.log(account); // そのacccountIdをdealerAccountIdにもつアカウント(Distributor)を検索する const distributor = accountsOutputFileStep1.find( - (distributor) => - account.type === MIGRATION_TYPE.DISTRIBUTOR && - distributor.dealerAccountId === account.accountId + (distributor) => distributor.accountId === account.dealerAccountId ); - // DistributorのdealerAccountIdをBC(Countryの親)に付け替える - distributor.dealerAccountId = account.dealerAccountId; + console.log(distributor); + if (distributor) { + // DistributorのdealerAccountIdをBC(Countryの親)に付け替える + distributor.dealerAccountId = account.dealerAccountId; + } } }); // typeがCountryのアカウントを取り除く From f03342bc5519dc1cc12bc450271582d8f8215b2f Mon Sep 17 00:00:00 2001 From: "makabe.t" Date: Thu, 22 Feb 2024 08:45:20 +0000 Subject: [PATCH 09/10] =?UTF-8?q?Merged=20PR=20777:=20=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E5=89=8A=E9=99=A4=E3=83=84=E3=83=BC=E3=83=AB=E4=BD=9C?= =?UTF-8?q?=E6=88=90=EF=BC=8B=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3569: データ削除ツール作成+動作確認](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3569) - クライアントに不要なフォルダが残っていたので削除しました。 ## レビューポイント - 共有 ## UIの変更 - なし ## 動作確認状況 - ローカルで確認 --- .../client/src/common/error/code.ts | 70 ------------------- .../src/common/error/makeErrorResponse.ts | 10 --- .../client/src/common/error/message.ts | 59 ---------------- .../client/src/common/error/types/types.ts | 15 ---- 4 files changed, 154 deletions(-) delete mode 100644 data_migration_tools/client/src/common/error/code.ts delete mode 100644 data_migration_tools/client/src/common/error/makeErrorResponse.ts delete mode 100644 data_migration_tools/client/src/common/error/message.ts delete mode 100644 data_migration_tools/client/src/common/error/types/types.ts diff --git a/data_migration_tools/client/src/common/error/code.ts b/data_migration_tools/client/src/common/error/code.ts deleted file mode 100644 index 3c488da..0000000 --- a/data_migration_tools/client/src/common/error/code.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* -エラーコード作成方針 -E+6桁(数字)で構成する。 -- 1~2桁目の値は種類(業務エラー、システムエラー...) -- 3~4桁目の値は原因箇所(トークン、DB、...) -- 5~6桁目の値は任意の重複しない値 -ex) -E00XXXX : システムエラー(通信エラーやDB接続失敗など) -E01XXXX : 業務エラー -EXX00XX : 内部エラー(内部プログラムのエラー) -EXX01XX : トークンエラー(トークン認証関連) -EXX02XX : DBエラー(DB関連) -EXX03XX : ADB2Cエラー(DB関連) -*/ -export const ErrorCodes = [ - 'E009999', // 汎用エラー - 'E000101', // トークン形式不正エラー - 'E000102', // トークン有効期限切れエラー - 'E000103', // トークン非アクティブエラー - 'E000104', // トークン署名エラー - 'E000105', // トークン発行元エラー - 'E000106', // トークンアルゴリズムエラー - 'E000107', // トークン不足エラー - 'E000108', // トークン権限エラー - 'E000301', // ADB2Cへのリクエスト上限超過エラー - 'E000401', // IPアドレス未設定エラー - 'E000501', // リクエストID未設定エラー - 'E010001', // パラメータ形式不正エラー - 'E010201', // 未認証ユーザエラー - 'E010202', // 認証済ユーザエラー - 'E010203', // 管理ユーザ権限エラー - 'E010204', // ユーザ不在エラー - 'E010205', // DBのRoleが想定外の値エラー - 'E010206', // DBのTierが想定外の値エラー - 'E010207', // ユーザーのRole変更不可エラー - 'E010208', // ユーザーの暗号化パスワード不足エラー - 'E010209', // ユーザーの同意済み利用規約バージョンが最新でないエラー - 'E010301', // メールアドレス登録済みエラー - 'E010302', // authorId重複エラー - 'E010401', // PONumber重複エラー - 'E010501', // アカウント不在エラー - 'E010502', // アカウント情報変更不可エラー - 'E010503', // 代行操作不許可エラー - 'E010504', // アカウントロックエラー - 'E010601', // タスク変更不可エラー(タスクが変更できる状態でない、またはタスクが存在しない) - 'E010602', // タスク変更権限不足エラー - 'E010603', // タスク不在エラー - 'E010701', // Blobファイル不在エラー - 'E010801', // ライセンス不在エラー - 'E010802', // ライセンス取り込み済みエラー - 'E010803', // ライセンス発行済みエラー - 'E010804', // ライセンス不足エラー - 'E010805', // ライセンス有効期限切れエラー - 'E010806', // ライセンス割り当て不可エラー - 'E010807', // ライセンス割り当て解除済みエラー - 'E010808', // ライセンス注文キャンセル不可エラー - 'E010809', // ライセンス発行キャンセル不可エラー(ステータスが変えられている場合) - 'E010810', // ライセンス発行キャンセル不可エラー(発行から一定期間経過した場合) - 'E010811', // ライセンス発行キャンセル不可エラー(発行したライセンスが割り当てされている場合) - 'E010812', // ライセンス未割当エラー - 'E010908', // タイピストグループ不在エラー - 'E010909', // タイピストグループ名重複エラー - 'E011001', // ワークタイプ重複エラー - 'E011002', // ワークタイプ登録上限超過エラー - 'E011003', // ワークタイプ不在エラー - 'E011004', // ワークタイプ使用中エラー - 'E012001', // テンプレートファイル不在エラー - 'E013001', // ワークフローのAuthorIDとWorktypeIDのペア重複エラー - 'E013002', // ワークフロー不在エラー -] as const; diff --git a/data_migration_tools/client/src/common/error/makeErrorResponse.ts b/data_migration_tools/client/src/common/error/makeErrorResponse.ts deleted file mode 100644 index 0a677b4..0000000 --- a/data_migration_tools/client/src/common/error/makeErrorResponse.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { errors } from './message'; -import { ErrorCodeType, ErrorResponse } from './types/types'; - -export const makeErrorResponse = (errorcode: ErrorCodeType): ErrorResponse => { - const msg = errors[errorcode]; - return { - code: errorcode, - message: msg, - }; -}; diff --git a/data_migration_tools/client/src/common/error/message.ts b/data_migration_tools/client/src/common/error/message.ts deleted file mode 100644 index 9383694..0000000 --- a/data_migration_tools/client/src/common/error/message.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Errors } from './types/types'; - -// エラーコードとメッセージ対応表 -export const errors: Errors = { - E009999: 'Internal Server Error.', - E000101: 'Token invalid format Error.', - E000102: 'Token expired Error.', - E000103: 'Token not before Error', - E000104: 'Token invalid signature Error.', - E000105: 'Token invalid issuer Error.', - E000106: 'Token invalid algorithm Error.', - E000107: 'Token is not exist Error.', - E000108: 'Token authority failed Error.', - E000301: 'ADB2C request limit exceeded Error', - E000401: 'IP address not found Error.', - E000501: 'Request ID not found Error.', - E010001: 'Param invalid format Error.', - E010201: 'Email not verified user Error.', - E010202: 'Email already verified user Error.', - E010203: 'Administrator Permissions Error.', - E010204: 'User not Found Error.', - E010205: 'Role from DB is unexpected value Error.', - E010206: 'Tier from DB is unexpected value Error.', - E010207: 'User role change not allowed Error.', - E010208: 'User encryption password not found Error.', - E010209: 'Accepted term not latest Error.', - E010301: 'This email user already created Error', - E010302: 'This AuthorId already used Error', - E010401: 'This PoNumber already used Error', - E010501: 'Account not Found Error.', - E010502: 'Account information cannot be changed Error.', - E010503: 'Delegation not allowed Error.', - E010504: 'Account is locked Error.', - E010601: 'Task is not Editable Error', - E010602: 'No task edit permissions Error', - E010603: 'Task not found Error.', - E010701: 'File not found in Blob Storage Error.', - E010801: 'License not exist Error', - E010802: 'License already activated Error', - E010803: 'License already issued Error', - E010804: 'License shortage Error', - E010805: 'License is expired Error', - E010806: 'License is unavailable Error', - E010807: 'License is already deallocated Error', - E010808: 'Order cancel failed Error', - E010809: 'Already license order status changed Error', - E010810: 'Cancellation period expired error', - E010811: 'Already license allocated Error', - E010812: 'License not allocated Error', - E010908: 'Typist Group not exist Error', - E010909: 'Typist Group name already exist Error', - E011001: 'This WorkTypeID already used Error', - E011002: 'WorkTypeID create limit exceeded Error', - E011003: 'WorkTypeID not found Error', - E011004: 'WorkTypeID is in use Error', - E012001: 'Template file not found Error', - E013001: 'AuthorId and WorktypeId pair already exists Error', - E013002: 'Workflow not found Error', -}; diff --git a/data_migration_tools/client/src/common/error/types/types.ts b/data_migration_tools/client/src/common/error/types/types.ts deleted file mode 100644 index 8746924..0000000 --- a/data_migration_tools/client/src/common/error/types/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { ErrorCodes } from '../code'; - -export class ErrorResponse { - @ApiProperty() - message: string; - @ApiProperty() - code: string; -} - -export type ErrorCodeType = (typeof ErrorCodes)[number]; - -export type Errors = { - [P in ErrorCodeType]: string; -}; From fbdfeee73cee400281d8b839f304e12ca6ffadcf Mon Sep 17 00:00:00 2001 From: "makabe.t" Date: Thu, 22 Feb 2024 11:42:31 +0000 Subject: [PATCH 10/10] =?UTF-8?q?Merged=20PR=20778:=20=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E3=83=84=E3=83=BC=E3=83=AB=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3788: 削除ツールの修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3788) - ADB2Cの削除に失敗するので対応しました。 - 最後のページの場合に削除より先に抜けていたので、削除処理を先にやるように修正しました。 ## レビューポイント - 共有 ## UIの変更 - なし ## 動作確認状況 - developで確認 --- .../server/src/features/delete/delete.service.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/data_migration_tools/server/src/features/delete/delete.service.ts b/data_migration_tools/server/src/features/delete/delete.service.ts index 3055d5b..3644220 100644 --- a/data_migration_tools/server/src/features/delete/delete.service.ts +++ b/data_migration_tools/server/src/features/delete/delete.service.ts @@ -12,7 +12,7 @@ export class DeleteService { private readonly deleteRepositoryService: DeleteRepositoryService, private readonly blobstorageService: BlobstorageService, private readonly adB2cService: AdB2cService - ) {} + ) { } /** * データを削除する @@ -31,13 +31,14 @@ export class DeleteService { // ADB2Cからユーザ情報を取得する const { users, hasNext } = await this.adB2cService.getUsers(context); - // ユーザーがいない場合はループを抜ける - if (!hasNext) { - break; - } const externalIds = users.map((user) => user.id); await this.adB2cService.deleteUsers(context, externalIds); + + // 削除していないユーザーがいない場合はループを抜ける + if (!hasNext) { + break; + } } // データベースからデータを削除する