feat(client-types, types, medusa, inventory): Inventory item and reservation item datamodel updates (#3971)
* add fields * add title in migration * update api endpoints to reflect datamodel changes * update migration exports for inventory module * add changeset * add created_by for reservation item
This commit is contained in:
1 parent
09e206fc1b
commit
7fd22ecb4d
15 files changed
+180
-24
No files matched your search
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/client-types": patch
|
||||||
|
"@medusajs/inventory": patch
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Feat(client-types, inventory, medusa, types): add `title`, `thumbnail` and `description to inventory item and `description` to reservation item.
|
||||||
@@ -20,6 +20,18 @@ export interface InventoryItemDTO {
|
|||||||
* The Manufacturers Identification code that identifies the manufacturer of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
* The Manufacturers Identification code that identifies the manufacturer of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
||||||
*/
|
*/
|
||||||
mid_code?: string
|
mid_code?: string
|
||||||
|
/**
|
||||||
|
* Title of the inventory item
|
||||||
|
*/
|
||||||
|
title?: string
|
||||||
|
/**
|
||||||
|
* Description of the inventory item
|
||||||
|
*/
|
||||||
|
description?: string
|
||||||
|
/**
|
||||||
|
* Thumbnail for the inventory item
|
||||||
|
*/
|
||||||
|
thumbnail?: string
|
||||||
/**
|
/**
|
||||||
* The material and composition that the Inventory Item is made of, May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
* The material and composition that the Inventory Item is made of, May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,6 +19,14 @@ export interface ReservationItemDTO {
|
|||||||
* The id of the inventory item the reservation relates to
|
* The id of the inventory item the reservation relates to
|
||||||
*/
|
*/
|
||||||
inventory_item_id: string
|
inventory_item_id: string
|
||||||
|
/**
|
||||||
|
* Description of the reservation item
|
||||||
|
*/
|
||||||
|
description?: string
|
||||||
|
/**
|
||||||
|
* UserId of user who created the reservation item
|
||||||
|
*/
|
||||||
|
created_by?: string
|
||||||
/**
|
/**
|
||||||
* The id of the reservation item
|
* The id of the reservation item
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as setup from "./schema-migrations/1665748086258-inventory_setup"
|
|
||||||
import * as addExternalId from "./schema-migrations/1675761451145-add_reservation_external_id"
|
import * as addExternalId from "./schema-migrations/1675761451145-add_reservation_external_id"
|
||||||
|
import * as descriptionsAndThumbnail from "./schema-migrations/1682927363119-item_descriptions_and_thumbnail"
|
||||||
|
import * as setup from "./schema-migrations/1665748086258-inventory_setup"
|
||||||
|
|
||||||
export default [setup, addExternalId]
|
export default [setup, addExternalId, descriptionsAndThumbnail]
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||||
|
|
||||||
|
export class itemDescriptionsAndThumbnail1682927363119
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE inventory_item
|
||||||
|
ADD "title" character varying,
|
||||||
|
ADD "description" character varying,
|
||||||
|
ADD "thumbnail" character varying;
|
||||||
|
`)
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "reservation_item"
|
||||||
|
ADD "description" character varying,
|
||||||
|
ADD "created_by" character varying;
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE reservation_item
|
||||||
|
DROP COLUMN "title",
|
||||||
|
DROP COLUMN "description",
|
||||||
|
DROP COLUMN "thumbnail";
|
||||||
|
`)
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "reservation_item"
|
||||||
|
DROP COLUMN "description",
|
||||||
|
DROP COLUMN "created_by";
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { generateEntityId, SoftDeletableEntity } from "@medusajs/utils"
|
|
||||||
import { BeforeInsert, Column, Entity, Index } from "typeorm"
|
import { BeforeInsert, Column, Entity, Index } from "typeorm"
|
||||||
|
import { SoftDeletableEntity, generateEntityId } from "@medusajs/utils"
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class InventoryItem extends SoftDeletableEntity {
|
export class InventoryItem extends SoftDeletableEntity {
|
||||||
@@ -34,6 +34,15 @@ export class InventoryItem extends SoftDeletableEntity {
|
|||||||
@Column({ default: true })
|
@Column({ default: true })
|
||||||
requires_shipping: boolean
|
requires_shipping: boolean
|
||||||
|
|
||||||
|
@Column({ type: "text", nullable: true })
|
||||||
|
description: string | null
|
||||||
|
|
||||||
|
@Column({ type: "text", nullable: true })
|
||||||
|
title: string | null
|
||||||
|
|
||||||
|
@Column({ type: "text", nullable: true })
|
||||||
|
thumbnail: string | null
|
||||||
|
|
||||||
@Column({ type: "jsonb", nullable: true })
|
@Column({ type: "jsonb", nullable: true })
|
||||||
metadata: Record<string, unknown> | null
|
metadata: Record<string, unknown> | null
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { generateEntityId, SoftDeletableEntity } from "@medusajs/utils"
|
|
||||||
import { BeforeInsert, Column, Entity, Index } from "typeorm"
|
import { BeforeInsert, Column, Entity, Index } from "typeorm"
|
||||||
|
import { SoftDeletableEntity, generateEntityId } from "@medusajs/utils"
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class ReservationItem extends SoftDeletableEntity {
|
export class ReservationItem extends SoftDeletableEntity {
|
||||||
@@ -21,6 +21,12 @@ export class ReservationItem extends SoftDeletableEntity {
|
|||||||
@Column({ type: "text", nullable: true })
|
@Column({ type: "text", nullable: true })
|
||||||
external_id: string | null
|
external_id: string | null
|
||||||
|
|
||||||
|
@Column({ type: "text", nullable: true })
|
||||||
|
description: string | null
|
||||||
|
|
||||||
|
@Column({ type: "text", nullable: true })
|
||||||
|
created_by: string | null
|
||||||
|
|
||||||
@Column({ type: "jsonb", nullable: true })
|
@Column({ type: "jsonb", nullable: true })
|
||||||
metadata: Record<string, unknown> | null
|
metadata: Record<string, unknown> | null
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,9 @@ export default class InventoryItemService {
|
|||||||
height: data.height,
|
height: data.height,
|
||||||
width: data.width,
|
width: data.width,
|
||||||
requires_shipping: data.requires_shipping,
|
requires_shipping: data.requires_shipping,
|
||||||
|
description: data.description,
|
||||||
|
thumbnail: data.thumbnail,
|
||||||
|
title: data.title,
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = await itemRepository.save(inventoryItem)
|
const result = await itemRepository.save(inventoryItem)
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ export default class ReservationItemService {
|
|||||||
quantity: data.quantity,
|
quantity: data.quantity,
|
||||||
metadata: data.metadata,
|
metadata: data.metadata,
|
||||||
external_id: data.external_id,
|
external_id: data.external_id,
|
||||||
|
description: data.description,
|
||||||
|
created_by: data.created_by,
|
||||||
})
|
})
|
||||||
|
|
||||||
const [newReservationItem] = await Promise.all([
|
const [newReservationItem] = await Promise.all([
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { IInventoryService } from "@medusajs/types"
|
|
||||||
import { MedusaError } from "@medusajs/utils"
|
|
||||||
import { IsNumber, IsObject, IsOptional, IsString } from "class-validator"
|
import { IsNumber, IsObject, IsOptional, IsString } from "class-validator"
|
||||||
import { EntityManager } from "typeorm"
|
|
||||||
import {
|
import {
|
||||||
ProductVariantInventoryService,
|
ProductVariantInventoryService,
|
||||||
ProductVariantService,
|
ProductVariantService,
|
||||||
} from "../../../../services"
|
} from "../../../../services"
|
||||||
|
|
||||||
|
import { EntityManager } from "typeorm"
|
||||||
import { FindParams } from "../../../../types/common"
|
import { FindParams } from "../../../../types/common"
|
||||||
import { validator } from "../../../../utils/validator"
|
import { IInventoryService } from "@medusajs/types"
|
||||||
|
import { MedusaError } from "@medusajs/utils"
|
||||||
import { createInventoryItemTransaction } from "./transaction/create-inventory-item"
|
import { createInventoryItemTransaction } from "./transaction/create-inventory-item"
|
||||||
|
import { validator } from "../../../../utils/validator"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [post] /admin/inventory-items
|
* @oas [post] /admin/inventory-items
|
||||||
@@ -221,6 +222,18 @@ export class AdminPostInventoryItemsReq {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
material?: string
|
material?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
title?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
description?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
thumbnail?: string
|
||||||
|
|
||||||
@IsObject()
|
@IsObject()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
metadata?: Record<string, unknown>
|
metadata?: Record<string, unknown>
|
||||||
|
|||||||
+15
-8
@@ -1,11 +1,3 @@
|
|||||||
import { IInventoryService, InventoryItemDTO } from "@medusajs/types"
|
|
||||||
import { MedusaError } from "@medusajs/utils"
|
|
||||||
import { EntityManager } from "typeorm"
|
|
||||||
import { ulid } from "ulid"
|
|
||||||
import {
|
|
||||||
ProductVariantInventoryService,
|
|
||||||
ProductVariantService,
|
|
||||||
} from "../../../../../services"
|
|
||||||
import {
|
import {
|
||||||
DistributedTransaction,
|
DistributedTransaction,
|
||||||
TransactionHandlerType,
|
TransactionHandlerType,
|
||||||
@@ -14,6 +6,15 @@ import {
|
|||||||
TransactionState,
|
TransactionState,
|
||||||
TransactionStepsDefinition,
|
TransactionStepsDefinition,
|
||||||
} from "../../../../../utils/transaction"
|
} from "../../../../../utils/transaction"
|
||||||
|
import { IInventoryService, InventoryItemDTO } from "@medusajs/types"
|
||||||
|
import {
|
||||||
|
ProductVariantInventoryService,
|
||||||
|
ProductVariantService,
|
||||||
|
} from "../../../../../services"
|
||||||
|
|
||||||
|
import { EntityManager } from "typeorm"
|
||||||
|
import { MedusaError } from "@medusajs/utils"
|
||||||
|
import { ulid } from "ulid"
|
||||||
|
|
||||||
enum actions {
|
enum actions {
|
||||||
createInventoryItem = "createInventoryItem",
|
createInventoryItem = "createInventoryItem",
|
||||||
@@ -53,6 +54,9 @@ type CreateInventoryItemInput = {
|
|||||||
origin_country?: string
|
origin_country?: string
|
||||||
mid_code?: string
|
mid_code?: string
|
||||||
material?: string
|
material?: string
|
||||||
|
title?: string
|
||||||
|
description?: string
|
||||||
|
thumbnail?: string
|
||||||
metadata?: Record<string, unknown>
|
metadata?: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +88,9 @@ export const createInventoryItemTransaction = async (
|
|||||||
length: input.length,
|
length: input.length,
|
||||||
height: input.height,
|
height: input.height,
|
||||||
width: input.width,
|
width: input.width,
|
||||||
|
title: input.title,
|
||||||
|
description: input.description,
|
||||||
|
thumbnail: input.thumbnail,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { IInventoryService } from "@medusajs/types"
|
|
||||||
import { IsBoolean, IsNumber, IsOptional, IsString } from "class-validator"
|
import { IsBoolean, IsNumber, IsOptional, IsString } from "class-validator"
|
||||||
import { Request, Response } from "express"
|
import { Request, Response } from "express"
|
||||||
|
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
import { FindParams } from "../../../../types/common"
|
import { FindParams } from "../../../../types/common"
|
||||||
|
import { IInventoryService } from "@medusajs/types"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [post] /admin/inventory-items/{id}
|
* @oas [post] /admin/inventory-items/{id}
|
||||||
@@ -159,6 +160,18 @@ export class AdminPostInventoryItemsInventoryItemReq {
|
|||||||
@IsNumber()
|
@IsNumber()
|
||||||
width?: number
|
width?: number
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
title?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
description?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
thumbnail?: string
|
||||||
|
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
requires_shipping?: boolean
|
requires_shipping?: boolean
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import { IsNumber, IsObject, IsOptional, IsString } from "class-validator"
|
||||||
|
|
||||||
import { IInventoryService } from "@medusajs/types"
|
import { IInventoryService } from "@medusajs/types"
|
||||||
import { isDefined } from "@medusajs/utils"
|
import { isDefined } from "@medusajs/utils"
|
||||||
import { IsNumber, IsObject, IsOptional, IsString } from "class-validator"
|
|
||||||
import { validateUpdateReservationQuantity } from "./utils/validate-reservation-quantity"
|
import { validateUpdateReservationQuantity } from "./utils/validate-reservation-quantity"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,6 +74,8 @@ export default async (req, res) => {
|
|||||||
const inventoryService: IInventoryService =
|
const inventoryService: IInventoryService =
|
||||||
req.scope.resolve("inventoryService")
|
req.scope.resolve("inventoryService")
|
||||||
|
|
||||||
|
const userId: string = req.user.id || req.user.userId
|
||||||
|
|
||||||
if (isDefined(validatedBody.line_item_id)) {
|
if (isDefined(validatedBody.line_item_id)) {
|
||||||
await validateUpdateReservationQuantity(
|
await validateUpdateReservationQuantity(
|
||||||
validatedBody.line_item_id,
|
validatedBody.line_item_id,
|
||||||
@@ -84,9 +87,10 @@ export default async (req, res) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const reservation = await inventoryService.createReservationItem(
|
const reservation = await inventoryService.createReservationItem({
|
||||||
validatedBody
|
...validatedBody,
|
||||||
)
|
created_by: userId,
|
||||||
|
})
|
||||||
|
|
||||||
res.status(200).json({ reservation })
|
res.status(200).json({ reservation })
|
||||||
}
|
}
|
||||||
@@ -128,6 +132,10 @@ export class AdminPostReservationsReq {
|
|||||||
@IsNumber()
|
@IsNumber()
|
||||||
quantity: number
|
quantity: number
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
description?: string
|
||||||
|
|
||||||
@IsObject()
|
@IsObject()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
metadata?: Record<string, unknown>
|
metadata?: Record<string, unknown>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { IInventoryService } from "@medusajs/types"
|
|
||||||
import { isDefined } from "@medusajs/utils"
|
|
||||||
import { IsNumber, IsObject, IsOptional, IsString } from "class-validator"
|
import { IsNumber, IsObject, IsOptional, IsString } from "class-validator"
|
||||||
|
|
||||||
import { EntityManager } from "typeorm"
|
import { EntityManager } from "typeorm"
|
||||||
|
import { IInventoryService } from "@medusajs/types"
|
||||||
import { LineItemService } from "../../../../services"
|
import { LineItemService } from "../../../../services"
|
||||||
|
import { isDefined } from "@medusajs/utils"
|
||||||
import { validateUpdateReservationQuantity } from "./utils/validate-reservation-quantity"
|
import { validateUpdateReservationQuantity } from "./utils/validate-reservation-quantity"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,6 +121,10 @@ export class AdminPostReservationsReservationReq {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
location_id?: string
|
location_id?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
description?: string
|
||||||
|
|
||||||
@IsObject()
|
@IsObject()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
metadata?: Record<string, unknown>
|
metadata?: Record<string, unknown>
|
||||||
|
|||||||
@@ -21,6 +21,15 @@ import {
|
|||||||
* mid_code:
|
* mid_code:
|
||||||
* description: The Manufacturers Identification code that identifies the manufacturer of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
* description: The Manufacturers Identification code that identifies the manufacturer of the Inventory Item. May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
||||||
* type: string
|
* type: string
|
||||||
|
* title:
|
||||||
|
* description: "Title of the inventory item"
|
||||||
|
* type: string
|
||||||
|
* description:
|
||||||
|
* description: "Description of the inventory item"
|
||||||
|
* type: string
|
||||||
|
* thumbnail:
|
||||||
|
* description: "Thumbnail for the inventory item"
|
||||||
|
* type: string
|
||||||
* material:
|
* material:
|
||||||
* description: The material and composition that the Inventory Item is made of, May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
* description: The material and composition that the Inventory Item is made of, May be used by Fulfillment Providers to pass customs information to shipping carriers.
|
||||||
* type: string
|
* type: string
|
||||||
@@ -68,6 +77,9 @@ export type InventoryItemDTO = {
|
|||||||
length?: number | null
|
length?: number | null
|
||||||
height?: number | null
|
height?: number | null
|
||||||
width?: number | null
|
width?: number | null
|
||||||
|
title?: string | null
|
||||||
|
description?: string | null
|
||||||
|
thumbnail?: string | null
|
||||||
metadata?: Record<string, unknown> | null
|
metadata?: Record<string, unknown> | null
|
||||||
created_at: string | Date
|
created_at: string | Date
|
||||||
updated_at: string | Date
|
updated_at: string | Date
|
||||||
@@ -94,6 +106,12 @@ export type InventoryItemDTO = {
|
|||||||
* inventory_item_id:
|
* inventory_item_id:
|
||||||
* description: "The id of the inventory item the reservation relates to"
|
* description: "The id of the inventory item the reservation relates to"
|
||||||
* type: string
|
* type: string
|
||||||
|
* description:
|
||||||
|
* description: "Description of the reservation item"
|
||||||
|
* type: string
|
||||||
|
* created_by:
|
||||||
|
* description: "UserId of user who created the reservation item"
|
||||||
|
* type: string
|
||||||
* quantity:
|
* quantity:
|
||||||
* description: "The id of the reservation item"
|
* description: "The id of the reservation item"
|
||||||
* type: number
|
* type: number
|
||||||
@@ -120,6 +138,8 @@ export type ReservationItemDTO = {
|
|||||||
inventory_item_id: string
|
inventory_item_id: string
|
||||||
quantity: number
|
quantity: number
|
||||||
line_item_id?: string | null
|
line_item_id?: string | null
|
||||||
|
description?: string | null
|
||||||
|
created_by?: string | null
|
||||||
metadata: Record<string, unknown> | null
|
metadata: Record<string, unknown> | null
|
||||||
created_at: string | Date
|
created_at: string | Date
|
||||||
updated_at: string | Date
|
updated_at: string | Date
|
||||||
@@ -184,6 +204,8 @@ export type FilterableReservationItemProps = {
|
|||||||
line_item_id?: string | string[]
|
line_item_id?: string | string[]
|
||||||
inventory_item_id?: string | string[]
|
inventory_item_id?: string | string[]
|
||||||
location_id?: string | string[]
|
location_id?: string | string[]
|
||||||
|
description?: string
|
||||||
|
created_by?: string | string[]
|
||||||
quantity?: number | NumericalComparisonOperator
|
quantity?: number | NumericalComparisonOperator
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,6 +228,9 @@ export type CreateInventoryItemInput = {
|
|||||||
length?: number
|
length?: number
|
||||||
height?: number
|
height?: number
|
||||||
width?: number
|
width?: number
|
||||||
|
title?: string
|
||||||
|
description?: string
|
||||||
|
thumbnail?: string
|
||||||
metadata?: Record<string, unknown> | null
|
metadata?: Record<string, unknown> | null
|
||||||
hs_code?: string
|
hs_code?: string
|
||||||
requires_shipping?: boolean
|
requires_shipping?: boolean
|
||||||
@@ -216,8 +241,10 @@ export type CreateReservationItemInput = {
|
|||||||
inventory_item_id: string
|
inventory_item_id: string
|
||||||
location_id: string
|
location_id: string
|
||||||
quantity: number
|
quantity: number
|
||||||
metadata?: Record<string, unknown> | null
|
description?: string
|
||||||
|
created_by?: string
|
||||||
external_id?: string
|
external_id?: string
|
||||||
|
metadata?: Record<string, unknown> | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FilterableInventoryLevelProps = {
|
export type FilterableInventoryLevelProps = {
|
||||||
@@ -244,6 +271,7 @@ export type UpdateInventoryLevelInput = {
|
|||||||
export type UpdateReservationItemInput = {
|
export type UpdateReservationItemInput = {
|
||||||
quantity?: number
|
quantity?: number
|
||||||
location_id?: string
|
location_id?: string
|
||||||
|
description?: string
|
||||||
metadata?: Record<string, unknown> | null
|
metadata?: Record<string, unknown> | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user