├── .changeset ├── README.md └── config.json ├── .github └── workflows │ └── deploy.yml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── clean.sh ├── docs ├── .nojekyll ├── assets │ ├── highlight.css │ ├── icons.css │ ├── icons.png │ ├── icons@2x.png │ ├── main.js │ ├── search.js │ ├── style.css │ ├── widgets.png │ └── widgets@2x.png ├── classes │ └── _sveltekit_cdk_constructsv2.SvelteDistribution.html ├── index.html ├── interfaces │ ├── _sveltekit_cdk_adapter.AdapterParams.html │ ├── _sveltekit_cdk_constructsv2.RendererProps.html │ └── _sveltekit_cdk_constructsv2.SvelteDistributionProps.html ├── modules.html └── modules │ ├── _sveltekit_cdk_adapter.html │ └── _sveltekit_cdk_constructsv2.html ├── package.json ├── packages ├── adapter │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── finalize-build.cjs │ ├── package.json │ ├── prepare-build.cjs │ ├── shims.js │ ├── src │ │ ├── files │ │ │ ├── ambient.d.ts │ │ │ ├── app.d.ts │ │ │ ├── at-edge-handler.ts │ │ │ ├── header-blacklist.ts │ │ │ └── util.ts │ │ └── index.ts │ └── tsconfig.json ├── constructsv2 │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── prepare-build.cjs │ ├── src │ │ ├── common.ts │ │ ├── distribution.ts │ │ └── index.ts │ └── tsconfig.json ├── sample-site-v2 │ ├── .gitignore │ ├── .npmrc │ ├── README.md │ ├── package.json │ ├── src │ │ ├── app.d.ts │ │ ├── app.html │ │ ├── lib │ │ │ └── images │ │ │ │ ├── github.svg │ │ │ │ ├── svelte-logo.svg │ │ │ │ ├── svelte-welcome.png │ │ │ │ └── svelte-welcome.webp │ │ └── routes │ │ │ ├── +layout.svelte │ │ │ ├── +page.svelte │ │ │ ├── +page.ts │ │ │ ├── Counter.svelte │ │ │ ├── Header.svelte │ │ │ ├── about │ │ │ ├── +page.svelte │ │ │ └── +page.ts │ │ │ ├── styles.css │ │ │ └── sverdle │ │ │ ├── +page.server.ts │ │ │ ├── +page.svelte │ │ │ ├── game.ts │ │ │ ├── how-to-play │ │ │ ├── +page.svelte │ │ │ └── +page.ts │ │ │ ├── reduced-motion.ts │ │ │ └── words.server.ts │ ├── static │ │ ├── favicon.png │ │ └── robots.txt │ ├── svelte.config.js │ ├── tsconfig.json │ └── vite.config.js ├── sample-stack-v2 │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── bin │ │ └── sample-stack-v2.ts │ ├── cdk.context.json │ ├── cdk.json │ ├── jest.config.js │ ├── lib │ │ └── sample-stack-v2-stack.ts │ ├── package.json │ ├── test │ │ └── sample-stack-v2.test.ts │ └── tsconfig.json ├── test-stack │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── bin │ │ └── test-stack.ts │ ├── cdk.json │ ├── jest.config.js │ ├── lib │ │ └── test-stack.ts │ ├── package.json │ └── tsconfig.json └── test │ ├── .gitignore │ ├── .npmrc │ ├── README.md │ ├── package.json │ ├── src │ ├── app.d.ts │ ├── app.html │ ├── lib │ │ ├── Test.svelte │ │ └── test │ │ │ ├── binaryRequestBody.ts │ │ │ ├── caching.ts │ │ │ ├── index.ts │ │ │ ├── prerendered.ts │ │ │ ├── prerenderedContentType.ts │ │ │ ├── ssr.ts │ │ │ ├── static.ts │ │ │ └── types.ts │ └── routes │ │ ├── endpoints │ │ ├── headers.json.ts │ │ ├── icon.png.ts │ │ └── msgpack.json.ts │ │ ├── index.svelte │ │ ├── my-ip.svelte │ │ ├── my-ip.ts │ │ └── ssr │ │ ├── [slug].svelte │ │ └── maxage-5.svelte │ ├── static │ └── favicon.png │ ├── svelte.config.js │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── tsconfig.json └── typedoc.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.6.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "linked": [], 6 | "access": "restricted", 7 | "baseBranch": "main", 8 | "updateInternalDependencies": "patch", 9 | "ignore": [ 10 | "sample-site-v2", 11 | "sample-stack-v2", 12 | "test", 13 | "test-stack" 14 | ] 15 | } -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Deploy 5 | 6 | on: 7 | push: 8 | branches: [main] 9 | 10 | jobs: 11 | builds-on-every-os: 12 | strategy: 13 | matrix: 14 | os: [macos-latest, ubuntu-latest, windows-latest] 15 | node-version: [16.x] 16 | runs-on: ${{ matrix.os }} 17 | steps: 18 | - uses: actions/checkout@v3 19 | - uses: pnpm/action-setup@v2.2.4 20 | with: 21 | version: latest 22 | - uses: actions/setup-node@v3 23 | with: 24 | node-version: 16 25 | # cache: pnpm 26 | - run: node --version 27 | - run: pnpm --version 28 | - run: pnpm adapter-deps 29 | - run: pnpm build-adapter 30 | - run: pnpm install 31 | - run: pnpm build-sample 32 | 33 | deploy-demo: 34 | name: Deploy demo site 35 | runs-on: ubuntu-latest 36 | steps: 37 | - uses: actions/checkout@v3 38 | - uses: pnpm/action-setup@v2.2.4 39 | with: 40 | version: 7.19 41 | - uses: actions/setup-node@v3 42 | with: 43 | node-version: 16 44 | # cache: pnpm 45 | - run: pnpm adapter-deps 46 | - run: pnpm build-adapter 47 | - run: pnpm install 48 | - run: pnpm build-sample 49 | - run: pnpm deploy-sample 50 | env: 51 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 52 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 53 | AWS_DEFAULT_REGION: "eu-central-1" 54 | 55 | # deploy-test: 56 | # name: Deploy test site 57 | # runs-on: ubuntu-latest 58 | # steps: 59 | # - uses: actions/checkout@v2 60 | # - uses: pnpm/action-setup@v2.2.0 61 | # with: 62 | # version: latest 63 | # - uses: actions/setup-node@v2 64 | # with: 65 | # node-version: "16.x" 66 | # cache: pnpm 67 | # - run: pnpm adapter-deps 68 | # - run: pnpm build-adapter 69 | # - run: pnpm install 70 | # - run: pnpm build-test 71 | # - run: pnpm deploy-test 72 | # env: 73 | # AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 74 | # AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 75 | # AWS_DEFAULT_REGION: "eu-central-1" 76 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .pnpm-debug.log 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "yaml.schemas": { 3 | "https://json.schemastore.org/github-workflow.json": "file:///Users/juhani/src/sveltekit-cdk/.github/workflows/deploy.yml" 4 | } 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Juhani Ränkimies 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 CDK Adapter 2 | 3 | > ### WARNING: Not maintained 4 | > 5 | > Have a look at [SST](https://docs.sst.dev/) instead. 6 | 7 | 8 | > ### WARNING: Not for production, yet!! 9 | > 10 | > No compatibility between versions is garanteed while in [initial development](https://semver.org/#spec-item-4). It's recommended to use exact version in `package.json` to avoid suprices. 11 | 12 | This repo contains tooling to deploy SvelteKit sites to AWS using CDK. 13 | 14 | Tools are split to two packages: **adapter** that plugs into the sveltekit project, and 15 | **constructs** that are imported to CDK project to integrate SvelteKit site to other parts 16 | of your system. 17 | 18 | - **[@sveltekit-cdk/adapter](https://github.com/juranki/sveltekit-cdk/tree/main/packages/adapter#readme)** 19 | - plugs into the sveltekit project and makes site available to be consumed in CDK stacks 20 | - [![npm version](https://badge.fury.io/js/@sveltekit-cdk%2Fadapter.svg)](https://badge.fury.io/js/@sveltekit-cdk%2Fadapter) 21 | 22 | - **[@sveltekit-cdk/constructsv2](https://github.com/juranki/sveltekit-cdk/tree/main/packages/constructsv2#readme)** 23 | - SvelteDistribution construct bundles and deploys the site to Lambda@Edge and S3, and distributes it with CloudFront 24 | - [![npm version](https://badge.fury.io/js/@sveltekit-cdk%2Fconstructsv2.svg)](https://badge.fury.io/js/@sveltekit-cdk%2Fconstructsv2) 25 | 26 | ![](https://user-images.githubusercontent.com/6607/153542454-250fc3c6-7c83-401a-aade-73e03939ac2e.png) 27 | ## Howto 28 | 29 | **TODO: fill in details** 30 | 31 | 1. init sveltekit project 32 | 2. init cdk project 33 | 3. add adapter to sveltekit project and point it to cdk project 34 | 4. add constructs to cdk project 35 | 5. optionally edit cdk stacks to 36 | - hook site up with other resources 37 | - add custom domain and certificate 38 | - adjust capacity allocation 39 | - ... 40 | 41 | ## Status 42 | 43 | - In initial development, API IS NOT STABLE! 44 | - I feel quite confident about overall structure 45 | - Areas of uncertainty that are likely to cause significant changes (== opinions, feedback and advice appreciated) 46 | - ~~how to design constructs to be both intuitive and flexible; how much flexibility is really needed~~ **(2022-02-12: focus on ease or use and robustness, even at the expence of flexibility)** 47 | - ~~dependency management of constructs: cdk moves fast, v1 and v2 have different approaches to packaging and versioning~~ **(2022-02-12: only support v2)** 48 | - ~~adapter interface of sveltekit might still change a little~~ 49 | 50 | ### Links 51 | 52 | - [API reference](https://juranki.github.io/sveltekit-cdk/) 53 | - [@sveltekit-cdk/adapter changelog](https://github.com/juranki/sveltekit-cdk/blob/main/packages/adapter/CHANGELOG.md) 54 | - [@sveltekit-cdk/constructsv2 changelog](https://github.com/juranki/sveltekit-cdk/blob/main/packages/constructsv2/CHANGELOG.md) 55 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | rm -rf node_modules packages/adapter/node_modules packages/sample-site-v2/node_modules packages/test/node_modules packages/constructsv2/node_modules packages/sample-stack-v2/node_modules packages/test-stack/node_modules 3 | rm -rf packages/adapter/dist 4 | rm -rf packages/constructsv2/dist 5 | rm -rf packages/sample-site-v2/.svelte-kit 6 | rm -rf packages/sample-stack-v2/svetekit 7 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-code-background: #F5F5F5; 3 | --dark-code-background: #1E1E1E; 4 | } 5 | 6 | @media (prefers-color-scheme: light) { :root { 7 | --code-background: var(--light-code-background); 8 | } } 9 | 10 | @media (prefers-color-scheme: dark) { :root { 11 | --code-background: var(--dark-code-background); 12 | } } 13 | 14 | body.light { 15 | --code-background: var(--light-code-background); 16 | } 17 | 18 | body.dark { 19 | --code-background: var(--dark-code-background); 20 | } 21 | 22 | pre, code { background: var(--code-background); } 23 | -------------------------------------------------------------------------------- /docs/assets/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juranki/sveltekit-cdk/1fc170fc01eb9bae76b49d8d48056ee3b506f9c9/docs/assets/icons.png -------------------------------------------------------------------------------- /docs/assets/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juranki/sveltekit-cdk/1fc170fc01eb9bae76b49d8d48056ee3b506f9c9/docs/assets/icons@2x.png -------------------------------------------------------------------------------- /docs/assets/search.js: -------------------------------------------------------------------------------- 1 | window.searchData = JSON.parse("{\"kinds\":{\"2\":\"Module\",\"64\":\"Function\",\"128\":\"Class\",\"256\":\"Interface\",\"512\":\"Constructor\",\"1024\":\"Property\",\"65536\":\"Type literal\",\"4194304\":\"Type alias\"},\"rows\":[{\"id\":0,\"kind\":2,\"name\":\"@sveltekit-cdk/adapter\",\"url\":\"modules/_sveltekit_cdk_adapter.html\",\"classes\":\"tsd-kind-module\"},{\"id\":1,\"kind\":64,\"name\":\"adapter\",\"url\":\"modules/_sveltekit_cdk_adapter.html#adapter\",\"classes\":\"tsd-kind-function tsd-parent-kind-module\",\"parent\":\"@sveltekit-cdk/adapter\"},{\"id\":2,\"kind\":256,\"name\":\"AdapterParams\",\"url\":\"interfaces/_sveltekit_cdk_adapter.AdapterParams.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"@sveltekit-cdk/adapter\"},{\"id\":3,\"kind\":1024,\"name\":\"cdkProjectPath\",\"url\":\"interfaces/_sveltekit_cdk_adapter.AdapterParams.html#cdkProjectPath\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/adapter.AdapterParams\"},{\"id\":4,\"kind\":1024,\"name\":\"artifactPath\",\"url\":\"interfaces/_sveltekit_cdk_adapter.AdapterParams.html#artifactPath\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/adapter.AdapterParams\"},{\"id\":5,\"kind\":4194304,\"name\":\"StaticRoutes\",\"url\":\"modules/_sveltekit_cdk_adapter.html#StaticRoutes\",\"classes\":\"tsd-kind-type-alias tsd-parent-kind-module\",\"parent\":\"@sveltekit-cdk/adapter\"},{\"id\":6,\"kind\":2,\"name\":\"@sveltekit-cdk/constructsv2\",\"url\":\"modules/_sveltekit_cdk_constructsv2.html\",\"classes\":\"tsd-kind-module\"},{\"id\":7,\"kind\":128,\"name\":\"SvelteDistribution\",\"url\":\"classes/_sveltekit_cdk_constructsv2.SvelteDistribution.html\",\"classes\":\"tsd-kind-class tsd-parent-kind-module\",\"parent\":\"@sveltekit-cdk/constructsv2\"},{\"id\":8,\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/_sveltekit_cdk_constructsv2.SvelteDistribution.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class tsd-is-overwrite\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistribution\"},{\"id\":9,\"kind\":1024,\"name\":\"distribution\",\"url\":\"classes/_sveltekit_cdk_constructsv2.SvelteDistribution.html#distribution\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistribution\"},{\"id\":10,\"kind\":1024,\"name\":\"bucket\",\"url\":\"classes/_sveltekit_cdk_constructsv2.SvelteDistribution.html#bucket\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistribution\"},{\"id\":11,\"kind\":1024,\"name\":\"function\",\"url\":\"classes/_sveltekit_cdk_constructsv2.SvelteDistribution.html#function\",\"classes\":\"tsd-kind-property tsd-parent-kind-class\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistribution\"},{\"id\":12,\"kind\":256,\"name\":\"SvelteDistributionProps\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"@sveltekit-cdk/constructsv2\"},{\"id\":13,\"kind\":1024,\"name\":\"artifactPath\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html#artifactPath\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistributionProps\"},{\"id\":14,\"kind\":1024,\"name\":\"rendererProps\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html#rendererProps\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistributionProps\"},{\"id\":15,\"kind\":1024,\"name\":\"priceClass\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html#priceClass\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistributionProps\"},{\"id\":16,\"kind\":1024,\"name\":\"originRequestPolicy\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html#originRequestPolicy\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistributionProps\"},{\"id\":17,\"kind\":1024,\"name\":\"cachePolicy\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html#cachePolicy\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistributionProps\"},{\"id\":18,\"kind\":1024,\"name\":\"bucketProps\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html#bucketProps\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistributionProps\"},{\"id\":19,\"kind\":1024,\"name\":\"certificateArn\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html#certificateArn\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistributionProps\"},{\"id\":20,\"kind\":1024,\"name\":\"domainNames\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html#domainNames\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.SvelteDistributionProps\"},{\"id\":21,\"kind\":256,\"name\":\"RendererProps\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.RendererProps.html\",\"classes\":\"tsd-kind-interface tsd-parent-kind-module\",\"parent\":\"@sveltekit-cdk/constructsv2\"},{\"id\":22,\"kind\":1024,\"name\":\"artifactPath\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.RendererProps.html#artifactPath\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.RendererProps\"},{\"id\":23,\"kind\":1024,\"name\":\"environment\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.RendererProps.html#environment\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.RendererProps\"},{\"id\":24,\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.RendererProps.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.RendererProps\"},{\"id\":25,\"kind\":1024,\"name\":\"logLevel\",\"url\":\"interfaces/_sveltekit_cdk_constructsv2.RendererProps.html#logLevel\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"@sveltekit-cdk/constructsv2.RendererProps\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"parent\"],\"fieldVectors\":[[\"name/0\",[0,0.138,1,13.266]],[\"parent/0\",[]],[\"name/1\",[2,29.774]],[\"parent/1\",[0,0.018,1,1.733]],[\"name/2\",[3,29.774]],[\"parent/2\",[0,0.018,1,1.733]],[\"name/3\",[4,29.774]],[\"parent/3\",[0,0.018,5,2.301]],[\"name/4\",[6,21.046]],[\"parent/4\",[0,0.018,5,2.301]],[\"name/5\",[7,29.774]],[\"parent/5\",[0,0.018,1,1.733]],[\"name/6\",[0,0.138,8,13.266]],[\"parent/6\",[]],[\"name/7\",[9,29.774]],[\"parent/7\",[0,0.018,8,1.733]],[\"name/8\",[10,29.774]],[\"parent/8\",[0,0.018,11,1.733]],[\"name/9\",[12,29.774]],[\"parent/9\",[0,0.018,11,1.733]],[\"name/10\",[13,29.774]],[\"parent/10\",[0,0.018,11,1.733]],[\"name/11\",[14,29.774]],[\"parent/11\",[0,0.018,11,1.733]],[\"name/12\",[15,29.774]],[\"parent/12\",[0,0.018,8,1.733]],[\"name/13\",[6,21.046]],[\"parent/13\",[0,0.018,16,1.118]],[\"name/14\",[17,24.512]],[\"parent/14\",[0,0.018,16,1.118]],[\"name/15\",[18,29.774]],[\"parent/15\",[0,0.018,16,1.118]],[\"name/16\",[19,29.774]],[\"parent/16\",[0,0.018,16,1.118]],[\"name/17\",[20,29.774]],[\"parent/17\",[0,0.018,16,1.118]],[\"name/18\",[21,29.774]],[\"parent/18\",[0,0.018,16,1.118]],[\"name/19\",[22,29.774]],[\"parent/19\",[0,0.018,16,1.118]],[\"name/20\",[23,29.774]],[\"parent/20\",[0,0.018,16,1.118]],[\"name/21\",[17,24.512]],[\"parent/21\",[0,0.018,8,1.733]],[\"name/22\",[6,21.046]],[\"parent/22\",[0,0.018,24,1.733]],[\"name/23\",[25,29.774]],[\"parent/23\",[0,0.018,24,1.733]],[\"name/24\",[26,29.774]],[\"parent/24\",[0,0.018,24,1.733]],[\"name/25\",[27,29.774]],[\"parent/25\",[0,0.018,24,1.733]]],\"invertedIndex\":[[\"__type\",{\"_index\":26,\"name\":{\"24\":{}},\"parent\":{}}],[\"adapter\",{\"_index\":2,\"name\":{\"1\":{}},\"parent\":{}}],[\"adapterparams\",{\"_index\":3,\"name\":{\"2\":{}},\"parent\":{}}],[\"artifactpath\",{\"_index\":6,\"name\":{\"4\":{},\"13\":{},\"22\":{}},\"parent\":{}}],[\"bucket\",{\"_index\":13,\"name\":{\"10\":{}},\"parent\":{}}],[\"bucketprops\",{\"_index\":21,\"name\":{\"18\":{}},\"parent\":{}}],[\"cachepolicy\",{\"_index\":20,\"name\":{\"17\":{}},\"parent\":{}}],[\"cdk/adapter\",{\"_index\":1,\"name\":{\"0\":{}},\"parent\":{\"1\":{},\"2\":{},\"5\":{}}}],[\"cdk/adapter.adapterparams\",{\"_index\":5,\"name\":{},\"parent\":{\"3\":{},\"4\":{}}}],[\"cdk/constructsv2\",{\"_index\":8,\"name\":{\"6\":{}},\"parent\":{\"7\":{},\"12\":{},\"21\":{}}}],[\"cdk/constructsv2.rendererprops\",{\"_index\":24,\"name\":{},\"parent\":{\"22\":{},\"23\":{},\"24\":{},\"25\":{}}}],[\"cdk/constructsv2.sveltedistribution\",{\"_index\":11,\"name\":{},\"parent\":{\"8\":{},\"9\":{},\"10\":{},\"11\":{}}}],[\"cdk/constructsv2.sveltedistributionprops\",{\"_index\":16,\"name\":{},\"parent\":{\"13\":{},\"14\":{},\"15\":{},\"16\":{},\"17\":{},\"18\":{},\"19\":{},\"20\":{}}}],[\"cdkprojectpath\",{\"_index\":4,\"name\":{\"3\":{}},\"parent\":{}}],[\"certificatearn\",{\"_index\":22,\"name\":{\"19\":{}},\"parent\":{}}],[\"constructor\",{\"_index\":10,\"name\":{\"8\":{}},\"parent\":{}}],[\"distribution\",{\"_index\":12,\"name\":{\"9\":{}},\"parent\":{}}],[\"domainnames\",{\"_index\":23,\"name\":{\"20\":{}},\"parent\":{}}],[\"environment\",{\"_index\":25,\"name\":{\"23\":{}},\"parent\":{}}],[\"function\",{\"_index\":14,\"name\":{\"11\":{}},\"parent\":{}}],[\"loglevel\",{\"_index\":27,\"name\":{\"25\":{}},\"parent\":{}}],[\"originrequestpolicy\",{\"_index\":19,\"name\":{\"16\":{}},\"parent\":{}}],[\"priceclass\",{\"_index\":18,\"name\":{\"15\":{}},\"parent\":{}}],[\"rendererprops\",{\"_index\":17,\"name\":{\"14\":{},\"21\":{}},\"parent\":{}}],[\"staticroutes\",{\"_index\":7,\"name\":{\"5\":{}},\"parent\":{}}],[\"sveltedistribution\",{\"_index\":9,\"name\":{\"7\":{}},\"parent\":{}}],[\"sveltedistributionprops\",{\"_index\":15,\"name\":{\"12\":{}},\"parent\":{}}],[\"sveltekit\",{\"_index\":0,\"name\":{\"0\":{},\"6\":{}},\"parent\":{\"1\":{},\"2\":{},\"3\":{},\"4\":{},\"5\":{},\"7\":{},\"8\":{},\"9\":{},\"10\":{},\"11\":{},\"12\":{},\"13\":{},\"14\":{},\"15\":{},\"16\":{},\"17\":{},\"18\":{},\"19\":{},\"20\":{},\"21\":{},\"22\":{},\"23\":{},\"24\":{},\"25\":{}}}]],\"pipeline\":[]}}"); -------------------------------------------------------------------------------- /docs/assets/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juranki/sveltekit-cdk/1fc170fc01eb9bae76b49d8d48056ee3b506f9c9/docs/assets/widgets.png -------------------------------------------------------------------------------- /docs/assets/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juranki/sveltekit-cdk/1fc170fc01eb9bae76b49d8d48056ee3b506f9c9/docs/assets/widgets@2x.png -------------------------------------------------------------------------------- /docs/classes/_sveltekit_cdk_constructsv2.SvelteDistribution.html: -------------------------------------------------------------------------------- 1 | SvelteDistribution | sveltekit-cdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • Construct
    • SvelteDistribution

