mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-05-02 09:45:00 +00:00
feat: add minLevel property to metadata.json files and update permission levels in levels.lua
This commit is contained in:
@@ -15,7 +15,7 @@ export const useLuaDiagnostics = (monaco: Monaco | null) =>
|
||||
endColumn: word.endColumn,
|
||||
}
|
||||
|
||||
const suggestions: any[] = [
|
||||
const suggestions: monaco.languages.CompletionItem[] = [
|
||||
{
|
||||
label: 'context.data',
|
||||
kind: monaco.languages.CompletionItemKind.Property,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { Comment } from '../../types/level-types'
|
||||
|
||||
const mockCreate = vi.fn()
|
||||
const mockAdapter = { create: mockCreate }
|
||||
@@ -14,7 +15,7 @@ describe('addComment', () => {
|
||||
mockCreate.mockReset()
|
||||
})
|
||||
|
||||
it.each([
|
||||
const cases: Array<{ name: string; comment: Comment }> = [
|
||||
{
|
||||
name: 'basic comment',
|
||||
comment: { id: 'c1', userId: 'u1', content: 'Hello', createdAt: 1000 },
|
||||
@@ -23,10 +24,12 @@ describe('addComment', () => {
|
||||
name: 'reply comment',
|
||||
comment: { id: 'c2', userId: 'u1', content: 'Reply', createdAt: 2000, parentId: 'c1' },
|
||||
},
|
||||
])('should add $name', async ({ comment }) => {
|
||||
]
|
||||
|
||||
it.each(cases)('should add $name', async ({ comment }) => {
|
||||
mockCreate.mockResolvedValue(undefined)
|
||||
|
||||
await addComment(comment as any)
|
||||
await addComment(comment)
|
||||
|
||||
expect(mockCreate).toHaveBeenCalledWith(
|
||||
'Comment',
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Comment } from '../../types/level-types'
|
||||
|
||||
type DBALCommentRecord = {
|
||||
id: string
|
||||
userId: string
|
||||
content: string
|
||||
createdAt: number | string | Date
|
||||
updatedAt?: number | string | Date | null
|
||||
parentId?: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all comments from database
|
||||
*/
|
||||
export async function getComments(): Promise<Comment[]> {
|
||||
const adapter = getAdapter()
|
||||
const result = await adapter.list('Comment')
|
||||
return (result.data as any[]).map(c => ({
|
||||
const result = (await adapter.list('Comment')) as { data: DBALCommentRecord[] }
|
||||
return result.data.map(c => ({
|
||||
id: c.id,
|
||||
userId: c.userId,
|
||||
content: c.content,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { LuaScript } from '../../types/level-types'
|
||||
|
||||
const mockList = vi.fn()
|
||||
const mockDelete = vi.fn()
|
||||
@@ -23,7 +24,7 @@ describe('setLuaScripts', () => {
|
||||
mockDelete.mockResolvedValue(undefined)
|
||||
mockCreate.mockResolvedValue(undefined)
|
||||
|
||||
await setLuaScripts([
|
||||
const scripts: LuaScript[] = [
|
||||
{
|
||||
id: 'new',
|
||||
name: 'New',
|
||||
@@ -32,7 +33,9 @@ describe('setLuaScripts', () => {
|
||||
allowedGlobals: ['math'],
|
||||
timeoutMs: 1500,
|
||||
},
|
||||
] as any)
|
||||
]
|
||||
|
||||
await setLuaScripts(scripts)
|
||||
|
||||
expect(mockDelete).toHaveBeenCalledTimes(1)
|
||||
expect(mockCreate).toHaveBeenCalledTimes(1)
|
||||
|
||||
@@ -2,6 +2,10 @@ import type { LuaScript } from '../../types/level-types'
|
||||
import { getAdapter } from '../core/dbal-client'
|
||||
import { serializeLuaScript } from './serialization/serialize-lua-script'
|
||||
|
||||
type DBALLuaScriptRecord = {
|
||||
id: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all Lua scripts (replaces existing)
|
||||
*/
|
||||
@@ -9,8 +13,8 @@ export async function setLuaScripts(scripts: LuaScript[]): Promise<void> {
|
||||
const adapter = getAdapter()
|
||||
|
||||
// Delete existing scripts
|
||||
const existing = await adapter.list('LuaScript')
|
||||
for (const s of existing.data as any[]) {
|
||||
const existing = (await adapter.list('LuaScript')) as { data: DBALLuaScriptRecord[] }
|
||||
for (const s of existing.data) {
|
||||
await adapter.delete('LuaScript', s.id)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
|
||||
type DBALWorkflowRecord = {
|
||||
id: string
|
||||
name: string
|
||||
description?: string | null
|
||||
nodes: string
|
||||
edges: string
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all workflows
|
||||
*/
|
||||
export async function getWorkflows(): Promise<Workflow[]> {
|
||||
const adapter = getAdapter()
|
||||
const result = await adapter.list('Workflow')
|
||||
return (result.data as any[]).map(w => ({
|
||||
const result = (await adapter.list('Workflow')) as { data: DBALWorkflowRecord[] }
|
||||
return result.data.map(w => ({
|
||||
id: w.id,
|
||||
name: w.name,
|
||||
description: w.description || undefined,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
|
||||
const mockList = vi.fn()
|
||||
const mockDelete = vi.fn()
|
||||
@@ -23,7 +24,11 @@ describe('setWorkflows', () => {
|
||||
mockDelete.mockResolvedValue(undefined)
|
||||
mockCreate.mockResolvedValue(undefined)
|
||||
|
||||
await setWorkflows([{ id: 'new', name: 'New', nodes: [], edges: [], enabled: true }] as any)
|
||||
const workflows: Workflow[] = [
|
||||
{ id: 'new', name: 'New', nodes: [], edges: [], enabled: true },
|
||||
]
|
||||
|
||||
await setWorkflows(workflows)
|
||||
|
||||
expect(mockDelete).toHaveBeenCalledTimes(1)
|
||||
expect(mockCreate).toHaveBeenCalledTimes(1)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
|
||||
type DBALWorkflowRecord = {
|
||||
id: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all workflows (replaces existing)
|
||||
*/
|
||||
@@ -8,8 +12,8 @@ export async function setWorkflows(workflows: Workflow[]): Promise<void> {
|
||||
const adapter = getAdapter()
|
||||
|
||||
// Delete existing workflows
|
||||
const existing = await adapter.list('Workflow')
|
||||
for (const w of existing.data as any[]) {
|
||||
const existing = (await adapter.list('Workflow')) as { data: DBALWorkflowRecord[] }
|
||||
for (const w of existing.data) {
|
||||
await adapter.delete('Workflow', w.id)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
|
||||
const mockUpdate = vi.fn()
|
||||
const mockAdapter = { update: mockUpdate }
|
||||
@@ -20,7 +21,7 @@ describe('updateWorkflow', () => {
|
||||
])('should update $id', async ({ id, updates }) => {
|
||||
mockUpdate.mockResolvedValue(undefined)
|
||||
|
||||
await updateWorkflow(id, updates as any)
|
||||
await updateWorkflow(id, updates as Partial<Workflow>)
|
||||
|
||||
expect(mockUpdate).toHaveBeenCalledWith('Workflow', id, expect.any(Object))
|
||||
})
|
||||
|
||||
@@ -9,5 +9,6 @@
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": []
|
||||
}
|
||||
},
|
||||
"minLevel": 4
|
||||
}
|
||||
@@ -9,5 +9,6 @@
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -8,7 +8,17 @@
|
||||
"category": "editors",
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"scripts": ["json", "lua", "theme"],
|
||||
"components": ["CodeEditor", "JsonEditor", "LuaEditor", "ThemeEditor"]
|
||||
}
|
||||
}
|
||||
"scripts": [
|
||||
"json",
|
||||
"lua",
|
||||
"theme"
|
||||
],
|
||||
"components": [
|
||||
"CodeEditor",
|
||||
"JsonEditor",
|
||||
"LuaEditor",
|
||||
"ThemeEditor"
|
||||
]
|
||||
},
|
||||
"minLevel": 5
|
||||
}
|
||||
@@ -9,5 +9,6 @@
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 5
|
||||
}
|
||||
@@ -8,7 +8,15 @@
|
||||
"category": "ui",
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": ["StatCard", "DashboardGrid", "Widget"],
|
||||
"scripts": ["stats", "layout"]
|
||||
}
|
||||
"components": [
|
||||
"StatCard",
|
||||
"DashboardGrid",
|
||||
"Widget"
|
||||
],
|
||||
"scripts": [
|
||||
"stats",
|
||||
"layout"
|
||||
]
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -9,5 +9,6 @@
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": []
|
||||
}
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -8,7 +8,17 @@
|
||||
"category": "ui",
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": ["FormField", "EmailField", "PasswordField", "NumberField", "SearchBar"],
|
||||
"scripts": ["fields", "validate"]
|
||||
}
|
||||
"components": [
|
||||
"FormField",
|
||||
"EmailField",
|
||||
"PasswordField",
|
||||
"NumberField",
|
||||
"SearchBar"
|
||||
],
|
||||
"scripts": [
|
||||
"fields",
|
||||
"validate"
|
||||
]
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -9,5 +9,6 @@
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -6,9 +6,19 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions"],
|
||||
"dependencies": [
|
||||
"ui_permissions"
|
||||
],
|
||||
"exports": {
|
||||
"components": ["Sidebar", "NavigationMenu", "Breadcrumbs"],
|
||||
"scripts": ["sidebar", "menu"]
|
||||
}
|
||||
"components": [
|
||||
"Sidebar",
|
||||
"NavigationMenu",
|
||||
"Breadcrumbs"
|
||||
],
|
||||
"scripts": [
|
||||
"sidebar",
|
||||
"menu"
|
||||
]
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -9,5 +9,6 @@
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": []
|
||||
}
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -6,9 +6,20 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "editors",
|
||||
"dependencies": ["form_builder"],
|
||||
"dependencies": [
|
||||
"form_builder"
|
||||
],
|
||||
"exports": {
|
||||
"scripts": ["fields", "tables", "relations"],
|
||||
"components": ["SchemaEditor", "TableEditor", "FieldEditor"]
|
||||
}
|
||||
}
|
||||
"scripts": [
|
||||
"fields",
|
||||
"tables",
|
||||
"relations"
|
||||
],
|
||||
"components": [
|
||||
"SchemaEditor",
|
||||
"TableEditor",
|
||||
"FieldEditor"
|
||||
]
|
||||
},
|
||||
"minLevel": 5
|
||||
}
|
||||
@@ -39,5 +39,6 @@
|
||||
"social_hub_feed_post_2_body",
|
||||
"social_hub_feed_post_2_badge"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -9,5 +9,6 @@
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -6,9 +6,19 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions"],
|
||||
"dependencies": [
|
||||
"ui_permissions"
|
||||
],
|
||||
"exports": {
|
||||
"components": ["AccessDenied", "AuthGate", "PageLoader"],
|
||||
"scripts": ["denied", "gate"]
|
||||
}
|
||||
}
|
||||
"components": [
|
||||
"AccessDenied",
|
||||
"AuthGate",
|
||||
"PageLoader"
|
||||
],
|
||||
"scripts": [
|
||||
"denied",
|
||||
"gate"
|
||||
]
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -8,7 +8,15 @@
|
||||
"category": "ui",
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": ["ConfirmDialog", "AlertDialog", "FormDialog"],
|
||||
"scripts": ["confirm", "alert"]
|
||||
}
|
||||
}
|
||||
"components": [
|
||||
"ConfirmDialog",
|
||||
"AlertDialog",
|
||||
"FormDialog"
|
||||
],
|
||||
"scripts": [
|
||||
"confirm",
|
||||
"alert"
|
||||
]
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -8,8 +8,13 @@
|
||||
"category": "ui",
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": ["AppFooter"],
|
||||
"scripts": ["footer"],
|
||||
"components": [
|
||||
"AppFooter"
|
||||
],
|
||||
"scripts": [
|
||||
"footer"
|
||||
],
|
||||
"pages": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -6,10 +6,17 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions"],
|
||||
"dependencies": [
|
||||
"ui_permissions"
|
||||
],
|
||||
"exports": {
|
||||
"components": ["AppHeader"],
|
||||
"scripts": ["header"],
|
||||
"components": [
|
||||
"AppHeader"
|
||||
],
|
||||
"scripts": [
|
||||
"header"
|
||||
],
|
||||
"pages": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -6,10 +6,18 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions"],
|
||||
"dependencies": [
|
||||
"ui_permissions"
|
||||
],
|
||||
"exports": {
|
||||
"pages": ["level1"],
|
||||
"scripts": ["home_ui", "navigate"],
|
||||
"pages": [
|
||||
"level1"
|
||||
],
|
||||
"scripts": [
|
||||
"home_ui",
|
||||
"navigate"
|
||||
],
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -8,8 +8,13 @@
|
||||
"category": "ui",
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"components": ["IntroSection"],
|
||||
"scripts": ["intro"],
|
||||
"components": [
|
||||
"IntroSection"
|
||||
],
|
||||
"scripts": [
|
||||
"intro"
|
||||
],
|
||||
"pages": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -6,10 +6,21 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions", "ui_header", "ui_intro"],
|
||||
"dependencies": [
|
||||
"ui_permissions",
|
||||
"ui_header",
|
||||
"ui_intro"
|
||||
],
|
||||
"exports": {
|
||||
"pages": ["level2"],
|
||||
"scripts": ["layout", "profile", "comments"],
|
||||
"pages": [
|
||||
"level2"
|
||||
],
|
||||
"scripts": [
|
||||
"layout",
|
||||
"profile",
|
||||
"comments"
|
||||
],
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 2
|
||||
}
|
||||
@@ -6,10 +6,21 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions", "ui_header", "ui_intro"],
|
||||
"dependencies": [
|
||||
"ui_permissions",
|
||||
"ui_header",
|
||||
"ui_intro"
|
||||
],
|
||||
"exports": {
|
||||
"pages": ["level3"],
|
||||
"scripts": ["layout", "users", "moderation"],
|
||||
"pages": [
|
||||
"level3"
|
||||
],
|
||||
"scripts": [
|
||||
"layout",
|
||||
"users",
|
||||
"moderation"
|
||||
],
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 3
|
||||
}
|
||||
@@ -6,10 +6,21 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions", "ui_header", "ui_intro"],
|
||||
"dependencies": [
|
||||
"ui_permissions",
|
||||
"ui_header",
|
||||
"ui_intro"
|
||||
],
|
||||
"exports": {
|
||||
"pages": ["level4"],
|
||||
"scripts": ["layout", "schemas", "workflows"],
|
||||
"pages": [
|
||||
"level4"
|
||||
],
|
||||
"scripts": [
|
||||
"layout",
|
||||
"schemas",
|
||||
"workflows"
|
||||
],
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 4
|
||||
}
|
||||
@@ -6,10 +6,21 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions", "ui_header", "ui_intro"],
|
||||
"dependencies": [
|
||||
"ui_permissions",
|
||||
"ui_header",
|
||||
"ui_intro"
|
||||
],
|
||||
"exports": {
|
||||
"pages": ["level5"],
|
||||
"scripts": ["layout", "tenants", "transfer"],
|
||||
"pages": [
|
||||
"level5"
|
||||
],
|
||||
"scripts": [
|
||||
"layout",
|
||||
"tenants",
|
||||
"transfer"
|
||||
],
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 5
|
||||
}
|
||||
@@ -6,10 +6,18 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "ui",
|
||||
"dependencies": ["ui_permissions"],
|
||||
"dependencies": [
|
||||
"ui_permissions"
|
||||
],
|
||||
"exports": {
|
||||
"pages": ["login"],
|
||||
"scripts": ["login_ui", "login_actions"],
|
||||
"pages": [
|
||||
"login"
|
||||
],
|
||||
"scripts": [
|
||||
"login_ui",
|
||||
"login_actions"
|
||||
],
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -22,5 +22,6 @@
|
||||
"pages": [],
|
||||
"scripts": [],
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -8,7 +8,10 @@
|
||||
"category": "ui",
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"scripts": ["permissions"],
|
||||
"scripts": [
|
||||
"permissions"
|
||||
],
|
||||
"components": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"minLevel": 1
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
-- Permission level constants (5-level system)
|
||||
-- Permission level constants (6-level system)
|
||||
return {
|
||||
PUBLIC = 1,
|
||||
USER = 2,
|
||||
ADMIN = 3,
|
||||
GOD = 4,
|
||||
SUPERGOD = 5
|
||||
MODERATOR = 3,
|
||||
ADMIN = 4,
|
||||
GOD = 5,
|
||||
SUPERGOD = 6
|
||||
}
|
||||
|
||||
@@ -6,9 +6,20 @@
|
||||
"icon": "static_content/icon.svg",
|
||||
"author": "MetaBuilder",
|
||||
"category": "managers",
|
||||
"dependencies": ["ui_permissions", "data_table"],
|
||||
"dependencies": [
|
||||
"ui_permissions",
|
||||
"data_table"
|
||||
],
|
||||
"exports": {
|
||||
"scripts": ["list", "actions"],
|
||||
"components": ["UserManagement", "UserList", "UserActions"]
|
||||
}
|
||||
}
|
||||
"scripts": [
|
||||
"list",
|
||||
"actions"
|
||||
],
|
||||
"components": [
|
||||
"UserManagement",
|
||||
"UserList",
|
||||
"UserActions"
|
||||
]
|
||||
},
|
||||
"minLevel": 4
|
||||
}
|
||||
@@ -8,7 +8,16 @@
|
||||
"category": "editors",
|
||||
"dependencies": [],
|
||||
"exports": {
|
||||
"scripts": ["editor", "status", "run"],
|
||||
"components": ["WorkflowEditor", "WorkflowRunCard", "WorkflowRunStatus"]
|
||||
}
|
||||
}
|
||||
"scripts": [
|
||||
"editor",
|
||||
"status",
|
||||
"run"
|
||||
],
|
||||
"components": [
|
||||
"WorkflowEditor",
|
||||
"WorkflowRunCard",
|
||||
"WorkflowRunStatus"
|
||||
]
|
||||
},
|
||||
"minLevel": 5
|
||||
}
|
||||
Reference in New Issue
Block a user