├── .editorconfig ├── .gitignore ├── .idea └── .idea.cf-svelte.dir │ └── .idea │ ├── .gitignore │ ├── encodings.xml │ ├── indexLayout.xml │ ├── sqldialects.xml │ └── vcs.xml ├── .npmrc ├── LICENSE ├── README.md ├── eslint.config.mjs ├── migrations └── 0000_initial.sql ├── package-lock.json ├── package.json ├── playwright.config.ts ├── src ├── app.d.ts ├── app.html ├── hooks.server.ts ├── index.test.ts ├── lib │ └── index.ts └── routes │ ├── +page.svelte │ └── api │ ├── [...catchall] │ └── +server.ts │ ├── d1 │ └── [id] │ │ └── +server.ts │ └── kv │ └── [key] │ └── +server.ts ├── static ├── favicon.png └── robots.txt ├── svelte.config.js ├── tests └── test.ts ├── tsconfig.json ├── vite.config.ts └── wrangler.toml /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = tab 7 | indent_size = 2 8 | tab_width = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | ij_javascript_spaces_within_imports = true 14 | ij_javascript_force_quote_style = true 15 | ij_javascript_use_double_quotes = false 16 | 17 | ij_typescript_spaces_within_imports = true 18 | ij_typescript_force_quote_style = true 19 | ij_typescript_use_double_quotes = false 20 | 21 | [*.cs] 22 | indent_size = 4 23 | tab_width = 4 24 | 25 | [*.md] 26 | max_line_length = off 27 | trim_trailing_whitespace = false 28 | 29 | [*.csv] 30 | max_line_length = off 31 | end_of_line = crlf 32 | 33 | [*.{csproj,sln}] 34 | end_of_line = crlf 35 | 36 | [package.json] 37 | indent_style = space 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | .vercel 10 | /.cert 11 | /.mf 12 | /.wrangler 13 | /test-results 14 | .output 15 | vite.config.js.timestamp-* 16 | vite.config.ts.timestamp-* 17 | -------------------------------------------------------------------------------- /.idea/.idea.cf-svelte.dir/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /modules.xml 6 | /contentModel.xml 7 | /.idea.cf-svelte.iml 8 | /projectSettingsUpdater.xml 9 | # Editor-based HTTP Client requests 10 | /httpRequests/ 11 | # Datasource local storage ignored files 12 | /dataSources/ 13 | /dataSources.local.xml 14 | /dataSources.xml 15 | -------------------------------------------------------------------------------- /.idea/.idea.cf-svelte.dir/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.cf-svelte.dir/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/.idea.cf-svelte.dir/.idea/sqldialects.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.idea.cf-svelte.dir/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | resolution-mode=highest 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Stephen Darnell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sveltekit starter for Cloudflare that allows easier local development 2 | 3 | This starter was initially created with C3 (Create Cloudflare CLI), 4 | and then enhanced with a few things: 5 | - Allow `npm start` to start a local dev environment (same as `npm run dev`) 6 | - Support for a trusted SSL cert using `mkcert` 7 | - Add the Svelte Inspector 8 | - Add an example migration for the database 9 | 10 | # create-svelte 11 | 12 | The initial project was created with: 13 | 14 | ```bash 15 | npm create cloudflare@latest cf-svelte -- --framework=svelte 16 | ``` 17 | 18 | # mkcert 19 | 20 | To get a trusted SSL certificate when testing locally, we use the `mkcert` package, 21 | see https://github.com/FiloSottile/mkcert 22 | 23 | If you haven't used it before, you will need install it the first time. 24 | ``` 25 | $ mkcert -install 26 | Created a new local CA 27 | The local CA is now installed in the system trust store! 28 | The local CA is now installed in the Firefox trust store (requires browser restart)! 29 | ``` 30 | 31 | Then your app can use a local cert with a shorter lifespan. These are stored in the 32 | `.cert` directory, and can be setup or refreshed with: 33 | ```bash 34 | npm run cert 35 | ``` 36 | 37 | # Svelte inspector 38 | 39 | When running locally you can enable the inspector by pressing 40 | Cmd ⌘ + Shift ⇧ on Mac, otherwise Ctrl ⌃ + Shift ⇧. 41 | Then highlight and click on components. 42 | 43 | See https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/inspector.md 44 | 45 | # D1 Migration 46 | 47 | To apply the recorded migrations, use: 48 | ``` 49 | $ npm run migration:add 50 | or 51 | $ npx wrangler d1 migrations apply DB --local 52 | Migrations to be applied: 53 | ┌──────────────────┐ 54 | │ name │ 55 | ├──────────────────┤ 56 | │ 0000_initial.sql │ 57 | └──────────────────┘ 58 | ? About to apply 1 migration(s) 59 | Your database may not be available to serve requests during the migration, continue? › (Y/n) 60 | o Mapping SQL input into an array of statements 61 | o Loading f6c5717c-3866-45d3-b4e7-20b332e359e0 from .wrangler/state/v3/d1 62 | ┌──────────────────┬────────┐ 63 | │ name │ status │ 64 | ├──────────────────┼────────┤ 65 | │ 0000_initial.sql │ (tick) │ 66 | └──────────────────┴────────┘ 67 | ``` 68 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslint from '@eslint/js'; 2 | import svelte from 'eslint-plugin-svelte'; 3 | import globals from 'globals'; 4 | import ts_eslint from 'typescript-eslint'; 5 | import stylistic from '@stylistic/eslint-plugin'; 6 | import jsdocPlugin from 'eslint-plugin-jsdoc'; 7 | 8 | export default ts_eslint.config( 9 | { 10 | plugins: { 11 | '@stylistic': stylistic, 12 | } 13 | }, 14 | eslint.configs.recommended, 15 | ...ts_eslint.configs.recommended, 16 | ...svelte.configs['flat/recommended'], 17 | jsdocPlugin.configs['flat/recommended-typescript'], 18 | { 19 | languageOptions: { 20 | globals: { 21 | ...globals.browser, 22 | ...globals.node 23 | } 24 | } 25 | }, 26 | { 27 | files: ['**/*.svelte'], 28 | languageOptions: { 29 | parserOptions: { 30 | parser: ts_eslint.parser 31 | } 32 | } 33 | }, 34 | { 35 | rules: { 36 | '@typescript-eslint/adjacent-overload-signatures': 'error', 37 | '@typescript-eslint/dot-notation': 'off', 38 | '@typescript-eslint/explicit-function-return-type': 'off', 39 | '@typescript-eslint/explicit-member-accessibility': [ 40 | 'off', 41 | { 42 | 'accessibility': 'explicit' 43 | } 44 | ], 45 | '@stylistic/member-delimiter-style': [ 46 | 'error', 47 | { 48 | 'multiline': { 49 | 'delimiter': 'semi', 50 | 'requireLast': true 51 | }, 52 | 'singleline': { 53 | 'delimiter': 'comma' 54 | } 55 | } 56 | ], 57 | '@typescript-eslint/no-explicit-any': 'off', 58 | '@typescript-eslint/no-inferrable-types': [ 59 | 'error', 60 | { 61 | 'ignoreParameters': true 62 | } 63 | ], 64 | 65 | 'no-shadow': 'off', 66 | '@typescript-eslint/no-shadow': 'error', 67 | 68 | 'no-unused-expressions': 'off', 69 | '@typescript-eslint/no-unused-expressions': 'error', 70 | 71 | '@typescript-eslint/no-unused-vars': [ 72 | 'warn', 73 | { 'argsIgnorePattern': '^_' } 74 | ], 75 | '@typescript-eslint/prefer-for-of': 'error', 76 | '@typescript-eslint/prefer-function-type': 'error', 77 | '@typescript-eslint/prefer-namespace-keyword': 'error', 78 | 79 | '@stylistic/quotes': [ 80 | 'error', 81 | 'single', 82 | { 'allowTemplateLiterals': true } 83 | ], 84 | 85 | '@stylistic/semi': [ 86 | 'error', 87 | 'always' 88 | ], 89 | '@stylistic/type-annotation-spacing': 'error', 90 | '@typescript-eslint/unified-signatures': 'warn', 91 | 'arrow-body-style': 'off', 92 | 'arrow-parens': [ 93 | 'error', 94 | 'as-needed' 95 | ], 96 | 'brace-style': [ 97 | 'error', 98 | '1tbs' 99 | ], 100 | 'comma-dangle': [ 101 | 'error', { 102 | 'arrays': 'ignore', 103 | 'objects': 'ignore', 104 | 'imports': 'ignore', 105 | 'exports': 'ignore', 106 | 'functions': 'never' 107 | } 108 | ], 109 | 'complexity': 'off', 110 | 'constructor-super': 'error', 111 | 'curly': ['error', 'multi-line', 'consistent'], 112 | 'dot-notation': 'off', 113 | 'eol-last': 'error', 114 | 'eqeqeq': ['error', 'always', {'null': 'ignore'}], 115 | 'guard-for-in': 'error', 116 | 'id-denylist': [ 117 | 'error', 118 | 'any', 119 | 'Number', 120 | 'number', 121 | 'String', 122 | 'string', 123 | 'Boolean', 124 | 'boolean', 125 | 'Undefined', 126 | 'undefined' 127 | ], 128 | 'id-match': 'error', 129 | '@stylistic/indent': ['warn', 'tab', { 130 | 'FunctionDeclaration': {'parameters': 'off'}, 131 | 'SwitchCase': 1, 132 | }], 133 | 'jsdoc/require-jsdoc': 'off', 134 | 'jsdoc/require-param': 'off', 135 | 'jsdoc/require-returns': 'off', 136 | 'jsdoc/check-alignment': 'error', 137 | 'jsdoc/check-indentation': 'off', 138 | 'jsdoc/check-tag-names': 'off', // Off because it warns about @type 139 | 'jsdoc/newline-after-description': 'off', 140 | 'jsdoc/no-types': 'error', 141 | 'key-spacing': ['warn', { 'beforeColon': false }], 142 | 'max-classes-per-file': 'off', 143 | 'max-len': [ 144 | 'warn', 145 | { 146 | 'code': 140, 147 | 'tabWidth': 2, 148 | } 149 | ], 150 | 'new-parens': 'error', 151 | 'no-bitwise': 'off', 152 | 'no-caller': 'error', 153 | 'no-cond-assign': 'error', 154 | 'no-console': [ 155 | 'warn', 156 | { 157 | 'allow': [ 158 | 'dir', 159 | 'log', 160 | 'warn', 161 | 'error' 162 | ] 163 | } 164 | ], 165 | 'no-debugger': 'error', 166 | 'no-eval': 'error', 167 | 'no-fallthrough': 'warn', 168 | 'no-multiple-empty-lines': 'warn', 169 | 'no-new-wrappers': 'error', 170 | 'no-restricted-imports': [ 171 | 'error', 172 | 'rxjs/Rx' 173 | ], 174 | 'no-throw-literal': 'error', 175 | 'no-undef-init': 'error', 176 | 'no-underscore-dangle': 'off', 177 | 'no-unsafe-finally': 'error', 178 | 'no-unused-labels': 'error', 179 | 'no-use-before-define': 'off', 180 | 'no-var': 'error', 181 | 'object-shorthand': 'off', 182 | 'prefer-arrow/prefer-arrow-functions': 'off', 183 | 'prefer-const': 'error', 184 | 'radix': 'error', 185 | 'space-before-function-paren': [ 186 | 'error', 187 | { 188 | 'anonymous': 'never', 189 | 'asyncArrow': 'always', 190 | 'named': 'never' 191 | } 192 | ], 193 | 'spaced-comment': 'off', 194 | 195 | 'no-mixed-spaces-and-tabs': ['warn', 'smart-tabs'], 196 | 'no-trailing-spaces': 'off', // Don't need ESLint's rule, so turn it off 197 | 'svelte/no-trailing-spaces': 'error', 198 | 'svelte/button-has-type': 'warn', 199 | 'svelte/html-quotes': ['error', {'prefer': 'double'}], 200 | 'svelte/no-spaces-around-equal-signs-in-attribute': 'error', 201 | 'svelte/prefer-class-directive': 'off', // Until more flexible. See https://github.com/sveltejs/eslint-plugin-svelte/issues/689 202 | 'svelte/block-lang': ['error', {'script': 'ts'}], 203 | } 204 | }, 205 | { 206 | ignores: ['build/', '.svelte-kit/', 'dist/', 'node_modules/', 'node_modules'], 207 | } 208 | ); 209 | -------------------------------------------------------------------------------- /migrations/0000_initial.sql: -------------------------------------------------------------------------------- 1 | -- Migration number: 0000 2023-09-25T21:00:01.014Z 2 | 3 | CREATE TABLE users ( 4 | id INTEGER PRIMARY KEY, 5 | email TEXT, 6 | createdAt DATETIME DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) 7 | ); 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cf-svelte", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "vite dev --host", 7 | "dev": "vite dev --host", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "cert": "rm -rf .cert && mkdir -p .cert && mkcert -key-file ./.cert/key.pem -cert-file ./.cert/cert.pem localhost 127.0.0.1", 11 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 12 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 13 | "lint": "eslint .", 14 | "migration:apply": "wrangler d1 migrations apply DB --local", 15 | "test": "npm run test:integration && npm run test:unit", 16 | "test:integration": "playwright test", 17 | "test:unit": "vitest", 18 | "pages:dev": "wrangler pages dev --compatibility-date=2023-09-25 --proxy 5173 -- npm run dev", 19 | "pages:deploy": "npm run build && wrangler pages deploy .svelte-kit/cloudflare" 20 | }, 21 | "devDependencies": { 22 | "@eslint/js": "^9.12.0", 23 | "@playwright/test": "^1.48.0", 24 | "@stylistic/eslint-plugin": "^2.9.0", 25 | "@sveltejs/adapter-cloudflare": "^4.7.3", 26 | "@sveltejs/kit": "^2.7.1", 27 | "@sveltejs/vite-plugin-svelte": "^3.1.2", 28 | "@types/eslint": "^9.6.0", 29 | "eslint": "^9.0.0", 30 | "eslint-plugin-jsdoc": "^50.4.1", 31 | "eslint-plugin-prefer-arrow": "^1.2.3", 32 | "eslint-plugin-svelte": "^2.36.0", 33 | "globals": "^15.0.0", 34 | "svelte": "^4.2.19", 35 | "svelte-check": "^4.0.5", 36 | "tslib": "^2.7.0", 37 | "typescript": "^5.3.3", 38 | "typescript-eslint": "^8.0.0", 39 | "vite": "^5.4.9", 40 | "vitest": "^2.1.3" 41 | }, 42 | "type": "module" 43 | } 44 | -------------------------------------------------------------------------------- /playwright.config.ts: -------------------------------------------------------------------------------- 1 | import type { PlaywrightTestConfig } from '@playwright/test'; 2 | 3 | const config: PlaywrightTestConfig = { 4 | webServer: { 5 | command: 'npm run build && npm run preview', 6 | port: 4173 7 | }, 8 | testDir: 'tests', 9 | testMatch: /(.+\.)?(test|spec)\.[jt]s/ 10 | }; 11 | 12 | export default config; 13 | -------------------------------------------------------------------------------- /src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://kit.svelte.dev/docs/types#app 2 | // for information about these interfaces 3 | 4 | declare global { 5 | namespace App { 6 | interface Platform { 7 | env: { 8 | // COUNTER: DurableObjectNamespace; 9 | KV: KVNamespace; 10 | DB: D1Database; 11 | }; 12 | caches: CacheStorage & { default: Cache } | CacheStorage_3; 13 | cf: CfProperties; 14 | ctx: ExecutionContext; 15 | } 16 | } 17 | } 18 | 19 | export {}; 20 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/hooks.server.ts: -------------------------------------------------------------------------------- 1 | // /src/hooks.server.ts 2 | import type { Handle } from '@sveltejs/kit'; 3 | 4 | export const handle = (async ({ event, resolve }) => { 5 | // TODO: Implement hooks such as auth checks etc. here 6 | 7 | return resolve(event); 8 | }) satisfies Handle; 9 | -------------------------------------------------------------------------------- /src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | 3 | describe('sum test', () => { 4 | it('adds 1 + 2 to equal 3', () => { 5 | expect(1 + 2).toBe(3); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/lib/index.ts: -------------------------------------------------------------------------------- 1 | // place files you want to import through the `$lib` alias in this folder. 2 | -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 28 | 29 |