Index

Constructors

Properties

bucket: Bucket
distribution: Distribution
function?: EdgeFunction

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | sveltekit-cdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

sveltekit-cdk

2 | 3 |

SvelteKit CDK Adapter

4 |
5 |
6 | 7 | 8 |

WARNING: Not for production, yet!!

9 |
10 |

No compatibility between versions is garanteed while in initial development. It's recommended to use exact version in package.json to avoid suprices.

11 |
12 |

This repo contains tooling to deploy SvelteKit sites to AWS using CDK.

13 |

Tools are split to two packages: adapter that plugs into the sveltekit project, and 14 | constructs that are imported to CDK project to integrate SvelteKit site to other parts 15 | of your system.

16 |
    17 |
  • @sveltekit-cdk/adapter

    18 |
      19 |
    • plugs into the sveltekit project and makes site available to be consumed in CDK stacks
    • 20 |
    • npm version
    • 21 |
    22 |
  • 23 |
  • @sveltekit-cdk/constructsv2

    24 |
      25 |
    • SvelteDistribution construct bundles and deploys the site to Lambda@Edge and S3, and distributes it with CloudFront
    • 26 |
    • npm version
    • 27 |
    28 |
  • 29 |
30 |

31 | 32 | 33 |

Howto

34 |
35 |

TODO: fill in details

36 |
    37 |
  1. init sveltekit project
  2. 38 |
  3. init cdk project
  4. 39 |
  5. add adapter to sveltekit project and point it to cdk project
  6. 40 |
  7. add constructs to cdk project
  8. 41 |
  9. optionally edit cdk stacks to
      42 |
    • hook site up with other resources
    • 43 |
    • add custom domain and certificate
    • 44 |
    • adjust capacity allocation
    • 45 |
    • ...
    • 46 |
    47 |
  10. 48 |
49 | 50 | 51 |

Status

52 |
53 |
    54 |
  • In initial development, API IS NOT STABLE!
  • 55 |
  • I feel quite confident about overall structure
  • 56 |
  • Areas of uncertainty that are likely to cause significant changes (== opinions, feedback and advice appreciated)
      57 |
    • how to design constructs to be both intuitive and flexible; how much flexibility is really needed (2022-02-12: focus on ease or use and robustness, even at the expence of flexibility)
    • 58 |
    • dependency management of constructs: cdk moves fast, v1 and v2 have different approaches to packaging and versioning (2022-02-12: only support v2)
    • 59 |
    • adapter interface of sveltekit might still change a little
    • 60 |
    61 |
  • 62 |
63 | 64 | 65 |

Links

66 |
67 | 72 |

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/interfaces/_sveltekit_cdk_adapter.AdapterParams.html: -------------------------------------------------------------------------------- 1 | AdapterParams | sveltekit-cdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • AdapterParams

Index

Properties

artifactPath?: string
2 |

Path to store sveltekit artifacts.

3 |

One of cdkProjectPath or artifactPath is required.

4 |
default

${cdkProjectPath}/sveltekit

5 |
cdkProjectPath?: string
6 |

Location of CDK project.

7 |

One of cdkProjectPath or artifactPath is required.

8 |

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/interfaces/_sveltekit_cdk_constructsv2.RendererProps.html: -------------------------------------------------------------------------------- 1 | RendererProps | sveltekit-cdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • RendererProps

Index

Properties

artifactPath?: string
2 |

Location of sveltekit artifacts

3 |
default

'sveltekit'

4 |
environment?: {}
5 |

Environment variables for the backend implementation

6 |

Type declaration

  • [key: string]: string
logLevel?: "ERROR" | "WARN" | "INFO" | "DEBUG"
7 |

Logging verbosity (default: INFO)

8 |

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/interfaces/_sveltekit_cdk_constructsv2.SvelteDistributionProps.html: -------------------------------------------------------------------------------- 1 | SvelteDistributionProps | sveltekit-cdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • SvelteDistributionProps

Index

Properties

artifactPath?: string
2 |

Location of sveltekit artifacts

3 |
default

'sveltekit'

4 |
bucketProps?: BucketProps
5 |

Bucket props for the svelteStaticBucket s3 bucket.

6 |
link

https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-s3.BucketProps.html

7 |
cachePolicy?: ICachePolicy
8 |

Cache policy determies caching for dynamic content.

9 |

Note: static content is cached using default setting (CACHING_OPTIMIZED).

10 |
default

CACHING_DISABLED

11 |
link

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html

12 |
certificateArn?: string
13 |

Certificate to use with the CloudFront Distribution

14 |
default

undefined

15 |
domainNames?: string[]
16 |

Domain names to associate with the CloudFront Distribution

17 |
default

undefined

18 |
originRequestPolicy?: IOriginRequestPolicy
19 |

Origin request policy determines which parts of requests 20 | CloudFront passes to your backend

21 |
default

AllViewer managed policy

22 |
link

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html

23 |
priceClass?: PriceClass
rendererProps?: RendererProps
28 |

Props for Lambda@Edge renderer

29 |

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/modules.html: -------------------------------------------------------------------------------- 1 | sveltekit-cdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

sveltekit-cdk

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/modules/_sveltekit_cdk_adapter.html: -------------------------------------------------------------------------------- 1 | @sveltekit-cdk/adapter | sveltekit-cdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Module @sveltekit-cdk/adapter

Index

Interfaces

Type Aliases

Functions

Type Aliases

StaticRoutes: Record<string, "prerendered" | "static">

Functions

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/modules/_sveltekit_cdk_constructsv2.html: -------------------------------------------------------------------------------- 1 | @sveltekit-cdk/constructsv2 | sveltekit-cdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Module @sveltekit-cdk/constructsv2

Generated using TypeDoc

