afdsfdasafsd
This commit is contained in:
parent
8dae161d7c
commit
5fc85b610f
7 changed files with 155 additions and 57 deletions
|
@ -46,11 +46,9 @@
|
|||
"@auth/sveltekit": "^0.2.2",
|
||||
"@ltd/j-toml": "^1.38.0",
|
||||
"@rgossiaux/svelte-headlessui": "^1.0.2",
|
||||
"@xmcl/modrinth": "^1.1.0",
|
||||
"minio": "^7.0.32",
|
||||
"nano": "^10.1.2",
|
||||
"nanoid": "^4.0.1",
|
||||
"octokit": "^2.0.14",
|
||||
"svelte-feather-icons": "^4.0.0",
|
||||
"zod": "^3.20.6"
|
||||
}
|
||||
|
|
65
src/lib/modrinth.ts
Normal file
65
src/lib/modrinth.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
const searchProjectsResponse = z.object({
|
||||
hits: z.object({
|
||||
slug: z.string().regex(/^[\w!@$()`.+,"\-']{3,64}$/),
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
categories: z.string().array().default([]),
|
||||
client_side: z.enum(["required", "optional", "unsupported"]),
|
||||
server_side: z.enum(["required", "optional", "unsupported"]),
|
||||
project_type: z.enum(["mod", "modpack", "resourcepack", "shader"]),
|
||||
downloads: z.number(),
|
||||
icon_url: z.string().url(),
|
||||
color: z.number(),
|
||||
project_id: z.string(),
|
||||
author: z.string(),
|
||||
display_categories: z.string().array().default([]),
|
||||
versions: z.string().array(),
|
||||
follows: z.number(),
|
||||
date_created: z.string().datetime({offset: true}),
|
||||
date_modified: z.string().datetime({offset: true}),
|
||||
latest_version: z.string().optional(),
|
||||
license: z.string(),
|
||||
gallery: z.string().array().default([]),
|
||||
featured_gallery: z.string().optional(),
|
||||
}).array(),
|
||||
offset: z.number(),
|
||||
limit: z.number(),
|
||||
total_hits: z.number()
|
||||
});
|
||||
|
||||
const searchProjectsRequest = z.object({
|
||||
query: z.string().optional(),
|
||||
facets: z.string().regex(/^(categories|versions|license|project_type):(.+)$/).array().array().default([]),
|
||||
index: z.enum(["relevance", "downloads", "follows", "newest", "updated"]).default("relevance"),
|
||||
offset: z.number().default(0),
|
||||
limit: z.number().default(10),
|
||||
filters: z.string().optional()
|
||||
});
|
||||
|
||||
function searchProjectsRequestToUrlParams(request: z.infer<typeof searchProjectsRequest>): URLSearchParams {
|
||||
const params = new URLSearchParams();
|
||||
if (typeof request.query != 'undefined') {
|
||||
params.set("query", request.query);
|
||||
}
|
||||
params.set("facets", JSON.stringify(request.facets));
|
||||
params.set("index", request.index);
|
||||
params.set("offset", request.offset.toString());
|
||||
params.set("limit", request.limit.toString());
|
||||
if (typeof request.filters != 'undefined') {
|
||||
params.set("filters", request.filters);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
export async function searchProjects(request: z.input<typeof searchProjectsRequest>): Promise<z.infer<typeof searchProjectsResponse>> {
|
||||
const parsedRequest = searchProjectsRequest.parse(request);
|
||||
const params = searchProjectsRequestToUrlParams(parsedRequest);
|
||||
const response = await fetch("https://api.modrinth.com/v2/search?" + params.toString(), {
|
||||
headers: {
|
||||
"User-Agent": "NotModdermore/noversion (+https://git.skye.vg/me/not-moddermore/)"
|
||||
}
|
||||
});
|
||||
return searchProjectsResponse.parse(await response.json());
|
||||
}
|
|
@ -5,7 +5,7 @@ import { fileTreeSchema } from '$lib/types-zod';
|
|||
import { get_blobs } from '$lib/utils';
|
||||
import type { Modpack } from '$lib/types';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { minioClient, nano } from '$lib/clients';
|
||||
import { minioClient, nano } from '$lib/server/clients';
|
||||
|
||||
export const actions: Actions = {
|
||||
default: async (event) => {
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
let fileTree: Folder = {
|
||||
type: 'folder',
|
||||
children: {
|
||||
mods: { type: 'folder', children: {
|
||||
"quark.pw.toml": {
|
||||
mods: {
|
||||
type: 'folder',
|
||||
children: {
|
||||
'quark.pw.toml': {
|
||||
type: 'file',
|
||||
inline: true,
|
||||
metafile: true,
|
||||
|
@ -37,9 +39,10 @@ file-id = 4366541
|
|||
project-id = 243121
|
||||
`,
|
||||
sha1: '478805ce54b082dadb1042ccfb46a68cfde3fc35',
|
||||
sha512: '5d364049ff53af2154ccae58dd53d2111ef592b21bff03705314cd6d12378cfeb6376b8bc3065ac59e1c9452447bec0eb345ecc19f0de1a17c20ea374f802f05'
|
||||
sha512:
|
||||
'5d364049ff53af2154ccae58dd53d2111ef592b21bff03705314cd6d12378cfeb6376b8bc3065ac59e1c9452447bec0eb345ecc19f0de1a17c20ea374f802f05'
|
||||
},
|
||||
"waystones.pw.toml": {
|
||||
'waystones.pw.toml': {
|
||||
type: 'file',
|
||||
inline: true,
|
||||
metafile: true,
|
||||
|
@ -58,13 +61,23 @@ mod-id = "LOpKHB2A"
|
|||
version = "2sIhirkG"
|
||||
`,
|
||||
sha1: '25f4b57fbd8a985b4872bb8fdadd14580b0f9f81',
|
||||
sha512: '125fb6fc706363753c1c201192024415a23c1098c8e44d5deeaf5448215d83108b9a9a5aba0a029dd9015eff536dc1da63d16c3be0d7f9e39d6f482b8ce008c3'
|
||||
sha512:
|
||||
'125fb6fc706363753c1c201192024415a23c1098c8e44d5deeaf5448215d83108b9a9a5aba0a029dd9015eff536dc1da63d16c3be0d7f9e39d6f482b8ce008c3'
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
};
|
||||
let blobs: Blob[] = [];
|
||||
let isOpen = false;
|
||||
|
||||
let searchTerm = '';
|
||||
async function search() {
|
||||
// const result = await modrinthClient.searchProjects({
|
||||
// te
|
||||
// })
|
||||
// console.log(result)
|
||||
}
|
||||
</script>
|
||||
|
||||
<TabGroup>
|
||||
|
@ -74,30 +87,32 @@ version = "2sIhirkG"
|
|||
</TabList>
|
||||
<TabPanels>
|
||||
<TabPanel>
|
||||
<h1>Mods <button><PlusIcon /></button></h1>
|
||||
<FlattenedFileList tree={fileTree.children.mods ?? { type: 'folder', children: {} }} />
|
||||
<h1>Mods <button on:click={() => isOpen = true}><PlusIcon /></button></h1>
|
||||
<FlattenedFileList tree={fileTree.children.mods?.type == 'folder'
|
||||
? fileTree.children.mods
|
||||
: { type: 'folder', children: {} }} />
|
||||
<h1>Resource Packs <button><PlusIcon /></button></h1>
|
||||
<FlattenedFileList
|
||||
tree={fileTree.children.resourcepacks ?? { type: 'folder', children: {} }}
|
||||
tree={fileTree.children.resourcepacks?.type == 'folder'
|
||||
? fileTree.children.resourcepacks
|
||||
: { type: 'folder', children: {} }}
|
||||
/>
|
||||
<h1>Shader Packs <button><PlusIcon /></button></h1>
|
||||
<FlattenedFileList tree={fileTree.children.shaderpacks ?? { type: 'folder', children: {} }} />
|
||||
<FlattenedFileList
|
||||
tree={fileTree.children.shaderpacks?.type == 'folder'
|
||||
? fileTree.children.shaderpacks
|
||||
: { type: 'folder', children: {} }}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel>Content 2</TabPanel>
|
||||
<TabPanel>{JSON.stringify(fileTree)}</TabPanel>
|
||||
</TabPanels>
|
||||
</TabGroup>
|
||||
|
||||
<Dialog open={isOpen} on:close={() => (isOpen = false)}>
|
||||
<DialogOverlay />
|
||||
|
||||
<DialogTitle>Deactivate account</DialogTitle>
|
||||
<DialogDescription>This will permanently deactivate your account</DialogDescription>
|
||||
|
||||
<p>
|
||||
Are you sure you want to deactivate your account? All of your data will be permanently removed.
|
||||
This action cannot be undone.
|
||||
</p>
|
||||
|
||||
<button on:click={() => (isOpen = false)}>Deactivate</button>
|
||||
<button on:click={() => (isOpen = false)}>Cancel</button>
|
||||
<Dialog open={isOpen} on:close={() => (isOpen = false)} class="fixed top-0 left-0 w-screen h-screen flex justify-center items-center">
|
||||
<DialogOverlay class="fixed top-0 left-0 bg-base opacity-50 w-screen h-screen" />
|
||||
<div class="z-10 bg-surface0 rounded-xl shadow-xl p-5">
|
||||
<DialogTitle>Add Mod</DialogTitle>
|
||||
<DialogDescription>Add a mod to your modpack</DialogDescription>
|
||||
<input type="text" placeholder="Search" bind:value={searchTerm}><button on:click={search}>Search</button>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<script lang="ts">
|
||||
import type { FileTree, File } from '$lib/types';
|
||||
import type { FileTree, File, Folder } from '$lib/types';
|
||||
import { metafileSchema } from '$lib/packwiz-types';
|
||||
import toml from '@ltd/j-toml';
|
||||
export let tree: FileTree;
|
||||
import { XIcon } from 'svelte-feather-icons';
|
||||
export let tree: Folder;
|
||||
function getFilesRecursively(tree: FileTree): [string[], File][] {
|
||||
if (tree.type == 'file') {
|
||||
return [[[], tree]];
|
||||
|
@ -18,6 +19,17 @@
|
|||
}
|
||||
return result;
|
||||
}
|
||||
function deletePath(path: string[], base: Folder) {
|
||||
if (path.length <= 1) {
|
||||
delete base.children[path[0]];
|
||||
} else {
|
||||
const newBase = base.children[path.shift() ?? ''];
|
||||
if (newBase.type == 'file') {
|
||||
return;
|
||||
}
|
||||
deletePath(path, newBase);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
|
@ -25,7 +37,15 @@
|
|||
<li>
|
||||
{#if mod[1].inline && mod[1].metafile}
|
||||
{@const parsed = metafileSchema.parse(toml.parse(mod[1].content))}
|
||||
<h2>{parsed.name} ({mod[0].join('/')})</h2>
|
||||
<h2>
|
||||
{parsed.name} ({mod[0].join('/')})
|
||||
<button
|
||||
on:click={() => {
|
||||
deletePath(mod[0], tree);
|
||||
tree = tree;
|
||||
}}><XIcon /></button
|
||||
>
|
||||
</h2>
|
||||
{#if parsed.update.curseforge}
|
||||
<a
|
||||
href="https://minecraft.curseforge.com/projects/{parsed.update.curseforge[
|
||||
|
|
Loading…
Reference in a new issue