wip
This commit is contained in:
parent
82526ad4f3
commit
def7959bb3
|
@ -53,6 +53,7 @@
|
|||
- Fix: 絵文字ピッカーでバッテリーの絵文字が複数表示される問題を修正 #12197
|
||||
|
||||
### Server
|
||||
- Feat: Registry APIがサードパーティから利用可能になりました
|
||||
- Enhance: RedisへのTLのキャッシュ(FTT)をオフにできるように
|
||||
- Enhance: フォローしているチャンネルをフォロー解除した時(またはその逆)、タイムラインに反映される間隔を改善
|
||||
- Enhance: プロフィールの自己紹介欄のMFMが連合するようになりました
|
||||
|
|
|
@ -231,6 +231,7 @@ import * as ep___i_registry_keysWithType from './endpoints/i/registry/keys-with-
|
|||
import * as ep___i_registry_keys from './endpoints/i/registry/keys.js';
|
||||
import * as ep___i_registry_remove from './endpoints/i/registry/remove.js';
|
||||
import * as ep___i_registry_scopes from './endpoints/i/registry/scopes.js';
|
||||
import * as ep___i_registry_scopesWithDomain from './endpoints/i/registry/scopes-with-domain.js';
|
||||
import * as ep___i_registry_set from './endpoints/i/registry/set.js';
|
||||
import * as ep___i_revokeToken from './endpoints/i/revoke-token.js';
|
||||
import * as ep___i_signinHistory from './endpoints/i/signin-history.js';
|
||||
|
@ -589,6 +590,7 @@ const $i_registry_keysWithType: Provider = { provide: 'ep:i/registry/keys-with-t
|
|||
const $i_registry_keys: Provider = { provide: 'ep:i/registry/keys', useClass: ep___i_registry_keys.default };
|
||||
const $i_registry_remove: Provider = { provide: 'ep:i/registry/remove', useClass: ep___i_registry_remove.default };
|
||||
const $i_registry_scopes: Provider = { provide: 'ep:i/registry/scopes', useClass: ep___i_registry_scopes.default };
|
||||
const $i_registry_scopesWithDomain: Provider = { provide: 'ep:i/registry/scopes-with-domain', useClass: ep___i_registry_scopesWithDomain.default };
|
||||
const $i_registry_set: Provider = { provide: 'ep:i/registry/set', useClass: ep___i_registry_set.default };
|
||||
const $i_revokeToken: Provider = { provide: 'ep:i/revoke-token', useClass: ep___i_revokeToken.default };
|
||||
const $i_signinHistory: Provider = { provide: 'ep:i/signin-history', useClass: ep___i_signinHistory.default };
|
||||
|
@ -951,6 +953,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
|
|||
$i_registry_keys,
|
||||
$i_registry_remove,
|
||||
$i_registry_scopes,
|
||||
$i_registry_scopesWithDomain,
|
||||
$i_registry_set,
|
||||
$i_revokeToken,
|
||||
$i_signinHistory,
|
||||
|
@ -1307,6 +1310,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
|
|||
$i_registry_keys,
|
||||
$i_registry_remove,
|
||||
$i_registry_scopes,
|
||||
$i_registry_scopesWithDomain,
|
||||
$i_registry_set,
|
||||
$i_revokeToken,
|
||||
$i_signinHistory,
|
||||
|
|
|
@ -231,6 +231,7 @@ import * as ep___i_registry_keysWithType from './endpoints/i/registry/keys-with-
|
|||
import * as ep___i_registry_keys from './endpoints/i/registry/keys.js';
|
||||
import * as ep___i_registry_remove from './endpoints/i/registry/remove.js';
|
||||
import * as ep___i_registry_scopes from './endpoints/i/registry/scopes.js';
|
||||
import * as ep___i_registry_scopesWithDomain from './endpoints/i/registry/scopes-with-domain.js';
|
||||
import * as ep___i_registry_set from './endpoints/i/registry/set.js';
|
||||
import * as ep___i_revokeToken from './endpoints/i/revoke-token.js';
|
||||
import * as ep___i_signinHistory from './endpoints/i/signin-history.js';
|
||||
|
@ -587,6 +588,7 @@ const eps = [
|
|||
['i/registry/keys', ep___i_registry_keys],
|
||||
['i/registry/remove', ep___i_registry_remove],
|
||||
['i/registry/scopes', ep___i_registry_scopes],
|
||||
['i/registry/scopes-with-domain', ep___i_registry_scopesWithDomain],
|
||||
['i/registry/set', ep___i_registry_set],
|
||||
['i/revoke-token', ep___i_revokeToken],
|
||||
['i/signin-history', ep___i_signinHistory],
|
||||
|
|
|
@ -10,8 +10,6 @@ import { DI } from '@/di-symbols.js';
|
|||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -30,11 +28,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.registryItemsRepository)
|
||||
private registryItemsRepository: RegistryItemsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.where('item.domain IS NULL')
|
||||
.andWhere('item.userId = :userId', { userId: me.id })
|
||||
.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
super(meta, paramDef, async (ps, me, accessToken) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item');
|
||||
if (accessToken) {
|
||||
query.where('item.domain = :domain', { domain: accessToken.id });
|
||||
}
|
||||
query.andWhere('item.userId = :userId', { userId: me.id });
|
||||
query.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
|
||||
const items = await query.getMany();
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ import { ApiError } from '../../../error.js';
|
|||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
|
||||
errors: {
|
||||
noSuchKey: {
|
||||
message: 'No such key.',
|
||||
|
@ -30,6 +28,7 @@ export const paramDef = {
|
|||
scope: { type: 'array', default: [], items: {
|
||||
type: 'string', pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
|
||||
} },
|
||||
domain: { type: 'string', nullable: true },
|
||||
},
|
||||
required: ['key'],
|
||||
} as const;
|
||||
|
@ -40,12 +39,20 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.registryItemsRepository)
|
||||
private registryItemsRepository: RegistryItemsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.where('item.domain IS NULL')
|
||||
.andWhere('item.userId = :userId', { userId: me.id })
|
||||
.andWhere('item.key = :key', { key: ps.key })
|
||||
.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
super(meta, paramDef, async (ps, me, accessToken) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item');
|
||||
if (accessToken) {
|
||||
query.where('item.domain = :domain', { domain: accessToken.id });
|
||||
} else {
|
||||
if (ps.domain) {
|
||||
query.where('item.domain = :domain', { domain: ps.domain });
|
||||
} else {
|
||||
query.where('item.domain IS NULL');
|
||||
}
|
||||
}
|
||||
query.andWhere('item.userId = :userId', { userId: me.id });
|
||||
query.andWhere('item.key = :key', { key: ps.key });
|
||||
query.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
|
||||
const item = await query.getOne();
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ import { ApiError } from '../../../error.js';
|
|||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
|
||||
errors: {
|
||||
noSuchKey: {
|
||||
message: 'No such key.',
|
||||
|
@ -40,9 +38,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.registryItemsRepository)
|
||||
private registryItemsRepository: RegistryItemsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(meta, paramDef, async (ps, me, accessToken) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.where('item.domain IS NULL')
|
||||
.where(accessToken == null ? 'item.domain IS NULL' : 'item.domain = :domain', { domain: accessToken?.id })
|
||||
.andWhere('item.userId = :userId', { userId: me.id })
|
||||
.andWhere('item.key = :key', { key: ps.key })
|
||||
.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
|
|
|
@ -10,8 +10,6 @@ import { DI } from '@/di-symbols.js';
|
|||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -20,6 +18,7 @@ export const paramDef = {
|
|||
scope: { type: 'array', default: [], items: {
|
||||
type: 'string', pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
|
||||
} },
|
||||
domain: { type: 'string', nullable: true },
|
||||
},
|
||||
required: [],
|
||||
} as const;
|
||||
|
@ -30,11 +29,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.registryItemsRepository)
|
||||
private registryItemsRepository: RegistryItemsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.where('item.domain IS NULL')
|
||||
.andWhere('item.userId = :userId', { userId: me.id })
|
||||
.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
super(meta, paramDef, async (ps, me, accessToken) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item');
|
||||
if (accessToken) {
|
||||
query.where('item.domain = :domain', { domain: accessToken.id });
|
||||
} else {
|
||||
if (ps.domain) {
|
||||
query.where('item.domain = :domain', { domain: ps.domain });
|
||||
} else {
|
||||
query.where('item.domain IS NULL');
|
||||
}
|
||||
}
|
||||
query.andWhere('item.userId = :userId', { userId: me.id });
|
||||
query.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
|
||||
const items = await query.getMany();
|
||||
|
||||
|
@ -43,13 +50,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
for (const item of items) {
|
||||
const type = typeof item.value;
|
||||
res[item.key] =
|
||||
item.value === null ? 'null' :
|
||||
Array.isArray(item.value) ? 'array' :
|
||||
type === 'number' ? 'number' :
|
||||
type === 'string' ? 'string' :
|
||||
type === 'boolean' ? 'boolean' :
|
||||
type === 'object' ? 'object' :
|
||||
null as never;
|
||||
item.value === null ? 'null' :
|
||||
Array.isArray(item.value) ? 'array' :
|
||||
type === 'number' ? 'number' :
|
||||
type === 'string' ? 'string' :
|
||||
type === 'boolean' ? 'boolean' :
|
||||
type === 'object' ? 'object' :
|
||||
null as never;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -10,8 +10,6 @@ import { DI } from '@/di-symbols.js';
|
|||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -30,10 +28,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.registryItemsRepository)
|
||||
private registryItemsRepository: RegistryItemsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(meta, paramDef, async (ps, me, accessToken) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.select('item.key')
|
||||
.where('item.domain IS NULL')
|
||||
.where(accessToken == null ? 'item.domain IS NULL' : 'item.domain = :domain', { domain: accessToken?.id })
|
||||
.andWhere('item.userId = :userId', { userId: me.id })
|
||||
.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ import { ApiError } from '../../../error.js';
|
|||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
|
||||
errors: {
|
||||
noSuchKey: {
|
||||
message: 'No such key.',
|
||||
|
@ -40,9 +38,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.registryItemsRepository)
|
||||
private registryItemsRepository: RegistryItemsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(meta, paramDef, async (ps, me, accessToken) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.where('item.domain IS NULL')
|
||||
.where(accessToken == null ? 'item.domain IS NULL' : 'item.domain = :domain', { domain: accessToken?.id })
|
||||
.andWhere('item.userId = :userId', { userId: me.id })
|
||||
.andWhere('item.key = :key', { key: ps.key })
|
||||
.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { RegistryItemsRepository } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
secure: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.registryItemsRepository)
|
||||
private registryItemsRepository: RegistryItemsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.select(['item.scope', 'item.domain'])
|
||||
.where('item.userId = :userId', { userId: me.id });
|
||||
|
||||
const items = await query.getMany();
|
||||
|
||||
const res = [] as { domain: string | null; scopes: string[][] }[];
|
||||
|
||||
for (const item of items) {
|
||||
const target = res.find(x => x.domain === item.domain);
|
||||
if (target) {
|
||||
if (target.scopes.some(scope => scope.join('.') === item.scope.join('.'))) continue;
|
||||
target.scopes.push(item.scope);
|
||||
} else {
|
||||
res.push({
|
||||
domain: item.domain,
|
||||
scopes: [item.scope],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -10,8 +10,6 @@ import { DI } from '@/di-symbols.js';
|
|||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -26,10 +24,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.registryItemsRepository)
|
||||
private registryItemsRepository: RegistryItemsRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(meta, paramDef, async (ps, me, accessToken) => {
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.select('item.scope')
|
||||
.where('item.domain IS NULL')
|
||||
.where(accessToken == null ? 'item.domain IS NULL' : 'item.domain = :domain', { domain: accessToken?.id })
|
||||
.andWhere('item.userId = :userId', { userId: me.id });
|
||||
|
||||
const items = await query.getMany();
|
||||
|
|
|
@ -12,8 +12,6 @@ import { DI } from '@/di-symbols.js';
|
|||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
||||
secure: true,
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
@ -37,9 +35,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private idService: IdService,
|
||||
private globalEventService: GlobalEventService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
super(meta, paramDef, async (ps, me, accessToken) => {
|
||||
// TODO: 作成できるキーの数を制限する
|
||||
|
||||
const query = this.registryItemsRepository.createQueryBuilder('item')
|
||||
.where('item.domain IS NULL')
|
||||
.where(accessToken == null ? 'item.domain IS NULL' : 'item.domain = :domain', { domain: accessToken?.id })
|
||||
.andWhere('item.userId = :userId', { userId: me.id })
|
||||
.andWhere('item.key = :key', { key: ps.key })
|
||||
.andWhere('item.scope = :scope', { scope: ps.scope });
|
||||
|
@ -56,19 +56,21 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
id: this.idService.gen(),
|
||||
updatedAt: new Date(),
|
||||
userId: me.id,
|
||||
domain: null,
|
||||
domain: accessToken == null ? null : accessToken.id,
|
||||
scope: ps.scope,
|
||||
key: ps.key,
|
||||
value: ps.value,
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: サードパーティアプリが傍受出来てしまうのでどうにかする
|
||||
this.globalEventService.publishMainStream(me.id, 'registryUpdated', {
|
||||
scope: ps.scope,
|
||||
key: ps.key,
|
||||
value: ps.value,
|
||||
});
|
||||
if (accessToken == null) {
|
||||
// TODO: サードパーティアプリが傍受出来てしまうのでどうにかする
|
||||
this.globalEventService.publishMainStream(me.id, 'registryUpdated', {
|
||||
scope: ps.scope,
|
||||
key: ps.key,
|
||||
value: ps.value,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<FormSplit>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts._registry.domain }}</template>
|
||||
<template #value>{{ i18n.ts.system }}</template>
|
||||
<template #value>{{ props.domain === '@' ? i18n.ts.system : props.domain.toUpperCase() }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts._registry.scope }}</template>
|
||||
|
@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<FormSection v-if="keys">
|
||||
<template #label>{{ i18n.ts.keys }}</template>
|
||||
<div class="_formLinks">
|
||||
<FormLink v-for="key in keys" :to="`/registry/value/system/${scope.join('/')}/${key[0]}`" class="_monospace">{{ key[0] }}<template #suffix>{{ key[1].toUpperCase() }}</template></FormLink>
|
||||
<FormLink v-for="key in keys" :to="`/registry/value/${props.domain}/${scope.join('/')}/${key[0]}`" class="_monospace">{{ key[0] }}<template #suffix>{{ key[1].toUpperCase() }}</template></FormLink>
|
||||
</div>
|
||||
</FormSection>
|
||||
</div>
|
||||
|
@ -46,15 +46,17 @@ import FormSplit from '@/components/form/split.vue';
|
|||
|
||||
const props = defineProps<{
|
||||
path: string;
|
||||
domain: string;
|
||||
}>();
|
||||
|
||||
const scope = $computed(() => props.path.split('/'));
|
||||
const scope = $computed(() => props.path ? props.path.split('/') : []);
|
||||
|
||||
let keys = $ref(null);
|
||||
|
||||
function fetchKeys() {
|
||||
os.api('i/registry/keys-with-type', {
|
||||
scope: scope,
|
||||
domain: props.domain === '@' ? null : props.domain,
|
||||
}).then(res => {
|
||||
keys = Object.entries(res).sort((a, b) => a[0].localeCompare(b[0]));
|
||||
});
|
||||
|
|
|
@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<FormSplit>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts._registry.domain }}</template>
|
||||
<template #value>{{ i18n.ts.system }}</template>
|
||||
<template #value>{{ props.domain === '@' ? i18n.ts.system : props.domain.toUpperCase() }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts._registry.scope }}</template>
|
||||
|
@ -58,6 +58,7 @@ import FormInfo from '@/components/MkInfo.vue';
|
|||
|
||||
const props = defineProps<{
|
||||
path: string;
|
||||
domain: string;
|
||||
}>();
|
||||
|
||||
const scope = $computed(() => props.path.split('/').slice(0, -1));
|
||||
|
@ -70,6 +71,7 @@ function fetchValue() {
|
|||
os.api('i/registry/get-detail', {
|
||||
scope,
|
||||
key,
|
||||
domain: props.domain === '@' ? null : props.domain,
|
||||
}).then(res => {
|
||||
value = res;
|
||||
valueForEditor = JSON5.stringify(res.value, null, '\t');
|
||||
|
|
|
@ -9,12 +9,16 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkSpacer :contentMax="600" :marginMin="16">
|
||||
<MkButton primary @click="createKey">{{ i18n.ts._registry.createKey }}</MkButton>
|
||||
|
||||
<FormSection v-if="scopes">
|
||||
<template #label>{{ i18n.ts.system }}</template>
|
||||
<div class="_formLinks">
|
||||
<FormLink v-for="scope in scopes" :to="`/registry/keys/system/${scope.join('/')}`" class="_monospace">{{ scope.join('/') }}</FormLink>
|
||||
<div v-if="scopesWithDomain">
|
||||
<div v-for="domain in scopesWithDomain" :key="domain.domain">
|
||||
<FormSection>
|
||||
<template #label>{{ domain.domain ? domain.domain.toUpperCase() : i18n.ts.system }}</template>
|
||||
<div class="_formLinks">
|
||||
<FormLink v-for="scope in domain.scopes" :to="`/registry/keys/${domain.domain ?? '@'}/${scope.join('/')}`" class="_monospace">{{ scope.length === 0 ? '(root)' : scope.join('/') }}</FormLink>
|
||||
</div>
|
||||
</FormSection>
|
||||
</div>
|
||||
</FormSection>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
@ -28,11 +32,11 @@ import FormLink from '@/components/form/link.vue';
|
|||
import FormSection from '@/components/form/section.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
|
||||
let scopes = $ref(null);
|
||||
let scopesWithDomain = $ref(null);
|
||||
|
||||
function fetchScopes() {
|
||||
os.api('i/registry/scopes').then(res => {
|
||||
scopes = res.slice().sort((a, b) => a.join('/').localeCompare(b.join('/')));
|
||||
os.api('i/registry/scopes-with-domain').then(res => {
|
||||
scopesWithDomain = res;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import { AsyncComponentLoader, defineAsyncComponent, inject } from 'vue';
|
||||
import { Router } from '@/nirax';
|
||||
import { Router } from '@/nirax.js';
|
||||
import { $i, iAmModerator } from '@/account.js';
|
||||
import MkLoading from '@/pages/_loading_.vue';
|
||||
import MkError from '@/pages/_error_.vue';
|
||||
|
@ -318,10 +318,10 @@ export const routes = [{
|
|||
name: 'avatarDecorations',
|
||||
component: page(() => import('./pages/avatar-decorations.vue')),
|
||||
}, {
|
||||
path: '/registry/keys/system/:path(*)?',
|
||||
path: '/registry/keys/:domain/:path(*)?',
|
||||
component: page(() => import('./pages/registry.keys.vue')),
|
||||
}, {
|
||||
path: '/registry/value/system/:path(*)?',
|
||||
path: '/registry/value/:domain/:path(*)?',
|
||||
component: page(() => import('./pages/registry.value.vue')),
|
||||
}, {
|
||||
path: '/registry',
|
||||
|
|
Loading…
Reference in New Issue