-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sveltekit-cdk", 3 | "version": "0.0.1", 4 | "description": "Tools for deploying SvelteKit to AWS using CDK", 5 | "private": true, 6 | "main": "index.js", 7 | "scripts": { 8 | "adapter-deps": "pnpm --filter=\"@sveltekit-cdk/*\" install", 9 | "build-adapter": "pnpm --filter=\"@sveltekit-cdk/*\" build", 10 | "build-sample": "pnpm --filter=\"sample-site-v2\" build", 11 | "build-test": "pnpm --filter=\"test\" build", 12 | "synth": "pnpm --filter=\"sample-stack-v2\" synth", 13 | "diff": "pnpm --filter=\"sample-stack-v2\" diff", 14 | "deploy-sample": "pnpm --filter=\"sample-stack-v2\" run deploy --all", 15 | "deploy-test": "pnpm --filter=\"test-stack\" run deploy", 16 | "bump": "changeset version", 17 | "pub": "pnpm --filter=\"@sveltekit-cdk/*\" publish --access public" 18 | }, 19 | "keywords": [], 20 | "author": "juhani@juranki.com", 21 | "license": "MIT", 22 | "devDependencies": { 23 | "@changesets/cli": "^2.17.0", 24 | "typedoc": "^0.22.17", 25 | "typescript": "^4.7.3" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/adapter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /packages/adapter/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/adapter/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # sveltekit-cdk-adapter 2 | 3 | ## 0.11.0 4 | 5 | ### Minor Changes 6 | 7 | - 1fce418: BREAKING! remove headers adapter option (all headers passed to app by default) 8 | 9 | ## 0.10.0 10 | 11 | ### Minor Changes 12 | 13 | - c99f66b: remove deprecated AwsServerlessAdapter 14 | 15 | ## 0.9.1 16 | 17 | ### Patch Changes 18 | 19 | - d8184ce: add missing peer dependency 20 | 21 | ## 0.9.0 22 | 23 | ### Minor Changes 24 | 25 | - update sveltekit to ^1.0.0 26 | - fix handling of request headers 27 | 28 | ### Patch Changes 29 | 30 | - init sveltekit server 31 | - simplify handling of pre-rendered routes 32 | - node-fetch > undici 33 | 34 | ## 0.8.0 35 | 36 | ### Minor Changes 37 | 38 | - adjust to sveltekit changes (remove writeStatic, sveltejs/kit#5618) 39 | 40 | ### Patch Changes 41 | 42 | - fix warnings when bundling site (#11) 43 | - allow + in path of static file (related to sveltejs/kit#5748) 44 | 45 | ## 0.7.7 46 | 47 | ### Patch Changes 48 | 49 | - adjust to sveltekit changes (sveltejs/kit#4934) 50 | 51 | ## 0.7.6 52 | 53 | ### Patch Changes 54 | 55 | - add client address provider 56 | 57 | ## 0.7.5 58 | 59 | ### Patch Changes 60 | 61 | - 7399f8f: Allow CDK tokens (values that are evaluated during deploy) in renderer environment 62 | 63 | ## 0.7.4 64 | 65 | ### Patch Changes 66 | 67 | - 2cdd82b: adjust to adapter changes (1.0.0-next.282 -> 1.0.0-next.292) 68 | 69 | ## 0.7.3 70 | 71 | ### Patch Changes 72 | 73 | - fix build on win32 74 | 75 | ## 0.7.2 76 | 77 | ### Patch Changes 78 | 79 | - a863f90: adjust to breaking changes in @sveltejs/kit@1.0.0-next.280 80 | - 1a10ef9: fix transformation of binary request body 81 | - 4e8a024: fix transformation of binary response body 82 | 83 | ## 0.7.1 84 | 85 | ### Patch Changes 86 | 87 | - fix routing for /index.svelte when it's not prerendered 88 | 89 | ## 0.7.0 90 | 91 | ### Major Changes 92 | 93 | - BREAKING: Drop support for CDK v1 94 | - BREAKING: only support one configuration of CloudFront, Lambda@Edge and S3 95 | 96 | ### Patch Changes 97 | 98 | - Solve problems with prerendered pages 99 | - Fix problems with caching of SSR pages 100 | - Block headers that are blacklisted by CloudFront 101 | 102 | ## 0.6.2 103 | 104 | ### Patch Changes 105 | 106 | - refactor shim handling and adapter compile order 107 | - change package type to esmodule 108 | 109 | ## 0.6.1 110 | 111 | ### Patch Changes 112 | 113 | - Construct Request object with body 114 | 115 | ## 0.6.0 116 | 117 | ### Minor Changes 118 | 119 | - Comply with changes in SvelteKit adapter interface (1.0.0-next.240) 120 | 121 | ## 0.5.0 122 | 123 | ### Minor Changes 124 | 125 | - Adjust to changes in SvelteKit adapter interface (contributed by KayoticSully) 126 | 127 | ## 0.4.0 128 | 129 | ### Minor Changes 130 | 131 | - inject environment variables to lambda@edge adapter 132 | 133 | ### Patch Changes 134 | 135 | - handle empty response body in lambda@edge adapter 136 | 137 | ## 0.3.1 138 | 139 | ### Patch Changes 140 | 141 | - log level handling in renderer adapters 142 | - exclude externals from api doc 143 | 144 | ## 0.3.0 145 | 146 | ### Minor Changes 147 | 148 | - Add option to deploy rendered as Lambda@Edge function that is 149 | attached to the distribution. 150 | 151 | Caused some refactoring in constructs and definately broke the API. 152 | Api still doesn't feel right, so expect more of that. 153 | 154 | ## 0.2.1 155 | 156 | ### Patch Changes 157 | 158 | - 5ba4e28: update package info for npm 159 | 160 | ## 0.2.0 161 | 162 | ### Minor Changes 163 | 164 | - This is initial release, which provides just enough functionality to deploy the demo site. 165 | -------------------------------------------------------------------------------- /packages/adapter/README.md: -------------------------------------------------------------------------------- 1 | # @sveltekit-cdk/adapter 2 | 3 | [![npm version](https://badge.fury.io/js/@sveltekit-cdk%2Fadapter.svg)](https://badge.fury.io/js/@sveltekit-cdk%2Fadapter) 4 | 5 | > ### WARNING: Not for production, yet!! 6 | > 7 | > No compatibility between versions is garanteed while in [initial development](https://semver.org/#spec-item-4). It's recommended to use exact version in `package.json` to avoid suprices. 8 | 9 | ## Intro 10 | 11 | Prepare the artifacts for your SvelteKit site using this adapter. 12 | 13 | Then use `SvelteDistribution` construct from [@sveltekit-cdk/constructsv2](https://github.com/juranki/sveltekit-cdk/tree/main/packages/constructsv2#readme) 14 | to include the site to your CDK stack. 15 | 16 | ## Instructions 17 | 18 | 1. In sveltekit project: 19 | ```bash 20 | > npm i -s @sveltekit-cdk/adapter 21 | ``` 22 | 2. In `svelte.config.js` 23 | ```javascript 24 | import preprocess from 'svelte-preprocess'; 25 | import { adapter } from '@sveltekit-cdk/adapter' 26 | 27 | const config = { 28 | preprocess: preprocess(), 29 | 30 | kit: { 31 | // hydrate the
element in src/app.html 32 | target: '#svelte', 33 | adapter: adapter({ 34 | cdkProjectPath: '../the-cdk-project' 35 | }) 36 | } 37 | }; 38 | 39 | export default config; 40 | ``` 41 | 42 | 43 | ### Links 44 | 45 | - [API reference](https://juranki.github.io/sveltekit-cdk/modules/_sveltekit_cdk_adapter.html) 46 | - [Changelog](https://github.com/juranki/sveltekit-cdk/blob/main/packages/adapter/CHANGELOG.md) 47 | 48 | -------------------------------------------------------------------------------- /packages/adapter/finalize-build.cjs: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | fs.copyFileSync(path.join(__dirname, 'shims.js'), path.join(__dirname, 'dist', 'files', 'shims.js')) -------------------------------------------------------------------------------- /packages/adapter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@sveltekit-cdk/adapter", 3 | "version": "0.11.0", 4 | "description": "Plug this adapter to your SvelteKit project to deploy using AWS CDK", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/juranki/sveltekit-cdk.git" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/juranki/sveltekit-cdk/issues" 11 | }, 12 | "homepage": "https://github.com/juranki/sveltekit-cdk#readme", 13 | "license": "MIT", 14 | "main": "dist/index.js", 15 | "types": "dist/index.d.ts", 16 | "type": "module", 17 | "scripts": { 18 | "build": "node prepare-build.cjs && tsc && node finalize-build.cjs" 19 | }, 20 | "keywords": [ 21 | "sveltekit", 22 | "aws", 23 | "cdk" 24 | ], 25 | "author": "juhani@juranki.com", 26 | "devDependencies": { 27 | "@sveltejs/kit": "^1.0.0", 28 | "@types/aws-lambda": "^8.10.109", 29 | "@types/node": "17.0.39", 30 | "rimraf": "^3.0.2", 31 | "typescript": "^4.7.3", 32 | "undici": "5.14.0", 33 | "vite": "^4.0.0" 34 | }, 35 | "dependencies": { 36 | "esbuild": "^0.14.42" 37 | }, 38 | "peerDependencies": { 39 | "@sveltejs/kit": "^1.0.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/adapter/prepare-build.cjs: -------------------------------------------------------------------------------- 1 | require('rimraf')('dist', (err) => { 2 | if(err) { 3 | throw err 4 | } 5 | }) -------------------------------------------------------------------------------- /packages/adapter/shims.js: -------------------------------------------------------------------------------- 1 | import { installPolyfills } from '@sveltejs/kit/node/polyfills'; 2 | installPolyfills() -------------------------------------------------------------------------------- /packages/adapter/src/files/ambient.d.ts: -------------------------------------------------------------------------------- 1 | export { } 2 | declare global { 3 | export { HeadersInit, Response, Request, Headers } from 'undici'; 4 | } -------------------------------------------------------------------------------- /packages/adapter/src/files/app.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'SERVER' { 2 | export { Server } from '@sveltejs/kit'; 3 | } 4 | 5 | declare module 'MANIFEST' { 6 | import { SSRManifest } from '@sveltejs/kit'; 7 | 8 | export const manifest: SSRManifest; 9 | } 10 | 11 | declare module 'PRERENDERED' { 12 | export const prerenderedPages: { [route: string]: string } 13 | } 14 | 15 | declare var SVELTEKIT_CDK_ENV_MAP: Record | undefined 16 | declare var SVELTEKIT_CDK_LOG_LEVEL: 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' -------------------------------------------------------------------------------- /packages/adapter/src/files/at-edge-handler.ts: -------------------------------------------------------------------------------- 1 | import { Server } from 'SERVER' 2 | import { manifest } from 'MANIFEST' 3 | import { prerenderedPages } from 'PRERENDERED' 4 | import type { 5 | CloudFrontHeaders, 6 | CloudFrontRequest, 7 | CloudFrontRequestHandler, 8 | CloudFrontResultResponse 9 | } from 'aws-lambda' 10 | import { log, toRawBody } from './util' 11 | import { isBlaclisted } from './header-blacklist' 12 | 13 | const server = new Server(manifest) 14 | let envReady = false 15 | let initDone = false 16 | const svelteEnv: { [key: string]: string } = {} 17 | 18 | export const handler: CloudFrontRequestHandler = async (event, context) => { 19 | 20 | log('DEBUG', 'incoming event', event) 21 | 22 | if (event.Records.length !== 1) { 23 | log('ERROR', 'bad request', event) 24 | return { 25 | status: '400', 26 | statusDescription: 'bad request', 27 | } 28 | } 29 | const request = event.Records[0].cf.request 30 | const config = event.Records[0].cf.config 31 | const customHeaders = request.origin?.s3?.customHeaders 32 | const uri: string = request.uri === '' ? '/' : request.uri 33 | 34 | if (prerenderedPages[uri]) { 35 | log('DEBUG', 'loadPrerendered', { 36 | uri: request.uri, 37 | path: prerenderedPages[uri] 38 | }) 39 | request.uri = `/${prerenderedPages[uri]}` 40 | request.headers = getS3Headers(request) 41 | return request 42 | } 43 | 44 | if (!envReady && SVELTEKIT_CDK_ENV_MAP && customHeaders) { 45 | for (const headerName in SVELTEKIT_CDK_ENV_MAP) { 46 | process.env[SVELTEKIT_CDK_ENV_MAP[headerName]] = customHeaders[headerName][0].value 47 | svelteEnv[SVELTEKIT_CDK_ENV_MAP[headerName]] = customHeaders[headerName][0].value 48 | } 49 | log('DEBUG', 'process.env', process.env) 50 | envReady = true 51 | } 52 | 53 | if (!initDone) { 54 | await server.init({ env: svelteEnv }) 55 | initDone = true 56 | } 57 | 58 | if (request.body && request.body.inputTruncated) { 59 | log('ERROR', 'input trucated', request) 60 | log('ERROR', 'ref', 'https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html#lambda-at-edge-function-restrictions') 61 | throw new Error("input truncated"); 62 | } 63 | 64 | const domain = request.headers.host.length > 0 ? request.headers.host[0].value : config.distributionDomainName 65 | const querystring = request.querystring ? `?${request.querystring}` : '' 66 | 67 | const headers = transformIncomingHeaders(request.headers) 68 | log('DEBUG', 'request headers', headers) 69 | log('DEBUG', 'domain', headers) 70 | 71 | const input: Request = new Request(`https://${domain}${request.uri}${querystring}`, { 72 | headers, 73 | method: request.method, 74 | body: request.body && request.body.data.length > 0 ? toRawBody(request.body) : undefined, 75 | }) 76 | 77 | const rendered = await server.respond(input, { 78 | getClientAddress() { 79 | const addrHeader = request.headers['x-forwarded-for'] 80 | if (addrHeader) { 81 | return addrHeader[0].value 82 | } 83 | return '' 84 | }, 85 | }) 86 | 87 | if (rendered) { 88 | const outgoing: CloudFrontResultResponse = await transformResponse(rendered) 89 | log('DEBUG', 'outgoing response', outgoing) 90 | log('INFO', 'handler', { 91 | path: request.uri, 92 | status: rendered.status, 93 | }) 94 | return outgoing 95 | } 96 | 97 | log('INFO', 'handler', { 98 | path: request.uri, 99 | status: 404, 100 | }) 101 | return { 102 | status: '404', 103 | statusDescription: 'not found', 104 | } 105 | } 106 | 107 | function transformIncomingHeaders(headers: CloudFrontHeaders): HeadersInit { 108 | return Object.fromEntries( 109 | Object.entries(headers).map(([k, vs]) => ( 110 | [k, vs[0].value] 111 | )) 112 | ) 113 | } 114 | 115 | function bodyEncondingFromMime(mime: string | null): 'base64' | 'text' | undefined { 116 | if (!mime) return undefined 117 | mime = mime.split(';')[0] // remove parameters 118 | if (mime.startsWith('text/')) return 'text' 119 | if (mime.endsWith('+xml')) return 'text' 120 | if ([ 121 | 'application/json', 122 | 'application/xml', 123 | 'application/js', 124 | 'application/javascript', 125 | ].includes(mime)) return 'text' 126 | 127 | return 'base64' 128 | } 129 | 130 | async function transformResponse(rendered: Response): Promise { 131 | const bodyEncoding = bodyEncondingFromMime(rendered.headers.get('content-type')) 132 | let body: string | undefined 133 | 134 | if (bodyEncoding === 'text') { 135 | body = await rendered.text() 136 | } else if (bodyEncoding === 'base64') { 137 | const aBuf = await rendered.arrayBuffer() 138 | const buf = Buffer.from(aBuf) 139 | body = buf.toString('base64') 140 | } 141 | 142 | return { 143 | status: rendered.status.toString(), 144 | headers: transformOutgoingHeaders(rendered.headers), 145 | body, 146 | bodyEncoding, 147 | } 148 | } 149 | 150 | function transformOutgoingHeaders(headers: Headers): CloudFrontHeaders { 151 | const rv: CloudFrontHeaders = {} 152 | headers.forEach((v: string, k: string) => { 153 | if (isBlaclisted(k.toLowerCase())) return 154 | rv[k.toLowerCase()] = [{ 155 | key: k, 156 | value: v, 157 | }] 158 | }) 159 | // default to not caching SSR content 160 | if (!rv['cache-control']) { 161 | rv['cache-control'] = [{ 162 | key: 'Cache-Control', 163 | value: 'no-store', 164 | }] 165 | } 166 | return rv 167 | } 168 | 169 | /** 170 | * Headers for s3 GetObject request 171 | */ 172 | function getS3Headers(request: CloudFrontRequest): CloudFrontHeaders { 173 | return { 174 | host: [{key: 'Host', value: request.origin!.s3!.domainName}], 175 | accept: request.headers.accept, 176 | 'x-forwarded-for': request.headers['x-forwarded-for'], 177 | 'user-agent': [{key: 'User-Agent', value: 'Amazon CloudFront'}], 178 | via: request.headers.via, 179 | pragma: [{key: 'Pragma', value: 'no-cache'}], 180 | 'cache-control': [{key: 'Cache-Control', value: 'no-cache'}], 181 | } 182 | } 183 | 184 | -------------------------------------------------------------------------------- /packages/adapter/src/files/header-blacklist.ts: -------------------------------------------------------------------------------- 1 | // https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html 2 | 3 | import { log } from "./util" 4 | 5 | export function isBlaclisted(header: string): boolean { 6 | if (blacklist.includes(header)) { 7 | log('WARN', 'App.render emitted blacklisted header', header) 8 | return true 9 | } 10 | if (readonly.includes(header)) { 11 | log('WARN', 'App.render emitted readonly header', header) 12 | return true 13 | } 14 | for (const b of prefixBlacklist) { 15 | if (header.startsWith(b)) { 16 | log('WARN', 'App.render emitted blacklisted header', header) 17 | return true 18 | } 19 | } 20 | return false 21 | } 22 | 23 | const blacklist = [ 24 | 'connection', 25 | 'expect', 26 | 'keep-alive', 27 | 'proxy-authenticate', 28 | 'proxy-authorization', 29 | 'proxy-connection', 30 | 'trailer', 31 | 'upgrade', 32 | 'x-accel-buffering', 33 | 'x-accel-charset', 34 | 'x-accel-limit-rate', 35 | 'x-accel-redirect', 36 | 'x-cache', 37 | 'x-forwarded-proto', 38 | 'x-real-ip', 39 | ] 40 | 41 | const prefixBlacklist = [ 42 | 'x-amz-cf-', 43 | 'x-edge-', 44 | ] 45 | 46 | const readonly = [ 47 | 'accept-encoding', 48 | 'content-length', 49 | 'if-modified-since', 50 | 'if-none-match', 51 | 'if-range', 52 | 'if-unmodified-since', 53 | 'transfer-encoding', 54 | 'via', 55 | ] -------------------------------------------------------------------------------- /packages/adapter/src/files/util.ts: -------------------------------------------------------------------------------- 1 | 2 | // LOGGING UTILITIES 3 | export type LogLevel = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' 4 | 5 | const logLevels: { [k: string]: number } = { 6 | ERROR: 4, 7 | WARN: 3, 8 | INFO: 2, 9 | DEBUG: 1, 10 | } 11 | export function log(level: LogLevel, msg: string, data: any): void { 12 | if (logLevels[level] && logLevels[level] >= logLevels[SVELTEKIT_CDK_LOG_LEVEL]) { 13 | console.log(JSON.stringify({ level, msg, data })) 14 | } 15 | } 16 | 17 | 18 | // REQUEST TRANSFORMATION UTILITIES 19 | export interface BodyInfo { 20 | data: string 21 | encoding: 'base64' | 'text' 22 | } 23 | 24 | export function toRawBody(body: BodyInfo): Buffer | string { 25 | return body.encoding === 'base64' 26 | ? Buffer.from(body.data, 'base64') 27 | : body.data 28 | } 29 | -------------------------------------------------------------------------------- /packages/adapter/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Adapter, Builder } from '@sveltejs/kit' 2 | import * as path from 'path' 3 | import { build } from 'esbuild' 4 | import { writeFileSync, mkdirSync, renameSync } from 'fs'; 5 | 6 | export interface AdapterParams { 7 | /** 8 | * Location of CDK project. 9 | * 10 | * One of `cdkProjectPath` or `artifactPath` is required. 11 | */ 12 | cdkProjectPath?: string 13 | /** 14 | * Path to store sveltekit artifacts. 15 | * 16 | * One of `cdkProjectPath` or `artifactPath` is required. 17 | * 18 | * @default ${cdkProjectPath}/sveltekit 19 | */ 20 | artifactPath?: string 21 | } 22 | 23 | /** 24 | * Returns adapter that prepares SvelteKit site for deployment with AWS CDK V2 25 | */ 26 | export function adapter({ cdkProjectPath, artifactPath }: AdapterParams): Adapter { 27 | if (!cdkProjectPath && !artifactPath) { 28 | throw new Error("at least one of cdkProjectPath or artifactPath is required"); 29 | } 30 | return { 31 | name: 'sveltekit-cdk-adapter', 32 | async adapt(builder): Promise { 33 | let dirname = path.dirname(import.meta.url).split('file://')[1] 34 | if (process.platform === 'win32') { 35 | // remove first slash from path 36 | dirname = dirname.substring(1) 37 | } 38 | const targetPath = artifactPath || path.join(cdkProjectPath!, 'sveltekit') 39 | const files = path.join(dirname, 'files'); 40 | const dirs = { 41 | prerendered: path.join(targetPath, 'prerendered'), 42 | static: path.join(targetPath, 'static'), 43 | lambda: path.join(targetPath, 'lambda'), 44 | } 45 | 46 | builder.rimraf(targetPath) 47 | builder.rimraf(builder.getBuildDirectory('cdk')) 48 | 49 | const prerendered = builder.writePrerendered(dirs.prerendered) 50 | const clientfiles = builder.writeClient(dirs.static) 51 | 52 | // UGLY WORKAROUND FOR CF/S3 ROUTING FOR FILES WITH + IN PATH 53 | for (let filename of clientfiles.filter(f => f.includes('+'))) { 54 | const newFilename = filename.replaceAll('+', ' ') 55 | renameSync(path.join(dirs.static, filename), path.join(dirs.static, newFilename)) 56 | } 57 | 58 | writeFileSync( 59 | path.join(targetPath, 'client.json'), 60 | `[${clientfiles.map(p => `"${p}"`).join(',')}]` 61 | ) 62 | 63 | writeRoutes( 64 | path.join(targetPath, 'routes.json'), 65 | prerendered, clientfiles 66 | ) 67 | mkdirSync(builder.getBuildDirectory('cdk'), { recursive: true }) 68 | const copiedFiles = builder.copy(files, builder.getBuildDirectory('cdk'), { 69 | replace: { 70 | SERVER: '../output/server/index', 71 | MANIFEST: '../output/server/manifest', 72 | PRERENDERED: './prerendered', 73 | } 74 | }) 75 | writePrerenderedTs( 76 | path.join(builder.getBuildDirectory('cdk'), 'prerendered.ts'), 77 | builder, 78 | ) 79 | await build({ 80 | entryPoints: [path.join(builder.getBuildDirectory('cdk'), 'at-edge-handler.js')], 81 | outfile: path.join(dirs.lambda, 'at-edge/handler.js'), 82 | bundle: true, 83 | platform: 'node', 84 | inject: [path.join(builder.getBuildDirectory('cdk'), 'shims.js')], 85 | }) 86 | builder.log(`CDK artifacts were written to ${targetPath}`) 87 | }, 88 | } 89 | } 90 | export type StaticRoutes = Record 91 | function writeRoutes(path: string, pre: string[], cli: string[]) { 92 | const rv: StaticRoutes = {}; 93 | 94 | cli.forEach(p => { 95 | const ps = p.split('/') 96 | const glob = ps.length > 1 ? `${ps[0]}/*` : p 97 | rv[glob] = 'static' 98 | }); 99 | pre.forEach(p => { 100 | let glob: string 101 | if (p === 'index.html') { 102 | glob = '/' 103 | } else { 104 | const ps = p.split('/') 105 | glob = ps.length > 1 ? `${ps[0]}/*` : p 106 | glob = `/${glob}` 107 | } 108 | if (rv[glob] === 'static') { 109 | throw new Error('CDK Adapter cannot handle top level routes that mix static and pre-rendered content, yet') 110 | } 111 | rv[glob] = 'prerendered' 112 | }) 113 | 114 | writeFileSync(path, JSON.stringify(rv, null, 2)) 115 | } 116 | function writePrerenderedTs(path: string, builder: Builder) { 117 | const prerenderedPages: { [route: string]: string } = {} 118 | builder.prerendered.pages.forEach((v, k) => { 119 | prerenderedPages[k] = v.file 120 | }) 121 | writeFileSync( 122 | path, 123 | [ 124 | `export const prerenderedPages = ${JSON.stringify(prerenderedPages)}` 125 | ].join('\n') 126 | ) 127 | } 128 | -------------------------------------------------------------------------------- /packages/adapter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ES2020", 4 | "outDir": "dist", 5 | "target": "ES2020", 6 | "allowJs": true, 7 | "allowSyntheticDefaultImports": true, 8 | "baseUrl": "src", 9 | "declaration": true, 10 | "esModuleInterop": true, 11 | "inlineSourceMap": false, 12 | "sourceMap": true, 13 | "lib": [ 14 | "esnext" 15 | ], 16 | "listEmittedFiles": false, 17 | "listFiles": false, 18 | "moduleResolution": "node", 19 | "noFallthroughCasesInSwitch": true, 20 | "pretty": true, 21 | "resolveJsonModule": true, 22 | "rootDir": "src", 23 | "skipLibCheck": true, 24 | "strict": true, 25 | "traceResolution": false, 26 | "types": [ 27 | "node" 28 | ] 29 | }, 30 | "exclude": [ 31 | "node_modules", 32 | "dist" 33 | ], 34 | "include": [ 35 | "src" 36 | ] 37 | } -------------------------------------------------------------------------------- /packages/constructsv2/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /packages/constructsv2/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/constructsv2/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @sveltekit-cdk/constructsv2 2 | 3 | ## 0.6.0 4 | 5 | ### Minor Changes 6 | 7 | - 1fce418: BREAKING! remove headers adapter option (all headers passed to app by default) 8 | 9 | ## 0.5.0 10 | 11 | ### Minor Changes 12 | 13 | - dccc547: build only commonjs package 14 | 15 | ### Patch Changes 16 | 17 | - 3931799: update cdk versions and remove unused deps 18 | 19 | ## 0.4.0 20 | 21 | ### Minor Changes 22 | 23 | - fix handling of request headers 24 | 25 | ## 0.3.5 26 | 27 | ### Patch Changes 28 | 29 | - set tsc target to es2020 30 | 31 | ## 0.3.4 32 | 33 | ### Patch Changes 34 | 35 | - upgrade lambda runtime (14 -> 16) 36 | 37 | ## 0.3.3 38 | 39 | ### Patch Changes 40 | 41 | - add client address provider 42 | 43 | ## 0.3.2 44 | 45 | ### Patch Changes 46 | 47 | - 7399f8f: Allow CDK tokens (values that are evaluated during deploy) in renderer environment 48 | 49 | ## 0.3.1 50 | 51 | ### Patch Changes 52 | 53 | - fix routing for /index.svelte when it's not prerendered 54 | 55 | ## 0.3.0 56 | 57 | ### Major Changes 58 | 59 | - BREAKING: Drop support for CDK v1 60 | - BREAKING: only support one configuration of CloudFront, Lambda@Edge and S3 61 | 62 | ### Patch Changes 63 | 64 | - Solve problems with prerendered pages 65 | 66 | ## 0.2.5 67 | 68 | ### Patch Changes 69 | 70 | - set distribution defaultRootObject to index.html 71 | 72 | ## 0.2.4 73 | 74 | ### Patch Changes 75 | 76 | - revert lambda@edge memory increase 77 | 78 | ## 0.2.3 79 | 80 | ### Patch Changes 81 | 82 | - increase lambda@edge ssr timeout and memory 83 | 84 | ## 0.2.2 85 | 86 | ### Patch Changes 87 | 88 | - add distribution function -prop to be able to grant permissions to lambda@edge ssr 89 | 90 | ## 0.2.1 91 | 92 | ### Patch Changes 93 | 94 | - add tag that is recognized by aws construct hub 95 | 96 | ## 0.2.0 97 | 98 | ### Minor Changes 99 | 100 | - Implement CDK v2 variant of @sveltekit-cdk/constructs 101 | -------------------------------------------------------------------------------- /packages/constructsv2/README.md: -------------------------------------------------------------------------------- 1 | # @sveltekit-cdk/constructsv2 2 | 3 | [![npm version](https://badge.fury.io/js/@sveltekit-cdk%2Fconstructsv2.svg)](https://badge.fury.io/js/@sveltekit-cdk%2Fconstructsv2) 4 | 5 | > ### WARNING: Not for production, yet!! 6 | > 7 | > No compatibility between versions is garanteed while in [initial development](https://semver.org/#spec-item-4). It's recommended to use exact version in `package.json` to avoid suprices. 8 | 9 | Use constructs from this package to add SvelteKit 10 | site to your CDK v2 project. 11 | 12 | 1. Add [@sveltekit-cdk/adapter](https://github.com/juranki/sveltekit-cdk/tree/main/packages/adapter#readme) to your SvelteKit project to get 13 | the site artifacts 14 | 1. Use constructs from this package in you CDK stacks 15 | to deploy the site 16 | 17 | ### Links 18 | 19 | - [API reference](https://juranki.github.io/sveltekit-cdk/modules/_sveltekit_cdk_constructsv2.html) 20 | - [Changelog](https://github.com/juranki/sveltekit-cdk/blob/main/packages/constructsv2/CHANGELOG.md) -------------------------------------------------------------------------------- /packages/constructsv2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@sveltekit-cdk/constructsv2", 3 | "version": "0.6.0", 4 | "description": "Add SvelteKit site to CDK stack", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/juranki/sveltekit-cdk.git" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/juranki/sveltekit-cdk/issues" 11 | }, 12 | "homepage": "https://github.com/juranki/sveltekit-cdk#readme", 13 | "license": "MIT", 14 | "main": "dist/index.js", 15 | "types": "dist/index.d.ts", 16 | "scripts": { 17 | "build": "node prepare-build.cjs && tsc -p tsconfig.json" 18 | }, 19 | "keywords": [ 20 | "sveltekit", 21 | "aws", 22 | "cdk", 23 | "awscdk" 24 | ], 25 | "author": "juhani@juranki.com", 26 | "devDependencies": { 27 | "@types/aws-lambda": "^8.10.98", 28 | "@types/node": "17.0.39", 29 | "aws-cdk-lib": "^2.59.0", 30 | "constructs": "^10.1.209", 31 | "rimraf": "^3.0.2", 32 | "typescript": "^4.7.3" 33 | }, 34 | "dependencies": { 35 | "esbuild": "^0.14.42" 36 | }, 37 | "peerDependencies": { 38 | "aws-cdk-lib": "^2.59.0", 39 | "constructs": "^10.1.209" 40 | } 41 | } -------------------------------------------------------------------------------- /packages/constructsv2/prepare-build.cjs: -------------------------------------------------------------------------------- 1 | require('rimraf')('dist', (err) => { 2 | if(err) { 3 | throw err 4 | } 5 | }) -------------------------------------------------------------------------------- /packages/constructsv2/src/common.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_ARTIFACT_PATH = 'sveltekit' 2 | 3 | export interface RendererProps { 4 | /** 5 | * Location of sveltekit artifacts 6 | * 7 | * @default 'sveltekit' 8 | */ 9 | artifactPath?: string 10 | /** 11 | * Environment variables for the backend implementation 12 | */ 13 | environment?: { 14 | [key: string]: string; 15 | } 16 | /** 17 | * Logging verbosity (default: INFO) 18 | */ 19 | logLevel?: 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' 20 | } 21 | 22 | export type StaticRoutes = Record 23 | -------------------------------------------------------------------------------- /packages/constructsv2/src/distribution.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from 'constructs' 2 | import { Duration } from 'aws-cdk-lib' 3 | import * as cdn from 'aws-cdk-lib/aws-cloudfront' 4 | import * as cdnOrigins from 'aws-cdk-lib/aws-cloudfront-origins' 5 | import * as s3 from 'aws-cdk-lib/aws-s3' 6 | import { DEFAULT_ARTIFACT_PATH, RendererProps, StaticRoutes } from './common' 7 | import { readFileSync } from 'fs' 8 | import { join } from 'path' 9 | import { buildSync } from 'esbuild' 10 | import { Certificate } from 'aws-cdk-lib/aws-certificatemanager' 11 | import * as lambda from 'aws-cdk-lib/aws-lambda' 12 | import { CacheControl } from 'aws-cdk-lib/aws-codepipeline-actions' 13 | import { BucketDeployment, Source } from 'aws-cdk-lib/aws-s3-deployment' 14 | import { randomBytes } from 'crypto' 15 | 16 | export interface SvelteDistributionProps { 17 | /** 18 | * Location of sveltekit artifacts 19 | * 20 | * @default 'sveltekit' 21 | */ 22 | artifactPath?: string 23 | 24 | /** 25 | * Props for Lambda@Edge renderer 26 | */ 27 | rendererProps?: RendererProps 28 | 29 | /** 30 | * PriceClass 31 | * 32 | * @link https://docs.aws.amazon.com/cdk/api/latest/typescript/api/aws-cloudfront/priceclass.html#aws_cloudfront_PriceClass 33 | * @default PriceClass.PRICE_CLASS_100 34 | */ 35 | priceClass?: cdn.PriceClass 36 | /** 37 | * Origin request policy determines which parts of requests 38 | * CloudFront passes to your backend 39 | * 40 | * @default AllViewer managed policy 41 | * @link https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html 42 | */ 43 | originRequestPolicy?: cdn.IOriginRequestPolicy 44 | 45 | /** 46 | * Cache policy determies caching for dynamic content. 47 | * 48 | * Note: static content is cached using default setting (CACHING_OPTIMIZED). 49 | * 50 | * @default CACHING_DISABLED 51 | * @link https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html 52 | */ 53 | cachePolicy?: cdn.ICachePolicy 54 | 55 | /** 56 | * Bucket props for the svelteStaticBucket s3 bucket. 57 | * 58 | * @link https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-s3.BucketProps.html 59 | */ 60 | bucketProps?: s3.BucketProps 61 | 62 | /** 63 | * Certificate to use with the CloudFront Distribution 64 | * 65 | * @default undefined 66 | */ 67 | certificateArn?: string 68 | 69 | /** 70 | * Domain names to associate with the CloudFront Distribution 71 | * 72 | * @default undefined 73 | */ 74 | domainNames?: Array 75 | } 76 | 77 | export class SvelteDistribution extends Construct { 78 | distribution: cdn.Distribution 79 | bucket: s3.Bucket 80 | function?: cdn.experimental.EdgeFunction 81 | constructor(scope: Construct, id: string, props: SvelteDistributionProps) { 82 | super(scope, id) 83 | 84 | // validate pros and apply defaults 85 | checkProps(props) 86 | const artifactPath = props.artifactPath || DEFAULT_ARTIFACT_PATH 87 | const staticPath = join(artifactPath, 'static') 88 | const prerenderedPath = join(artifactPath, 'prerendered') 89 | const routesPath = join(artifactPath, 'routes.json') 90 | const routes: StaticRoutes = JSON.parse(readFileSync(routesPath, { encoding: 'utf8' })) 91 | const envUtils = new EnvUtil(props.rendererProps?.environment || {}) 92 | 93 | 94 | // origins 95 | const bucketProps = props.bucketProps || {} 96 | this.bucket = new s3.Bucket(this, 'svelteStaticBucket', bucketProps); 97 | 98 | const s3static = new cdnOrigins.S3Origin(this.bucket, { 99 | originPath: 'static' 100 | }) 101 | const origin = new cdnOrigins.S3Origin(this.bucket, { 102 | originPath: 'prerendered', 103 | customHeaders: envUtils.customHeaders(), 104 | }) 105 | 106 | // cache and origin request policies 107 | const originRequestPolicy = props.originRequestPolicy || cdn.OriginRequestPolicy.ALL_VIEWER 108 | const cachePolicy = props.cachePolicy || new cdn.CachePolicy(this, 'svelteDynamicCachePolicy', { 109 | cookieBehavior: cdn.CacheCookieBehavior.all(), 110 | }) 111 | 112 | // at edge lambda 113 | let edgeLambdas: cdn.EdgeLambda[] | undefined = undefined 114 | 115 | const bundleDir = join(artifactPath, 'lambda/at-edge-env') 116 | const outfile = join(bundleDir, 'handler.js') 117 | const code = buildSync({ 118 | entryPoints: [join(artifactPath, 'lambda/at-edge/handler.js')], 119 | outfile, 120 | bundle: true, 121 | platform: 'node', 122 | target: ['es2020'], 123 | define: { 124 | SVELTEKIT_CDK_LOG_LEVEL: JSON.stringify(props.rendererProps?.logLevel || 'INFO'), 125 | SVELTEKIT_CDK_ENV_MAP: envUtils.mappingJSON(), 126 | } 127 | }) 128 | if (code.errors.length > 0) { 129 | console.log('bundling lambda failed') 130 | throw new Error(code.errors.map(e => (e.text)).join('\n')); 131 | } 132 | 133 | this.function = new cdn.experimental.EdgeFunction(this, 'svelteHandler', { 134 | code: lambda.Code.fromAsset(bundleDir), 135 | handler: 'handler.handler', 136 | runtime: lambda.Runtime.NODEJS_16_X, 137 | timeout: Duration.seconds(5), 138 | memorySize: 512, 139 | logRetention: 7, 140 | }) 141 | 142 | edgeLambdas = [{ 143 | eventType: cdn.LambdaEdgeEventType.ORIGIN_REQUEST, 144 | functionVersion: this.function.currentVersion, 145 | includeBody: true, 146 | }] 147 | 148 | // distribution 149 | this.distribution = new cdn.Distribution(this, 'distro', { 150 | priceClass: props.priceClass || cdn.PriceClass.PRICE_CLASS_100, 151 | defaultBehavior: { 152 | origin, 153 | viewerProtocolPolicy: cdn.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, 154 | edgeLambdas, 155 | allowedMethods: cdn.AllowedMethods.ALLOW_ALL, 156 | originRequestPolicy: edgeLambdas ? originRequestPolicy : undefined, 157 | cachePolicy: edgeLambdas ? cachePolicy : undefined, 158 | }, 159 | domainNames: props.domainNames ? props.domainNames : undefined, 160 | certificate: props.certificateArn ? Certificate.fromCertificateArn(this, 'domainCert', props.certificateArn) : undefined, 161 | }) 162 | 163 | let hasPrerendered = false 164 | // routes for static content 165 | Object.entries(routes).forEach(([glob, origin]) => { 166 | if (origin === 'static') { 167 | this.distribution.addBehavior(glob, s3static, { 168 | viewerProtocolPolicy: cdn.ViewerProtocolPolicy.REDIRECT_TO_HTTPS 169 | }) 170 | } else if (origin === 'prerendered') { 171 | hasPrerendered = true 172 | } 173 | }) 174 | 175 | if (hasPrerendered) { 176 | // deploy with explicit content type to set it correctly for prerendered 177 | new BucketDeployment(this, 'sveltePrerenderedDeployment', { 178 | destinationBucket: this.bucket, 179 | destinationKeyPrefix: 'prerendered', 180 | sources: [Source.asset(prerenderedPath)], 181 | distribution: this.distribution, 182 | cacheControl: [ 183 | CacheControl.maxAge(Duration.days(365)) 184 | ], 185 | distributionPaths: Object.entries(routes).filter(([_, t]) => (t === 'prerendered')).map(([r, _]) => r), 186 | }) 187 | 188 | } 189 | 190 | new BucketDeployment(this, 'svelteStaticDeployment', { 191 | destinationBucket: this.bucket, 192 | destinationKeyPrefix: 'static', 193 | sources: [Source.asset(staticPath)], 194 | distribution: this.distribution, 195 | cacheControl: [ 196 | CacheControl.maxAge(Duration.days(365)) 197 | ], 198 | distributionPaths: Object.entries(routes).filter(([_, t]) => (t === 'static')).map(([r, _]) => `/${r}`), 199 | }) 200 | } 201 | } 202 | 203 | function checkProps(props: SvelteDistributionProps) { 204 | if (props.certificateArn && !props.domainNames) { 205 | throw new Error("domainNames must be provided when setting a certificateArn") 206 | } 207 | } 208 | 209 | /** 210 | * Prepare structures for passing env vars into Lambda@Edge 211 | */ 212 | class EnvUtil { 213 | values: Record 214 | headers: Record 215 | 216 | constructor(env:Record) { 217 | this.values = env 218 | this.headers = Object.fromEntries( 219 | Object.keys(env).map(k => [k, `x-env-${randomBytes(9).toString('hex')}`]) 220 | ) 221 | } 222 | 223 | mappingJSON = () => { 224 | return JSON.stringify(Object.fromEntries( 225 | Object.entries(this.headers).map(([k,v]) => ([v,k])))) 226 | } 227 | 228 | customHeaders = () => { 229 | return Object.fromEntries(Object.entries(this.values).map(([k,v]) => ( 230 | [this.headers[k], v] 231 | ))) 232 | } 233 | } 234 | 235 | -------------------------------------------------------------------------------- /packages/constructsv2/src/index.ts: -------------------------------------------------------------------------------- 1 | export { SvelteDistribution, SvelteDistributionProps } from './distribution' 2 | export { RendererProps } from './common' -------------------------------------------------------------------------------- /packages/constructsv2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "target": "ESNext", 5 | "allowJs": true, 6 | "allowSyntheticDefaultImports": true, 7 | "baseUrl": "src", 8 | "declaration": true, 9 | "esModuleInterop": true, 10 | "inlineSourceMap": false, 11 | "sourceMap": true, 12 | "lib": ["esnext"], 13 | "listEmittedFiles": false, 14 | "listFiles": false, 15 | "moduleResolution": "node", 16 | "noFallthroughCasesInSwitch": true, 17 | "pretty": true, 18 | "resolveJsonModule": true, 19 | "rootDir": "src", 20 | "skipLibCheck": true, 21 | "strict": true, 22 | "traceResolution": false, 23 | "types": ["node"], 24 | "outDir": "dist" 25 | }, 26 | "exclude": ["node_modules", "dist"], 27 | "include": ["src"] 28 | } 29 | -------------------------------------------------------------------------------- /packages/sample-site-v2/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | .vercel 10 | .output 11 | vite.config.js.timestamp-* 12 | vite.config.ts.timestamp-* 13 | -------------------------------------------------------------------------------- /packages/sample-site-v2/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /packages/sample-site-v2/README.md: -------------------------------------------------------------------------------- 1 | # create-svelte 2 | 3 | Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). 4 | 5 | ## Creating a project 6 | 7 | If you're seeing this, you've probably already done this step. Congrats! 8 | 9 | ```bash 10 | # create a new project in the current directory 11 | npm create svelte@latest 12 | 13 | # create a new project in my-app 14 | npm create svelte@latest my-app 15 | ``` 16 | 17 | ## Developing 18 | 19 | Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: 20 | 21 | ```bash 22 | npm run dev 23 | 24 | # or start the server and open the app in a new browser tab 25 | npm run dev -- --open 26 | ``` 27 | 28 | ## Building 29 | 30 | To create a production version of your app: 31 | 32 | ```bash 33 | npm run build 34 | ``` 35 | 36 | You can preview the production build with `npm run preview`. 37 | 38 | > To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. 39 | -------------------------------------------------------------------------------- /packages/sample-site-v2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sample-site-v2", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "vite dev", 6 | "build": "vite build", 7 | "preview": "vite preview", 8 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 9 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 10 | "prepare": "svelte-kit sync" 11 | }, 12 | "devDependencies": { 13 | "@sveltekit-cdk/adapter": "workspace:*", 14 | "@fontsource/fira-mono": "^4.5.10", 15 | "@neoconfetti/svelte": "^1.0.0", 16 | "@sveltejs/kit": "^1.0.0", 17 | "@types/cookie": "^0.5.1", 18 | "svelte": "^3.54.0", 19 | "svelte-check": "^2.9.2", 20 | "tslib": "^2.4.1", 21 | "typescript": "^4.9.3", 22 | "vite": "^4.0.0" 23 | }, 24 | "type": "module" 25 | } 26 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://kit.svelte.dev/docs/types#app 2 | // for information about these interfaces 3 | // and what to do when importing types 4 | declare namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface Platform {} 9 | } 10 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/lib/images/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 9 | 16 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/lib/images/svelte-logo.svg: -------------------------------------------------------------------------------- 1 | svelte-logo -------------------------------------------------------------------------------- /packages/sample-site-v2/src/lib/images/svelte-welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juranki/sveltekit-cdk/1fc170fc01eb9bae76b49d8d48056ee3b506f9c9/packages/sample-site-v2/src/lib/images/svelte-welcome.png -------------------------------------------------------------------------------- /packages/sample-site-v2/src/lib/images/svelte-welcome.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juranki/sveltekit-cdk/1fc170fc01eb9bae76b49d8d48056ee3b506f9c9/packages/sample-site-v2/src/lib/images/svelte-welcome.webp -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 | 9 |
10 | 11 |
12 | 13 | 16 |
17 | 18 | 54 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | Home 9 | 10 | 11 | 12 |
13 |

