added update image route
This commit is contained in:
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
1. `pnpm install`
|
||||||
|
2. `pnpm initialize_data`
|
||||||
|
3. `docker compose up`
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
import { db } from "./src/db";
|
import { db } from "./src/db";
|
||||||
import { group, opinion, zone, province } from "./src/schema.ts";
|
import { group, opinion, zone, province } from "./src/schema";
|
||||||
import { Groups, Opinions, Provinces, Districts } from "./initialData.ts";
|
import { Groups, Opinions, Provinces, Districts } from "./initialData";
|
||||||
|
import { createBucket, createClient } from "./src/minio";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
let mc = createClient();
|
||||||
|
await createBucket(mc);
|
||||||
|
|
||||||
const isInitialized = await db.query.group
|
const isInitialized = await db.query.group
|
||||||
.findMany()
|
.findMany()
|
||||||
.then((groups) => groups.length > 0);
|
.then((groups) => groups.length > 0);
|
||||||
|
|||||||
10
drizzle/0001_chilly_bullseye.sql
Normal file
10
drizzle/0001_chilly_bullseye.sql
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE `image_to_user` (
|
||||||
|
`user_id` integer PRIMARY KEY NOT NULL,
|
||||||
|
`image_name` text NOT NULL,
|
||||||
|
`created_on` integer DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
|
||||||
|
);
|
||||||
|
--> statement-breakpoint
|
||||||
|
DROP TABLE `phone_tokens`;--> statement-breakpoint
|
||||||
|
ALTER TABLE users ADD `image` text;--> statement-breakpoint
|
||||||
|
CREATE INDEX `image_idx` ON `users` (`image`);
|
||||||
484
drizzle/meta/0001_snapshot.json
Normal file
484
drizzle/meta/0001_snapshot.json
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
{
|
||||||
|
"version": "5",
|
||||||
|
"dialect": "sqlite",
|
||||||
|
"id": "2cf2acb7-cc98-4f28-8ead-5916b87b7683",
|
||||||
|
"prevId": "58f80520-7300-4bc4-943d-87568666e42d",
|
||||||
|
"tables": {
|
||||||
|
"groups": {
|
||||||
|
"name": "groups",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"groups_name_unique": {
|
||||||
|
"name": "groups_name_unique",
|
||||||
|
"columns": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"image_to_user": {
|
||||||
|
"name": "image_to_user",
|
||||||
|
"columns": {
|
||||||
|
"user_id": {
|
||||||
|
"name": "user_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"image_name": {
|
||||||
|
"name": "image_name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"created_on": {
|
||||||
|
"name": "created_on",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "CURRENT_TIMESTAMP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"image_to_user_user_id_users_id_fk": {
|
||||||
|
"name": "image_to_user_user_id_users_id_fk",
|
||||||
|
"tableFrom": "image_to_user",
|
||||||
|
"tableTo": "users",
|
||||||
|
"columnsFrom": [
|
||||||
|
"user_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"opinions": {
|
||||||
|
"name": "opinions",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"name": "type",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'3Choice'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"opinions_name_unique": {
|
||||||
|
"name": "opinions_name_unique",
|
||||||
|
"columns": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"provinces": {
|
||||||
|
"name": "provinces",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"provinces_name_unique": {
|
||||||
|
"name": "provinces_name_unique",
|
||||||
|
"columns": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"name": "users",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": true
|
||||||
|
},
|
||||||
|
"firstName": {
|
||||||
|
"name": "firstName",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"lastName": {
|
||||||
|
"name": "lastName",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"name": "title",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"cid": {
|
||||||
|
"name": "cid",
|
||||||
|
"type": "text(13)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"age": {
|
||||||
|
"name": "age",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"phone": {
|
||||||
|
"name": "phone",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"public_phone": {
|
||||||
|
"name": "public_phone",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"facebook": {
|
||||||
|
"name": "facebook",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"twitter": {
|
||||||
|
"name": "twitter",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"tiktok": {
|
||||||
|
"name": "tiktok",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"other_social": {
|
||||||
|
"name": "other_social",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"name": "image",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"job": {
|
||||||
|
"name": "job",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"education": {
|
||||||
|
"name": "education",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"vision": {
|
||||||
|
"name": "vision",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"reason": {
|
||||||
|
"name": "reason",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"group_id": {
|
||||||
|
"name": "group_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"zone_id": {
|
||||||
|
"name": "zone_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"users_cid_unique": {
|
||||||
|
"name": "users_cid_unique",
|
||||||
|
"columns": [
|
||||||
|
"cid"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
},
|
||||||
|
"users_phone_unique": {
|
||||||
|
"name": "users_phone_unique",
|
||||||
|
"columns": [
|
||||||
|
"phone"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
},
|
||||||
|
"phone_idx": {
|
||||||
|
"name": "phone_idx",
|
||||||
|
"columns": [
|
||||||
|
"phone"
|
||||||
|
],
|
||||||
|
"isUnique": false
|
||||||
|
},
|
||||||
|
"image_idx": {
|
||||||
|
"name": "image_idx",
|
||||||
|
"columns": [
|
||||||
|
"image"
|
||||||
|
],
|
||||||
|
"isUnique": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {
|
||||||
|
"users_group_id_groups_id_fk": {
|
||||||
|
"name": "users_group_id_groups_id_fk",
|
||||||
|
"tableFrom": "users",
|
||||||
|
"tableTo": "groups",
|
||||||
|
"columnsFrom": [
|
||||||
|
"group_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"users_zone_id_zones_id_fk": {
|
||||||
|
"name": "users_zone_id_zones_id_fk",
|
||||||
|
"tableFrom": "users",
|
||||||
|
"tableTo": "zones",
|
||||||
|
"columnsFrom": [
|
||||||
|
"zone_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"user_opinions": {
|
||||||
|
"name": "user_opinions",
|
||||||
|
"columns": {
|
||||||
|
"user_id": {
|
||||||
|
"name": "user_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"opinion_id": {
|
||||||
|
"name": "opinion_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"choice": {
|
||||||
|
"name": "choice",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'deciding'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"user_opinions_user_id_users_id_fk": {
|
||||||
|
"name": "user_opinions_user_id_users_id_fk",
|
||||||
|
"tableFrom": "user_opinions",
|
||||||
|
"tableTo": "users",
|
||||||
|
"columnsFrom": [
|
||||||
|
"user_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"user_opinions_opinion_id_opinions_id_fk": {
|
||||||
|
"name": "user_opinions_opinion_id_opinions_id_fk",
|
||||||
|
"tableFrom": "user_opinions",
|
||||||
|
"tableTo": "opinions",
|
||||||
|
"columnsFrom": [
|
||||||
|
"opinion_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"user_opinions_user_id_opinion_id_pk": {
|
||||||
|
"columns": [
|
||||||
|
"opinion_id",
|
||||||
|
"user_id"
|
||||||
|
],
|
||||||
|
"name": "user_opinions_user_id_opinion_id_pk"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"zones": {
|
||||||
|
"name": "zones",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"province_id": {
|
||||||
|
"name": "province_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"zones_name_province_id_unique": {
|
||||||
|
"name": "zones_name_province_id_unique",
|
||||||
|
"columns": [
|
||||||
|
"name",
|
||||||
|
"province_id"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {
|
||||||
|
"zones_province_id_provinces_id_fk": {
|
||||||
|
"name": "zones_province_id_provinces_id_fk",
|
||||||
|
"tableFrom": "zones",
|
||||||
|
"tableTo": "provinces",
|
||||||
|
"columnsFrom": [
|
||||||
|
"province_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"_meta": {
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {},
|
||||||
|
"columns": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,13 @@
|
|||||||
"when": 1713548458041,
|
"when": 1713548458041,
|
||||||
"tag": "0000_right_nebula",
|
"tag": "0000_right_nebula",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 1,
|
||||||
|
"version": "5",
|
||||||
|
"when": 1713599233997,
|
||||||
|
"tag": "0001_chilly_bullseye",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
"drizzle-zod": "^0.5.1",
|
"drizzle-zod": "^0.5.1",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"minio": "^7.1.3",
|
||||||
"trpc-playground": "^1.0.4",
|
"trpc-playground": "^1.0.4",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
|
|||||||
205
pnpm-lock.yaml
generated
205
pnpm-lock.yaml
generated
@@ -29,6 +29,9 @@ dependencies:
|
|||||||
jsonwebtoken:
|
jsonwebtoken:
|
||||||
specifier: ^9.0.2
|
specifier: ^9.0.2
|
||||||
version: 9.0.2
|
version: 9.0.2
|
||||||
|
minio:
|
||||||
|
specifier: ^7.1.3
|
||||||
|
version: 7.1.3
|
||||||
trpc-playground:
|
trpc-playground:
|
||||||
specifier: ^1.0.4
|
specifier: ^1.0.4
|
||||||
version: 1.0.4(@trpc/server@10.45.2)(@types/node@20.12.7)(express@4.19.2)(typescript@5.4.5)(zod@3.22.4)
|
version: 1.0.4(@trpc/server@10.45.2)(@types/node@20.12.7)(express@4.19.2)(typescript@5.4.5)(zod@3.22.4)
|
||||||
@@ -898,6 +901,12 @@ packages:
|
|||||||
'@types/send': 0.17.4
|
'@types/send': 0.17.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@zxing/text-encoding@0.9.0:
|
||||||
|
resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==}
|
||||||
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
|
optional: true
|
||||||
|
|
||||||
/abbrev@1.1.1:
|
/abbrev@1.1.1:
|
||||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -941,6 +950,17 @@ packages:
|
|||||||
resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
|
resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/async@3.2.5:
|
||||||
|
resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/available-typed-arrays@1.0.7:
|
||||||
|
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dependencies:
|
||||||
|
possible-typed-array-names: 1.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/balanced-match@1.0.2:
|
/balanced-match@1.0.2:
|
||||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -1001,6 +1021,12 @@ packages:
|
|||||||
readable-stream: 3.6.2
|
readable-stream: 3.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/block-stream2@2.1.0:
|
||||||
|
resolution: {integrity: sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==}
|
||||||
|
dependencies:
|
||||||
|
readable-stream: 3.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/body-parser@1.20.2:
|
/body-parser@1.20.2:
|
||||||
resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
|
resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
|
||||||
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
|
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
|
||||||
@@ -1041,6 +1067,14 @@ packages:
|
|||||||
fill-range: 7.0.1
|
fill-range: 7.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/browser-or-node@2.1.1:
|
||||||
|
resolution: {integrity: sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/buffer-crc32@0.2.13:
|
||||||
|
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/buffer-equal-constant-time@1.0.1:
|
/buffer-equal-constant-time@1.0.1:
|
||||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -1250,6 +1284,11 @@ packages:
|
|||||||
supports-color: 5.5.0
|
supports-color: 5.5.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/decode-uri-component@0.2.2:
|
||||||
|
resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==}
|
||||||
|
engines: {node: '>=0.10'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/decompress-response@6.0.0:
|
/decompress-response@6.0.0:
|
||||||
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -1710,6 +1749,13 @@ packages:
|
|||||||
micromatch: 4.0.5
|
micromatch: 4.0.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/fast-xml-parser@4.3.6:
|
||||||
|
resolution: {integrity: sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
strnum: 1.0.5
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fastq@1.17.1:
|
/fastq@1.17.1:
|
||||||
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
|
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1750,6 +1796,11 @@ packages:
|
|||||||
to-regex-range: 5.0.1
|
to-regex-range: 5.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/filter-obj@1.1.0:
|
||||||
|
resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/finalhandler@1.2.0:
|
/finalhandler@1.2.0:
|
||||||
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
|
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
@@ -1772,6 +1823,12 @@ packages:
|
|||||||
semver-regex: 4.0.5
|
semver-regex: 4.0.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/for-each@0.3.3:
|
||||||
|
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||||
|
dependencies:
|
||||||
|
is-callable: 1.2.7
|
||||||
|
dev: false
|
||||||
|
|
||||||
/forwarded@0.2.0:
|
/forwarded@0.2.0:
|
||||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -1908,6 +1965,13 @@ packages:
|
|||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/has-tostringtag@1.0.2:
|
||||||
|
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dependencies:
|
||||||
|
has-symbols: 1.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/hasown@2.0.2:
|
/hasown@2.0.2:
|
||||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -1980,6 +2044,19 @@ packages:
|
|||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/ipaddr.js@2.2.0:
|
||||||
|
resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/is-arguments@1.1.1:
|
||||||
|
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dependencies:
|
||||||
|
call-bind: 1.0.7
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-binary-path@2.1.0:
|
/is-binary-path@2.1.0:
|
||||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1987,11 +2064,23 @@ packages:
|
|||||||
binary-extensions: 2.3.0
|
binary-extensions: 2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/is-callable@1.2.7:
|
||||||
|
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-extglob@2.1.1:
|
/is-extglob@2.1.1:
|
||||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/is-generator-function@1.0.10:
|
||||||
|
resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dependencies:
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-glob@4.0.3:
|
/is-glob@4.0.3:
|
||||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -2023,6 +2112,13 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/is-typed-array@1.1.13:
|
||||||
|
resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dependencies:
|
||||||
|
which-typed-array: 1.1.15
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-what@4.1.16:
|
/is-what@4.1.16:
|
||||||
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
|
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
|
||||||
engines: {node: '>=12.13'}
|
engines: {node: '>=12.13'}
|
||||||
@@ -2045,6 +2141,10 @@ packages:
|
|||||||
dreamopt: 0.8.0
|
dreamopt: 0.8.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/json-stream@1.0.0:
|
||||||
|
resolution: {integrity: sha512-H/ZGY0nIAg3QcOwE1QN/rK/Fa7gJn7Ii5obwp6zyPO4xiPNwpIMjqy2gwjBEGqzkF/vSWEIBQCBuN19hYiL6Qg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/jsonwebtoken@9.0.2:
|
/jsonwebtoken@9.0.2:
|
||||||
resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==}
|
resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==}
|
||||||
engines: {node: '>=12', npm: '>=6'}
|
engines: {node: '>=12', npm: '>=6'}
|
||||||
@@ -2252,6 +2352,26 @@ packages:
|
|||||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/minio@7.1.3:
|
||||||
|
resolution: {integrity: sha512-xPrLjWkTT5E7H7VnzOjF//xBp9I40jYB4aWhb2xTFopXXfw+Wo82DDWngdUju7Doy3Wk7R8C4LAgwhLHHnf0wA==}
|
||||||
|
engines: {node: ^16 || ^18 || >=20}
|
||||||
|
dependencies:
|
||||||
|
async: 3.2.5
|
||||||
|
block-stream2: 2.1.0
|
||||||
|
browser-or-node: 2.1.1
|
||||||
|
buffer-crc32: 0.2.13
|
||||||
|
fast-xml-parser: 4.3.6
|
||||||
|
ipaddr.js: 2.2.0
|
||||||
|
json-stream: 1.0.0
|
||||||
|
lodash: 4.17.21
|
||||||
|
mime-types: 2.1.35
|
||||||
|
query-string: 7.1.3
|
||||||
|
through2: 4.0.2
|
||||||
|
web-encoding: 1.1.5
|
||||||
|
xml: 1.0.1
|
||||||
|
xml2js: 0.5.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/mkdirp-classic@0.5.3:
|
/mkdirp-classic@0.5.3:
|
||||||
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -2459,6 +2579,11 @@ packages:
|
|||||||
nice-napi: 1.0.2
|
nice-napi: 1.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/possible-typed-array-names@1.0.0:
|
||||||
|
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss@8.4.38:
|
/postcss@8.4.38:
|
||||||
resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
|
resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
@@ -2516,6 +2641,16 @@ packages:
|
|||||||
side-channel: 1.0.6
|
side-channel: 1.0.6
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/query-string@7.1.3:
|
||||||
|
resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dependencies:
|
||||||
|
decode-uri-component: 0.2.2
|
||||||
|
filter-obj: 1.1.0
|
||||||
|
split-on-first: 1.1.0
|
||||||
|
strict-uri-encode: 2.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/queue-microtask@1.2.3:
|
/queue-microtask@1.2.3:
|
||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -2612,6 +2747,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/sax@1.3.0:
|
||||||
|
resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/semver-regex@4.0.5:
|
/semver-regex@4.0.5:
|
||||||
resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==}
|
resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -2782,11 +2921,21 @@ packages:
|
|||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/split-on-first@1.1.0:
|
||||||
|
resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/statuses@2.0.1:
|
/statuses@2.0.1:
|
||||||
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
|
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/strict-uri-encode@2.0.0:
|
||||||
|
resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/string_decoder@1.3.0:
|
/string_decoder@1.3.0:
|
||||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2812,6 +2961,10 @@ packages:
|
|||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/strnum@1.0.5:
|
||||||
|
resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/strtok3@7.0.0:
|
/strtok3@7.0.0:
|
||||||
resolution: {integrity: sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==}
|
resolution: {integrity: sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==}
|
||||||
engines: {node: '>=14.16'}
|
engines: {node: '>=14.16'}
|
||||||
@@ -2854,6 +3007,12 @@ packages:
|
|||||||
readable-stream: 3.6.2
|
readable-stream: 3.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/through2@4.0.2:
|
||||||
|
resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
|
||||||
|
dependencies:
|
||||||
|
readable-stream: 3.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/timers-ext@0.1.7:
|
/timers-ext@0.1.7:
|
||||||
resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==}
|
resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3008,6 +3167,16 @@ packages:
|
|||||||
/util-deprecate@1.0.2:
|
/util-deprecate@1.0.2:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
|
/util@0.12.5:
|
||||||
|
resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
|
||||||
|
dependencies:
|
||||||
|
inherits: 2.0.4
|
||||||
|
is-arguments: 1.1.1
|
||||||
|
is-generator-function: 1.0.10
|
||||||
|
is-typed-array: 1.1.13
|
||||||
|
which-typed-array: 1.1.15
|
||||||
|
dev: false
|
||||||
|
|
||||||
/utils-merge@1.0.1:
|
/utils-merge@1.0.1:
|
||||||
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
||||||
engines: {node: '>= 0.4.0'}
|
engines: {node: '>= 0.4.0'}
|
||||||
@@ -3078,6 +3247,25 @@ packages:
|
|||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/web-encoding@1.1.5:
|
||||||
|
resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==}
|
||||||
|
dependencies:
|
||||||
|
util: 0.12.5
|
||||||
|
optionalDependencies:
|
||||||
|
'@zxing/text-encoding': 0.9.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/which-typed-array@1.1.15:
|
||||||
|
resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==}
|
||||||
|
engines: {node: '>= 0.4'}
|
||||||
|
dependencies:
|
||||||
|
available-typed-arrays: 1.0.7
|
||||||
|
call-bind: 1.0.7
|
||||||
|
for-each: 0.3.3
|
||||||
|
gopd: 1.0.1
|
||||||
|
has-tostringtag: 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/which@1.3.1:
|
/which@1.3.1:
|
||||||
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
|
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -3100,6 +3288,23 @@ packages:
|
|||||||
/wrappy@1.0.2:
|
/wrappy@1.0.2:
|
||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
|
/xml2js@0.5.0:
|
||||||
|
resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==}
|
||||||
|
engines: {node: '>=4.0.0'}
|
||||||
|
dependencies:
|
||||||
|
sax: 1.3.0
|
||||||
|
xmlbuilder: 11.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/xml@1.0.1:
|
||||||
|
resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/xmlbuilder@11.0.1:
|
||||||
|
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
|
||||||
|
engines: {node: '>=4.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/xss@1.0.15:
|
/xss@1.0.15:
|
||||||
resolution: {integrity: sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==}
|
resolution: {integrity: sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==}
|
||||||
engines: {node: '>= 0.10.0'}
|
engines: {node: '>= 0.10.0'}
|
||||||
|
|||||||
@@ -4,4 +4,12 @@ export const Config = {
|
|||||||
"T4kE6/tIqCVEZYg9lwsqeJjYfOoXTXSXDEMyParsJjj57CjSdkrfPOLWP74/9lJpcBA=",
|
"T4kE6/tIqCVEZYg9lwsqeJjYfOoXTXSXDEMyParsJjj57CjSdkrfPOLWP74/9lJpcBA=",
|
||||||
token_duration: process.env.TOKEN_DURATION || "365d",
|
token_duration: process.env.TOKEN_DURATION || "365d",
|
||||||
api_url: process.env.API_URL || "http://localhost:3000",
|
api_url: process.env.API_URL || "http://localhost:3000",
|
||||||
|
bucketName: process.env.BUCKET_NAME || "sorvor",
|
||||||
|
minioEndpoint: process.env.MINIO_ENDPOINT || "localhost",
|
||||||
|
minioSSL: (process.env.MINIO_SSL && process.env.MINIO_SSL == "true") || false,
|
||||||
|
minioPort: parseInt(process.env.MINIO_PORT || "9000"),
|
||||||
|
minioAccessKey: process.env.MINIO_ACCESS_KEY || "minioadmin",
|
||||||
|
minioSecretKey:
|
||||||
|
process.env.MINIO_SECRET_KEY ||
|
||||||
|
"K7RSS3iy/191QBeYwLJALtxGfZIHJVdBigSMdBXjqNE=",
|
||||||
};
|
};
|
||||||
|
|||||||
40
src/minio.ts
Normal file
40
src/minio.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import * as minio from "minio";
|
||||||
|
import { Config } from "./config";
|
||||||
|
|
||||||
|
export function createClient() {
|
||||||
|
const mc = new minio.Client({
|
||||||
|
endPoint: Config.minioEndpoint,
|
||||||
|
useSSL: Config.minioSSL,
|
||||||
|
port: Config.minioPort,
|
||||||
|
accessKey: Config.minioAccessKey,
|
||||||
|
secretKey: Config.minioSecretKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
return mc;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createUploadImageUrl(
|
||||||
|
mc: minio.Client,
|
||||||
|
objectName: string,
|
||||||
|
contentType: string
|
||||||
|
) {
|
||||||
|
let policy = mc.newPostPolicy();
|
||||||
|
policy.setKey(objectName);
|
||||||
|
policy.setBucket(Config.bucketName);
|
||||||
|
let expires = new Date();
|
||||||
|
expires.setSeconds(30 * 60);
|
||||||
|
policy.setExpires(expires);
|
||||||
|
policy.setContentType(contentType);
|
||||||
|
policy.setContentDisposition(`attachment; filename="${objectName}"`);
|
||||||
|
policy.setContentLengthRange(1, 3 * 1024 * 1024);
|
||||||
|
let rs = await mc.presignedPostPolicy(policy);
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createBucket(mc: minio.Client) {
|
||||||
|
if (!(await mc.bucketExists(Config.bucketName))) {
|
||||||
|
await mc.makeBucket(Config.bucketName);
|
||||||
|
} else {
|
||||||
|
console.log("Bucket already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ export const user = sqliteTable(
|
|||||||
twitter: text("twitter"),
|
twitter: text("twitter"),
|
||||||
tiktok: text("tiktok"),
|
tiktok: text("tiktok"),
|
||||||
otherSocial: text("other_social"),
|
otherSocial: text("other_social"),
|
||||||
|
image: text("image"),
|
||||||
email: text("email"),
|
email: text("email"),
|
||||||
job: text("job").notNull(),
|
job: text("job").notNull(),
|
||||||
education: text("education").notNull(),
|
education: text("education").notNull(),
|
||||||
@@ -38,6 +39,7 @@ export const user = sqliteTable(
|
|||||||
},
|
},
|
||||||
(t) => ({
|
(t) => ({
|
||||||
phone_idx: index("phone_idx").on(t.phone),
|
phone_idx: index("phone_idx").on(t.phone),
|
||||||
|
image_idx: index("image_idx").on(t.image),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -127,10 +129,12 @@ export const provinceRelation = relations(province, ({ many }) => ({
|
|||||||
zones: many(zone),
|
zones: many(zone),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
//----------------PhoneToken
|
//----------------ImageToUser
|
||||||
export const phoneToken = sqliteTable("phone_tokens", {
|
export const imageToUser = sqliteTable("image_to_user", {
|
||||||
phone: text("phone").primaryKey(),
|
userId: integer("user_id")
|
||||||
token: text("token").notNull(),
|
.primaryKey()
|
||||||
|
.references(() => user.id),
|
||||||
|
imageName: text("image_name").notNull(),
|
||||||
createdOn: integer("created_on", { mode: "timestamp" }).default(
|
createdOn: integer("created_on", { mode: "timestamp" }).default(
|
||||||
sql`CURRENT_TIMESTAMP`
|
sql`CURRENT_TIMESTAMP`
|
||||||
),
|
),
|
||||||
|
|||||||
171
src/userRoute.ts
171
src/userRoute.ts
@@ -1,12 +1,13 @@
|
|||||||
import { router, publicProcedure, protectedProcedure } from "./trpc";
|
import { router, publicProcedure, protectedProcedure } from "./trpc";
|
||||||
import { db } from "./db";
|
import { db } from "./db";
|
||||||
import { opinion, user, userOpinion } from "./schema";
|
import { imageToUser, opinion, user, userOpinion } from "./schema";
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { SQL, eq } from "drizzle-orm";
|
import { SQL, count, eq } from "drizzle-orm";
|
||||||
import { Config } from "./config";
|
import { Config } from "./config";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import * as jwt from "jsonwebtoken";
|
import * as jwt from "jsonwebtoken";
|
||||||
|
import { createClient, createUploadImageUrl } from "./minio";
|
||||||
|
|
||||||
const userInsertSchema = createInsertSchema(user, {
|
const userInsertSchema = createInsertSchema(user, {
|
||||||
cid: (schema) =>
|
cid: (schema) =>
|
||||||
@@ -33,6 +34,41 @@ type UserInsertSchema = z.infer<typeof userInsertSchema>;
|
|||||||
type UserUpdateSchema = z.infer<typeof userUpdateSchema>;
|
type UserUpdateSchema = z.infer<typeof userUpdateSchema>;
|
||||||
|
|
||||||
export const userRoute = router({
|
export const userRoute = router({
|
||||||
|
createUser: publicProcedure
|
||||||
|
.input(
|
||||||
|
userInsertSchema.omit({ id: true }).extend({
|
||||||
|
opinions: opinionInsertSchema,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.mutation(
|
||||||
|
async ({ input }) => await createUser({ ...input }, input.opinions)
|
||||||
|
),
|
||||||
|
// changeImage: protectedProcedure
|
||||||
|
updateUser: protectedProcedure
|
||||||
|
.input(userUpdateSchema)
|
||||||
|
.mutation(async ({ input, ctx }) => await updateUser(ctx.user.id, input)),
|
||||||
|
login: publicProcedure
|
||||||
|
.input(z.object({ cid: z.string(), phone: z.string() }))
|
||||||
|
.mutation(async ({ input }) => await login(input.cid, input.phone)),
|
||||||
|
changeOpinion: protectedProcedure
|
||||||
|
.input(opinionUpdateSchema)
|
||||||
|
.mutation(
|
||||||
|
async ({ input, ctx }) =>
|
||||||
|
await changeOpinion(input.opinionId, ctx.user.id, input.choice)
|
||||||
|
),
|
||||||
|
requestChangeImage: protectedProcedure
|
||||||
|
.input(z.object({ imageName: z.string(), contentType: z.string() }))
|
||||||
|
.mutation(
|
||||||
|
async ({ input, ctx }) =>
|
||||||
|
await requestChangeImage(
|
||||||
|
ctx.user.id,
|
||||||
|
input.imageName,
|
||||||
|
input.contentType
|
||||||
|
)
|
||||||
|
),
|
||||||
|
confirmChangeImage: protectedProcedure.mutation(
|
||||||
|
async ({ ctx }) => await confirmChangeImage(ctx.user.id, ctx.user.image)
|
||||||
|
),
|
||||||
getAllUser: publicProcedure
|
getAllUser: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
@@ -53,27 +89,6 @@ export const userRoute = router({
|
|||||||
input.zone
|
input.zone
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
createUser: publicProcedure
|
|
||||||
.input(
|
|
||||||
userInsertSchema.omit({ id: true }).extend({
|
|
||||||
opinions: opinionInsertSchema,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.mutation(
|
|
||||||
async ({ input }) => await createUser({ ...input }, input.opinions)
|
|
||||||
),
|
|
||||||
updateUser: protectedProcedure
|
|
||||||
.input(userUpdateSchema)
|
|
||||||
.mutation(async ({ input, ctx }) => await updateUser(ctx.user.id, input)),
|
|
||||||
login: publicProcedure
|
|
||||||
.input(z.object({ cid: z.string(), phone: z.string() }))
|
|
||||||
.mutation(async ({ input }) => await login(input.cid, input.phone)),
|
|
||||||
changeOpinion: protectedProcedure
|
|
||||||
.input(opinionUpdateSchema)
|
|
||||||
.mutation(
|
|
||||||
async ({ input, ctx }) =>
|
|
||||||
await changeOpinion(input.opinionId, ctx.user.id, input.choice)
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function getAllUser(
|
async function getAllUser(
|
||||||
@@ -112,6 +127,7 @@ async function getAllUser(
|
|||||||
phone: hidePhone(u.phone),
|
phone: hidePhone(u.phone),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createUser(
|
async function createUser(
|
||||||
newUser: UserInsertSchema,
|
newUser: UserInsertSchema,
|
||||||
opinions: OpinionInsertSchema
|
opinions: OpinionInsertSchema
|
||||||
@@ -154,12 +170,6 @@ async function login(cid: string, phone: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createJWT(phone: string) {
|
|
||||||
return jwt.sign({ phone: phone }, Config.jwt_secret, {
|
|
||||||
expiresIn: "365d",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function changeOpinion(
|
async function changeOpinion(
|
||||||
opinionId: number,
|
opinionId: number,
|
||||||
userId: number,
|
userId: number,
|
||||||
@@ -203,6 +213,99 @@ async function changeOpinion(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function requestChangeImage(
|
||||||
|
userId: number,
|
||||||
|
imageName: string,
|
||||||
|
contentType: string
|
||||||
|
) {
|
||||||
|
const mc = createClient();
|
||||||
|
// Check if the image is valid
|
||||||
|
const allowedImageTypes = z.enum(["image/png", "image/jpeg", "image/webp"]);
|
||||||
|
if (!allowedImageTypes.safeParse(contentType).success) {
|
||||||
|
throw new TRPCError({
|
||||||
|
message: "Only PNG, JPEG, and WEBP images are allowed",
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const allowedExtension = z.enum(["png", "jpeg", "jpg", "webp"]);
|
||||||
|
const extension = imageName.split(".").pop();
|
||||||
|
if (!allowedExtension.safeParse(extension).success) {
|
||||||
|
throw new TRPCError({
|
||||||
|
message: "only .png, .jpeg, .jpg, and .webp extensions are allowed",
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Create a unique image name
|
||||||
|
let tryCount = 0;
|
||||||
|
let objectName: string | null = null;
|
||||||
|
while (tryCount < 3) {
|
||||||
|
let imageName = `${generateRandomString()}.${extension}`;
|
||||||
|
let ok = await db
|
||||||
|
.select({ value: count(user.image) })
|
||||||
|
.from(user)
|
||||||
|
.where(eq(user.image, imageName))
|
||||||
|
.then((v) => v[0].value === 0);
|
||||||
|
if (ok) {
|
||||||
|
objectName = imageName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (objectName === null) {
|
||||||
|
throw new TRPCError({
|
||||||
|
message: "Unable to create image request (conflicting name)",
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Store a record in the database
|
||||||
|
await db
|
||||||
|
.insert(imageToUser)
|
||||||
|
.values({ userId, imageName: objectName })
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: [imageToUser.userId],
|
||||||
|
set: { imageName: objectName },
|
||||||
|
});
|
||||||
|
return await createUploadImageUrl(mc, objectName, contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function confirmChangeImage(userId: number, oldImage: string | null) {
|
||||||
|
const mc = createClient();
|
||||||
|
let rs = await db
|
||||||
|
.select({ imageName: imageToUser.imageName })
|
||||||
|
.from(imageToUser)
|
||||||
|
.where(eq(imageToUser.userId, userId));
|
||||||
|
if (rs.length === 0) {
|
||||||
|
throw new TRPCError({
|
||||||
|
message: "No image request found",
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let imageName = rs[0].imageName;
|
||||||
|
const isImageExist = await mc
|
||||||
|
.statObject(Config.bucketName, imageName)
|
||||||
|
.then(() => true)
|
||||||
|
.catch(() => false);
|
||||||
|
if (!isImageExist) {
|
||||||
|
throw new TRPCError({
|
||||||
|
message: "Image not found",
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const promises: Promise<any>[] = [];
|
||||||
|
if (oldImage) {
|
||||||
|
promises.push(mc.removeObject(Config.bucketName, oldImage).catch(() => {}));
|
||||||
|
}
|
||||||
|
const updateUser = db
|
||||||
|
.update(user)
|
||||||
|
.set({ image: imageName })
|
||||||
|
.where(eq(user.id, userId));
|
||||||
|
const deleteRecord = db
|
||||||
|
.delete(imageToUser)
|
||||||
|
.where(eq(imageToUser.userId, userId));
|
||||||
|
await Promise.all([...promises, updateUser, deleteRecord]);
|
||||||
|
return { status: "success" };
|
||||||
|
}
|
||||||
|
|
||||||
function isValidThaiID(id: string) {
|
function isValidThaiID(id: string) {
|
||||||
if (!/^\d{13}$/.test(id)) {
|
if (!/^\d{13}$/.test(id)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -219,3 +322,13 @@ function hidePhone(phone: string | null) {
|
|||||||
if (phone === null) return phone;
|
if (phone === null) return phone;
|
||||||
return phone.slice(0, 2).concat("******").concat(phone.slice(-3));
|
return phone.slice(0, 2).concat("******").concat(phone.slice(-3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createJWT(phone: string) {
|
||||||
|
return jwt.sign({ phone: phone }, Config.jwt_secret, {
|
||||||
|
expiresIn: "365d",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateRandomString() {
|
||||||
|
return Math.random().toString(36).substring(2, 15);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user