diff --git a/.eslintrc.cjs b/.eslintrc.cjs index bd14d207c..2e749bdc5 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,20 +1,15 @@ +/* eslint-env node */ +require("@rushstack/eslint-patch/modern-module-resolution"); + module.exports = { root: true, - parser: '@typescript-eslint/parser', - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], - plugins: ['svelte3', '@typescript-eslint'], - ignorePatterns: ['*.cjs'], - overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], - settings: { - 'svelte3/typescript': () => require('typescript'), - }, + extends: [ + "plugin:vue/vue3-essential", + "eslint:recommended", + "@vue/eslint-config-typescript", + "@vue/eslint-config-prettier", + ], parserOptions: { - sourceType: 'module', - ecmaVersion: 2020, + ecmaVersion: "latest", }, - env: { - browser: true, - es2017: true, - node: true, - }, -} +}; diff --git a/.githooks/pre-push b/.githooks/pre-push deleted file mode 100755 index 98b445160..000000000 --- a/.githooks/pre-push +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -set -e - -pnpm install --frozen-lockfile -pnpm lint -pnpm check \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index a9240b47f..000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: CI - -on: [push, pull_request] - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - submodules: recursive - - uses: pnpm/action-setup@v2.2.2 - with: - version: 7 - - name: Install Node.js - uses: actions/setup-node@v3 - with: - node-version: 16 - cache: pnpm - - name: Install dependencies - run: pnpm install --frozen-lockfile - - name: Run build - run: VITE_API_URL="https://staging-api.modrinth.com/v2/" pnpm build - - name: Run package - run: pnpm package - - name: Run lint - run: pnpm lint - - name: Run check - run: pnpm check - - release: - needs: [lint] - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/main' - steps: - - name: Checkout - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: 7 - - name: Install Node.js - uses: actions/setup-node@v3 - with: - node-version: 16 - cache: pnpm - registry-url: 'https://registry.npmjs.org' - - name: Bump version - run: pnpm version patch --commit-hooks false --git-tag-version false - - uses: EndBug/add-and-commit@v9 - with: - message: 'Bump package version [skip ci]' - default_author: github_actions - - name: Install dependencies - run: pnpm install --frozen-lockfile - - name: Package - run: pnpm package - - name: Publish - run: | - cd package - npm publish --tag alpha - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 6bf0d3530..000000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Deploy - -on: push - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Wait for CF Pages - id: cf-pages - uses: WalshyDev/cf-pages-await@v1 - with: - project: 'omorphia' - apiToken: ${{ secrets.CF_API_TOKEN }} - accountId: '9ddae624c98677d68d93df6e524a6061' - githubToken: ${{ secrets.GITHUB_TOKEN }} - commitHash: ${{ steps.push-changes.outputs.commit-hash }} diff --git a/.gitignore b/.gitignore index 02c2a3723..38adffa64 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,28 @@ -.DS_Store +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + node_modules -/build -/.svelte-kit -/package -.env -.env.* -!.env.example -.vercel -generated/* -!/**/.gitkeep \ No newline at end of file +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index f76babdc9..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "locales"] - path = locales - url = https://github.com/modrinth/translations diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 73c496441..000000000 --- a/.npmignore +++ /dev/null @@ -1,31 +0,0 @@ -.DS_Store -node_modules/ -build/ -.svelte-kit/ -package/ -.env -.env.* -!.env.example -.vercel -generated/ -.githooks/ -.github/ -.idea/ -.vscode/ -docs/ -generated/ -locales/ -.eslintrc.cjs -.gitignore -.gitmodules -.npmignore -.npmrc -.prettierignore -.prettierrc -postcss.config.cjs -mdsvex.config.js -svelte.config.js -tsconfig.json -pnpm-lock.yaml - -src/ \ No newline at end of file diff --git a/.npmrc b/.npmrc index c42da845b..34717ad78 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ -engine-strict = true +fetch-retry-mintimeout=20000 +fetch-retry-maxtimeout=120000 diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 9eb6341ae..000000000 --- a/.prettierignore +++ /dev/null @@ -1,15 +0,0 @@ -.DS_Store -node_modules -/.svelte-kit -/package -.mf/ -build/ -.idea/ -.vscode/ -.vercel_build_output -.pnpm-debug.log -generated/ -.pnpm-store/ -locales/ -pnpm-lock.yaml -.nuxt/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 97d814092..000000000 --- a/.prettierrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "useTabs": true, - "singleQuote": true, - "printWidth": 100, - "bracketSameLine": true, - "semi": false -} diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 5f564f780..000000000 --- a/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -# MIT License - -Copyright © `2022` `Modrinth` - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 60b2c4823..970926040 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,46 @@ -# Omorphia +# omorphia -Omorphia is Modrinth's component, style, and utility library for Svelte projects. It includes: +This template should help get you started developing with Vue 3 in Vite. -- 🧩 Typed components which enhance HTML elements and provide a consistent UI -- 🎨 CSS classes to easily style elements with a coherent style -- 🧰 Typed utilities to solve common tasks quick and dependably -- ⚙️ Configuration for SvelteKit and PostCSS to simplify setups -- 🚚 A Rollup plugin to generate a cache of heavily used API requests and OpenAPI types +## Recommended IDE Setup -Read the documentation at [omorphia.modrinth.com.](https://omorphia.modrinth.com) +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). -## Developing +## Type Support for `.vue` Imports in TS -The library lives in the `src/` folder, and the documentation lives in the `docs/` folder. +TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. -### Getting started +If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: -Install [Node (16.5+)](https://docs.volta.sh/guide/getting-started) and [PNPM](https://pnpm.io/installation) prior to developing. +1. Disable the built-in TypeScript Extension + 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette + 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` +2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. -To start the dev server, install dependencies and run `pnpm dev`: +## Customize configuration -```bash -pnpm install # Install dependencies -pnpm dev # Run dev server +See [Vite Configuration Reference](https://vitejs.dev/config/). + +## Project Setup + +```sh +npm install ``` -To use the git hooks in the repo, which will save you waiting for CI to tell you that you forgot to lint, run this: +### Compile and Hot-Reload for Development -```bash -git config core.hookspath .githooks +```sh +npm run dev ``` -### Adding new components +### Type-Check, Compile and Minify for Production -> Replace `ComponentName` with your component name in the steps below - -1. Create a `ComponentName.svelte` file in `src/components` -2. Add an export for your component in [./src/index.ts](./src/index.ts) - ``` - export { default as ComponentName } from './components/ComponentName.svelte' - ``` -3. Create a `ComponentName.md` file for documentation in `docs/routes/components` -4. Add an example of your component in your `ComponentName.md` file, like so: - - ````md - ```svelte example raised - - - - ``` - ```` - -## Building - -To build the documentation site, run: - -```bash -pnpm build +```sh +npm run build +``` + +### Lint with [ESLint](https://eslint.org/) + +```sh +npm run lint ``` diff --git a/docs/app.d.ts b/docs/app.d.ts deleted file mode 100644 index 36396ad5c..000000000 --- a/docs/app.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// -/// - -// See https://kit.svelte.dev/docs/types#the-app-namespace -// for information about these interfaces -declare namespace App { - // interface Locals {} - // interface Platform {} - // interface Session {} - // interface Stuff {} -} diff --git a/docs/app.html b/docs/app.html deleted file mode 100644 index 71ea53915..000000000 --- a/docs/app.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - %sveltekit.head% - - - %sveltekit.body% - - diff --git a/docs/assets/omorphia.svg b/docs/assets/omorphia.svg deleted file mode 100644 index 4c7c7f660..000000000 --- a/docs/assets/omorphia.svg +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/docs/components/Example.svelte b/docs/components/Example.svelte deleted file mode 100644 index e2e2cecc7..000000000 --- a/docs/components/Example.svelte +++ /dev/null @@ -1,76 +0,0 @@ - - -
-
- -
-
-
- -
-
-
-
- - diff --git a/docs/components/Header.svelte b/docs/components/Header.svelte deleted file mode 100644 index 2de1f7317..000000000 --- a/docs/components/Header.svelte +++ /dev/null @@ -1,111 +0,0 @@ - - -
-
- - diff --git a/docs/components/Sidebar.svelte b/docs/components/Sidebar.svelte deleted file mode 100644 index a77f4d1b3..000000000 --- a/docs/components/Sidebar.svelte +++ /dev/null @@ -1,161 +0,0 @@ - - - - - diff --git a/docs/dummyStore.ts b/docs/dummyStore.ts deleted file mode 100644 index 1fbc59558..000000000 --- a/docs/dummyStore.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { writable } from 'svelte/store' - -// Used in `src/utils/send.ts` -export const token = writable('') diff --git a/docs/global.d.ts b/docs/global.d.ts deleted file mode 100644 index 7b018e1d5..000000000 --- a/docs/global.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -declare module '$assets/images/*' -declare module '$locales/*' - -declare module '*.svg?component' { - import type { SvelteComponentTyped } from 'svelte/internal' - class SVGComponent extends SvelteComponentTyped<{ class: string }> {} - export default SVGComponent -} diff --git a/docs/layout/page.svelte b/docs/layout/page.svelte deleted file mode 100644 index 9815839a3..000000000 --- a/docs/layout/page.svelte +++ /dev/null @@ -1,139 +0,0 @@ - - - - {title ? `${title} • Omorphia` : 'Omorphia'} - - - -{#if title}

