fix(backend): add detailed schema to fetch-rss
endpoint (#13764)
This commit is contained in:
parent
e2ff5f58b2
commit
2ff90a80d4
5 changed files with 234 additions and 11 deletions
|
@ -20,13 +20,188 @@ export const meta = {
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
image: {
|
||||||
|
type: 'object',
|
||||||
|
optional: true,
|
||||||
|
properties: {
|
||||||
|
link: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
type: 'string',
|
||||||
|
optional: false,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
paginationLinks: {
|
||||||
|
type: 'object',
|
||||||
|
optional: true,
|
||||||
|
properties: {
|
||||||
|
self: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
first: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
next: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
prev: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
items: {
|
items: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
optional: false,
|
||||||
items: {
|
items: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
link: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
guid: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
pubDate: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
creator: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
summary: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
isoDate: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
categories: {
|
||||||
|
type: 'array',
|
||||||
|
optional: true,
|
||||||
|
items: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
contentSnippet: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
enclosure: {
|
||||||
|
type: 'object',
|
||||||
|
optional: true,
|
||||||
|
properties: {
|
||||||
|
url: {
|
||||||
|
type: 'string',
|
||||||
|
optional: false,
|
||||||
|
},
|
||||||
|
length: {
|
||||||
|
type: 'number',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
feedUrl: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
itunes: {
|
||||||
|
type: 'object',
|
||||||
|
optional: true,
|
||||||
|
additionalProperties: true,
|
||||||
|
properties: {
|
||||||
|
image: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
owner: {
|
||||||
|
type: 'object',
|
||||||
|
optional: true,
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
summary: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
explicit: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
categories: {
|
||||||
|
type: 'array',
|
||||||
|
optional: true,
|
||||||
|
items: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keywords: {
|
||||||
|
type: 'array',
|
||||||
|
optional: true,
|
||||||
|
items: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
import MarqueeText from '@/components/MkMarquee.vue';
|
import MarqueeText from '@/components/MkMarquee.vue';
|
||||||
import { useInterval } from '@/scripts/use-interval.js';
|
import { useInterval } from '@/scripts/use-interval.js';
|
||||||
import { shuffle } from '@/scripts/shuffle.js';
|
import { shuffle } from '@/scripts/shuffle.js';
|
||||||
|
@ -42,13 +43,13 @@ const props = defineProps<{
|
||||||
refreshIntervalSec?: number;
|
refreshIntervalSec?: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const items = ref([]);
|
const items = ref<Misskey.entities.FetchRssResponse['items']>([]);
|
||||||
const fetching = ref(true);
|
const fetching = ref(true);
|
||||||
const key = ref(0);
|
const key = ref(0);
|
||||||
|
|
||||||
const tick = () => {
|
const tick = () => {
|
||||||
window.fetch(`/api/fetch-rss?url=${props.url}`, {}).then(res => {
|
window.fetch(`/api/fetch-rss?url=${props.url}`, {}).then(res => {
|
||||||
res.json().then(feed => {
|
res.json().then((feed: Misskey.entities.FetchRssResponse) => {
|
||||||
if (props.shuffle) {
|
if (props.shuffle) {
|
||||||
shuffle(feed.items);
|
shuffle(feed.items);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch, computed } from 'vue';
|
import { ref, watch, computed } from 'vue';
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
import { useWidgetPropsManager, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
import { useWidgetPropsManager, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
||||||
import { GetFormResultType } from '@/scripts/form.js';
|
import { GetFormResultType } from '@/scripts/form.js';
|
||||||
import MkContainer from '@/components/MkContainer.vue';
|
import MkContainer from '@/components/MkContainer.vue';
|
||||||
|
@ -64,7 +65,7 @@ const { widgetProps, configure } = useWidgetPropsManager(name,
|
||||||
emit,
|
emit,
|
||||||
);
|
);
|
||||||
|
|
||||||
const rawItems = ref([]);
|
const rawItems = ref<Misskey.entities.FetchRssResponse['items']>([]);
|
||||||
const items = computed(() => rawItems.value.slice(0, widgetProps.maxEntries));
|
const items = computed(() => rawItems.value.slice(0, widgetProps.maxEntries));
|
||||||
const fetching = ref(true);
|
const fetching = ref(true);
|
||||||
const fetchEndpoint = computed(() => {
|
const fetchEndpoint = computed(() => {
|
||||||
|
@ -79,8 +80,8 @@ const tick = () => {
|
||||||
|
|
||||||
window.fetch(fetchEndpoint.value, {})
|
window.fetch(fetchEndpoint.value, {})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(feed => {
|
.then((feed: Misskey.entities.FetchRssResponse) => {
|
||||||
rawItems.value = feed.items ?? [];
|
rawItems.value = feed.items;
|
||||||
fetching.value = false;
|
fetching.value = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch, computed } from 'vue';
|
import { ref, watch, computed } from 'vue';
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
import { useWidgetPropsManager, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
import { useWidgetPropsManager, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
|
||||||
import MarqueeText from '@/components/MkMarquee.vue';
|
import MarqueeText from '@/components/MkMarquee.vue';
|
||||||
import { GetFormResultType } from '@/scripts/form.js';
|
import { GetFormResultType } from '@/scripts/form.js';
|
||||||
|
@ -87,7 +88,7 @@ const { widgetProps, configure } = useWidgetPropsManager(name,
|
||||||
emit,
|
emit,
|
||||||
);
|
);
|
||||||
|
|
||||||
const rawItems = ref([]);
|
const rawItems = ref<Misskey.entities.FetchRssResponse['items']>([]);
|
||||||
const items = computed(() => {
|
const items = computed(() => {
|
||||||
const newItems = rawItems.value.slice(0, widgetProps.maxEntries);
|
const newItems = rawItems.value.slice(0, widgetProps.maxEntries);
|
||||||
if (widgetProps.shuffle) {
|
if (widgetProps.shuffle) {
|
||||||
|
@ -110,8 +111,8 @@ const tick = () => {
|
||||||
|
|
||||||
window.fetch(fetchEndpoint.value, {})
|
window.fetch(fetchEndpoint.value, {})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(feed => {
|
.then((feed: Misskey.entities.FetchRssResponse) => {
|
||||||
rawItems.value = feed.items ?? [];
|
rawItems.value = feed.items;
|
||||||
fetching.value = false;
|
fetching.value = false;
|
||||||
key.value++;
|
key.value++;
|
||||||
});
|
});
|
||||||
|
|
|
@ -26065,7 +26065,52 @@ export type operations = {
|
||||||
200: {
|
200: {
|
||||||
content: {
|
content: {
|
||||||
'application/json': {
|
'application/json': {
|
||||||
items: Record<string, never>[];
|
image?: {
|
||||||
|
link?: string;
|
||||||
|
url: string;
|
||||||
|
title?: string;
|
||||||
|
};
|
||||||
|
paginationLinks?: {
|
||||||
|
self?: string;
|
||||||
|
first?: string;
|
||||||
|
next?: string;
|
||||||
|
last?: string;
|
||||||
|
prev?: string;
|
||||||
|
};
|
||||||
|
link?: string;
|
||||||
|
title?: string;
|
||||||
|
items: {
|
||||||
|
link?: string;
|
||||||
|
guid?: string;
|
||||||
|
title?: string;
|
||||||
|
pubDate?: string;
|
||||||
|
creator?: string;
|
||||||
|
summary?: string;
|
||||||
|
content?: string;
|
||||||
|
isoDate?: string;
|
||||||
|
categories?: string[];
|
||||||
|
contentSnippet?: string;
|
||||||
|
enclosure?: {
|
||||||
|
url: string;
|
||||||
|
length?: number;
|
||||||
|
type?: string;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
feedUrl?: string;
|
||||||
|
description?: string;
|
||||||
|
itunes?: {
|
||||||
|
image?: string;
|
||||||
|
owner?: {
|
||||||
|
name?: string;
|
||||||
|
email?: string;
|
||||||
|
};
|
||||||
|
author?: string;
|
||||||
|
summary?: string;
|
||||||
|
explicit?: string;
|
||||||
|
categories?: string[];
|
||||||
|
keywords?: string[];
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue