initial commit

This commit is contained in:
Hunter Johnston 2023-02-04 11:44:27 -05:00
commit b15148ca19
31 changed files with 2560 additions and 0 deletions

13
.eslintignore Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

20
.eslintrc.cjs Normal file
View File

@ -0,0 +1,20 @@
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')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020
},
env: {
browser: true,
es2017: true,
node: true
}
};

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
prisma/dev.sqlite

1
.npmrc Normal file
View File

@ -0,0 +1 @@
engine-strict=true

13
.prettierignore Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

21
.prettierrc Normal file
View File

@ -0,0 +1,21 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"semi": false,
"printWidth": 100,
"plugins": [
"prettier-plugin-svelte"
],
"pluginSearchDirs": [
"."
],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}

38
README.md Normal file
View File

@ -0,0 +1,38 @@
# create-svelte
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

BIN
code.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

41
package.json Normal file
View File

@ -0,0 +1,41 @@
{
"name": "sk-prisma-quickstart",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"test": "playwright test",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test:unit": "vitest",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@playwright/test": "^1.28.1",
"@sveltejs/adapter-auto": "^1.0.0",
"@sveltejs/kit": "^1.0.0",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^4.0.0",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.8.1",
"prisma": "^4.9.0",
"rome": "^11.0.0",
"svelte": "^3.54.0",
"svelte-check": "^3.0.1",
"tslib": "^2.4.1",
"typescript": "^4.9.3",
"vite": "^4.0.0",
"vitest": "^0.25.3"
},
"type": "module",
"dependencies": {
"@picocss/pico": "^1.5.6",
"@prisma/client": "^4.9.0"
}
}

11
playwright.config.ts Normal file
View File

@ -0,0 +1,11 @@
import type { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
webServer: {
command: 'npm run build && npm run preview',
port: 4173
},
testDir: 'tests'
};
export default config;

2054
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

17
prisma/schema.prisma Normal file
View File

@ -0,0 +1,17 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./dev.sqlite"
}
model Article {
id Int @id @default(autoincrement())
title String
content String
}

13
rome.json Normal file
View File

@ -0,0 +1,13 @@
{
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"semicolons": "asNeeded"
}
}
}

13
src/app.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
import type { PrismaClient } from "@prisma/client"
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
var __prisma: PrismaClient
}
export {}

12
src/app.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

7
src/index.test.ts Normal file
View File

@ -0,0 +1,7 @@
import { describe, it, expect } from 'vitest';
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
});

9
src/lib/server/prisma.ts Normal file
View File

@ -0,0 +1,9 @@
import { PrismaClient } from "@prisma/client"
const prisma = global.__prisma || new PrismaClient()
if (process.env.NODE_ENV === "development") {
global.__prisma = prisma
}
export { prisma }

21
src/routes/+layout.svelte Normal file
View File

@ -0,0 +1,21 @@
<script lang="ts">
import '@picocss/pico'
</script>
<div class="container">
<nav>
<ul>
<li>
<strong>
<a href="/"> Blogly </a>
</strong>
</li>
</ul>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/register">Register</a></li>
<li><a href="/login" role="button">Login</a></li>
</ul>
</nav>
<slot />
</div>

View File

@ -0,0 +1,57 @@
import type { Actions, PageServerLoad } from "./$types"
import { prisma } from "$lib/server/prisma"
import { fail } from "@sveltejs/kit"
export const load: PageServerLoad = async () => {
return {
articles: await prisma.article.findMany(),
}
}
export const actions: Actions = {
createArticle: async ({ request }) => {
const { title, content } = Object.fromEntries(await request.formData()) as {
title: string
content: string
}
try {
await prisma.article.create({
data: {
title,
content,
},
})
} catch (err) {
console.error(err)
return fail(500, { message: "Could not create the article." })
}
return {
status: 201,
}
},
deleteArticle: async ({ url }) => {
const id = url.searchParams.get("id")
if (!id) {
return fail(400, { message: "Invalid request" })
}
try {
await prisma.article.delete({
where: {
id: Number(id),
},
})
} catch (err) {
console.error(err)
return fail(500, {
message: "Something went wrong deleting your article",
})
}
return {
status: 200,
}
},
}