Welcome to SvelteKit

30 |

Visit kit.svelte.dev to read the documentation

31 | 32 |

33 | 34 | 35 |

36 |

KV Timestamp: {timestampKV}

37 | 38 |

39 | 40 | 41 | 42 |

43 |

D1 Record: {JSON.stringify(timestampD1)}

44 | -------------------------------------------------------------------------------- /src/routes/api/[...catchall]/+server.ts: -------------------------------------------------------------------------------- 1 | import { error } from '@sveltejs/kit'; 2 | 3 | function NotFound() { 4 | error(404, 'API endpoint not found'); 5 | } 6 | 7 | export { 8 | NotFound as GET, 9 | NotFound as POST, 10 | NotFound as PUT, 11 | NotFound as PATCH, 12 | NotFound as DELETE, 13 | }; 14 | -------------------------------------------------------------------------------- /src/routes/api/d1/[id]/+server.ts: -------------------------------------------------------------------------------- 1 | import { error, json } from '@sveltejs/kit'; 2 | import type { RequestHandler } from '@sveltejs/kit'; 3 | import type { D1Database } from '@cloudflare/workers-types'; 4 | 5 | export const GET: RequestHandler = async ({params, platform, setHeaders}) => { 6 | console.log(`D1 GET called ${params.id}`); 7 | if (params.id == null) error(400, 'Missing id'); 8 | const DB: D1Database = platform?.env.DB; 9 | const result = await DB.prepare('SELECT * from users WHERE id = ?') 10 | .bind(params.id).first(); 11 | if (result == null) error(404); 12 | console.dir(result); 13 | setHeaders({'Cache-Control': 'max-age=0'}); 14 | return json(result); 15 | }; 16 | 17 | export const PUT: RequestHandler = async ({params, platform}) => { 18 | console.log(`D1 PUT called ${params.id}`); 19 | if (params.id == null) error(400, 'Missing id'); 20 | const DB: D1Database = platform?.env.DB; 21 | const result = await DB.prepare('INSERT INTO users (id, email) VALUES(?, ?)') 22 | .bind(1, 'test@example.com').run(); 23 | console.dir(result); 24 | return new Response(null, {status: 204}); 25 | }; 26 | 27 | export const DELETE: RequestHandler = async ({params, platform}) => { 28 | console.log(`D1 DELETE called ${params.id}`); 29 | if (params.id == null) error(400, 'Missing id'); 30 | const DB: D1Database = platform?.env.DB; 31 | const result = await DB.prepare('DELETE FROM users WHERE id = ?') 32 | .bind(1).run(); 33 | console.dir(result); 34 | return new Response(null, {status: 204}); 35 | }; 36 | -------------------------------------------------------------------------------- /src/routes/api/kv/[key]/+server.ts: -------------------------------------------------------------------------------- 1 | import { error, json } from '@sveltejs/kit'; 2 | import type { RequestHandler } from '@sveltejs/kit'; 3 | import type { KVNamespace } from '@cloudflare/workers-types'; 4 | 5 | export const GET: RequestHandler = async ({params, platform, setHeaders}) => { 6 | console.log('KV GET called'); 7 | if (params.key == null) error(400, 'Missing key'); 8 | const KV: KVNamespace = platform?.env.KV; 9 | const result = await KV.get(params.key); 10 | if (result == null) error(404); 11 | setHeaders({'Cache-Control': 'max-age=0'}); 12 | return json(result); 13 | }; 14 | 15 | export const PUT: RequestHandler = async ({params, url, platform}) => { 16 | console.log('KV PUT called'); 17 | if (params.key == null) error(400, 'Missing key'); 18 | const KV: KVNamespace = platform?.env.KV; 19 | const value = url.searchParams.get('value') || 'VALUE'; 20 | await KV.put(params.key, value); 21 | return new Response(null, {status: 204}); 22 | }; 23 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdarnell/cf-svelte/3883b8d0743a76d7127889dc8b89920be629efa6/static/favicon.png -------------------------------------------------------------------------------- /static/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-cloudflare'; 2 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://kit.svelte.dev/docs/integrations#preprocessors 7 | // for more information about preprocessors 8 | preprocess: [vitePreprocess({})], 9 | 10 | vitePlugin: { 11 | inspector: true, 12 | }, 13 | 14 | kit: { 15 | // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. 16 | // If your environment is not supported or you settled on a specific environment, switch out the adapter. 17 | // See https://kit.svelte.dev/docs/adapters for more information about adapters. 18 | adapter: adapter(), 19 | }, 20 | }; 21 | 22 | export default config; 23 | -------------------------------------------------------------------------------- /tests/test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from '@playwright/test'; 2 | 3 | test('index page has expected h1', async ({ page }) => { 4 | await page.goto('/'); 5 | await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible(); 6 | }); 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true 12 | } 13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias 14 | // 15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 16 | // from the referenced tsconfig.json - TypeScript does not merge them in 17 | } 18 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | import { defineConfig } from 'vitest/config'; 3 | import fs from 'fs'; 4 | 5 | let certKey: string|Buffer|undefined; 6 | let certCert: string|Buffer|undefined; 7 | 8 | if (fs.existsSync('./.cert/key.pem')) { 9 | certKey = fs.readFileSync('./.cert/key.pem'); 10 | certCert = fs.readFileSync('./.cert/cert.pem'); 11 | } else { 12 | console.log('Missing HTTPS key/cert. You may need to run: npm run cert'); 13 | } 14 | 15 | export default defineConfig({ 16 | plugins: [sveltekit()], 17 | server: { 18 | https: { 19 | // See https://stackoverflow.com/questions/69417788/vite-https-on-localhost 20 | key: certKey, 21 | cert: certCert, 22 | }, 23 | }, 24 | test: { 25 | include: ['src/**/*.{test,spec}.{js,ts}'], 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /wrangler.toml: -------------------------------------------------------------------------------- 1 | 2 | compatibility_date = "2023-08-01" 3 | 4 | kv_namespaces = [ 5 | { binding = "KV", id = "22e634f6-f58f-4492-afcc-3e3935ffd2f9" }, 6 | ] 7 | 8 | [[d1_databases]] 9 | binding = "DB" 10 | database_name = "test-db" 11 | database_id = "f6c5717c-3866-45d3-b4e7-20b332e359e0" 12 | preview_database_id = "0a83bfd7-9827-44f8-9ad4-a0fe906818c3" 13 | --------------------------------------------------------------------------------