14 | 15 | 16 | 17 | Welcome 18 | 19 | 20 | 21 | to your new
SvelteKit app 22 |

23 | 24 |

25 | try editing src/routes/+page.svelte 26 |

27 | 28 | 29 |
30 | 31 | 60 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/+page.ts: -------------------------------------------------------------------------------- 1 | // since there's no dynamic data here, we can prerender 2 | // it so that it gets served as a static asset in production 3 | export const prerender = true; 4 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/Counter.svelte: -------------------------------------------------------------------------------- 1 | 15 | 16 |
17 | 22 | 23 |
24 |
25 | 26 | {Math.floor($displayed_count)} 27 |
28 |
29 | 30 | 35 |
36 | 37 | 103 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/Header.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 |
9 | 10 | SvelteKit 11 | 12 |
13 | 14 | 33 | 34 |
35 | 36 | GitHub 37 | 38 |
39 |
40 | 41 | 130 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/about/+page.svelte: -------------------------------------------------------------------------------- 1 | 2 | About 3 | 4 | 5 | 6 |
7 |

About this app

8 | 9 |

10 | This is a SvelteKit app. You can make your own by typing the 11 | following into your command line and following the prompts: 12 |

13 | 14 |
npm create svelte@latest
15 | 16 |

17 | The page you're looking at is purely static HTML, with no client-side interactivity needed. 18 | Because of that, we don't need to load any JavaScript. Try viewing the page's source, or opening 19 | the devtools network panel and reloading. 20 |