35
src/routes/+page.svelte Normal file
View File

@ -0,0 +1,35 @@
<script lang="ts">
import type { PageData } from './$types'
export let data: PageData
$: ({ articles } = data)
</script>
<div class="grid">
<div>
<h2>Articles:</h2>
{#each articles as article}
<article>
<header>{article.title}</header>
<p>
{article.content}
</p>
<form action="?/deleteArticle&id={article.id}" method="POST">
<button type="submit" class="outline secondary">Delete Article</button>
</form>
<a href="/{article.id}" role="button" class="outline constrast" style="width: 100%;"
>Edit Article</a
>
</article>
{/each}
</div>
<form action="?/createArticle" method="POST">
<h3>New Article</h3>
<label for="title"> Title </label>
<input type="text" id="title" name="title" />
<label for="title"> Title </label>
<textarea id="content" name="content" rows={5} />
<button type="submit">Add Article</button>
</form>
</div>

View File

@ -0,0 +1,49 @@
import type { Actions, PageServerLoad } from "./$types"
import { prisma } from "$lib/server/prisma"
import { error, fail } from "@sveltejs/kit"
export const load: PageServerLoad = async ({ params }) => {
const getArticle = async () => {
const article = await prisma.article.findUnique({
where: {
id: Number(params.articleId),
},
})
if (!article) {
throw error(404, "Article not found")
}
return article
}
return {
article: getArticle(),
}
}
export const actions: Actions = {
updateArticle: async ({ request, params }) => {
const { title, content } = Object.fromEntries(await request.formData()) as {
title: string
content: string
}
try {
await prisma.article.update({
where: {
id: Number(params.articleId),
},
data: {
title,
content,
},
})
} catch (err) {
console.error(err)
return fail(500, { message: "Could not update article" })
}
return {
status: 200,
}
},
}

View File

@ -0,0 +1,15 @@
<script lang="ts">
import type { PageData } from './$types'
export let data: PageData
$: ({ article } = data)
</script>
<form action="?/updateArticle" method="POST">
<h3>Editing: {article.title}</h3>
<label for="title"> Title </label>
<input type="text" id="title" name="title" value={article.title} />
<label for="title"> Title </label>
<textarea id="content" name="content" rows={5} value={article.content} />
<button type="submit">Update Article</button>
</form>

View File

View File

@ -0,0 +1,14 @@
<form>
<hgroup>
<h2>Login</h2>
<h3>Welcome back!</h3>
</hgroup>
<label for="email">Email address</label>
<input type="email" id="email" name="email" required />
<label for="email">Password</label>
<input type="email" id="email" name="password" required />
<button type="submit">Login</button>
</form>
<p>Don't have an account? <a href="/register">Register</a></p>

View File

View File

@ -0,0 +1,26 @@
<form>
<hgroup>
<h2>Register</h2>
<h3>To post articles, you'll need an account.</h3>
</hgroup>
<div class="grid">
<label for="firstname">
First name
<input type="text" id="firstname" name="firstname" required />
</label>
<label for="lastname">
Last name
<input type="text" id="lastname" name="lastname" required />
</label>
</div>
<label for="email">Email address</label>
<input type="email" id="email" name="email" required />
<label for="email">Password</label>
<input type="email" id="email" name="password" required />
<button type="submit">Register</button>
</form>
<p>Already have an account? <a href="/login">Login</a></p>

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

15
svelte.config.js Normal file
View File

@ -0,0 +1,15 @@
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/kit/vite';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
adapter: adapter()
}
};
export default config;

6
tests/test.ts Normal file
View File

@ -0,0 +1,6 @@
import { expect, test } from '@playwright/test';
test('index page has expected h1', async ({ page }) => {
await page.goto('/');
expect(await page.textContent('h1')).toBe('Welcome to SvelteKit');
});

17
tsconfig.json Normal file
View File

@ -0,0 +1,17 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

11
vite.config.ts Normal file
View File

@ -0,0 +1,11 @@
import { sveltekit } from '@sveltejs/kit/vite';
import type { UserConfig } from 'vite';
const config: UserConfig = {
plugins: [sveltekit()],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
}
};
export default config;