mirror of
https://github.com/bs-community/blessing-skin-plugins.git
synced 2025-01-08 11:37:27 +08:00
inline globals
This commit is contained in:
parent
7aee47ae0e
commit
d8c71c616b
@ -2,12 +2,12 @@
|
|||||||
"preset": "ts-jest",
|
"preset": "ts-jest",
|
||||||
"resetMocks": true,
|
"resetMocks": true,
|
||||||
"timers": "modern",
|
"timers": "modern",
|
||||||
"moduleNameMapper": {
|
|
||||||
"blessing-skin": "<rootDir>/types.ts"
|
|
||||||
},
|
|
||||||
"transform": {
|
"transform": {
|
||||||
"^.+\\.svelte$": "@gplane/svelte-jest",
|
"^.+\\.svelte$": "@gplane/svelte-jest",
|
||||||
"^.+\\.tsx?$": "ts-jest"
|
"^.+\\.tsx?$": "ts-jest"
|
||||||
},
|
},
|
||||||
"setupFilesAfterEnv": ["@testing-library/jest-dom/extend-expect"]
|
"setupFilesAfterEnv": [
|
||||||
|
"@testing-library/jest-dom/extend-expect",
|
||||||
|
"<rootDir>/setup-test.ts"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import hljs from 'highlight.js/lib/core'
|
import hljs from 'highlight.js/lib/core'
|
||||||
import json from 'highlight.js/lib/languages/json'
|
import json from 'highlight.js/lib/languages/json'
|
||||||
import { site_name, base_url } from 'blessing-skin'
|
|
||||||
|
|
||||||
hljs.registerLanguage('json', json)
|
hljs.registerLanguage('json', json)
|
||||||
|
|
||||||
@ -10,14 +9,14 @@ document
|
|||||||
.querySelector('#download-extra-list')
|
.querySelector('#download-extra-list')
|
||||||
?.addEventListener('click', () => {
|
?.addEventListener('click', () => {
|
||||||
const content = JSON.stringify({
|
const content = JSON.stringify({
|
||||||
name: site_name,
|
name: globalThis.blessing.site_name,
|
||||||
type: 'CustomSkinAPI',
|
type: 'CustomSkinAPI',
|
||||||
root: `${base_url}/csl/`,
|
root: `${globalThis.blessing.base_url}/csl/`,
|
||||||
})
|
})
|
||||||
|
|
||||||
const a = document.createElement('a')
|
const a = document.createElement('a')
|
||||||
const blob = new Blob([content], { type: 'application/json' })
|
const blob = new Blob([content], { type: 'application/json' })
|
||||||
a.download = `${site_name}.json`
|
a.download = `${globalThis.blessing.site_name}.json`
|
||||||
a.href = URL.createObjectURL(blob)
|
a.href = URL.createObjectURL(blob)
|
||||||
a.click()
|
a.click()
|
||||||
a.remove()
|
a.remove()
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { base_url, t } from 'blessing-skin'
|
|
||||||
|
|
||||||
const button = document.querySelector<HTMLAnchorElement>('.main-button')
|
const button = document.querySelector<HTMLAnchorElement>('.main-button')
|
||||||
if (button && button.href.endsWith('/auth/register')) {
|
if (button && button.href.endsWith('/auth/register')) {
|
||||||
button.textContent = t('auth.login')
|
button.textContent = globalThis.blessing.t('auth.login')
|
||||||
const url = new URL(base_url)
|
const url = new URL(globalThis.blessing.base_url)
|
||||||
url.pathname = '/auth/login'
|
url.pathname = '/auth/login'
|
||||||
button.href = url.toString()
|
button.href = url.toString()
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
import { fetch, notify } from 'blessing-skin'
|
|
||||||
|
|
||||||
document.querySelector('#update-uuid')?.addEventListener('click', async () => {
|
document.querySelector('#update-uuid')?.addEventListener('click', async () => {
|
||||||
const { code, message }: { code: null; message: string } = await fetch.post(
|
const { code, message }: { code: null; message: string } =
|
||||||
'/mojang/update-uuid',
|
await globalThis.blessing.fetch.post('/mojang/update-uuid')
|
||||||
)
|
const { toast } = globalThis.blessing.notify
|
||||||
const { toast } = notify
|
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
toast.success(message)
|
toast.success(message)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { nanoid } from 'nanoid'
|
import { nanoid } from 'nanoid'
|
||||||
import { fetch, t, notify } from 'blessing-skin'
|
|
||||||
import DomainsList from './DomainsList.svelte'
|
import DomainsList from './DomainsList.svelte'
|
||||||
|
|
||||||
|
const { fetch, t, notify } = globalThis.blessing
|
||||||
|
|
||||||
type Item = { id: string; value: string }
|
type Item = { id: string; value: string }
|
||||||
|
|
||||||
let isLoading = true
|
let isLoading = true
|
||||||
@ -13,12 +14,8 @@
|
|||||||
let isDenyListDirty = false
|
let isDenyListDirty = false
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const {
|
const { allow, deny }: { allow: string[]; deny: string[] } =
|
||||||
allow,
|
await fetch.get('/admin/restricted-email-domains')
|
||||||
deny,
|
|
||||||
}: { allow: string[]; deny: string[] } = await fetch.get(
|
|
||||||
'/admin/restricted-email-domains',
|
|
||||||
)
|
|
||||||
allowList = allow.map((value) => ({ id: nanoid(), value }))
|
allowList = allow.map((value) => ({ id: nanoid(), value }))
|
||||||
denyList = deny.map((value) => ({ id: nanoid(), value }))
|
denyList = deny.map((value) => ({ id: nanoid(), value }))
|
||||||
isLoading = false
|
isLoading = false
|
||||||
@ -80,7 +77,8 @@
|
|||||||
on:edit={() => (isAllowListDirty = true)}
|
on:edit={() => (isAllowListDirty = true)}
|
||||||
on:add={createAllowItem}
|
on:add={createAllowItem}
|
||||||
on:remove={(event) => removeAllowItem(event.detail)}
|
on:remove={(event) => removeAllowItem(event.detail)}
|
||||||
on:save={saveAllowList} />
|
on:save={saveAllowList}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<DomainsList
|
<DomainsList
|
||||||
@ -92,6 +90,7 @@
|
|||||||
on:edit={() => (isDenyListDirty = true)}
|
on:edit={() => (isDenyListDirty = true)}
|
||||||
on:add={createDenyItem}
|
on:add={createDenyItem}
|
||||||
on:remove={(event) => removeDenyItem(event.detail)}
|
on:remove={(event) => removeDenyItem(event.detail)}
|
||||||
on:save={saveDenyList} />
|
on:save={saveDenyList}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import { t } from 'blessing-skin'
|
|
||||||
|
const { t } = globalThis.blessing
|
||||||
|
|
||||||
type Item = { id: string; value: string }
|
type Item = { id: string; value: string }
|
||||||
|
|
||||||
@ -37,11 +38,13 @@
|
|||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
bind:value={item.value}
|
bind:value={item.value}
|
||||||
on:input={() => dispath('edit')} />
|
on:input={() => dispath('edit')}
|
||||||
|
/>
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
<button
|
<button
|
||||||
class="btn btn-secondary"
|
class="btn btn-secondary"
|
||||||
on:click={() => dispath('remove', item.id)}>
|
on:click={() => dispath('remove', item.id)}
|
||||||
|
>
|
||||||
<i class="fas fa-trash" />
|
<i class="fas fa-trash" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import { event } from 'blessing-skin'
|
globalThis.blessing.event.on(
|
||||||
|
'emailDomainsSuggestion',
|
||||||
|
(domains: Set<string>) => {
|
||||||
|
const allowListJSON = document.querySelector('#allowed-email-domains')
|
||||||
|
if (!allowListJSON) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
event.on('emailDomainsSuggestion', (domains: Set<string>) => {
|
const allowList: string[] = JSON.parse(allowListJSON.textContent ?? '[]')
|
||||||
const allowListJSON = document.querySelector('#allowed-email-domains')
|
if (allowList.length > 0) {
|
||||||
if (!allowListJSON) {
|
domains.clear()
|
||||||
return
|
allowList.forEach((domain) => domains.add(domain))
|
||||||
}
|
}
|
||||||
|
},
|
||||||
const allowList: string[] = JSON.parse(allowListJSON.textContent ?? '[]')
|
)
|
||||||
if (allowList.length > 0) {
|
|
||||||
domains.clear()
|
|
||||||
allowList.forEach((domain) => domains.add(domain))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { event } from 'blessing-skin'
|
globalThis.blessing.event.on(
|
||||||
|
'beforeFetch',
|
||||||
event.on('beforeFetch', (request: { data: Record<string, string> }) => {
|
(request: { data: Record<string, string> }) => {
|
||||||
const search = new URLSearchParams(location.search)
|
const search = new URLSearchParams(location.search)
|
||||||
request.data.share = search.get('share') || ''
|
request.data.share = search.get('share') || ''
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { fetch, t, notify } from 'blessing-skin'
|
|
||||||
|
const { fetch, t, notify } = globalThis.blessing
|
||||||
|
|
||||||
let description = ''
|
let description = ''
|
||||||
let raw = ''
|
let raw = ''
|
||||||
@ -51,23 +52,6 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
description-content :global(h1),
|
|
||||||
description-content :global(h2) {
|
|
||||||
padding-bottom: 0.3rem;
|
|
||||||
border-bottom: 1px solid #eaecef;
|
|
||||||
}
|
|
||||||
|
|
||||||
description-content :global(blockquote) {
|
|
||||||
color: #aaa;
|
|
||||||
border-left: 0.3rem solid #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
description-content :global(hr) {
|
|
||||||
border-top-width: 4px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
{#if canEdit || !isEmptyDescription}
|
{#if canEdit || !isEmptyDescription}
|
||||||
<div class="card card-secondary">
|
<div class="card card-secondary">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
@ -77,7 +61,8 @@
|
|||||||
<button
|
<button
|
||||||
class="btn btn-secondary btn-sm float-right"
|
class="btn btn-secondary btn-sm float-right"
|
||||||
title={t('texture-description.edit')}
|
title={t('texture-description.edit')}
|
||||||
on:click={editDescription}>
|
on:click={editDescription}
|
||||||
|
>
|
||||||
<i class="fas fa-edit" />
|
<i class="fas fa-edit" />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
@ -107,7 +92,8 @@
|
|||||||
<button
|
<button
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
disabled={isSubmitting || isLengthExceeded}
|
disabled={isSubmitting || isLengthExceeded}
|
||||||
on:click={submitDescription}>
|
on:click={submitDescription}
|
||||||
|
>
|
||||||
{#if isSubmitting}
|
{#if isSubmitting}
|
||||||
<span>
|
<span>
|
||||||
<i class="fas fa-sync fa-spin" />
|
<i class="fas fa-sync fa-spin" />
|
||||||
@ -117,7 +103,8 @@
|
|||||||
<button
|
<button
|
||||||
class="btn btn-secondary"
|
class="btn btn-secondary"
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
on:click={() => (isEditing = false)}>
|
on:click={() => (isEditing = false)}
|
||||||
|
>
|
||||||
{t('general.cancel')}
|
{t('general.cancel')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -125,3 +112,20 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
description-content :global(h1),
|
||||||
|
description-content :global(h2) {
|
||||||
|
padding-bottom: 0.3rem;
|
||||||
|
border-bottom: 1px solid #eaecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
description-content :global(blockquote) {
|
||||||
|
color: #aaa;
|
||||||
|
border-left: 0.3rem solid #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
description-content :global(hr) {
|
||||||
|
border-top-width: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { render, fireEvent, waitFor } from '@testing-library/svelte'
|
import { render, fireEvent, waitFor } from '@testing-library/svelte'
|
||||||
import { tick } from 'svelte'
|
import { tick } from 'svelte'
|
||||||
import { fetch, t } from 'blessing-skin'
|
|
||||||
import Description from './Description.svelte'
|
import Description from './Description.svelte'
|
||||||
|
|
||||||
|
const { fetch, t } = globalThis.blessing
|
||||||
|
|
||||||
test('render description', async () => {
|
test('render description', async () => {
|
||||||
const spy = jest.spyOn(fetch, 'get').mockResolvedValue('<div id="md"></div>')
|
const spy = jest.spyOn(fetch, 'get').mockResolvedValue('<div id="md"></div>')
|
||||||
render(Description, { props: { tid: 1 } })
|
render(Description, { props: { tid: 1 } })
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, onDestroy } from 'svelte'
|
import { onMount, onDestroy } from 'svelte'
|
||||||
import { event, t } from 'blessing-skin'
|
|
||||||
|
const { event, t } = globalThis.blessing
|
||||||
|
|
||||||
let description = ''
|
let description = ''
|
||||||
export let maxLength = Infinity
|
export let maxLength = Infinity
|
||||||
@ -18,7 +19,8 @@
|
|||||||
id="description-editor"
|
id="description-editor"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
rows="9"
|
rows="9"
|
||||||
bind:value={description} />
|
bind:value={description}
|
||||||
|
/>
|
||||||
{#if description.length > maxLength}
|
{#if description.length > maxLength}
|
||||||
<div class="alert alert-info mt-2">
|
<div class="alert alert-info mt-2">
|
||||||
{t('texture-description.exceeded', { max: maxLength })}
|
{t('texture-description.exceeded', { max: maxLength })}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { render, fireEvent } from '@testing-library/svelte'
|
import { render, fireEvent } from '@testing-library/svelte'
|
||||||
import { tick } from 'svelte'
|
import { tick } from 'svelte'
|
||||||
import { event, t } from 'blessing-skin'
|
|
||||||
import UploadEditor from './UploadEditor.svelte'
|
import UploadEditor from './UploadEditor.svelte'
|
||||||
|
|
||||||
|
const { event, t } = globalThis.blessing
|
||||||
|
|
||||||
test('submit data', () => {
|
test('submit data', () => {
|
||||||
const { getByLabelText } = render(UploadEditor)
|
const { getByLabelText } = render(UploadEditor)
|
||||||
fireEvent.input(getByLabelText(t('texture-description.description')), {
|
fireEvent.input(getByLabelText(t('texture-description.description')), {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { event } from 'blessing-skin'
|
|
||||||
import UploadEditor from './UploadEditor.svelte'
|
import UploadEditor from './UploadEditor.svelte'
|
||||||
|
|
||||||
event.on('mounted', () => {
|
globalThis.blessing.event.on('mounted', () => {
|
||||||
const input = document.querySelector<HTMLInputElement>('#description-limit')
|
const input = document.querySelector<HTMLInputElement>('#description-limit')
|
||||||
const maxLength = Number.parseInt(input?.value ?? '0') || Infinity
|
const maxLength = Number.parseInt(input?.value ?? '0') || Infinity
|
||||||
|
|
||||||
|
85
setup-test.ts
Normal file
85
setup-test.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { EventEmitter } from 'events'
|
||||||
|
|
||||||
|
class Toast {
|
||||||
|
success(message: string): void {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
info(message: string): void {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
warning(message: string): void {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
error(message: string): void {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const base_url = '/'
|
||||||
|
const locale = 'en'
|
||||||
|
const site_name = 'Blessing Skin'
|
||||||
|
|
||||||
|
function t(key: string, params?: object): string {
|
||||||
|
const data = params ? `(${JSON.stringify(params)})` : ''
|
||||||
|
|
||||||
|
return key + data
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetch = {
|
||||||
|
async get<T = any>(url: string, params?: Record<string, any>): Promise<T> {
|
||||||
|
url
|
||||||
|
params
|
||||||
|
return {} as T
|
||||||
|
},
|
||||||
|
async post<T = any>(url: string, data?: any): Promise<T> {
|
||||||
|
url
|
||||||
|
data
|
||||||
|
return {} as T
|
||||||
|
},
|
||||||
|
async put<T = any>(url: string, data?: any): Promise<T> {
|
||||||
|
url
|
||||||
|
data
|
||||||
|
return {} as T
|
||||||
|
},
|
||||||
|
async del<T = any>(url: string, data?: any): Promise<T> {
|
||||||
|
url
|
||||||
|
data
|
||||||
|
return {} as T
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const emitter = new EventEmitter()
|
||||||
|
const event = {
|
||||||
|
on(
|
||||||
|
eventName: string | symbol,
|
||||||
|
listener: (...args: any[]) => any,
|
||||||
|
): () => void {
|
||||||
|
emitter.on(eventName, listener)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
emitter.off(eventName, listener)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emit(eventName: string | symbol, payload?: object): void {
|
||||||
|
emitter.emit(eventName, payload)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const notify = {
|
||||||
|
showModal(options?: object): Promise<{ value: string }> {
|
||||||
|
return Promise.resolve({ value: JSON.stringify(options) })
|
||||||
|
},
|
||||||
|
toast: new Toast(),
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(globalThis, {
|
||||||
|
blessing: {
|
||||||
|
base_url,
|
||||||
|
locale,
|
||||||
|
site_name,
|
||||||
|
t,
|
||||||
|
fetch,
|
||||||
|
event,
|
||||||
|
notify,
|
||||||
|
},
|
||||||
|
})
|
@ -11,5 +11,5 @@
|
|||||||
},
|
},
|
||||||
"types": ["svelte", "jest", "node", "@testing-library/jest-dom"]
|
"types": ["svelte", "jest", "node", "@testing-library/jest-dom"]
|
||||||
},
|
},
|
||||||
"include": ["plugins/*/assets", "types.ts"]
|
"include": ["plugins/*/assets", "types.ts", "globals.d.ts"]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user