21 | 22 |

23 | The Sverdle page illustrates SvelteKit's data loading and form handling. Try 24 | using it with JavaScript disabled! 25 |

26 |
27 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/about/+page.ts: -------------------------------------------------------------------------------- 1 | import { dev } from '$app/environment'; 2 | 3 | // we don't need any JS on this page, though we'll load 4 | // it in dev so that we get hot module replacement 5 | export const csr = dev; 6 | 7 | // since there's no dynamic data here, we can prerender 8 | // it so that it gets served as a static asset in production 9 | export const prerender = true; 10 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/styles.css: -------------------------------------------------------------------------------- 1 | @import '@fontsource/fira-mono'; 2 | 3 | :root { 4 | --font-body: Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 5 | Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 6 | --font-mono: 'Fira Mono', monospace; 7 | --color-bg-0: rgb(202, 216, 228); 8 | --color-bg-1: hsl(209, 36%, 86%); 9 | --color-bg-2: hsl(224, 44%, 95%); 10 | --color-theme-1: #ff3e00; 11 | --color-theme-2: #4075a6; 12 | --color-text: rgba(0, 0, 0, 0.7); 13 | --column-width: 42rem; 14 | --column-margin-top: 4rem; 15 | font-family: var(--font-body); 16 | color: var(--color-text); 17 | } 18 | 19 | body { 20 | min-height: 100vh; 21 | margin: 0; 22 | background-attachment: fixed; 23 | background-color: var(--color-bg-1); 24 | background-size: 100vw 100vh; 25 | background-image: radial-gradient( 26 | 50% 50% at 50% 50%, 27 | rgba(255, 255, 255, 0.75) 0%, 28 | rgba(255, 255, 255, 0) 100% 29 | ), 30 | linear-gradient(180deg, var(--color-bg-0) 0%, var(--color-bg-1) 15%, var(--color-bg-2) 50%); 31 | } 32 | 33 | h1, 34 | h2, 35 | p { 36 | font-weight: 400; 37 | } 38 | 39 | p { 40 | line-height: 1.5; 41 | } 42 | 43 | a { 44 | color: var(--color-theme-1); 45 | text-decoration: none; 46 | } 47 | 48 | a:hover { 49 | text-decoration: underline; 50 | } 51 | 52 | h1 { 53 | font-size: 2rem; 54 | text-align: center; 55 | } 56 | 57 | h2 { 58 | font-size: 1rem; 59 | } 60 | 61 | pre { 62 | font-size: 16px; 63 | font-family: var(--font-mono); 64 | background-color: rgba(255, 255, 255, 0.45); 65 | border-radius: 3px; 66 | box-shadow: 2px 2px 6px rgb(255 255 255 / 25%); 67 | padding: 0.5em; 68 | overflow-x: auto; 69 | color: var(--color-text); 70 | } 71 | 72 | .text-column { 73 | display: flex; 74 | max-width: 48rem; 75 | flex: 0.6; 76 | flex-direction: column; 77 | justify-content: center; 78 | margin: 0 auto; 79 | } 80 | 81 | input, 82 | button { 83 | font-size: inherit; 84 | font-family: inherit; 85 | } 86 | 87 | button:focus:not(:focus-visible) { 88 | outline: none; 89 | } 90 | 91 | @media (min-width: 720px) { 92 | h1 { 93 | font-size: 2.4rem; 94 | } 95 | } 96 | 97 | .visually-hidden { 98 | border: 0; 99 | clip: rect(0 0 0 0); 100 | height: auto; 101 | margin: 0; 102 | overflow: hidden; 103 | padding: 0; 104 | position: absolute; 105 | width: 1px; 106 | white-space: nowrap; 107 | } 108 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/sverdle/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { fail } from '@sveltejs/kit'; 2 | import { Game } from './game'; 3 | import type { PageServerLoad, Actions } from './$types'; 4 | 5 | export const load = (({ cookies }) => { 6 | const game = new Game(cookies.get('sverdle')); 7 | 8 | return { 9 | /** 10 | * The player's guessed words so far 11 | */ 12 | guesses: game.guesses, 13 | 14 | /** 15 | * An array of strings like '__x_c' corresponding to the guesses, where 'x' means 16 | * an exact match, and 'c' means a close match (right letter, wrong place) 17 | */ 18 | answers: game.answers, 19 | 20 | /** 21 | * The correct answer, revealed if the game is over 22 | */ 23 | answer: game.answers.length >= 6 ? game.answer : null 24 | }; 25 | }) satisfies PageServerLoad; 26 | 27 | export const actions = { 28 | /** 29 | * Modify game state in reaction to a keypress. If client-side JavaScript 30 | * is available, this will happen in the browser instead of here 31 | */ 32 | update: async ({ request, cookies }) => { 33 | const game = new Game(cookies.get('sverdle')); 34 | 35 | const data = await request.formData(); 36 | const key = data.get('key'); 37 | 38 | const i = game.answers.length; 39 | 40 | if (key === 'backspace') { 41 | game.guesses[i] = game.guesses[i].slice(0, -1); 42 | } else { 43 | game.guesses[i] += key; 44 | } 45 | 46 | cookies.set('sverdle', game.toString()); 47 | }, 48 | 49 | /** 50 | * Modify game state in reaction to a guessed word. This logic always runs on 51 | * the server, so that people can't cheat by peeking at the JavaScript 52 | */ 53 | enter: async ({ request, cookies }) => { 54 | const game = new Game(cookies.get('sverdle')); 55 | 56 | const data = await request.formData(); 57 | const guess = data.getAll('guess') as string[]; 58 | 59 | if (!game.enter(guess)) { 60 | return fail(400, { badGuess: true }); 61 | } 62 | 63 | cookies.set('sverdle', game.toString()); 64 | }, 65 | 66 | restart: async ({ cookies }) => { 67 | cookies.delete('sverdle'); 68 | } 69 | } satisfies Actions; 70 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/sverdle/+page.svelte: -------------------------------------------------------------------------------- 1 | 83 | 84 | 85 | 86 | 87 | Sverdle 88 | 89 | 90 | 91 |

