feat(medusa): Add endpoints specific to DiscountConditions (#1355)
This commit is contained in:
committed by
GitHub
parent
a69b52e031
commit
9ca45ea492
@@ -14,3 +14,128 @@ Object {
|
||||
"type": "duplicate_error",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`/admin/discounts POST /admin/discounts/:id/conditions fails if more than one condition type is provided: Only one of products, customer_groups is allowed, Only one of customer_groups, products is allowed 1`] = `"Request failed with status code 400"`;
|
||||
|
||||
exports[`/admin/discounts POST /admin/discounts/:id/conditions should create a condition 1`] = `
|
||||
Object {
|
||||
"code": "TEST",
|
||||
"created_at": Any<String>,
|
||||
"deleted_at": null,
|
||||
"ends_at": null,
|
||||
"id": "test-discount",
|
||||
"is_disabled": false,
|
||||
"is_dynamic": false,
|
||||
"metadata": null,
|
||||
"parent_discount": null,
|
||||
"parent_discount_id": null,
|
||||
"regions": Array [],
|
||||
"rule": Object {
|
||||
"allocation": "total",
|
||||
"conditions": Array [
|
||||
Object {
|
||||
"created_at": Any<String>,
|
||||
"deleted_at": null,
|
||||
"discount_rule_id": Any<String>,
|
||||
"id": Any<String>,
|
||||
"metadata": null,
|
||||
"operator": "in",
|
||||
"type": "products",
|
||||
"updated_at": Any<String>,
|
||||
},
|
||||
],
|
||||
"created_at": Any<String>,
|
||||
"deleted_at": null,
|
||||
"description": null,
|
||||
"id": Any<String>,
|
||||
"metadata": null,
|
||||
"type": "percentage",
|
||||
"updated_at": Any<String>,
|
||||
"value": 10,
|
||||
},
|
||||
"rule_id": Any<String>,
|
||||
"starts_at": Any<String>,
|
||||
"updated_at": Any<String>,
|
||||
"usage_count": 0,
|
||||
"usage_limit": null,
|
||||
"valid_duration": null,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`/admin/discounts POST /admin/discounts/:id/conditions throws if discount does not exist: Discount with id does-not-exist was not found 1`] = `"Request failed with status code 404"`;
|
||||
|
||||
exports[`/admin/discounts POST /admin/discounts/:id/conditions/:condition_id should update a condition 1`] = `
|
||||
Object {
|
||||
"code": "TEST",
|
||||
"created_at": Any<String>,
|
||||
"deleted_at": null,
|
||||
"ends_at": null,
|
||||
"id": "test-discount",
|
||||
"is_disabled": false,
|
||||
"is_dynamic": false,
|
||||
"metadata": null,
|
||||
"parent_discount_id": null,
|
||||
"rule": Object {
|
||||
"allocation": "total",
|
||||
"conditions": Array [
|
||||
Object {
|
||||
"created_at": Any<String>,
|
||||
"deleted_at": null,
|
||||
"discount_rule_id": Any<String>,
|
||||
"id": Any<String>,
|
||||
"metadata": null,
|
||||
"operator": "in",
|
||||
"products": Array [
|
||||
Object {
|
||||
"collection_id": null,
|
||||
"created_at": Any<String>,
|
||||
"deleted_at": null,
|
||||
"description": null,
|
||||
"discountable": true,
|
||||
"external_id": null,
|
||||
"handle": null,
|
||||
"height": null,
|
||||
"hs_code": null,
|
||||
"id": "test-product",
|
||||
"is_giftcard": false,
|
||||
"length": null,
|
||||
"material": null,
|
||||
"metadata": null,
|
||||
"mid_code": null,
|
||||
"origin_country": null,
|
||||
"profile_id": Any<String>,
|
||||
"status": "draft",
|
||||
"subtitle": null,
|
||||
"thumbnail": null,
|
||||
"title": "Practical Frozen Fish",
|
||||
"type_id": Any<String>,
|
||||
"updated_at": Any<String>,
|
||||
"weight": null,
|
||||
"width": null,
|
||||
},
|
||||
],
|
||||
"type": "products",
|
||||
"updated_at": Any<String>,
|
||||
},
|
||||
],
|
||||
"created_at": Any<String>,
|
||||
"deleted_at": null,
|
||||
"description": null,
|
||||
"id": Any<String>,
|
||||
"metadata": null,
|
||||
"type": "percentage",
|
||||
"updated_at": Any<String>,
|
||||
"value": 10,
|
||||
},
|
||||
"rule_id": Any<String>,
|
||||
"starts_at": Any<String>,
|
||||
"updated_at": Any<String>,
|
||||
"usage_count": 0,
|
||||
"usage_limit": null,
|
||||
"valid_duration": null,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`/admin/discounts POST /admin/discounts/:id/conditions/:condition_id throws if condition does not exist: DiscountCondition with id does-not-exist was not found for Discount test-discount 1`] = `"Request failed with status code 404"`;
|
||||
|
||||
exports[`/admin/discounts POST /admin/discounts/:id/conditions/:condition_id throws if discount does not exist: Discount with id does-not-exist was not found 1`] = `"Request failed with status code 404"`;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const path = require("path")
|
||||
const {
|
||||
Region,
|
||||
DiscountRule,
|
||||
Discount,
|
||||
Customer,
|
||||
@@ -12,7 +11,6 @@ const { useApi } = require("../../../helpers/use-api")
|
||||
const { initDb, useDb } = require("../../../helpers/use-db")
|
||||
const adminSeeder = require("../../helpers/admin-seeder")
|
||||
const discountSeeder = require("../../helpers/discount-seeder")
|
||||
const { exportAllDeclaration } = require("@babel/types")
|
||||
const { simpleProductFactory } = require("../../factories")
|
||||
const {
|
||||
simpleDiscountFactory,
|
||||
@@ -433,7 +431,6 @@ describe("/admin/discounts", () => {
|
||||
await adminSeeder(dbConnection)
|
||||
await discountSeeder(dbConnection)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw err
|
||||
}
|
||||
})
|
||||
@@ -1468,41 +1465,37 @@ describe("/admin/discounts", () => {
|
||||
describe("POST /admin/discounts/:discount_id/dynamic-codes", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager
|
||||
try {
|
||||
await adminSeeder(dbConnection)
|
||||
await manager.insert(DiscountRule, {
|
||||
id: "test-discount-rule",
|
||||
description: "Dynamic rule",
|
||||
type: "percentage",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
})
|
||||
await manager.insert(Discount, {
|
||||
id: "test-discount",
|
||||
code: "DYNAMIC",
|
||||
is_dynamic: true,
|
||||
is_disabled: false,
|
||||
rule_id: "test-discount-rule",
|
||||
valid_duration: "P2Y",
|
||||
})
|
||||
await manager.insert(DiscountRule, {
|
||||
id: "test-discount-rule1",
|
||||
description: "Dynamic rule",
|
||||
type: "percentage",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
})
|
||||
await manager.insert(Discount, {
|
||||
id: "test-discount1",
|
||||
code: "DYNAMICCode",
|
||||
is_dynamic: true,
|
||||
is_disabled: false,
|
||||
rule_id: "test-discount-rule1",
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw err
|
||||
}
|
||||
|
||||
await adminSeeder(dbConnection)
|
||||
await manager.insert(DiscountRule, {
|
||||
id: "test-discount-rule",
|
||||
description: "Dynamic rule",
|
||||
type: "percentage",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
})
|
||||
await manager.insert(Discount, {
|
||||
id: "test-discount",
|
||||
code: "DYNAMIC",
|
||||
is_dynamic: true,
|
||||
is_disabled: false,
|
||||
rule_id: "test-discount-rule",
|
||||
valid_duration: "P2Y",
|
||||
})
|
||||
await manager.insert(DiscountRule, {
|
||||
id: "test-discount-rule1",
|
||||
description: "Dynamic rule",
|
||||
type: "percentage",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
})
|
||||
await manager.insert(Discount, {
|
||||
id: "test-discount1",
|
||||
code: "DYNAMICCode",
|
||||
is_dynamic: true,
|
||||
is_disabled: false,
|
||||
rule_id: "test-discount-rule1",
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
@@ -1554,7 +1547,7 @@ describe("/admin/discounts", () => {
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
// console.log(err)
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
@@ -1566,4 +1559,477 @@ describe("/admin/discounts", () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("DELETE /admin/discounts/:id/conditions/:condition_id", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager
|
||||
await adminSeeder(dbConnection)
|
||||
|
||||
await manager.insert(DiscountRule, {
|
||||
id: "test-discount-rule-fixed",
|
||||
description: "Test discount rule",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
})
|
||||
|
||||
const prod = await simpleProductFactory(dbConnection, { type: "pants" })
|
||||
|
||||
await simpleDiscountFactory(dbConnection, {
|
||||
id: "test-discount",
|
||||
code: "TEST",
|
||||
rule: {
|
||||
type: "percentage",
|
||||
value: "10",
|
||||
allocation: "total",
|
||||
conditions: [
|
||||
{
|
||||
type: "products",
|
||||
operator: "in",
|
||||
products: [prod.id],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
const db = useDb()
|
||||
await db.teardown()
|
||||
})
|
||||
|
||||
it("should delete condition", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const group = await dbConnection.manager.insert(CustomerGroup, {
|
||||
id: "customer-group-1",
|
||||
name: "vip-customers",
|
||||
})
|
||||
|
||||
await dbConnection.manager.insert(Customer, {
|
||||
id: "cus_1234",
|
||||
email: "oli@email.com",
|
||||
groups: [group],
|
||||
})
|
||||
|
||||
await simpleDiscountFactory(dbConnection, {
|
||||
id: "test-discount",
|
||||
code: "TEST",
|
||||
rule: {
|
||||
type: "percentage",
|
||||
value: "10",
|
||||
allocation: "total",
|
||||
conditions: [
|
||||
{
|
||||
id: "test-condition",
|
||||
type: "customer_groups",
|
||||
operator: "in",
|
||||
customer_groups: ["customer-group-1"],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const response = await api
|
||||
.delete("/admin/discounts/test-discount/conditions/test-condition", {
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
const disc = response.data
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(disc).toEqual(
|
||||
expect.objectContaining({
|
||||
id: "test-condition",
|
||||
deleted: true,
|
||||
object: "discount-condition",
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should not fail if condition does not exist", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const response = await api
|
||||
.delete("/admin/discounts/test-discount/conditions/test-condition", {
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
const disc = response.data
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(disc).toEqual(
|
||||
expect.objectContaining({
|
||||
id: "test-condition",
|
||||
deleted: true,
|
||||
object: "discount-condition",
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should fail if discount does not exist", async () => {
|
||||
const api = useApi()
|
||||
|
||||
try {
|
||||
await api.delete(
|
||||
"/admin/discounts/not-exist/conditions/test-condition",
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
expect(error.message).toMatchSnapshot(
|
||||
"Discount with id not-exist was not found"
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/discounts/:id/conditions", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager
|
||||
await adminSeeder(dbConnection)
|
||||
|
||||
await manager.insert(DiscountRule, {
|
||||
id: "test-discount-rule-fixed",
|
||||
description: "Test discount rule",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
})
|
||||
|
||||
await simpleDiscountFactory(dbConnection, {
|
||||
id: "test-discount",
|
||||
code: "TEST",
|
||||
rule: {
|
||||
type: "percentage",
|
||||
value: "10",
|
||||
allocation: "total",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
const db = useDb()
|
||||
await db.teardown()
|
||||
})
|
||||
|
||||
it("should create a condition", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const prod = await simpleProductFactory(dbConnection, { type: "pants" })
|
||||
|
||||
const response = await api
|
||||
.post(
|
||||
"/admin/discounts/test-discount/conditions",
|
||||
{
|
||||
operator: "in",
|
||||
products: [prod.id],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
const disc = response.data.discount
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(disc).toMatchSnapshot({
|
||||
id: "test-discount",
|
||||
code: "TEST",
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
rule_id: expect.any(String),
|
||||
starts_at: expect.any(String),
|
||||
rule: {
|
||||
id: expect.any(String),
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
conditions: [
|
||||
{
|
||||
id: expect.any(String),
|
||||
discount_rule_id: expect.any(String),
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it("fails if more than one condition type is provided", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const prod = await simpleProductFactory(dbConnection, { type: "pants" })
|
||||
|
||||
const group = await dbConnection.manager.insert(CustomerGroup, {
|
||||
id: "customer-group-1",
|
||||
name: "vip-customers",
|
||||
})
|
||||
|
||||
await dbConnection.manager.insert(Customer, {
|
||||
id: "cus_1234",
|
||||
email: "oli@email.com",
|
||||
groups: [group],
|
||||
})
|
||||
|
||||
try {
|
||||
await api.post(
|
||||
"/admin/discounts/test-discount/conditions",
|
||||
{
|
||||
operator: "in",
|
||||
products: [prod.id],
|
||||
customer_groups: ["customer-group-1"],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
expect(error.message).toMatchSnapshot(
|
||||
"Only one of products, customer_groups is allowed, Only one of customer_groups, products is allowed"
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("throws if discount does not exist", async () => {
|
||||
expect.assertions(1)
|
||||
|
||||
const api = useApi()
|
||||
|
||||
const prod2 = await simpleProductFactory(dbConnection, { type: "pants" })
|
||||
|
||||
try {
|
||||
await api.post(
|
||||
"/admin/discounts/does-not-exist/conditions/test-condition",
|
||||
{
|
||||
products: [prod2.id],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
expect(error.message).toMatchSnapshot(
|
||||
"Discount with id does-not-exist was not found"
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("POST /admin/discounts/:id/conditions/:condition_id", () => {
|
||||
beforeEach(async () => {
|
||||
const manager = dbConnection.manager
|
||||
await adminSeeder(dbConnection)
|
||||
|
||||
await manager.insert(DiscountRule, {
|
||||
id: "test-discount-rule-fixed",
|
||||
description: "Test discount rule",
|
||||
type: "fixed",
|
||||
value: 10,
|
||||
allocation: "total",
|
||||
})
|
||||
|
||||
const prod = await simpleProductFactory(dbConnection, { type: "pants" })
|
||||
|
||||
await simpleDiscountFactory(dbConnection, {
|
||||
id: "test-discount",
|
||||
code: "TEST",
|
||||
rule: {
|
||||
type: "percentage",
|
||||
value: "10",
|
||||
allocation: "total",
|
||||
conditions: [
|
||||
{
|
||||
id: "test-condition",
|
||||
type: "products",
|
||||
operator: "in",
|
||||
products: [prod.id],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
await simpleDiscountFactory(dbConnection, {
|
||||
id: "test-discount-2",
|
||||
code: "TEST2",
|
||||
rule: {
|
||||
type: "percentage",
|
||||
value: "10",
|
||||
allocation: "total",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
const db = useDb()
|
||||
await db.teardown()
|
||||
})
|
||||
|
||||
it("should update a condition", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const prod2 = await simpleProductFactory(dbConnection, {
|
||||
id: "test-product",
|
||||
type: "pants",
|
||||
})
|
||||
|
||||
const discount = await api
|
||||
.get("/admin/discounts/test-discount", {
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
const cond = discount.data.discount.rule.conditions[0]
|
||||
|
||||
const response = await api
|
||||
.post(
|
||||
`/admin/discounts/test-discount/conditions/${cond.id}?expand=rule,rule.conditions,rule.conditions.products`,
|
||||
{
|
||||
products: [prod2.id],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
const disc = response.data.discount
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
expect(disc).toMatchSnapshot({
|
||||
id: "test-discount",
|
||||
code: "TEST",
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
rule_id: expect.any(String),
|
||||
starts_at: expect.any(String),
|
||||
rule: {
|
||||
id: expect.any(String),
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
conditions: [
|
||||
{
|
||||
id: expect.any(String),
|
||||
discount_rule_id: expect.any(String),
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
products: [
|
||||
{
|
||||
created_at: expect.any(String),
|
||||
updated_at: expect.any(String),
|
||||
profile_id: expect.any(String),
|
||||
type_id: expect.any(String),
|
||||
id: "test-product",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it("throws if condition does not exist", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const prod2 = await simpleProductFactory(dbConnection, { type: "pants" })
|
||||
|
||||
try {
|
||||
await api.post(
|
||||
"/admin/discounts/test-discount/conditions/does-not-exist",
|
||||
{
|
||||
products: [prod2.id],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
expect(error.message).toMatchSnapshot(
|
||||
"DiscountCondition with id does-not-exist was not found for Discount test-discount"
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("throws if discount does not exist", async () => {
|
||||
expect.assertions(1)
|
||||
|
||||
const api = useApi()
|
||||
|
||||
const prod2 = await simpleProductFactory(dbConnection, { type: "pants" })
|
||||
|
||||
try {
|
||||
await api.post(
|
||||
"/admin/discounts/does-not-exist/conditions/test-condition",
|
||||
{
|
||||
products: [prod2.id],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
expect(error.message).toMatchSnapshot(
|
||||
"Discount with id does-not-exist was not found"
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it("throws if condition does not belong to discount", async () => {
|
||||
const api = useApi()
|
||||
|
||||
const prod2 = await simpleProductFactory(dbConnection, { type: "pants" })
|
||||
|
||||
try {
|
||||
await api.post(
|
||||
"/admin/discounts/test-discount-2/conditions/test-condition",
|
||||
{
|
||||
products: [prod2.id],
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer test_token",
|
||||
},
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
expect(error.message).toMatchSnapshot(
|
||||
"DiscountCondition with id test-condition was not found for Discount test-discount-2"
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -13,6 +13,7 @@ import faker from "faker"
|
||||
import { Connection } from "typeorm"
|
||||
|
||||
export type DiscuntConditionFactoryData = {
|
||||
id?: string
|
||||
rule_id: string
|
||||
type: DiscountConditionType
|
||||
operator: DiscountConditionOperator
|
||||
@@ -93,11 +94,17 @@ export const simpleDiscountConditionFactory = async (
|
||||
resources = data.customer_groups
|
||||
}
|
||||
|
||||
const condToSave = manager.create(DiscountCondition, {
|
||||
const toCreate = {
|
||||
type: data.type,
|
||||
operator: data.operator,
|
||||
discount_rule_id: data.rule_id,
|
||||
})
|
||||
}
|
||||
|
||||
if (data.id) {
|
||||
toCreate["id"] = data.id
|
||||
}
|
||||
|
||||
const condToSave = manager.create(DiscountCondition, toCreate)
|
||||
|
||||
const { conditionTable, resourceKey } = getJoinTableResourceIdentifiers(
|
||||
data.type
|
||||
|
||||
Reference in New Issue
Block a user