parent
6abbd6b2c0
commit
8dae161d7c
@ -0,0 +1,16 @@
|
||||
import Nano from 'nano';
|
||||
import Minio from 'minio';
|
||||
import {
|
||||
COUCHDB_URL,
|
||||
S3_ACCESS_KEY_ID,
|
||||
S3_ENDPOINT,
|
||||
S3_SECRET_ACCESS_KEY
|
||||
} from '$env/static/private';
|
||||
|
||||
export const nano = Nano(COUCHDB_URL);
|
||||
export const minioClient = new Minio.Client({
|
||||
endPoint: S3_ENDPOINT,
|
||||
useSSL: true,
|
||||
accessKey: S3_ACCESS_KEY_ID,
|
||||
secretKey: S3_SECRET_ACCESS_KEY
|
||||
});
|
@ -0,0 +1,145 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const packSchema = z.object({
|
||||
index: z.object({
|
||||
file: z.string(),
|
||||
'hash-format': z.enum(['sha256', 'sha512', 'sha1', 'md5', 'murmur2']),
|
||||
hash: z.string().regex(/^[a-fA-F0-9]+$/)
|
||||
}),
|
||||
name: z.string(),
|
||||
'pack-format': z.string().default('packwiz:1.0.0'),
|
||||
versions: z.object({
|
||||
minecraft: z.string(),
|
||||
fabric: z.string().optional(),
|
||||
forge: z.string().optional(),
|
||||
liteloader: z.string().optional(),
|
||||
quilt: z.string().optional()
|
||||
}),
|
||||
author: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
version: z.string().optional()
|
||||
});
|
||||
|
||||
export const indexSchema = z.object({
|
||||
'hash-format': z.enum(['sha256', 'sha512', 'sha1', 'md5', 'murmur2']),
|
||||
files: z
|
||||
.object({
|
||||
file: z.string(),
|
||||
hash: z.string().regex(/^[a-fA-F0-9]+$/),
|
||||
alias: z.string(),
|
||||
'hash-format': z.enum(['sha256', 'sha512', 'sha1', 'md5', 'murmur2']),
|
||||
metafile: z.boolean().default(false),
|
||||
preserve: z.boolean().default(false)
|
||||
})
|
||||
.array(),
|
||||
update: z
|
||||
.object({
|
||||
curseforge: z
|
||||
.object({
|
||||
'file-id': z.number(),
|
||||
'project-id': z.number()
|
||||
})
|
||||
.optional(),
|
||||
modrinth: z
|
||||
.object({
|
||||
'mod-id': z.string(),
|
||||
version: z.string()
|
||||
})
|
||||
.optional()
|
||||
})
|
||||
.default({})
|
||||
});
|
||||
|
||||
// export const metafileSchema = z.object({
|
||||
// download: z.object({
|
||||
// 'hash-format': z.enum(['sha256', 'sha512', 'sha1', 'md5', 'murmur2']),
|
||||
// hash: z.string().regex(/^[a-fA-F0-9]+$/),
|
||||
// url: z.string().url().optional(),
|
||||
// mode: z.enum(['url', 'metadata:curseforge']).default('url')
|
||||
// }),
|
||||
// filename: z.string(),
|
||||
// name: z.string(),
|
||||
// option: z
|
||||
// .object({
|
||||
// optional: z.boolean(),
|
||||
// default: z.boolean().default(false),
|
||||
// description: z.string().optional()
|
||||
// })
|
||||
// .default({ optional: false }),
|
||||
// side: z.enum(['server', 'client', 'both']).default('both'),
|
||||
// update: z
|
||||
// .object({
|
||||
// curseforge: z
|
||||
// .object({
|
||||
// 'file-id': z.bigint(),
|
||||
// 'project-id': z.bigint()
|
||||
// })
|
||||
// .optional(),
|
||||
// modrinth: z
|
||||
// .object({
|
||||
// 'mod-id': z.string(),
|
||||
// version: z.string()
|
||||
// })
|
||||
// .optional()
|
||||
// })
|
||||
// .default({})
|
||||
// });
|
||||
|
||||
const metafileBase = z.object({
|
||||
filename: z.string(),
|
||||
name: z.string(),
|
||||
option: z
|
||||
.object({
|
||||
optional: z.boolean(),
|
||||
default: z.boolean().default(false),
|
||||
description: z.string().optional()
|
||||
})
|
||||
.default({ optional: false }),
|
||||
side: z.enum(['server', 'client', 'both']).default('both')
|
||||
});
|
||||
|
||||
export const metafileSchema = z.union([
|
||||
metafileBase.extend({
|
||||
download: z.object({
|
||||
'hash-format': z.enum(['sha256', 'sha512', 'sha1', 'md5', 'murmur2']),
|
||||
hash: z.string().regex(/^[a-fA-F0-9]+$/),
|
||||
url: z.string().url(),
|
||||
mode: z.literal('url').default('url')
|
||||
}),
|
||||
update: z
|
||||
.object({
|
||||
curseforge: z
|
||||
.object({
|
||||
'file-id': z.bigint(),
|
||||
'project-id': z.bigint()
|
||||
})
|
||||
.optional(),
|
||||
modrinth: z
|
||||
.object({
|
||||
'mod-id': z.string(),
|
||||
version: z.string()
|
||||
})
|
||||
.optional()
|
||||
})
|
||||
.default({})
|
||||
}),
|
||||
metafileBase.extend({
|
||||
download: z.object({
|
||||
'hash-format': z.enum(['sha256', 'sha512', 'sha1', 'md5', 'murmur2']),
|
||||
hash: z.string().regex(/^[a-fA-F0-9]+$/),
|
||||
mode: z.literal('metadata:curseforge')
|
||||
}),
|
||||
update: z.object({
|
||||
curseforge: z.object({
|
||||
'file-id': z.bigint(),
|
||||
'project-id': z.bigint()
|
||||
}),
|
||||
modrinth: z
|
||||
.object({
|
||||
'mod-id': z.string(),
|
||||
version: z.string()
|
||||
})
|
||||
.optional()
|
||||
})
|
||||
})
|
||||
]);
|
@ -1 +1,2 @@
|
||||
Front Page Here
|
||||
<a href="/create">create</a>
|
||||
|
@ -1,7 +1,103 @@
|
||||
<script lang="ts">
|
||||
import type { PageData } from './$types';
|
||||
import FlattenedFileList from './FlattenedFileList.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
import type { Folder } from '$lib/types';
|
||||
import {
|
||||
Tab,
|
||||
TabGroup,
|
||||
TabList,
|
||||
TabPanel,
|
||||
TabPanels,
|
||||
Dialog,
|
||||
DialogOverlay,
|
||||
DialogTitle,
|
||||
DialogDescription
|
||||
} from '@rgossiaux/svelte-headlessui';
|
||||
import { PlusIcon } from 'svelte-feather-icons';
|
||||
let fileTree: Folder = {
|
||||
type: 'folder',
|
||||
children: {
|
||||
mods: { type: 'folder', children: {
|
||||
"quark.pw.toml": {
|
||||
type: 'file',
|
||||
inline: true,
|
||||
metafile: true,
|
||||
content: `name = "Quark"
|
||||
filename = "Quark-3.4-389.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
hash-format = "sha1"
|
||||
hash = "9a2fcfae363db7330abc7a658bc7e016ae72fb5e"
|
||||
mode = "metadata:curseforge"
|
||||
|
||||
[update]
|
||||
[update.curseforge]
|
||||
file-id = 4366541
|
||||
project-id = 243121
|
||||
`,
|
||||
sha1: '478805ce54b082dadb1042ccfb46a68cfde3fc35',
|
||||
sha512: '5d364049ff53af2154ccae58dd53d2111ef592b21bff03705314cd6d12378cfeb6376b8bc3065ac59e1c9452447bec0eb345ecc19f0de1a17c20ea374f802f05'
|
||||
},
|
||||
"waystones.pw.toml": {
|
||||
type: 'file',
|
||||
inline: true,
|
||||
metafile: true,
|
||||
content: `name = "Waystones"
|
||||
filename = "waystones-forge-1.19-11.1.0.jar"
|
||||
side = "both"
|
||||
|
||||
[download]
|
||||
url = "https://cdn.modrinth.com/data/LOpKHB2A/versions/11.1.0%2Bforge-1.19/waystones-forge-1.19-11.1.0.jar"
|
||||
hash-format = "sha1"
|
||||
hash = "24c5403c1d5791f977a0ba69f08cf7959169c685"
|
||||
|
||||
[update]
|
||||
[update.modrinth]
|
||||
mod-id = "LOpKHB2A"
|
||||
version = "2sIhirkG"
|
||||
`,
|
||||
sha1: '25f4b57fbd8a985b4872bb8fdadd14580b0f9f81',
|
||||
sha512: '125fb6fc706363753c1c201192024415a23c1098c8e44d5deeaf5448215d83108b9a9a5aba0a029dd9015eff536dc1da63d16c3be0d7f9e39d6f482b8ce008c3'
|
||||
}
|
||||
} }
|
||||
}
|
||||
};
|
||||
let blobs: Blob[] = [];
|
||||
let isOpen = false;
|
||||
</script>
|
||||
|
||||
{JSON.stringify(data.session.user)}
|
||||
<TabGroup>
|
||||
<TabList>
|
||||
<Tab>Simple</Tab>
|
||||
<Tab>Advanced</Tab>
|
||||
</TabList>
|
||||
<TabPanels>
|
||||
<TabPanel>
|
||||
<h1>Mods <button><PlusIcon /></button></h1>
|
||||
<FlattenedFileList tree={fileTree.children.mods ?? { type: 'folder', children: {} }} />
|
||||
<h1>Resource Packs <button><PlusIcon /></button></h1>
|
||||
<FlattenedFileList
|
||||
tree={fileTree.children.resourcepacks ?? { type: 'folder', children: {} }}
|
||||
/>
|
||||
<h1>Shader Packs <button><PlusIcon /></button></h1>
|
||||
<FlattenedFileList tree={fileTree.children.shaderpacks ?? { type: 'folder', children: {} }} />
|
||||
</TabPanel>
|
||||
<TabPanel>Content 2</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>
|
||||
|
@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import type { FileTree, File } from '$lib/types';
|
||||
import { metafileSchema } from '$lib/packwiz-types';
|
||||
import toml from '@ltd/j-toml';
|
||||
export let tree: FileTree;
|
||||
function getFilesRecursively(tree: FileTree): [string[], File][] {
|
||||
if (tree.type == 'file') {
|
||||
return [[[], tree]];
|
||||
}
|
||||
let result: [string[], File][] = [];
|
||||
for (const child in tree.children) {
|
||||
if (Object.prototype.hasOwnProperty.call(tree.children, child)) {
|
||||
const element = tree.children[child];
|
||||
result = result.concat(
|
||||
getFilesRecursively(element).map(([path, file]) => [[child].concat(path), file])
|
||||
);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
{#each getFilesRecursively(tree) as mod (mod[0])}
|
||||
<li>
|
||||
{#if mod[1].inline && mod[1].metafile}
|
||||
{@const parsed = metafileSchema.parse(toml.parse(mod[1].content))}
|
||||
<h2>{parsed.name} ({mod[0].join('/')})</h2>
|
||||
{#if parsed.update.curseforge}
|
||||
<a
|
||||
href="https://minecraft.curseforge.com/projects/{parsed.update.curseforge[
|
||||
'project-id'
|
||||
]}">Curseforge</a
|
||||
>
|
||||
{/if}
|
||||
{#if parsed.update.modrinth}
|
||||
<a href="https://modrinth.com/project/{parsed.update.modrinth['mod-id']}">Modrinth</a>
|
||||
{/if}
|
||||
{:else}
|
||||
<h2>{mod[0].join('/')}</h2>
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
Loading…
Reference in new issue