Sverdle

92 | 93 |
{ 97 | // prevent default callback from resetting the form 98 | return ({ update }) => { 99 | update({ reset: false }); 100 | }; 101 | }} 102 | > 103 | How to play 104 | 105 |
106 | {#each Array(6) as _, row} 107 | {@const current = row === i} 108 |

Row {row + 1}

109 |
110 | {#each Array(5) as _, column} 111 | {@const answer = data.answers[row]?.[column]} 112 | {@const value = data.guesses[row]?.[column] ?? ''} 113 | {@const selected = current && column === data.guesses[row].length} 114 | {@const exact = answer === 'x'} 115 | {@const close = answer === 'c'} 116 | {@const missing = answer === '_'} 117 |
118 | {value} 119 | 120 | {#if exact} 121 | (correct) 122 | {:else if close} 123 | (present) 124 | {:else if missing} 125 | (absent) 126 | {:else} 127 | empty 128 | {/if} 129 | 130 | 131 |
132 | {/each} 133 |
134 | {/each} 135 |
136 | 137 |
138 | {#if won || data.answers.length >= 6} 139 | {#if !won && data.answer} 140 |

the answer was "{data.answer}"

141 | {/if} 142 | 145 | {:else} 146 |
147 | 148 | 149 | 158 | 159 | {#each ['qwertyuiop', 'asdfghjkl', 'zxcvbnm'] as row} 160 |
161 | {#each row as letter} 162 | 174 | {/each} 175 |
176 | {/each} 177 |
178 | {/if} 179 |
180 |
181 | 182 | {#if won} 183 |
193 | {/if} 194 | 195 | 407 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/sverdle/game.ts: -------------------------------------------------------------------------------- 1 | import { words, allowed } from './words.server'; 2 | 3 | export class Game { 4 | index: number; 5 | guesses: string[]; 6 | answers: string[]; 7 | answer: string; 8 | 9 | /** 10 | * Create a game object from the player's cookie, or initialise a new game 11 | */ 12 | constructor(serialized: string | undefined = undefined) { 13 | if (serialized) { 14 | const [index, guesses, answers] = serialized.split('-'); 15 | 16 | this.index = +index; 17 | this.guesses = guesses ? guesses.split(' ') : []; 18 | this.answers = answers ? answers.split(' ') : []; 19 | } else { 20 | this.index = Math.floor(Math.random() * words.length); 21 | this.guesses = ['', '', '', '', '', '']; 22 | this.answers = [] ; 23 | } 24 | 25 | this.answer = words[this.index]; 26 | } 27 | 28 | /** 29 | * Update game state based on a guess of a five-letter word. Returns 30 | * true if the guess was valid, false otherwise 31 | */ 32 | enter(letters: string[]) { 33 | const word = letters.join(''); 34 | const valid = allowed.has(word); 35 | 36 | if (!valid) return false; 37 | 38 | this.guesses[this.answers.length] = word; 39 | 40 | const available = Array.from(this.answer); 41 | const answer = Array(5).fill('_'); 42 | 43 | // first, find exact matches 44 | for (let i = 0; i < 5; i += 1) { 45 | if (letters[i] === available[i]) { 46 | answer[i] = 'x'; 47 | available[i] = ' '; 48 | } 49 | } 50 | 51 | // then find close matches (this has to happen 52 | // in a second step, otherwise an early close 53 | // match can prevent a later exact match) 54 | for (let i = 0; i < 5; i += 1) { 55 | if (answer[i] === '_') { 56 | const index = available.indexOf(letters[i]); 57 | if (index !== -1) { 58 | answer[i] = 'c'; 59 | available[index] = ' '; 60 | } 61 | } 62 | } 63 | 64 | this.answers.push(answer.join('')); 65 | 66 | return true; 67 | } 68 | 69 | /** 70 | * Serialize game state so it can be set as a cookie 71 | */ 72 | toString() { 73 | return `${this.index}-${this.guesses.join(' ')}-${this.answers.join(' ')}`; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/sverdle/how-to-play/+page.svelte: -------------------------------------------------------------------------------- 1 | 2 | How to play Sverdle 3 | 4 | 5 | 6 |
7 |

How to play Sverdle

8 | 9 |

10 | Sverdle is a clone of Wordle, the 11 | word guessing game. To play, enter a five-letter English word. For example: 12 |

13 | 14 |
15 | r 16 | i 17 | t 18 | z 19 | y 20 |
21 | 22 |

23 | The y is in the right place. r and 24 | t 25 | are the right letters, but in the wrong place. The other letters are wrong, and can be discarded. 26 | Let's make another guess: 27 |

28 | 29 |
30 | p 31 | a 32 | r 33 | t 34 | y 35 |
36 | 37 |

This time we guessed right! You have six guesses to get the word.

38 | 39 |

40 | Unlike the original Wordle, Sverdle runs on the server instead of in the browser, making it 41 | impossible to cheat. It uses <form> and cookies to submit data, meaning you can 42 | even play with JavaScript disabled! 43 |

44 |
45 | 46 | 96 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/sverdle/how-to-play/+page.ts: -------------------------------------------------------------------------------- 1 | import { dev } from '$app/environment'; 2 | 3 | // we don't need any JS on this page, though we'll load 4 | // it in dev so that we get hot module replacement 5 | export const csr = dev; 6 | 7 | // since there's no dynamic data here, we can prerender 8 | // it so that it gets served as a static asset in production 9 | export const prerender = true; 10 | -------------------------------------------------------------------------------- /packages/sample-site-v2/src/routes/sverdle/reduced-motion.ts: -------------------------------------------------------------------------------- 1 | import { readable } from 'svelte/store'; 2 | import { browser } from '$app/environment'; 3 | 4 | const reduced_motion_query = '(prefers-reduced-motion: reduce)'; 5 | 6 | const get_initial_motion_preference = () => { 7 | if (!browser) return false; 8 | return window.matchMedia(reduced_motion_query).matches; 9 | }; 10 | 11 | export const reduced_motion = readable(get_initial_motion_preference(), (set) => { 12 | if (browser) { 13 | const set_reduced_motion = (event: MediaQueryListEvent) => { 14 | set(event.matches); 15 | }; 16 | const media_query_list = window.matchMedia(reduced_motion_query); 17 | media_query_list.addEventListener('change', set_reduced_motion); 18 | 19 | return () => { 20 | media_query_list.removeEventListener('change', set_reduced_motion); 21 | }; 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /packages/sample-site-v2/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juranki/sveltekit-cdk/1fc170fc01eb9bae76b49d8d48056ee3b506f9c9/packages/sample-site-v2/static/favicon.png -------------------------------------------------------------------------------- /packages/sample-site-v2/static/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /packages/sample-site-v2/svelte.config.js: -------------------------------------------------------------------------------- 1 | // import adapter from '@sveltejs/adapter-auto'; 2 | import { adapter } from '@sveltekit-cdk/adapter' 3 | import { vitePreprocess } from '@sveltejs/kit/vite'; 4 | 5 | /** @type {import('@sveltejs/kit').Config} */ 6 | const config = { 7 | // Consult https://kit.svelte.dev/docs/integrations#preprocessors 8 | // for more information about preprocessors 9 | preprocess: vitePreprocess(), 10 | 11 | kit: { 12 | adapter: adapter({ 13 | cdkProjectPath: '../sample-stack-v2' 14 | }) 15 | } 16 | }; 17 | 18 | export default config; 19 | -------------------------------------------------------------------------------- /packages/sample-site-v2/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 | -------------------------------------------------------------------------------- /packages/sample-site-v2/vite.config.js: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | 3 | /** @type {import('vite').UserConfig} */ 4 | const config = { 5 | plugins: [sveltekit()] 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /packages/sample-stack-v2/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | 10 | sveltekit -------------------------------------------------------------------------------- /packages/sample-stack-v2/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /packages/sample-stack-v2/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to your CDK TypeScript project! 2 | 3 | This is a blank project for TypeScript development with CDK. 4 | 5 | The `cdk.json` file tells the CDK Toolkit how to execute your app. 6 | 7 | ## Useful commands 8 | 9 | * `npm run build` compile typescript to js 10 | * `npm run watch` watch for changes and compile 11 | * `npm run test` perform the jest unit tests 12 | * `cdk deploy` deploy this stack to your default AWS account/region 13 | * `cdk diff` compare deployed stack with current state 14 | * `cdk synth` emits the synthesized CloudFormation template 15 | -------------------------------------------------------------------------------- /packages/sample-stack-v2/bin/sample-stack-v2.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import 'source-map-support/register'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | import { SimpleSvelteStack } from '../lib/sample-stack-v2-stack'; 5 | 6 | const app = new cdk.App(); 7 | new SimpleSvelteStack(app, 'SimpleSvelteStackV2', { 8 | env: { 9 | account: '480363651371', 10 | // when region is not us-east-1 cdk automatically creates 11 | // a separate stack that deploys edge function to us-east-1 12 | region: 'eu-central-1' 13 | }, 14 | zoneName: 'prudent-profile.com', 15 | fqdn: 'sveltekit-demo.prudent-profile.com' 16 | }); -------------------------------------------------------------------------------- /packages/sample-stack-v2/cdk.context.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosted-zone:account=480363651371:domainName=prudent-profile.com:region=eu-central-1": { 3 | "Id": "/hostedzone/Z00786777A0VN3XAPLMI", 4 | "Name": "prudent-profile.com." 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/sample-stack-v2/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts bin/sample-stack-v2.ts", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "**/*.d.ts", 11 | "**/*.js", 12 | "tsconfig.json", 13 | "package*.json", 14 | "yarn.lock", 15 | "node_modules", 16 | "test" 17 | ] 18 | }, 19 | "context": { 20 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 21 | "@aws-cdk/core:stackRelativeExports": true, 22 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 23 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 24 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, 25 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 26 | "@aws-cdk/core:target-partitions": [ 27 | "aws", 28 | "aws-cn" 29 | ] 30 | }, 31 | "requireApproval": "never" 32 | } 33 | -------------------------------------------------------------------------------- /packages/sample-stack-v2/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | roots: ['/test'], 4 | testMatch: ['**/*.test.ts'], 5 | transform: { 6 | '^.+\\.tsx?$': 'ts-jest' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /packages/sample-stack-v2/lib/sample-stack-v2-stack.ts: -------------------------------------------------------------------------------- 1 | import { Stack, StackProps } from 'aws-cdk-lib'; 2 | import { Construct } from 'constructs'; 3 | import { SvelteDistribution } from '@sveltekit-cdk/constructsv2' 4 | import { ARecord, HostedZone, RecordTarget } from 'aws-cdk-lib/aws-route53'; 5 | import { DnsValidatedCertificate } from 'aws-cdk-lib/aws-certificatemanager'; 6 | import { CloudFrontTarget } from 'aws-cdk-lib/aws-route53-targets'; 7 | 8 | export interface SimpleSvelteStackProps extends StackProps { 9 | zoneName: string 10 | fqdn: string 11 | } 12 | 13 | export class SimpleSvelteStack extends Stack { 14 | constructor(scope: Construct, id: string, props: SimpleSvelteStackProps) { 15 | super(scope, id, props); 16 | 17 | const hostedZone = HostedZone.fromLookup(this, 'HostedZone', { 18 | domainName: props.zoneName 19 | }) 20 | 21 | const cert = new DnsValidatedCertificate(this, 'Certificate', { 22 | domainName: props.fqdn, 23 | hostedZone, 24 | // CloudFront certs must be on us-east-1 25 | region: 'us-east-1' 26 | }) 27 | 28 | const svelteSite = new SvelteDistribution(this, 'svelteDistribution', { 29 | rendererProps: { 30 | logLevel: 'DEBUG', 31 | }, 32 | certificateArn: cert.certificateArn, 33 | domainNames: [props.fqdn] 34 | }) 35 | 36 | new ARecord(this, 'DNSRecord', { 37 | zone: hostedZone, 38 | recordName: props.fqdn, 39 | target: RecordTarget.fromAlias(new CloudFrontTarget(svelteSite.distribution)) 40 | }) 41 | 42 | } 43 | } -------------------------------------------------------------------------------- /packages/sample-stack-v2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sample-stack-v2", 3 | "version": "0.1.0", 4 | "bin": { 5 | "sample-stack-v2": "bin/sample-stack-v2.js" 6 | }, 7 | "scripts": { 8 | "build": "tsc", 9 | "watch": "tsc -w", 10 | "test": "jest", 11 | "cdk": "cdk", 12 | "synth": "cdk synth", 13 | "diff": "cdk diff", 14 | "deploy": "cdk deploy" 15 | }, 16 | "devDependencies": { 17 | "@types/jest": "^28.1.0", 18 | "@types/node": "17.0.39", 19 | "aws-cdk": "2.59.0", 20 | "jest": "^28.1.0", 21 | "ts-jest": "^28.0.4", 22 | "ts-node": "^10.8.1", 23 | "typescript": "~4.7.3" 24 | }, 25 | "dependencies": { 26 | "@sveltekit-cdk/constructsv2": "workspace:*", 27 | "aws-cdk-lib": "2.59.0", 28 | "constructs": "^10.1.209", 29 | "source-map-support": "^0.5.21" 30 | }, 31 | "private": true 32 | } 33 | -------------------------------------------------------------------------------- /packages/sample-stack-v2/test/sample-stack-v2.test.ts: -------------------------------------------------------------------------------- 1 | // import * as cdk from 'aws-cdk-lib'; 2 | // import { Template } from 'aws-cdk-lib/assertions'; 3 | // import * as SampleStackV2 from '../lib/sample-stack-v2-stack'; 4 | 5 | // example test. To run these tests, uncomment this file along with the 6 | // example resource in lib/sample-stack-v2-stack.ts 7 | test('SQS Queue Created', () => { 8 | // const app = new cdk.App(); 9 | // // WHEN 10 | // const stack = new SampleStackV2.SampleStackV2Stack(app, 'MyTestStack'); 11 | // // THEN 12 | // const template = Template.fromStack(stack); 13 | 14 | // template.hasResourceProperties('AWS::SQS::Queue', { 15 | // VisibilityTimeout: 300 16 | // }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/sample-stack-v2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es2018" 7 | ], 8 | "declaration": true, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "noImplicitThis": true, 13 | "alwaysStrict": true, 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": false, 18 | "inlineSourceMap": true, 19 | "inlineSources": true, 20 | "experimentalDecorators": true, 21 | "strictPropertyInitialization": false, 22 | "typeRoots": [ 23 | "./node_modules/@types" 24 | ] 25 | }, 26 | "exclude": [ 27 | "node_modules", 28 | "cdk.out" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /packages/test-stack/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | 10 | sveltekit -------------------------------------------------------------------------------- /packages/test-stack/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /packages/test-stack/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to your CDK TypeScript project! 2 | 3 | This is a blank project for TypeScript development with CDK. 4 | 5 | The `cdk.json` file tells the CDK Toolkit how to execute your app. 6 | 7 | ## Useful commands 8 | 9 | * `npm run build` compile typescript to js 10 | * `npm run watch` watch for changes and compile 11 | * `npm run test` perform the jest unit tests 12 | * `cdk deploy` deploy this stack to your default AWS account/region 13 | * `cdk diff` compare deployed stack with current state 14 | * `cdk synth` emits the synthesized CloudFormation template 15 | -------------------------------------------------------------------------------- /packages/test-stack/bin/test-stack.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import 'source-map-support/register'; 3 | import * as cdk from 'aws-cdk-lib'; 4 | import { SvelteKitTestStack } from '../lib/test-stack' 5 | 6 | const app = new cdk.App(); 7 | new SvelteKitTestStack(app, 'SvelteKitTest', { 8 | env: { account: '385180606991', region: 'us-east-1' }, 9 | }); -------------------------------------------------------------------------------- /packages/test-stack/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts bin/test-stack.ts", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "**/*.d.ts", 11 | "**/*.js", 12 | "tsconfig.json", 13 | "package*.json", 14 | "yarn.lock", 15 | "node_modules", 16 | "test" 17 | ] 18 | }, 19 | "context": { 20 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 21 | "@aws-cdk/core:stackRelativeExports": true, 22 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 23 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 24 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, 25 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 26 | "@aws-cdk/core:target-partitions": [ 27 | "aws", 28 | "aws-cn" 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/test-stack/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | roots: ['/test'], 4 | testMatch: ['**/*.test.ts'], 5 | transform: { 6 | '^.+\\.tsx?$': 'ts-jest' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /packages/test-stack/lib/test-stack.ts: -------------------------------------------------------------------------------- 1 | import { Stack, StackProps } from 'aws-cdk-lib'; 2 | import { Bucket } from 'aws-cdk-lib/aws-s3' 3 | import { Construct } from 'constructs'; 4 | import { SvelteDistribution } from '@sveltekit-cdk/constructsv2' 5 | 6 | export class SvelteKitTestStack extends Stack { 7 | constructor(scope: Construct, id: string, props?: StackProps) { 8 | super(scope, id, props); 9 | 10 | const bucket = new Bucket(this, 'dummyBucket') 11 | new SvelteDistribution(this, 'svelteDistribution', { 12 | rendererProps: { 13 | logLevel: 'DEBUG', 14 | environment: { 15 | TEST_ENV_VAR: 'test value', 16 | BUCKET_NAME: bucket.bucketName, 17 | }, 18 | } 19 | }) 20 | } 21 | } -------------------------------------------------------------------------------- /packages/test-stack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-stack", 3 | "version": "0.1.0", 4 | "bin": { 5 | "test-stack": "bin/test-stack.js" 6 | }, 7 | "scripts": { 8 | "build": "tsc", 9 | "watch": "tsc -w", 10 | "test": "jest", 11 | "cdk": "cdk", 12 | "synth": "cdk synth", 13 | "diff": "cdk diff", 14 | "deploy": "cdk deploy" 15 | }, 16 | "devDependencies": { 17 | "@types/jest": "^28.1.0", 18 | "@types/node": "17.0.39", 19 | "aws-cdk": "2.27.0", 20 | "jest": "^28.1.0", 21 | "ts-jest": "^28.0.4", 22 | "ts-node": "^10.8.1", 23 | "typescript": "~4.7.3" 24 | }, 25 | "dependencies": { 26 | "@aws-cdk/aws-apigatewayv2-alpha": "^2.27.0-alpha.0", 27 | "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.27.0-alpha.0", 28 | "@sveltekit-cdk/constructsv2": "workspace:*", 29 | "aws-cdk-lib": "2.27.0", 30 | "constructs": "^10.1.26", 31 | "source-map-support": "^0.5.21" 32 | }, 33 | "private": true 34 | } 35 | -------------------------------------------------------------------------------- /packages/test-stack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es2018" 7 | ], 8 | "declaration": true, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "noImplicitThis": true, 13 | "alwaysStrict": true, 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": false, 18 | "inlineSourceMap": true, 19 | "inlineSources": true, 20 | "experimentalDecorators": true, 21 | "strictPropertyInitialization": false, 22 | "typeRoots": [ 23 | "./node_modules/@types" 24 | ] 25 | }, 26 | "exclude": [ 27 | "node_modules", 28 | "cdk.out" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /packages/test/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | -------------------------------------------------------------------------------- /packages/test/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /packages/test/README.md: -------------------------------------------------------------------------------- 1 | # create-svelte 2 | 3 | Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). 4 | 5 | ## Creating a project 6 | 7 | If you're seeing this, you've probably already done this step. Congrats! 8 | 9 | ```bash 10 | # create a new project in the current directory 11 | npm init svelte@next 12 | 13 | # create a new project in my-app 14 | npm init svelte@next my-app 15 | ``` 16 | 17 | > Note: the `@next` is temporary 18 | 19 | ## Developing 20 | 21 | Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: 22 | 23 | ```bash 24 | npm run dev 25 | 26 | # or start the server and open the app in a new browser tab 27 | npm run dev -- --open 28 | ``` 29 | 30 | ## Building 31 | 32 | To create a production version of your app: 33 | 34 | ```bash 35 | npm run build 36 | ``` 37 | 38 | You can preview the production build with `npm run preview`. 39 | 40 | > To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs#adapters) for your target environment. 41 | -------------------------------------------------------------------------------- /packages/test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "svelte-kit dev", 6 | "build": "svelte-kit build", 7 | "package": "svelte-kit package", 8 | "preview": "svelte-kit preview", 9 | "check": "svelte-check --tsconfig ./tsconfig.json", 10 | "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch" 11 | }, 12 | "devDependencies": { 13 | "@sveltejs/kit": "1.0.0-next.348", 14 | "@sveltekit-cdk/adapter": "workspace:*", 15 | "msgpackr": "^1.6.1", 16 | "svelte": "^3.48.0", 17 | "svelte-check": "^2.7.2", 18 | "svelte-preprocess": "^4.10.6", 19 | "tslib": "^2.4.0", 20 | "typescript": "^4.7.3" 21 | }, 22 | "type": "module" 23 | } -------------------------------------------------------------------------------- /packages/test/src/app.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // See https://kit.svelte.dev/docs#typescript 4 | // for information about these interfaces 5 | declare namespace App { 6 | interface Locals {} 7 | 8 | interface Platform {} 9 | 10 | interface Session {} 11 | 12 | interface Stuff {} 13 | } 14 | -------------------------------------------------------------------------------- /packages/test/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 13 | 14 | 15 |
%sveltekit.body%
16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/test/src/lib/Test.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | {#if test} 7 |
8 |

{test.title}

9 |
{test.status}
10 |

{test.description}

11 | {#if test.error} 12 |
{test.error}
13 | {/if} 14 |
15 | {/if} 16 | 17 | 47 | -------------------------------------------------------------------------------- /packages/test/src/lib/test/binaryRequestBody.ts: -------------------------------------------------------------------------------- 1 | import { readable } from 'svelte/store' 2 | import type { Subscriber } from 'svelte/store' 3 | import type { Test } from './types' 4 | import { pack } from 'msgpackr' 5 | 6 | const test: Test = { 7 | title: 'Binary request body', 8 | description: 'Adapter can handle binary request body', 9 | status: 'initial' 10 | } 11 | 12 | export const binaryRequestBody = readable(test, (set) => { 13 | run(set) 14 | }) 15 | 16 | async function run(set: Subscriber) { 17 | let res: Response 18 | set({ 19 | ...test, 20 | status: 'running' 21 | }) 22 | try { 23 | res = await fetch('/endpoints/msgpack.json', { 24 | method: 'POST', 25 | body: pack({ 26 | test: 'payload' 27 | }), 28 | headers: { 29 | 'content-type': 'application/x-msgpack' 30 | } 31 | }) 32 | } catch (error) { 33 | set({ 34 | ...test, 35 | status: 'failure', 36 | error: error.toString() 37 | }) 38 | return 39 | } 40 | const t = res.status 41 | if (res.status !== 200) { 42 | set({ 43 | ...test, 44 | status: 'failure', 45 | error: `Expected status 200, got ${res.status}` 46 | }) 47 | return 48 | } 49 | let body:any 50 | try { 51 | body = await res.json() 52 | } catch (error) { 53 | set({ 54 | ...test, 55 | status: 'failure', 56 | error: error.toString() 57 | }) 58 | return 59 | } 60 | if (body.test !== 'payload') { 61 | set({ 62 | ...test, 63 | status: 'failure', 64 | error: 'unexpected return value' 65 | }) 66 | return 67 | } 68 | set({ 69 | ...test, 70 | status: 'success', 71 | }) 72 | } 73 | -------------------------------------------------------------------------------- /packages/test/src/lib/test/caching.ts: -------------------------------------------------------------------------------- 1 | import { readable } from 'svelte/store' 2 | import type { Subscriber } from 'svelte/store' 3 | import type { Test } from './types' 4 | import { browser } from '$app/env' 5 | 6 | const test: Test = { 7 | title: 'Caching', 8 | description: 'SSR pages without maxage are not cached. (10 attempts left)', 9 | status: 'initial' 10 | } 11 | 12 | export const caching = readable(test, (set) => { 13 | run(set) 14 | }) 15 | 16 | async function run(set: Subscriber) { 17 | if (!browser) return 18 | // generate a random slug 19 | const bytes = new Uint8Array(10) 20 | crypto.getRandomValues(bytes) 21 | let slug = '' 22 | bytes.forEach(n => { 23 | slug += n.toString(16).padStart(2,'0') 24 | }) 25 | // init counters 26 | let countDown = 10 27 | let sameCount = 0 28 | let previousTS = [] 29 | // set status 30 | set({ 31 | ...test, 32 | status: 'running' 33 | }) 34 | // set timer to pound the new page 35 | let intervalId = setInterval(async () => { 36 | set({ 37 | ...test, 38 | description: `SSR pages without maxage are not cached. (${countDown} attempts left)`, 39 | status: 'running' 40 | }) 41 | let res: Response 42 | let data: string 43 | try { 44 | res = await fetch(`/ssr/${slug}`) 45 | } catch (error) { 46 | set({ 47 | ...test, 48 | description: `SSR pages without maxage are not cached. (${countDown} attempts left)`, 49 | status: 'failure', 50 | error: error.toString() 51 | }) 52 | clearInterval(intervalId) 53 | return 54 | } 55 | try { 56 | data = await res.text() 57 | } catch (error) { 58 | set({ 59 | ...test, 60 | status: 'failure', 61 | description: `SSR pages without maxage are not cached. (${countDown} attempts left)`, 62 | error: error.toString() 63 | }) 64 | clearInterval(intervalId) 65 | return 66 | } 67 | const re = /Rendered at: (\S*)/g 68 | const match = re.exec(data) 69 | if (!match) { 70 | set({ 71 | ...test, 72 | status: 'failure', 73 | description: `SSR pages without maxage are not cached. (${countDown} attempts left)`, 74 | error: "Didn't find expected pattern in response" 75 | }) 76 | clearInterval(intervalId) 77 | return 78 | } 79 | if (previousTS.includes(match[1])) { 80 | set({ 81 | ...test, 82 | status: 'failure', 83 | description: `SSR pages without maxage are not cached. (${countDown} attempts left)`, 84 | error: "A page with same timestamp was served twise" 85 | }) 86 | clearInterval(intervalId) 87 | return 88 | } 89 | 90 | previousTS.push(match[1]) 91 | countDown-- 92 | if (countDown <= 0) { 93 | set({ 94 | ...test, 95 | status: 'success', 96 | description: `SSR pages without maxage are not cached.`, 97 | }) 98 | clearInterval(intervalId) 99 | return 100 | } 101 | }, 1000) 102 | 103 | } 104 | -------------------------------------------------------------------------------- /packages/test/src/lib/test/index.ts: -------------------------------------------------------------------------------- 1 | import { readable } from 'svelte/store' 2 | import type { Test } from './types' 3 | 4 | export { prerendered } from './prerendered' 5 | export { prerenderedContentType } from './prerenderedContentType' 6 | export { staticContent } from './static' 7 | export { ssr } from './ssr' 8 | export { caching } from './caching' 9 | export { binaryRequestBody } from './binaryRequestBody' 10 | 11 | export const requestHeaders = readable({ 12 | title: 'Request headers', 13 | description: 'Some set of important headers is successfully passed to an endpoint', 14 | status: 'todo' 15 | }) 16 | export const responseHeaders = readable({ 17 | title: 'Response headers', 18 | description: 'Some set of important headers is successfully passed from an endpoint', 19 | status: 'todo' 20 | }) 21 | export const cookies = readable({ 22 | title: 'Cookies', 23 | description: 'Setting cookies works', 24 | status: 'todo' 25 | }) 26 | export const cacheControl = readable({ 27 | title: 'Cache control', 28 | description: 'Cache obeys cache control headers', 29 | status: 'todo' 30 | }) -------------------------------------------------------------------------------- /packages/test/src/lib/test/prerendered.ts: -------------------------------------------------------------------------------- 1 | import { readable } from 'svelte/store' 2 | import type { Subscriber } from 'svelte/store' 3 | import type { Test } from './types' 4 | 5 | const test: Test = { 6 | title: 'Prerendered pages', 7 | description: 'Adapter serves build-time versions of prerendered pages, instead of rendering them again at runtime.', 8 | status: 'initial' 9 | } 10 | 11 | export const prerendered = readable(test, (set) => { 12 | run(set) 13 | }) 14 | 15 | async function run(set: Subscriber) { 16 | let res: Response 17 | let data: string 18 | set({ 19 | ...test, 20 | status: 'running' 21 | }) 22 | try { 23 | res = await fetch('/ssr/prerendered') 24 | } catch (error) { 25 | set({ 26 | ...test, 27 | status: 'failure', 28 | error: error.toString() 29 | }) 30 | return 31 | } 32 | try { 33 | data = await res.text() 34 | } catch (error) { 35 | set({ 36 | ...test, 37 | status: 'failure', 38 | error: error.toString() 39 | }) 40 | return 41 | } 42 | const re = /Prerendering: ([a-z]*)/g 43 | const match = re.exec(data) 44 | if (!match) { 45 | set({ 46 | ...test, 47 | status: 'failure', 48 | error: "Didn't find expected pattern in response" 49 | }) 50 | return 51 | } 52 | if (match[1] !== 'true') { 53 | set({ 54 | ...test, 55 | status: 'failure', 56 | error: `Expected prerendering = "true", got "${match[1]}"` 57 | }) 58 | return 59 | } 60 | 61 | set({ 62 | ...test, 63 | status: 'success', 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /packages/test/src/lib/test/prerenderedContentType.ts: -------------------------------------------------------------------------------- 1 | import { readable } from 'svelte/store' 2 | import type { Subscriber } from 'svelte/store' 3 | import type { Test } from './types' 4 | 5 | const test: Test = { 6 | title: 'Prerendered page content type', 7 | description: 'Content type of prerendered pages is text/html', 8 | status: 'initial' 9 | } 10 | 11 | export const prerenderedContentType = readable(test, (set) => { 12 | run(set) 13 | }) 14 | 15 | async function run(set: Subscriber) { 16 | let res: Response 17 | let data: string 18 | set({ 19 | ...test, 20 | status: 'running' 21 | }) 22 | try { 23 | res = await fetch('/ssr/prerendered') 24 | } catch (error) { 25 | set({ 26 | ...test, 27 | status: 'failure', 28 | error: error.toString() 29 | }) 30 | return 31 | } 32 | const t = res.headers.get('content-type') 33 | if (t !== 'text/html') { 34 | set({ 35 | ...test, 36 | status: 'failure', 37 | error: `Expected "text/html", got "${t}"` 38 | }) 39 | return 40 | } 41 | set({ 42 | ...test, 43 | status: 'success', 44 | }) 45 | } 46 | -------------------------------------------------------------------------------- /packages/test/src/lib/test/ssr.ts: -------------------------------------------------------------------------------- 1 | import { readable } from 'svelte/store' 2 | import type { Subscriber } from 'svelte/store' 3 | import type { Test } from './types' 4 | 5 | const test: Test = { 6 | title: 'SSR pages', 7 | description: 'Adapter is able to render SSR pages.', 8 | status: 'initial' 9 | } 10 | 11 | export const ssr = readable(test, (set) => { 12 | run(set) 13 | }) 14 | 15 | async function run(set: Subscriber) { 16 | let res: Response 17 | let data: string 18 | set({ 19 | ...test, 20 | status: 'running' 21 | }) 22 | try { 23 | res = await fetch('/ssr/dynamic') 24 | } catch (error) { 25 | set({ 26 | ...test, 27 | status: 'failure', 28 | error: error.toString() 29 | }) 30 | return 31 | } 32 | try { 33 | data = await res.text() 34 | } catch (error) { 35 | set({ 36 | ...test, 37 | status: 'failure', 38 | error: error.toString() 39 | }) 40 | return 41 | } 42 | const re = /Prerendering: ([a-z]*)/g 43 | const match = re.exec(data) 44 | if (!match) { 45 | set({ 46 | ...test, 47 | status: 'failure', 48 | error: "Didn't find expected pattern in response" 49 | }) 50 | return 51 | } 52 | if (match[1] !== 'false') { 53 | set({ 54 | ...test, 55 | status: 'failure', 56 | error: `Expected prerendering = "false", got "${match[1]}"` 57 | }) 58 | return 59 | } 60 | 61 | set({ 62 | ...test, 63 | status: 'success', 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /packages/test/src/lib/test/static.ts: -------------------------------------------------------------------------------- 1 | import { readable } from 'svelte/store' 2 | import type { Subscriber } from 'svelte/store' 3 | import type { Test } from './types' 4 | 5 | const test: Test = { 6 | title: 'Static assets', 7 | description: 'Static assets are served', 8 | status: 'initial' 9 | } 10 | 11 | export const staticContent = readable(test, (set) => { 12 | run(set) 13 | }) 14 | 15 | async function run(set: Subscriber) { 16 | let res: Response 17 | set({ 18 | ...test, 19 | status: 'running' 20 | }) 21 | try { 22 | res = await fetch('/favicon.png') 23 | } catch (error) { 24 | set({ 25 | ...test, 26 | status: 'failure', 27 | error: error.toString() 28 | }) 29 | return 30 | } 31 | const t = res.status 32 | if (res.status !== 200) { 33 | set({ 34 | ...test, 35 | status: 'failure', 36 | error: `Expected status 200, got ${res.status}` 37 | }) 38 | return 39 | } 40 | set({ 41 | ...test, 42 | status: 'success', 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /packages/test/src/lib/test/types.ts: -------------------------------------------------------------------------------- 1 | export interface Test { 2 | title: string 3 | description: string 4 | error?: string 5 | status: 'initial' | 'running' | 'success' | 'failure' | 'todo' 6 | } -------------------------------------------------------------------------------- /packages/test/src/routes/endpoints/headers.json.ts: -------------------------------------------------------------------------------- 1 | import type { RequestHandler } from "@sveltejs/kit"; 2 | 3 | export const get: RequestHandler = async ({ request }) => { 4 | const body = {} 5 | request.headers.forEach((v, k) => { body[k] = v }) 6 | return { 7 | body, 8 | headers: { 9 | 'cache-control': 'no-store' 10 | }, 11 | } 12 | } -------------------------------------------------------------------------------- /packages/test/src/routes/endpoints/icon.png.ts: -------------------------------------------------------------------------------- 1 | import type { RequestHandler } from "@sveltejs/kit"; 2 | 3 | const data = 'iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAQAAABpN6lAAAAAAXNSR0IArs4c6QAABd1JREFUeNrtXdtt6zgQVQkuwSWkhJTgElxCSnAJLiEluASXkP+IYgQDgiAIAiEYEARBOLuL7N3cm3XGpI4moR9nvvITmENyzjyp5I477rjjjkhgl+nKbMw23f8uZms26couk+uFXZqnbGecgSgu25mnq1NEuk73BkHykq7tIrl82IXZiLsun4bnCz8L5sk4A04uVgmvj+bFYBZxZpNcFuzCbA1mlRf7kFwK0pV5M1CQpyR+2EW2M9CS7DlyZvgwemryEq0K7PIX19+kCszm/efdpAp+Ed5NqmAq4VkUqND8KzUK2DBzuEs8ECXh5XDocQoDWpQwviI7R3ESXoEO5zCg9jwNr4/Jl4iQ8HJ08MWACua8vJ20BHESXo0RYeh8zsE2+R8iJLwDekzBiENs1yCc8CwaCKBVkO6Td8RJeAUGcBhxiOMMhBOeRYsP6Kkg3UdJeCVGzIUeVlb1MjrCO2JeuDNcENXeC4RHQLwGTmv5D6E2/4AOOujkS/CgsvzAo08QHn0GNsrL5wmPR0swgfLyLRymYECDHAYWJY4edGgEmdn0hSy/nLj3TTBxFt9lBfxNn51IeP3JG12cV9mXkq4Ugh0dwhtRw3whLSQcv8MM2gc2upfRIZdodDoVbtSPP094o0eaQ8Kg7w2ma73o/uiV6BKhT4TnI75qIuGVMDCxK+D8/jtMgYMN8CmqL5ml5xTA3/9m0t4XMMGSo8FIGEEV+1+Rzk64VJ9crFZXAWYr78lIOzvhYv84CSWhANoAdoSzw8mHx2GJzCB5AQrK2eGlxoheNy1mnubZ/xEljIIcUOjmhLJn0UHlnR1edElQKna5WQkv0vYp6d/3pLOjL/ZBUwEqe5+j+CU8Xb7NUPObzgA9bNDCa3QYT/wXh5K4AIoKKCEigPIKHD2yhDb8AixUFdBAQjt7xWAMVEL2nBCgFVCTFQPeqtjljyqgUKsY1ESrFKGA0Ciw4SoG7PVydjFTJWAqC/RkxUBGy99/3g+wkFEKFQMejrcAfDZoONfBoVoiL7/nDEh9AG1Q9F+gw5wYYTkrwIfDpdfPbNHAoQeF8IoQ0rV+RQgDfhbFd7RNSxXhGj+LjnOF+ZSI/fEzkOtXhtOVAWcHwtsjChSo0OI8atYb5PPCx1ktey3UG6mqEN8ZoH8NjrDh/51PiPCtMQfBveHLpAXBBMkHeEOoqQIHOzn3WOk7xHbpk9gYAKovaGrg3eh3jPvNgVh0CMX4/vPjVsDrI9cPzJfKHKcAfv+D67bBRk+WgVCAYiwgd3P0YnhUBhVAZVSEAmj7L6uhRIMjuv+kRX2StDhPs9BlAeWxdz5zKBKochzAC99r3BPFcbo9hhe+17jWjQW0x995Ms11u0TlKNCRC+V7jVsYIh9AUiDf8cWXynLdjFC68iiLCCVLapKY7zZ8Uc0DNB5D7brDNT3THcAroBMn+/UniUfkTG2IJ8Hu5I9yOIQTnsrodLbTDYMEohoC2KHCGPP7AZICJPTKwzWW7w/kAyEJnf5gFb//vBEUoD9cw1WG9RVQ8k9nyL3GbF2YH5VxkNBLhMdnjVkHWL9DCGiFpzPozjA+AOI7hHKPG5sLhEe6uzz781XB3stsNWjgMEwkvAPxlpw6EVYgwBIev3zeDFqM0EKHPI6XBO2Cit4VCI9ifr5LTL9HqA3PLjiiHYodmz2AAz9gke7VH9g27nuuQRPb3vu+HNGCADFNmu0Ys8f3h8gq4EvksrwR8R55BngV8NOk29C958/Am8bjGSOqS3lNPl3Nn9o8wl7S9wSy3ZxFrS5OwmOuwYdU6CGhRQETJ+HN1yuSo4L7YxByQAeHEhYmXsLz8QpJiZ3wfMYnCImf8ObqGbrqz6ecc4tu4AM6gbbg0gjPL1/s2T12mYTn5xec7SC9ZMLz5gR3tYTnB7vMnq+W8PztQbq/0e/GfToJ7kYX/5tZXGe7G/x25IncwSbdG/c1y5vtlS7984l4ffzbPqzN5l3++etqjvsdd9xxFfgLb6Q29nbWlxEAAAAASUVORK5CYII=' 4 | 5 | export const get: RequestHandler = async (_) => { 6 | const body = Buffer.from(data, 'base64') 7 | return { 8 | body, 9 | headers: { 10 | 'cache-control': 'no-store', 11 | 'content-type': 'image/png' 12 | }, 13 | } 14 | } -------------------------------------------------------------------------------- /packages/test/src/routes/endpoints/msgpack.json.ts: -------------------------------------------------------------------------------- 1 | import type { RequestHandler } from '@sveltejs/kit' 2 | import {unpack} from 'msgpackr' 3 | 4 | export const post: RequestHandler = async ({request}) => { 5 | const buf = await request.arrayBuffer() 6 | 7 | return { 8 | body: unpack(Buffer.from(buf)), 9 | headers: { 10 | 'cache-control': 'no-store', 11 | }, 12 | } 13 | } -------------------------------------------------------------------------------- /packages/test/src/routes/index.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | 21 | 22 | SvelteKit Adapter Test 23 | 24 | 25 | 26 |

Welcome to SvelteKit CDK Adapter test

27 | 28 | prerendered page 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /packages/test/src/routes/my-ip.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |

{clientAddress}

6 | -------------------------------------------------------------------------------- /packages/test/src/routes/my-ip.ts: -------------------------------------------------------------------------------- 1 | import type { RequestHandler } from "@sveltejs/kit"; 2 | 3 | export const get: RequestHandler = async ({ clientAddress }) => { 4 | const body = { clientAddress } 5 | return { 6 | body, 7 | } 8 | } -------------------------------------------------------------------------------- /packages/test/src/routes/ssr/[slug].svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 |

Prerendered page

11 | 12 |

13 | Prerendering: {prerendering} 14 |

15 | 16 |

17 | Browser: {browser} 18 |

19 | 20 |

21 | Slug: {$page.params.slug} 22 |

23 | 24 |

25 | Rendered at: {new Date().toISOString()} 26 |

27 | -------------------------------------------------------------------------------- /packages/test/src/routes/ssr/maxage-5.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |

This page should be cached for 5 seconds

11 | 12 |

13 | Rendered at: {new Date().toISOString()} 14 |

15 | -------------------------------------------------------------------------------- /packages/test/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juranki/sveltekit-cdk/1fc170fc01eb9bae76b49d8d48056ee3b506f9c9/packages/test/static/favicon.png -------------------------------------------------------------------------------- /packages/test/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { adapter } from '@sveltekit-cdk/adapter' 2 | import preprocess from 'svelte-preprocess'; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://github.com/sveltejs/svelte-preprocess 7 | // for more information about preprocessors 8 | preprocess: preprocess(), 9 | 10 | kit: { 11 | adapter: adapter({ 12 | cdkProjectPath: '../test-stack' 13 | }), 14 | } 15 | }; 16 | 17 | export default config; 18 | -------------------------------------------------------------------------------- /packages/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "moduleResolution": "node", 5 | "module": "es2020", 6 | "lib": ["es2020", "DOM"], 7 | "target": "es2020", 8 | /** 9 | svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript 10 | to enforce using \`import type\` instead of \`import\` for Types. 11 | */ 12 | "importsNotUsedAsValues": "error", 13 | "isolatedModules": true, 14 | "resolveJsonModule": true, 15 | /** 16 | To have warnings/errors of the Svelte compiler at the correct position, 17 | enable source maps by default. 18 | */ 19 | "sourceMap": true, 20 | "esModuleInterop": true, 21 | "skipLibCheck": true, 22 | "forceConsistentCasingInFileNames": true, 23 | "baseUrl": ".", 24 | "allowJs": true, 25 | "checkJs": true, 26 | "paths": { 27 | "$lib": ["src/lib"], 28 | "$lib/*": ["src/lib/*"] 29 | } 30 | }, 31 | "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"], 32 | "exclude": ["node_modules"] 33 | } 34 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/**" 3 | # exclude test site until migration is ready 4 | # https://github.com/sveltejs/kit/discussions/5774 5 | - "!packages/test*/**" 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "commonjs", /* Specify what module code is generated. */ 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 33 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 34 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 35 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 36 | // "resolveJsonModule": true, /* Enable importing .json files */ 37 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 38 | 39 | /* JavaScript Support */ 40 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 41 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 42 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 43 | 44 | /* Emit */ 45 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 46 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 47 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 48 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 49 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 50 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 51 | // "removeComments": true, /* Disable emitting comments. */ 52 | // "noEmit": true, /* Disable emitting files from a compilation. */ 53 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 54 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 55 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 56 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 59 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 60 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 61 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 62 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 63 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 64 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 65 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 66 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 67 | 68 | /* Interop Constraints */ 69 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 70 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 71 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 72 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 73 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 74 | 75 | /* Type Checking */ 76 | "strict": true, /* Enable all strict type-checking options. */ 77 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 78 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 79 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 80 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 81 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 82 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 83 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 84 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 85 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 86 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 87 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 88 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 89 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 90 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 91 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 92 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 93 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 94 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 95 | 96 | /* Completeness */ 97 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 98 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "entryPoints": [ 3 | "./packages/adapter", 4 | "./packages/constructsv2" 5 | ], 6 | "entryPointStrategy": "packages", 7 | "out": "docs", 8 | "exclude": "**/proxy-handler-v2.ts", 9 | "excludeExternals": true 10 | } --------------------------------------------------------------------------------