{title}

{/if} - - - Edit this page on GitHub - - -{#if api} -
- {#if api.props.length > 0} -

Properties

- - - - - - - - - - - {#each api.props as prop} - - - - - - - {/each} - -
NameTypeDefaultDescription
{prop.name}{prop.type ?? ''}{prop.value ?? ''} - {prop.constant ? '[Read only] ' : ''} - {@html markdownInline(prop.description?.replace('null', '') || '')} -
- {/if} - {#if api.events.length > 0} -

Events

- - - - - - - - - - {#each api.events as event} - - - - - - {/each} - -
NameForwardedDescription
{event.name}{!!event.parent}{event.description?.replace('null', '') || ''}
- {/if} - {#if api.slots.length > 0} -

Slots

- - - - - - - - - {#each api.slots as slot} - - - - - {/each} - -
NameFallback
{slot.name}{slot.fallback ?? 'None'}
- {/if} -
-{/if} - - diff --git a/docs/plugins/sveld.js b/docs/plugins/sveld.js deleted file mode 100644 index 08c97e99a..000000000 --- a/docs/plugins/sveld.js +++ /dev/null @@ -1,53 +0,0 @@ -import { ComponentParser } from 'sveld' -import * as svelte from 'svelte/compiler' -import fs from 'fs/promises' -import path from 'path' -import { preprocess } from '../../src/config/svelte.js' - -export default function sveld() { - return { - name: 'vite-plugin-sveld', - // This generates a `COMPONENT_API.json` with sveld in the `/_app` folder which is used by the docs about components - // TODO: Make more efficient & handle typescript types with `svelte2tsx` - async transform(src, id) { - if (id.includes('/src/components/')) { - await generateComponentApi() - } - }, - async buildStart() { - await generateComponentApi() - }, - } -} - -async function parseRaw(raw, filePath) { - let { code } = await svelte.preprocess(raw, preprocess, { - filename: filePath, - }) - return new ComponentParser({ - verbose: false, - }).parseSvelteComponent(code, { - filePath, - moduleName: filePath, - }) -} - -async function generateComponentApi() { - const output = {} - - const componentFiles = await fs.readdir(path.resolve('./src/components')) - - for (const fileName of componentFiles.filter((name) => name.endsWith('.svelte'))) { - const filePath = path.resolve('./src/components', fileName) - const raw = (await fs.readFile(filePath)).toString() - output[fileName] = await parseRaw(raw, filePath) - } - - try { - await fs.mkdir(path.resolve('./generated')) - } catch { - // Do nothing, directory already exists - } - - await fs.writeFile(path.resolve('./generated/COMPONENT_API.json'), JSON.stringify(output)) -} diff --git a/docs/routes/__layout.svelte b/docs/routes/__layout.svelte deleted file mode 100644 index f544ee998..000000000 --- a/docs/routes/__layout.svelte +++ /dev/null @@ -1,73 +0,0 @@ - - - - -
-
- -
-
- -
-
-
- - diff --git a/docs/routes/classes/Actions.md b/docs/routes/classes/Actions.md deleted file mode 100644 index 1273b81d2..000000000 --- a/docs/routes/classes/Actions.md +++ /dev/null @@ -1,15 +0,0 @@ -```svelte example raised - - -
- - - - Updated 12 days ago - -
-``` diff --git a/docs/routes/classes/Base.md b/docs/routes/classes/Base.md deleted file mode 100644 index ffdda5b3a..000000000 --- a/docs/routes/classes/Base.md +++ /dev/null @@ -1,5 +0,0 @@ -Base should be applied to a "root" element, like ``, to provide base styles for common things like text. The theme mode, `light-theme`, `dark-theme`, or `oled-theme`, should also be added to this element. - -```svelte example -
...
-``` diff --git a/docs/routes/classes/Card.md b/docs/routes/classes/Card.md deleted file mode 100644 index 252ca62fb..000000000 --- a/docs/routes/classes/Card.md +++ /dev/null @@ -1,33 +0,0 @@ -### A simple example - -```svelte example -
-

Moon/Distance to Earth

-

238,900 mi

-

- The moon's distance from Earth affects the strength of ocean tides and the appearance of solar - eclipses in our skies. The average distance between the blue planet and its only natural - satellite is about 238,855 miles (384,400 kilometers), according to NASA. -

-
-``` - -### A more complex example - -```svelte example - - -
-
- -
-
- -

Project

-

A project that has a description right here.

-
-``` diff --git a/docs/routes/classes/Divider.md b/docs/routes/classes/Divider.md deleted file mode 100644 index dc5ded069..000000000 --- a/docs/routes/classes/Divider.md +++ /dev/null @@ -1,7 +0,0 @@ -```svelte example raised -Some words could go here. - -
- -And some other words could go here. -``` diff --git a/docs/routes/classes/File.md b/docs/routes/classes/File.md deleted file mode 100644 index b8dcc8f17..000000000 --- a/docs/routes/classes/File.md +++ /dev/null @@ -1,14 +0,0 @@ -```svelte example raised - - -
-
- -
cool-mod.jar
- -
-
-``` diff --git a/docs/routes/classes/InfoTable.md b/docs/routes/classes/InfoTable.md deleted file mode 100644 index c34a8c1da..000000000 --- a/docs/routes/classes/InfoTable.md +++ /dev/null @@ -1,10 +0,0 @@ -```svelte example raised -
- License - MIT - Project ID - 11223344 - Visibilty - Approved -
-``` diff --git a/docs/routes/classes/Link.md b/docs/routes/classes/Link.md deleted file mode 100644 index e94688d77..000000000 --- a/docs/routes/classes/Link.md +++ /dev/null @@ -1,24 +0,0 @@ -### Single example - -```svelte example raised - Go somewhere! -``` - -### Group example - -```svelte example raised - - - -``` diff --git a/docs/routes/classes/Member.md b/docs/routes/classes/Member.md deleted file mode 100644 index a0f0bee8e..000000000 --- a/docs/routes/classes/Member.md +++ /dev/null @@ -1,13 +0,0 @@ -```svelte example raised - - - - -
- Prospector - Owner -
-
-``` diff --git a/docs/routes/classes/Stat.md b/docs/routes/classes/Stat.md deleted file mode 100644 index 06d7cff3c..000000000 --- a/docs/routes/classes/Stat.md +++ /dev/null @@ -1,32 +0,0 @@ -### Single Example - -```svelte example raised - - -
- - 123K stars -
-``` - -### Group Example - -```svelte example raised - - -
-
- - 4.1B downloads -
-
- - 3 followers -
-
-``` diff --git a/docs/routes/classes/Tags.md b/docs/routes/classes/Tags.md deleted file mode 100644 index 13f249dfd..000000000 --- a/docs/routes/classes/Tags.md +++ /dev/null @@ -1,15 +0,0 @@ -```svelte example raised - - -
-
- Food -
-
- World generation -
-
-``` diff --git a/docs/routes/classes/Title.md b/docs/routes/classes/Title.md deleted file mode 100644 index 4bf1376d2..000000000 --- a/docs/routes/classes/Title.md +++ /dev/null @@ -1,5 +0,0 @@ -```svelte example raised -

Tree Mod

-

Information

-

Members

-``` diff --git a/docs/routes/components/Avatar.md b/docs/routes/components/Avatar.md deleted file mode 100644 index 5288aec40..000000000 --- a/docs/routes/components/Avatar.md +++ /dev/null @@ -1,15 +0,0 @@ -Avatars are used for project icons and user profile pictures. Low resolution images are rendered pixelated to preserve pixel art. - -```svelte example raised - - - - - - - -``` diff --git a/docs/routes/components/Badge.md b/docs/routes/components/Badge.md deleted file mode 100644 index 11b511d02..000000000 --- a/docs/routes/components/Badge.md +++ /dev/null @@ -1,10 +0,0 @@ -```svelte example raised - - - - - - -``` diff --git a/docs/routes/components/Button.md b/docs/routes/components/Button.md deleted file mode 100644 index 9fa6e5e95..000000000 --- a/docs/routes/components/Button.md +++ /dev/null @@ -1,46 +0,0 @@ -### Single example - -```svelte example - - - -``` - -### Color variants example - -```svelte example raised - - -
- - - - - - - - - -
-``` - -### With icons example - -```svelte example - - -
- - -
-``` diff --git a/docs/routes/components/Checkbox.md b/docs/routes/components/Checkbox.md deleted file mode 100644 index 98ad27449..000000000 --- a/docs/routes/components/Checkbox.md +++ /dev/null @@ -1,20 +0,0 @@ -### Text-only Example - -```svelte example raised - - -Extra components -``` - -### Text with Icon Example - -```svelte example raised - - - Food -``` diff --git a/docs/routes/components/CheckboxList.md b/docs/routes/components/CheckboxList.md deleted file mode 100644 index eec59edde..000000000 --- a/docs/routes/components/CheckboxList.md +++ /dev/null @@ -1,36 +0,0 @@ -```svelte example raised - - - - -Selected: {selected} -``` diff --git a/docs/routes/components/CheckboxVirtualList.md b/docs/routes/components/CheckboxVirtualList.md deleted file mode 100644 index 55bde2400..000000000 --- a/docs/routes/components/CheckboxVirtualList.md +++ /dev/null @@ -1,20 +0,0 @@ -```svelte example raised - - - - -Selected: {selected} -``` diff --git a/docs/routes/components/Chips.md b/docs/routes/components/Chips.md deleted file mode 100644 index f5787a3b5..000000000 --- a/docs/routes/components/Chips.md +++ /dev/null @@ -1,47 +0,0 @@ -### Simple example - -```svelte example raised - - - -``` - -### Force an option to be selected with `neverEmpty` - -```svelte example raised - - - -``` diff --git a/docs/routes/components/Code.md b/docs/routes/components/Code.md deleted file mode 100644 index ef5b25b22..000000000 --- a/docs/routes/components/Code.md +++ /dev/null @@ -1,7 +0,0 @@ -```svelte example raised - - - -``` diff --git a/docs/routes/components/Field.md b/docs/routes/components/Field.md deleted file mode 100644 index 39ab4b6a0..000000000 --- a/docs/routes/components/Field.md +++ /dev/null @@ -1,12 +0,0 @@ -```svelte example raised - - - - - - - - -``` diff --git a/docs/routes/components/FileUpload.md b/docs/routes/components/FileUpload.md deleted file mode 100644 index 1ff410357..000000000 --- a/docs/routes/components/FileUpload.md +++ /dev/null @@ -1,31 +0,0 @@ -### Single constrained example - -```svelte example raised column - - - - - - -File name: {file?.name} -``` - -### Multiple example - -```svelte example raised column - - - - - - -Count: {files.length} -``` diff --git a/docs/routes/components/Modal.md b/docs/routes/components/Modal.md deleted file mode 100644 index 555063c97..000000000 --- a/docs/routes/components/Modal.md +++ /dev/null @@ -1,21 +0,0 @@ -```svelte example raised - - - - - -

Secret message goes here!

- -
- - - - - Are you sure you want to delete this gallery image? - - -``` diff --git a/docs/routes/components/ModalDeletion.md b/docs/routes/components/ModalDeletion.md deleted file mode 100644 index 9b397ad33..000000000 --- a/docs/routes/components/ModalDeletion.md +++ /dev/null @@ -1,13 +0,0 @@ -```svelte example raised - - - console.log('Do something...')}> - - -``` diff --git a/docs/routes/components/NavRow.md b/docs/routes/components/NavRow.md deleted file mode 100644 index 23d19952d..000000000 --- a/docs/routes/components/NavRow.md +++ /dev/null @@ -1,66 +0,0 @@ -`NavRow` works well for most horizontal navigation with less than 10 items. It can be used with paths & query params, and supports specific path level (depths). - -### Query example - -```svelte example - - -
- -
-``` - -### Route example - -```svelte example - - - -``` diff --git a/docs/routes/components/Pagination.md b/docs/routes/components/Pagination.md deleted file mode 100644 index 8d4b95eaf..000000000 --- a/docs/routes/components/Pagination.md +++ /dev/null @@ -1,9 +0,0 @@ -Use pagination to show a set of page numbers and navigation directions to move through paginated data. - -```svelte example - - - -``` diff --git a/docs/routes/components/Select.md b/docs/routes/components/Select.md deleted file mode 100644 index afa665ea0..000000000 --- a/docs/routes/components/Select.md +++ /dev/null @@ -1,36 +0,0 @@ -### Default option example - -```svelte example raised - - - -``` diff --git a/docs/routes/components/Slider.md b/docs/routes/components/Slider.md deleted file mode 100644 index 2c8e55e10..000000000 --- a/docs/routes/components/Slider.md +++ /dev/null @@ -1,7 +0,0 @@ -```svelte example raised - - - -``` diff --git a/docs/routes/components/TextInput.md b/docs/routes/components/TextInput.md deleted file mode 100644 index cdaf6679d..000000000 --- a/docs/routes/components/TextInput.md +++ /dev/null @@ -1,9 +0,0 @@ -```svelte example raised - - - - -``` diff --git a/docs/routes/index.md b/docs/routes/index.md deleted file mode 100644 index d0127adc7..000000000 --- a/docs/routes/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Introduction ---- - -## Overview - -Omorphia is Modrinth's component, style, and utility library for Svelte projects. It includes: - -- 🧩 Typed components which enhance HTML elements and provide a consistent UI -- 🎨 CSS classes to easily style elements with a coherent style -- 🧰 Typed utilities to solve common tasks quick and dependably -- ⚙️ Configuration for SvelteKit and PostCSS to simplify setups -- 🚚 A Rollup plugin to generate a cache of heavily used API requests and OpenAPI types - -Omorphia is used in [Knossos](https://github.com/modrinth/knossos) (modrinth.com) and [Theseus](https://github.com/modrinth/theseus) (Minecraft launcher). - -It uses [Svelte](https://svelte.dev/) to deliver the best performance with the least boilerplate. - -## Try Omorphia online - -You can try Omorphia online via [➜ **CodeSandbox** 💻](https://codesandbox.io/s/omorphia-starter-bsbgke). - -## Getting started - -Follow the instructions on the [➜ **setup page** 🛠️](/setup). diff --git a/docs/routes/setup.md b/docs/routes/setup.md deleted file mode 100644 index 2c6609cb6..000000000 --- a/docs/routes/setup.md +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: Setup ---- - -## `0.` Prerequisites - -First install the following: - -- [Node 16.x](https://docs.volta.sh/guide/getting-started) or higher -- [PNPM](https://pnpm.io/installation) (required for Modrinth projects) - -## `1.` Create a SvelteKit project - -Run the following command to create a SvelteKit project: - -```bash -pnpm create svelte -``` - -Follow the instructions to install dependencies and setup git. - -## `2.` Add Omorphia to your project - -```bash -pnpm add omorphia -``` - -## `3.` Setup translations - -Install the translations submodule: - -```bash -git submodule add https://github.com/modrinth/translations locales/ -``` - -Install `svelte-intl-precompile`: - -```bash -pnpm add svelte-intl-precompile -D -``` - -Add translations in `src/routes/__layout.svelte`: - -```html - -``` - -## `4.` Configure SvelteKit - -Add the following parts to your `svelte.config.js` file: - -```js -import adapter from '@sveltejs/adapter-auto' -import { preprocess } from 'omorphia/config/svelte' -import path from 'path' - -/** @type {import('@sveltejs/kit').Config} */ -const config = { - preprocess: [preprocess], - - kit: { - adapter: adapter(), - - alias: { - $generated: path.resolve('./generated'), - $stores: path.resolve('./src/stores'), - }, - }, -} - -export default config -``` - -Create a `src/stores/account.ts` file with a `token` store export: - -```ts -import { writable } from 'svelte/store' - -export const token = writable('') -``` - -## `5.` Configure Vite - -Add the following to your `vite.config.js` file: - -```js -import { plugins } from 'omorphia/config/vite.js' -import { Generator } from 'omorphia/plugins' -import precompileIntl from 'svelte-intl-precompile/sveltekit-plugin' - -/** @type {import('vite').UserConfig} */ -const config = { - plugins: [ - ...plugins, - precompileIntl('locales'), - Generator({ - gameVersions: true, - openapi: true, - // Add more if needed - }), - ], - - server: { - fs: { - allow: ['generated'], - }, - }, -} - -export default config -``` - -## `6.` Configure PostCSS - -Create a `postcss.config.cjs` file in the root of your project. - -Add the following line to that file: - -```js -module.exports = require('omorphia/config/postcss.cjs') -``` - -## `7.` Setup styles - -Import styles in `src/routes/__layout.svelte`: - -```html - -``` - -Add the `base` class and a theme to the `` tag in `src/app.html`: - -```html - - %sveltekit.body% - -``` - -## `8.` Setup fonts - -Copy the the `fonts/` folder from [Omorphia's repository](https://github.com/modrinth/omorphia/blob/main/docs/static/assets/fonts) and place them in the `static/` folder at the root of your project. - -Add the following preload tags to your head in `app.html` to speed up font loading: - - -```html - - - - - -``` - - -## `9.` Using Omorphia - -### Developing - -Start the development server with: - -```bash -pnpm dev -``` - -> To get Svelte language support in your code editor, [use this list of extensions.](https://sveltesociety.dev/tools#editor-support) - -### Components - -Use a component by importing from `omorphia`. For example, use the [Button component](/components/Button) like so: - -```svelte example raised - - - -``` - -### Utils - -Use a utility by importing from `omorphia/utils`. - -```svelte example raised - - -{ago(Date.now() - 100000)} -``` - -### Using icons and styles - -Follow the guides on the sidebar to learn how to use [icons](/usage/icons) and general concepts. diff --git a/docs/routes/usage/css.md b/docs/routes/usage/css.md deleted file mode 100644 index 5285b227e..000000000 --- a/docs/routes/usage/css.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Writing CSS ---- - -## Conventions - -### Avoid inconsistent CSS units - -Prefer using `rem` units, using only whole and half units, eg. `2rem` or `1.5rem`. If you need a specific pixel (`px`) measurement, use `px` and add comment explaining why you used it. The one exception is that `0.25rem` is allowed. - -> Using `rem` units lets you change the scale of the UI by simply changing the body font size. - -### Always use `HSL` colors - -### All colors should be theme variables - -## Abilities - -Omorphia leverages PostCSS to allow you to write in future-standards-compliant CSS. Browse [the CSSWG drafts](https://cssdb.org/) to see what is possible (not including stage 0). - -Notable features: - -- [Nesting](https://www.w3.org/TR/css-nesting-1/#example-aecb8796) -- [Gap](https://developer.mozilla.org/en-US/docs/Web/CSS/gap) -- [`clamp` function]() -- [Custom Media Queries](https://www.w3.org/TR/mediaqueries-5/#example-532b0adb) -- [`:has()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has) -- [place-content](https://developer.mozilla.org/en-US/docs/Web/CSS/place-content) - -## Styles - -Conform to [BEM styling](http://getbem.com/introduction/) wherever possible. When working in components, you may want to leverage [Svelte's conditional class shorthand](https://svelte.dev/tutorial/class-shorthand) instead of BEM's modifier class name format. diff --git a/docs/routes/usage/generator.md b/docs/routes/usage/generator.md deleted file mode 100644 index 1397ae034..000000000 --- a/docs/routes/usage/generator.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Generator plugin ---- - -The generator plugin creates static files from API responses to increase performance and perform tasks that would not be possible on the client. It regenerates files every 7 days, or when the plugin settings change. - -### Current options - -- `projectColors` (false) generates colors for every project -- `tags` (false) copies & parses tags from API -- `gameVersions` copies game versions from API -- `landingPage` gets icon urls for top 100 mods - -> All options are disabled by default - -## Configuration - -```js -import Generator from 'omorphia/plugins/generator' - -/** @type {import('@sveltejs/kit').Config} */ -const config = { - kit: { - vite: { - plugins: [ - Generator({ - projectColors: true, - tags: true, - gameVersions: true, - landingPage: true, - }), - ], - }, - }, -} - -export default config -``` diff --git a/docs/routes/usage/icons.md b/docs/routes/usage/icons.md deleted file mode 100644 index fdb96a9f7..000000000 --- a/docs/routes/usage/icons.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Icons ---- - -## Choosing icons - -The follwing icon packs are included with omorphia: - -`heroicons-outline` `lucide` `fa-regular` `heroicons-solid` `carbon` `simple-icons` - -Aim to find icons from `heroicons-outline` first, and then from the following packs if you can't find what you are looking for. [Browse icons...](https://icones.js.org/collection/heroicons-outline) - -## Using icons - -Import an icon in the ` - -

That's lovely!

-``` diff --git a/docs/routes/usage/illustrations.md b/docs/routes/usage/illustrations.md deleted file mode 100644 index e566150b1..000000000 --- a/docs/routes/usage/illustrations.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Using illustrations ---- - -Find an illustration from [unDraw](https://undraw.co/illustrations) and download it as an SVG. - -Put the illustration in the `src/assets/images/illustrations` folder. Rename it to `undraw_` + the illustration slug. - -Replace colors in the SVG with CSS variables such as `var(--color-brand)` and `var(--color-raised)`. For colors that are the same as the font color, use `currentColor`. - -Add the `.illustration` class to the SVG - -Import the SVG in the ` - - -``` diff --git a/docs/routes/usage/utils.md b/docs/routes/usage/utils.md deleted file mode 100644 index 727ace430..000000000 --- a/docs/routes/usage/utils.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Built-in utilities ---- - -## API requests - -Use the `send` function to make API requests. - -```svelte example raised - - -{#await project} - fetching... -{:then project} - {project.downloads} downloads -{/await} -``` - -## Markdown - -Use the markdown utilities to parse markdown text into HTML. Both markdown parsers have HTML sanitization built-in. - -### Body parser - -The `markdown` parser is designed for bodies of markdown text and supports images, tables, lists, and youtube `` - } else { - return `${text}` - } -} - -renderer.link = (href, title, text) => { - if (href === null) { - return text - } - let out = '' - return out -} - -marked.setOptions({ - renderer, - highlight, - langPrefix: 'hljs language-', - headerPrefix: '', - gfm: true, - smartLists: true, -}) - -function sanitize(html: string): string { - return insane(html, { - allowedAttributes: { - a: ['href', 'target', 'title', 'rel'], - iframe: ['allowfullscreen', 'src', 'width', 'height'], - img: ['src', 'width', 'height', 'alt'], - h1: ['id'], - h2: ['id'], - h3: ['id'], - h4: ['id'], - h5: ['id'], - h6: ['id'], - code: ['class'], - span: ['class'], - input: ['type', 'checked', 'disabled'], - font: ['color'], - details: ['open'], - }, - allowedClasses: {}, - allowedSchemes: ['http', 'https', 'mailto'], - allowedTags: [ - 'a', - 'b', - 'blockquote', - 'br', - 'caption', - 'center', - 'code', - 'del', - 'details', - 'div', - 'em', - 'font', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'hr', - 'i', - 'iframe', - 'img', - 'input', - 'ins', - 'kbd', - 'li', - 'main', - 'ol', - 'p', - 'pre', - 'span', - 'strike', - 'strong', - 'sub', - 'summary', - 'sup', - 'table', - 'tbody', - 'td', - 'th', - 'thead', - 'tr', - 'u', - 'ul', - ], - filter: ({ tag, attrs }): boolean => { - if (tag === 'iframe') { - return /^https?:\/\/(www\.)?(youtube|youtube-nocookie)\.com\/embed\/[a-zA-Z0-9_]{11}(\?)?(&modestbranding=1)?(&autoplay=0)?(&loop=1)?(&playlist=[a-zA-Z0-9_]{11})?(&rel=0)?$/.test( - attrs.src || '' - ) - } else if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag)) { - return attrs.id !== 'svelte' - } else if (tag === 'input') { - return attrs.type === 'checkbox' && attrs.disabled === '' - } else if (tag === 'code' || tag === 'span') { - return !attrs.class || attrs.class.replace(' ', '').startsWith('hljs') - } else { - return true - } - }, - transformText: null, - }) -} - -export function markdownInline(markdown: string): string { - return insane( - marked.parseInline(markdown), - { - allowedAttributes: { - a: ['href', 'target', 'title', 'rel'], - }, - allowedClasses: {}, - allowedSchemes: ['http', 'https', 'mailto'], - allowedTags: ['a', 'b', 'br', 'code', 'em', 'i', 'strike', 'strong', 'sub', 'sup', 'u'], - transformText: null, - }, - true - ) -} - -export function markdown(markdown: string): string { - return sanitize(marked.parse(markdown)) -} diff --git a/src/utils/permissions.ts b/src/utils/permissions.ts deleted file mode 100644 index 7a9c3f350..000000000 --- a/src/utils/permissions.ts +++ /dev/null @@ -1,42 +0,0 @@ -export class Permissions { - uploadVersions = false - deleteVersion = false - editDetails = false - editBody = false - manageInvites = false - removeMember = false - editMember = false - deleteProject = false - - get settingsPage(): boolean { - return this.manageInvites || this.removeMember || this.editMember || this.deleteProject - } - - toInteger(): number { - return ( - (this.uploadVersions ? 1 : 0) | - (this.deleteVersion ? 1 << 1 : 0) | - (this.editDetails ? 1 << 2 : 0) | - (this.editBody ? 1 << 3 : 0) | - (this.manageInvites ? 1 << 4 : 0) | - (this.removeMember ? 1 << 5 : 0) | - (this.editMember ? 1 << 6 : 0) | - (this.deleteProject ? 1 << 7 : 0) - ) - } - - constructor(from: number | 'ALL' | null) { - if (from === 'ALL' || from === 0b11111111 || from === null) { - Object.keys(this).forEach((v) => (this[v] = true)) - } else if (typeof from === 'number') { - this.uploadVersions = !!(from & (1 << 0)) - this.deleteVersion = !!(from & (1 << 1)) - this.editDetails = !!(from & (1 << 2)) - this.editBody = !!(from & (1 << 3)) - this.manageInvites = !!(from & (1 << 4)) - this.removeMember = !!(from & (1 << 5)) - this.editMember = !!(from & (1 << 6)) - this.deleteProject = !!(from & (1 << 7)) - } - } -} diff --git a/src/utils/send.ts b/src/utils/send.ts deleted file mode 100644 index 6272bd873..000000000 --- a/src/utils/send.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ /* `svelte-check` doesn't find issues but VSCode does */ -// @ts-ignore: `$stores/account` needs to be created in consumer package -import { token as tokenStore } from '$stores/account' -import { get, writable } from 'svelte/store' -import type { operations } from '$generated/openapi' - -export const fetching = writable(0) - -type method = 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'HEAD' - -/* On get requests with query params, pass them in data */ -export async function send( - method: method, - route: string, - data: // @ts-ignore: Not always present - | (operations[Operation]['requestBody']['content']['application/json'] & - // @ts-ignore - operations[Operation]['requestBody']['content']['multipart/form-data'] & - // @ts-ignore - operations[Operation]['parameters']['query']) - | FormData - | null = null, - options: { - token?: string - fetch?: (info: RequestInfo, init?: RequestInit) => Promise - file?: File - } = { - token: '', - } -): Promise< - // @ts-ignore: On some API routes, a response body is available, if not, defaults to `unknown` - operations[Operation]['responses'][200]['content']['application/json'] -> { - fetching.set(get(fetching) + 1) - - const fetchOptions: RequestInit = { - method, - headers: {}, - } - - const token = get(tokenStore) || options.token - if (token) { - fetchOptions.headers['Authorization'] = token - } - - let url = (import.meta.env.VITE_API_URL || 'https://api.modrinth.com/v2/') + route - - if (data) { - if (data instanceof FormData) { - fetchOptions.body = data - } else { - if (method === 'GET' || options.file) { - url += '?' + new URLSearchParams(data as Record).toString() - } else { - fetchOptions.headers['Content-Type'] = 'application/json' - fetchOptions.body = JSON.stringify(data) - } - if (options.file) { - fetchOptions.headers['Content-Type'] = options.file.type - fetchOptions.body = options.file - } - } - } - - const response = await (options.fetch || fetch)(url, fetchOptions) - - fetching.set(get(fetching) - 1) - - if (!response.ok) { - throw response - } - - let parsed: any - if (response.status !== 204) { - try { - parsed = await response.json() - } catch { - console.error('Could not parse API response') - } - } - - return parsed -} diff --git a/src/utils/uniqueId.ts b/src/utils/uniqueId.ts deleted file mode 100644 index 0fcb80a1e..000000000 --- a/src/utils/uniqueId.ts +++ /dev/null @@ -1,6 +0,0 @@ -let idCounter = 0 - -export function uniqueId(prefix = ''): string { - const id = ++idCounter - return prefix + id -} diff --git a/src/utils/versions.ts b/src/utils/versions.ts deleted file mode 100644 index f830318c5..000000000 --- a/src/utils/versions.ts +++ /dev/null @@ -1,83 +0,0 @@ -import gameVersions from '$generated/gameVersions.json' - -export function formatVersions(versionArray: string[]): string { - const allVersions = gameVersions.slice().reverse() - const allReleases = allVersions.filter((x) => x.version_type === 'release') - - const intervals = [] - let currentInterval = 0 - - for (let i = 0; i < versionArray.length; i++) { - const index = allVersions.findIndex((x) => x.version === versionArray[i]) - const releaseIndex = allReleases.findIndex((x) => x.version === versionArray[i]) - - if (i === 0) { - intervals.push([[versionArray[i], index, releaseIndex]]) - } else { - const intervalBase = intervals[currentInterval] - - if ( - (index - intervalBase[intervalBase.length - 1][1] === 1 || - releaseIndex - intervalBase[intervalBase.length - 1][2] === 1) && - (allVersions[intervalBase[0][1]].version_type === 'release' || - allVersions[index].version_type !== 'release') - ) { - intervalBase[1] = [versionArray[i], index, releaseIndex] - } else { - currentInterval += 1 - intervals[currentInterval] = [[versionArray[i], index, releaseIndex]] - } - } - } - - const newIntervals = [] - for (let i = 0; i < intervals.length; i++) { - const interval = intervals[i] - - if (interval.length === 2 && interval[0][2] !== -1 && interval[1][2] === -1) { - let lastSnapshot = null - for (let j = interval[1][1]; j > interval[0][1]; j--) { - if (allVersions[j].version_type === 'release') { - newIntervals.push([ - interval[0], - [ - allVersions[j].version, - j, - allReleases.findIndex((x) => x.version === allVersions[j].version), - ], - ]) - - if (lastSnapshot !== null && lastSnapshot !== j + 1) { - newIntervals.push([[allVersions[lastSnapshot].version, lastSnapshot, -1], interval[1]]) - } else { - newIntervals.push([interval[1]]) - } - - break - } else { - lastSnapshot = j - } - } - } else { - newIntervals.push(interval) - } - } - - const output = [] - - for (const interval of newIntervals) { - if (interval.length === 2) { - output.push(`${interval[0][0]}—${interval[1][0]}`) - } else { - output.push(interval[0][0]) - } - } - - return output.join(', ') -} - -export const getPrimary = (files: any[]) => files.find((file) => file.primary) || files[0] - -export function downloadUrl(file: any): string { - return import.meta.env.VITE_API_URL + `version_file/${file?.hashes.sha1}/download` -} diff --git a/src/views/AboutView.vue b/src/views/AboutView.vue new file mode 100644 index 000000000..756ad2a17 --- /dev/null +++ b/src/views/AboutView.vue @@ -0,0 +1,15 @@ + + + diff --git a/svelte.config.js b/svelte.config.js deleted file mode 100644 index 07e7979d7..000000000 --- a/svelte.config.js +++ /dev/null @@ -1,36 +0,0 @@ -import { mdsvex } from 'mdsvex' -import mdsvexConfig from './mdsvex.config.js' -import adapter from '@sveltejs/adapter-static' -import path from 'path' -import { preprocess } from './src/config/svelte.js' - -/** @type {import('@sveltejs/kit').Config} */ -export default { - extensions: ['.svelte', ...mdsvexConfig.extensions], - - preprocess: [preprocess, mdsvex(mdsvexConfig)], - - kit: { - adapter: adapter(), - prerender: { - default: true, - onError: 'continue', - }, - - alias: { - $generated: path.resolve('./generated'), - omorphia: path.resolve('./src'), - ['$stores/account']: path.resolve('./docs/dummyStore.ts'), - }, - - files: { - assets: 'docs/static', - hooks: 'docs/hooks', - lib: 'src', - params: 'docs/params', - routes: 'docs/routes', - serviceWorker: 'docs/service-worker', - template: 'docs/app.html', - }, - }, -} diff --git a/tsconfig.json b/tsconfig.json index 31914aa54..8d2359999 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,16 @@ { - "compilerOptions": { - "resolveJsonModule": true, - "esModuleInterop": true - }, - "include": [ - "./docs/**/*.js", - "./docs/**/*.ts", - "./docs/**/*.svelte", - "./src/**/*.js", - "./src/**/*.ts", - "./src/**/*.svelte" - ], - "extends": "./.svelte-kit/tsconfig.json" + "extends": "@vue/tsconfig/tsconfig.web.json", + "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + + "references": [ + { + "path": "./tsconfig.config.json" + } + ] } diff --git a/vite.config.js b/vite.config.js deleted file mode 100644 index 42266398b..000000000 --- a/vite.config.js +++ /dev/null @@ -1,35 +0,0 @@ -import { sveltekit } from '@sveltejs/kit/vite' -import { plugins } from './src/config/vite.js' -import examples from 'mdsvexamples/vite' -import sveld from './docs/plugins/sveld.js' -import Generator from './src/plugins/generator/index.js' -import precompileIntl from 'svelte-intl-precompile/sveltekit-plugin' - -/** @type {import('vite').UserConfig} */ -const config = { - plugins: [ - sveltekit(), - Generator({ - gameVersions: true, - openapi: true, - }), - ...plugins, - examples, - sveld(), - precompileIntl('locales'), - ], - - build: { - rollupOptions: { - external: ['/_app/COMPONENT_API.json'], - }, - }, - - server: { - fs: { - allow: ['generated', 'docs'], - }, - }, -} - -export default config