From 80eb6c8d530d93c6a31abee499bb04305d118f7a Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 27 Feb 2025 22:00:51 -0800 Subject: [PATCH 01/29] chore: federation --- .../.github/PULL_REQUEST_TEMPLATE.md | 15 + .../.github/workflows/deploy.yml | 174 + .../.github/workflows/version.yml | 54 + .../federation/epic-stack-remote/.gitignore | 26 + .../epic-stack-remote/.prettierignore | 15 + .../epic-stack-remote/.vscode/extensions.json | 11 + .../.vscode/remix.code-snippets | 80 + .../epic-stack-remote/.vscode/settings.json | 14 + .../epic-stack-remote/CONTRIBUTING.md | 87 + .../federation/epic-stack-remote/LICENSE.md | 18 + .../federation/epic-stack-remote/README.md | 54 + .../app/assets/favicons/apple-touch-icon.png | Bin 0 -> 8986 bytes .../app/assets/favicons/favicon.svg | 13 + .../app/components/error-boundary.tsx | 53 + .../app/components/floating-toolbar.tsx | 2 + .../app/components/forms.tsx | 202 + .../app/components/progress-bar.tsx | 63 + .../app/components/search-bar.tsx | 63 + .../app/components/spacer.tsx | 57 + .../app/components/toaster.tsx | 16 + .../app/components/ui/README.md | 7 + .../app/components/ui/button.tsx | 58 + .../app/components/ui/checkbox.tsx | 41 + .../app/components/ui/dropdown-menu.tsx | 206 + .../app/components/ui/icon.tsx | 77 + .../app/components/ui/input-otp.tsx | 70 + .../app/components/ui/input.tsx | 25 + .../app/components/ui/label.tsx | 24 + .../app/components/ui/sonner.tsx | 26 + .../app/components/ui/status-button.tsx | 78 + .../app/components/ui/textarea.tsx | 24 + .../app/components/ui/tooltip.tsx | 28 + .../app/components/user-dropdown.tsx | 68 + .../epic-stack-remote/app/entry.client.tsx | 11 + .../epic-stack-remote/app/entry.server.tsx | 116 + .../federation/epic-stack-remote/app/root.tsx | 260 + .../epic-stack-remote/app/routes.ts | 21 + .../epic-stack-remote/app/routes/$.tsx | 47 + .../_auth+/auth.$provider.callback.test.ts | 259 + .../routes/_auth+/auth.$provider.callback.ts | 197 + .../app/routes/_auth+/auth_.$provider.ts | 34 + .../app/routes/_auth+/forgot-password.tsx | 189 + .../app/routes/_auth+/login.server.ts | 158 + .../app/routes/_auth+/login.tsx | 204 + .../app/routes/_auth+/logout.tsx | 11 + .../app/routes/_auth+/onboarding.server.ts | 19 + .../app/routes/_auth+/onboarding.tsx | 232 + .../_auth+/onboarding_.$provider.server.ts | 19 + .../routes/_auth+/onboarding_.$provider.tsx | 280 + .../routes/_auth+/reset-password.server.ts | 34 + .../app/routes/_auth+/reset-password.tsx | 137 + .../app/routes/_auth+/signup.tsx | 185 + .../app/routes/_auth+/verify.server.ts | 200 + .../app/routes/_auth+/verify.tsx | 144 + .../app/routes/_marketing+/about.tsx | 3 + .../app/routes/_marketing+/index.tsx | 101 + .../app/routes/_marketing+/logos/docker.svg | 47 + .../app/routes/_marketing+/logos/eslint.svg | 17 + .../app/routes/_marketing+/logos/faker.svg | 736 + .../app/routes/_marketing+/logos/fly.svg | 1 + .../app/routes/_marketing+/logos/github.svg | 1 + .../app/routes/_marketing+/logos/logos.ts | 173 + .../app/routes/_marketing+/logos/msw.svg | 13 + .../routes/_marketing+/logos/playwright.svg | 9 + .../app/routes/_marketing+/logos/prettier.svg | 76 + .../app/routes/_marketing+/logos/prisma.svg | 9 + .../app/routes/_marketing+/logos/radix.svg | 1 + .../routes/_marketing+/logos/react-email.svg | 1 + .../app/routes/_marketing+/logos/remix.svg | 25 + .../app/routes/_marketing+/logos/resend.svg | 31 + .../app/routes/_marketing+/logos/sentry.svg | 6 + .../routes/_marketing+/logos/shadcn-ui.svg | 1 + .../app/routes/_marketing+/logos/sqlite.svg | 67 + .../app/routes/_marketing+/logos/stars.jpg | Bin 0 -> 391161 bytes .../app/routes/_marketing+/logos/tailwind.svg | 1 + .../_marketing+/logos/testing-library.png | Bin 0 -> 5803 bytes .../routes/_marketing+/logos/typescript.svg | 6 + .../app/routes/_marketing+/logos/vitest.svg | 5 + .../app/routes/_marketing+/logos/zod.svg | 46 + .../app/routes/_marketing+/privacy.tsx | 3 + .../app/routes/_marketing+/support.tsx | 3 + .../app/routes/_marketing+/tailwind-preset.ts | 27 + .../app/routes/_marketing+/tos.tsx | 3 + .../app/routes/_seo+/robots[.]txt.ts | 9 + .../app/routes/_seo+/sitemap[.]xml.ts | 17 + .../app/routes/admin+/cache.tsx | 244 + .../app/routes/admin+/cache_.lru.$cacheKey.ts | 31 + .../routes/admin+/cache_.sqlite.$cacheKey.ts | 31 + .../app/routes/admin+/cache_.sqlite.server.ts | 59 + .../app/routes/admin+/cache_.sqlite.tsx | 1 + .../epic-stack-remote/app/routes/me.tsx | 19 + .../routes/resources+/download-user-data.tsx | 62 + .../app/routes/resources+/healthcheck.tsx | 26 + .../resources+/note-images.$imageId.tsx | 22 + .../app/routes/resources+/theme-switch.tsx | 143 + .../resources+/user-images.$imageId.tsx | 22 + .../settings+/profile.change-email.server.tsx | 124 + .../routes/settings+/profile.change-email.tsx | 146 + .../routes/settings+/profile.connections.tsx | 212 + .../app/routes/settings+/profile.index.tsx | 358 + .../app/routes/settings+/profile.password.tsx | 173 + .../settings+/profile.password_.create.tsx | 124 + .../app/routes/settings+/profile.photo.tsx | 239 + .../app/routes/settings+/profile.tsx | 80 + .../settings+/profile.two-factor.disable.tsx | 62 + .../settings+/profile.two-factor.index.tsx | 90 + .../routes/settings+/profile.two-factor.tsx | 16 + .../settings+/profile.two-factor.verify.tsx | 229 + .../app/routes/users+/$username.test.tsx | 95 + .../app/routes/users+/$username.tsx | 127 + .../$username_+/__note-editor.server.tsx | 128 + .../users+/$username_+/__note-editor.tsx | 266 + .../users+/$username_+/notes.$noteId.tsx | 215 + .../$username_+/notes.$noteId_.edit.tsx | 50 + .../routes/users+/$username_+/notes.index.tsx | 27 + .../routes/users+/$username_+/notes.new.tsx | 12 + .../app/routes/users+/$username_+/notes.tsx | 99 + .../app/routes/users+/index.tsx | 112 + .../epic-stack-remote/app/styles/tailwind.css | 80 + .../app/utils/auth.server.ts | 240 + .../app/utils/cache.server.ts | 182 + .../app/utils/client-hints.tsx | 56 + .../app/utils/connections.server.ts | 33 + .../app/utils/connections.tsx | 57 + .../epic-stack-remote/app/utils/db.server.ts | 37 + .../app/utils/email.server.ts | 97 + .../epic-stack-remote/app/utils/env.server.ts | 65 + .../app/utils/extended-theme.ts | 102 + .../app/utils/file-uploads.server.ts | 16 + .../app/utils/headers.server.test.ts | 39 + .../app/utils/headers.server.ts | 114 + .../app/utils/honeypot.server.ts | 17 + .../app/utils/litefs.server.ts | 10 + .../app/utils/misc.error-message.test.ts | 24 + .../epic-stack-remote/app/utils/misc.tsx | 290 + .../app/utils/misc.use-double-check.test.tsx | 83 + .../app/utils/monitoring.client.tsx | 49 + .../app/utils/nonce-provider.ts | 5 + .../app/utils/permissions.server.ts | 60 + .../app/utils/providers/constants.ts | 3 + .../app/utils/providers/github.server.ts | 106 + .../app/utils/providers/provider.ts | 28 + .../app/utils/redirect-cookie.server.ts | 17 + .../app/utils/request-info.ts | 19 + .../app/utils/session.server.ts | 38 + .../app/utils/theme.server.ts | 19 + .../app/utils/timing.server.ts | 121 + .../app/utils/toast.server.ts | 62 + .../app/utils/totp.server.ts | 3 + .../app/utils/user-validation.ts | 48 + .../epic-stack-remote/app/utils/user.ts | 70 + .../app/utils/verification.server.ts | 13 + .../epic-stack-remote/components.json | 16 + .../epic-stack-remote/docs/README.md | 35 + .../federation/epic-stack-remote/docs/apis.md | 21 + .../epic-stack-remote/docs/authentication.md | 113 + .../epic-stack-remote/docs/caching.md | 84 + .../epic-stack-remote/docs/client-hints.md | 13 + .../epic-stack-remote/docs/community.md | 21 + .../epic-stack-remote/docs/database.md | 368 + .../docs/decisions/000-template.md | 12 + .../docs/decisions/001-typescript-only.md | 44 + .../docs/decisions/002-email-service.md | 41 + .../docs/decisions/003-sqlite.md | 83 + .../docs/decisions/004-github-actions.md | 49 + .../docs/decisions/005-client-pref-cookies.md | 94 + .../docs/decisions/006-native-esm.md | 38 + .../docs/decisions/007-sessions.md | 44 + .../decisions/008-content-security-policy.md | 32 + .../docs/decisions/009-region-selection.md | 32 + .../docs/decisions/010-memory-swap.md | 41 + .../docs/decisions/011-sitemaps.md | 33 + .../docs/decisions/012-cuid.md | 81 + .../docs/decisions/013-email-code.md | 40 + .../docs/decisions/014-totp.md | 114 + .../docs/decisions/015-monitoring.md | 36 + .../docs/decisions/016-source-maps.md | 70 + .../docs/decisions/017-resend-email.md | 29 + .../docs/decisions/018-images.md | 61 + .../docs/decisions/019-components.md | 80 + .../docs/decisions/020-icons.md | 42 + .../docs/decisions/021-node-version.md | 58 + .../docs/decisions/022-report-only-csp.md | 31 + .../docs/decisions/023-route-based-dialogs.md | 45 + .../docs/decisions/024-change-email.md | 68 + .../docs/decisions/025-rate-limiting.md | 62 + .../docs/decisions/026-path-aliases.md | 36 + .../docs/decisions/027-toasts.md | 36 + .../docs/decisions/028-permissions-rbac.md | 84 + .../docs/decisions/029-remix-auth.md | 22 + .../docs/decisions/030-github-auth.md | 69 + .../docs/decisions/031-imports.md | 76 + .../docs/decisions/032-csrf.md | 33 + .../docs/decisions/033-honeypot.md | 35 + .../docs/decisions/034-source-maps.md | 24 + .../docs/decisions/035-remove-csrf.md | 43 + .../docs/decisions/036-vite.md | 46 + .../037-generated-internal-command.md | 44 + .../docs/decisions/038-remove-cleanup-db.md | 45 + .../docs/decisions/README.md | 7 + .../epic-stack-remote/docs/deployment.md | 189 + .../epic-stack-remote/docs/email.md | 22 + .../epic-stack-remote/docs/examples.md | 146 + .../epic-stack-remote/docs/features.md | 55 + .../epic-stack-remote/docs/fonts.md | 152 + .../epic-stack-remote/docs/getting-started.md | 60 + .../docs/guiding-principles.md | 30 + .../epic-stack-remote/docs/icons.md | 41 + .../docs/managing-updates.md | 178 + .../epic-stack-remote/docs/memory.md | 17 + .../epic-stack-remote/docs/monitoring.md | 67 + .../epic-stack-remote/docs/permissions.md | 42 + .../epic-stack-remote/docs/redirects.md | 88 + .../epic-stack-remote/docs/routing.md | 145 + .../epic-stack-remote/docs/secrets.md | 37 + .../epic-stack-remote/docs/security.md | 85 + .../federation/epic-stack-remote/docs/seo.md | 51 + .../epic-stack-remote/docs/server-timing.md | 89 + .../epic-stack-remote/docs/testing.md | 48 + .../epic-stack-remote/docs/timezone.md | 37 + .../epic-stack-remote/docs/toasts.md | 62 + .../epic-stack-remote/docs/troubleshooting.md | 76 + .../epic-stack-remote/eslint.config.js | 14 + .../federation/epic-stack-remote/fly.toml | 61 + .../federation/epic-stack-remote/index.js | 31 + .../epic-stack-remote/other/Dockerfile | 95 + .../other/Dockerfile.dockerignore | 9 + .../epic-stack-remote/other/README.md | 9 + .../epic-stack-remote/other/build-icons.ts | 153 + .../epic-stack-remote/other/build-server.ts | 50 + .../epic-stack-remote/other/litefs.yml | 43 + .../epic-stack-remote/other/sly/sly.json | 11 + .../other/sly/transform-icon.ts | 19 + .../other/svg-icons/README.md | 11 + .../other/svg-icons/arrow-left.svg | 11 + .../other/svg-icons/arrow-right.svg | 11 + .../other/svg-icons/avatar.svg | 11 + .../other/svg-icons/camera.svg | 11 + .../other/svg-icons/check.svg | 11 + .../other/svg-icons/clock.svg | 11 + .../other/svg-icons/cross-1.svg | 11 + .../other/svg-icons/dots-horizontal.svg | 13 + .../other/svg-icons/download.svg | 13 + .../other/svg-icons/envelope-closed.svg | 13 + .../other/svg-icons/exit.svg | 11 + .../other/svg-icons/file-text.svg | 11 + .../other/svg-icons/github-logo.svg | 13 + .../other/svg-icons/laptop.svg | 11 + .../other/svg-icons/link-2.svg | 13 + .../other/svg-icons/lock-closed.svg | 11 + .../other/svg-icons/lock-open-1.svg | 11 + .../other/svg-icons/magnifying-glass.svg | 11 + .../other/svg-icons/moon.svg | 11 + .../other/svg-icons/pencil-1.svg | 11 + .../other/svg-icons/pencil-2.svg | 11 + .../other/svg-icons/plus.svg | 11 + .../other/svg-icons/question-mark-circled.svg | 13 + .../other/svg-icons/reset.svg | 11 + .../epic-stack-remote/other/svg-icons/sun.svg | 11 + .../other/svg-icons/trash.svg | 11 + .../other/svg-icons/update.svg | 11 + .../epic-stack-remote/package-lock.json | 17276 ++++++++++++++++ .../federation/epic-stack-remote/package.json | 172 + .../epic-stack-remote/playwright.config.ts | 42 + .../epic-stack-remote/postcss.config.js | 7 + .../20230914194400_init/migration.sql | 258 + .../prisma/migrations/migration_lock.toml | 3 + .../epic-stack-remote/prisma/schema.prisma | 169 + .../epic-stack-remote/prisma/seed.ts | 230 + .../epic-stack-remote/public/favicon.ico | Bin 0 -> 15406 bytes .../public/favicons/README.md | 12 + .../favicons/android-chrome-192x192.png | Bin 0 -> 10041 bytes .../favicons/android-chrome-512x512.png | Bin 0 -> 27787 bytes .../epic-stack-remote/public/img/user.png | Bin 0 -> 3012 bytes .../epic-stack-remote/public/site.webmanifest | 20 + .../epic-stack-remote/react-router.config.ts | 9 + .../epic-stack-remote/remix.init/gitignore | 29 + .../epic-stack-remote/remix.init/index.js | 4 + .../epic-stack-remote/remix.init/index.mjs | 315 + .../remix.init/package-lock.json | 1731 ++ .../epic-stack-remote/remix.init/package.json | 12 + .../epic-stack-remote/rsbuild.config.ts | 35 + .../epic-stack-remote/server/dev-build.js | 23 + .../epic-stack-remote/server/dev-server.js | 7 + .../epic-stack-remote/server/index.ts | 318 + .../server/utils/monitoring.ts | 47 + .../epic-stack-remote/tailwind.config.ts | 22 + .../epic-stack-remote/tests/db-utils.ts | 115 + .../epic-stack-remote/tests/e2e/2fa.test.ts | 64 + .../tests/e2e/error-boundary.test.ts | 9 + .../tests/e2e/note-images.test.ts | 140 + .../epic-stack-remote/tests/e2e/notes.test.ts | 74 + .../tests/e2e/onboarding.test.ts | 431 + .../tests/e2e/search.test.ts | 26 + .../tests/e2e/settings-profile.test.ts | 115 + .../tests/fixtures/github/ghost.jpg | Bin 0 -> 16411 bytes .../fixtures/images/kody-notes/cute-koala.png | Bin 0 -> 306392 bytes .../images/kody-notes/koala-coder.png | Bin 0 -> 406767 bytes .../images/kody-notes/koala-cuddle.png | Bin 0 -> 337477 bytes .../images/kody-notes/koala-eating.png | Bin 0 -> 454917 bytes .../images/kody-notes/koala-mentor.png | Bin 0 -> 309275 bytes .../images/kody-notes/koala-soccer.png | Bin 0 -> 340830 bytes .../fixtures/images/kody-notes/mountain.png | Bin 0 -> 520758 bytes .../tests/fixtures/images/notes/0.png | Bin 0 -> 596706 bytes .../tests/fixtures/images/notes/1.png | Bin 0 -> 690425 bytes .../tests/fixtures/images/notes/2.png | Bin 0 -> 445199 bytes .../tests/fixtures/images/notes/3.png | Bin 0 -> 395815 bytes .../tests/fixtures/images/notes/4.png | Bin 0 -> 322099 bytes .../tests/fixtures/images/notes/5.png | Bin 0 -> 290108 bytes .../tests/fixtures/images/notes/6.png | Bin 0 -> 573271 bytes .../tests/fixtures/images/notes/7.png | Bin 0 -> 503933 bytes .../tests/fixtures/images/notes/8.png | Bin 0 -> 493499 bytes .../tests/fixtures/images/notes/9.png | Bin 0 -> 439449 bytes .../tests/fixtures/images/user/0.jpg | Bin 0 -> 24127 bytes .../tests/fixtures/images/user/1.jpg | Bin 0 -> 18801 bytes .../tests/fixtures/images/user/2.jpg | Bin 0 -> 20850 bytes .../tests/fixtures/images/user/3.jpg | Bin 0 -> 25106 bytes .../tests/fixtures/images/user/4.jpg | Bin 0 -> 20368 bytes .../tests/fixtures/images/user/5.jpg | Bin 0 -> 23240 bytes .../tests/fixtures/images/user/6.jpg | Bin 0 -> 33405 bytes .../tests/fixtures/images/user/7.jpg | Bin 0 -> 22600 bytes .../tests/fixtures/images/user/8.jpg | Bin 0 -> 23605 bytes .../tests/fixtures/images/user/9.jpg | Bin 0 -> 27519 bytes .../tests/fixtures/images/user/README.md | 4 + .../tests/fixtures/images/user/kody.png | Bin 0 -> 347294 bytes .../epic-stack-remote/tests/mocks/README.md | 9 + .../epic-stack-remote/tests/mocks/github.ts | 193 + .../epic-stack-remote/tests/mocks/index.ts | 28 + .../epic-stack-remote/tests/mocks/resend.ts | 22 + .../epic-stack-remote/tests/mocks/utils.ts | 65 + .../tests/playwright-utils.ts | 162 + .../tests/setup/custom-matchers.ts | 169 + .../epic-stack-remote/tests/setup/db-setup.ts | 20 + .../tests/setup/global-setup.ts | 35 + .../tests/setup/setup-test-env.ts | 27 + .../epic-stack-remote/tests/utils.ts | 33 + .../epic-stack-remote/tsconfig.json | 17 + .../epic-stack-remote/types/deps.d.ts | 6 + .../epic-stack-remote/types/env.env.d.ts | 2 + .../epic-stack-remote/types/icon-name.d.ts | 3 + .../epic-stack-remote/types/reset.d.ts | 2 + .../.github/PULL_REQUEST_TEMPLATE.md | 15 + .../epic-stack/.github/workflows/deploy.yml | 174 + .../epic-stack/.github/workflows/version.yml | 54 + examples/federation/epic-stack/.gitignore | 26 + .../federation/epic-stack/.prettierignore | 15 + .../epic-stack/.vscode/extensions.json | 11 + .../epic-stack/.vscode/remix.code-snippets | 80 + .../epic-stack/.vscode/settings.json | 14 + .../federation/epic-stack/CONTRIBUTING.md | 87 + examples/federation/epic-stack/LICENSE.md | 18 + examples/federation/epic-stack/README.md | 54 + .../app/assets/favicons/apple-touch-icon.png | Bin 0 -> 8986 bytes .../app/assets/favicons/favicon.svg | 13 + .../app/components/error-boundary.tsx | 53 + .../app/components/floating-toolbar.tsx | 2 + .../epic-stack/app/components/forms.tsx | 202 + .../app/components/progress-bar.tsx | 63 + .../epic-stack/app/components/search-bar.tsx | 63 + .../epic-stack/app/components/spacer.tsx | 57 + .../epic-stack/app/components/toaster.tsx | 16 + .../epic-stack/app/components/ui/README.md | 7 + .../epic-stack/app/components/ui/button.tsx | 58 + .../epic-stack/app/components/ui/checkbox.tsx | 41 + .../app/components/ui/dropdown-menu.tsx | 206 + .../epic-stack/app/components/ui/icon.tsx | 77 + .../app/components/ui/input-otp.tsx | 70 + .../epic-stack/app/components/ui/input.tsx | 25 + .../epic-stack/app/components/ui/label.tsx | 24 + .../epic-stack/app/components/ui/sonner.tsx | 26 + .../app/components/ui/status-button.tsx | 78 + .../epic-stack/app/components/ui/textarea.tsx | 24 + .../epic-stack/app/components/ui/tooltip.tsx | 28 + .../app/components/user-dropdown.tsx | 68 + .../epic-stack/app/entry.client.tsx | 11 + .../epic-stack/app/entry.server.tsx | 116 + examples/federation/epic-stack/app/root.tsx | 260 + examples/federation/epic-stack/app/routes.ts | 21 + .../federation/epic-stack/app/routes/$.tsx | 47 + .../_auth+/auth.$provider.callback.test.ts | 259 + .../routes/_auth+/auth.$provider.callback.ts | 197 + .../app/routes/_auth+/auth_.$provider.ts | 34 + .../app/routes/_auth+/forgot-password.tsx | 189 + .../app/routes/_auth+/login.server.ts | 158 + .../epic-stack/app/routes/_auth+/login.tsx | 204 + .../epic-stack/app/routes/_auth+/logout.tsx | 11 + .../app/routes/_auth+/onboarding.server.ts | 19 + .../app/routes/_auth+/onboarding.tsx | 232 + .../_auth+/onboarding_.$provider.server.ts | 19 + .../routes/_auth+/onboarding_.$provider.tsx | 280 + .../routes/_auth+/reset-password.server.ts | 34 + .../app/routes/_auth+/reset-password.tsx | 137 + .../epic-stack/app/routes/_auth+/signup.tsx | 185 + .../app/routes/_auth+/verify.server.ts | 200 + .../epic-stack/app/routes/_auth+/verify.tsx | 144 + .../app/routes/_marketing+/about.tsx | 3 + .../app/routes/_marketing+/index.tsx | 101 + .../app/routes/_marketing+/logos/docker.svg | 47 + .../app/routes/_marketing+/logos/eslint.svg | 17 + .../app/routes/_marketing+/logos/faker.svg | 736 + .../app/routes/_marketing+/logos/fly.svg | 1 + .../app/routes/_marketing+/logos/github.svg | 1 + .../app/routes/_marketing+/logos/logos.ts | 173 + .../app/routes/_marketing+/logos/msw.svg | 13 + .../routes/_marketing+/logos/playwright.svg | 9 + .../app/routes/_marketing+/logos/prettier.svg | 76 + .../app/routes/_marketing+/logos/prisma.svg | 9 + .../app/routes/_marketing+/logos/radix.svg | 1 + .../routes/_marketing+/logos/react-email.svg | 1 + .../app/routes/_marketing+/logos/remix.svg | 25 + .../app/routes/_marketing+/logos/resend.svg | 31 + .../app/routes/_marketing+/logos/sentry.svg | 6 + .../routes/_marketing+/logos/shadcn-ui.svg | 1 + .../app/routes/_marketing+/logos/sqlite.svg | 67 + .../app/routes/_marketing+/logos/stars.jpg | Bin 0 -> 391161 bytes .../app/routes/_marketing+/logos/tailwind.svg | 1 + .../_marketing+/logos/testing-library.png | Bin 0 -> 5803 bytes .../routes/_marketing+/logos/typescript.svg | 6 + .../app/routes/_marketing+/logos/vitest.svg | 5 + .../app/routes/_marketing+/logos/zod.svg | 46 + .../app/routes/_marketing+/privacy.tsx | 3 + .../app/routes/_marketing+/support.tsx | 3 + .../app/routes/_marketing+/tailwind-preset.ts | 27 + .../epic-stack/app/routes/_marketing+/tos.tsx | 3 + .../app/routes/_seo+/robots[.]txt.ts | 9 + .../app/routes/_seo+/sitemap[.]xml.ts | 17 + .../epic-stack/app/routes/admin+/cache.tsx | 244 + .../app/routes/admin+/cache_.lru.$cacheKey.ts | 31 + .../routes/admin+/cache_.sqlite.$cacheKey.ts | 31 + .../app/routes/admin+/cache_.sqlite.server.ts | 59 + .../app/routes/admin+/cache_.sqlite.tsx | 1 + .../federation/epic-stack/app/routes/me.tsx | 19 + .../routes/resources+/download-user-data.tsx | 62 + .../app/routes/resources+/healthcheck.tsx | 26 + .../resources+/note-images.$imageId.tsx | 22 + .../app/routes/resources+/theme-switch.tsx | 143 + .../resources+/user-images.$imageId.tsx | 22 + .../settings+/profile.change-email.server.tsx | 124 + .../routes/settings+/profile.change-email.tsx | 146 + .../routes/settings+/profile.connections.tsx | 212 + .../app/routes/settings+/profile.index.tsx | 358 + .../app/routes/settings+/profile.password.tsx | 173 + .../settings+/profile.password_.create.tsx | 124 + .../app/routes/settings+/profile.photo.tsx | 239 + .../app/routes/settings+/profile.tsx | 80 + .../settings+/profile.two-factor.disable.tsx | 62 + .../settings+/profile.two-factor.index.tsx | 90 + .../routes/settings+/profile.two-factor.tsx | 16 + .../settings+/profile.two-factor.verify.tsx | 229 + .../app/routes/users+/$username.test.tsx | 95 + .../app/routes/users+/$username.tsx | 127 + .../$username_+/__note-editor.server.tsx | 128 + .../users+/$username_+/__note-editor.tsx | 266 + .../users+/$username_+/notes.$noteId.tsx | 215 + .../$username_+/notes.$noteId_.edit.tsx | 50 + .../routes/users+/$username_+/notes.index.tsx | 27 + .../routes/users+/$username_+/notes.new.tsx | 12 + .../app/routes/users+/$username_+/notes.tsx | 99 + .../epic-stack/app/routes/users+/index.tsx | 112 + .../epic-stack/app/styles/tailwind.css | 80 + .../epic-stack/app/utils/auth.server.ts | 240 + .../epic-stack/app/utils/cache.server.ts | 182 + .../epic-stack/app/utils/client-hints.tsx | 56 + .../app/utils/connections.server.ts | 33 + .../epic-stack/app/utils/connections.tsx | 57 + .../epic-stack/app/utils/db.server.ts | 37 + .../epic-stack/app/utils/email.server.ts | 97 + .../epic-stack/app/utils/env.server.ts | 65 + .../epic-stack/app/utils/extended-theme.ts | 102 + .../app/utils/file-uploads.server.ts | 16 + .../app/utils/headers.server.test.ts | 39 + .../epic-stack/app/utils/headers.server.ts | 114 + .../epic-stack/app/utils/honeypot.server.ts | 17 + .../epic-stack/app/utils/litefs.server.ts | 10 + .../app/utils/misc.error-message.test.ts | 24 + .../federation/epic-stack/app/utils/misc.tsx | 290 + .../app/utils/misc.use-double-check.test.tsx | 83 + .../app/utils/monitoring.client.tsx | 49 + .../epic-stack/app/utils/nonce-provider.ts | 5 + .../app/utils/permissions.server.ts | 60 + .../app/utils/providers/constants.ts | 3 + .../app/utils/providers/github.server.ts | 106 + .../app/utils/providers/provider.ts | 28 + .../app/utils/redirect-cookie.server.ts | 17 + .../epic-stack/app/utils/request-info.ts | 19 + .../epic-stack/app/utils/session.server.ts | 38 + .../epic-stack/app/utils/theme.server.ts | 19 + .../epic-stack/app/utils/timing.server.ts | 121 + .../epic-stack/app/utils/toast.server.ts | 62 + .../epic-stack/app/utils/totp.server.ts | 3 + .../epic-stack/app/utils/user-validation.ts | 48 + .../federation/epic-stack/app/utils/user.ts | 70 + .../app/utils/verification.server.ts | 13 + .../federation/epic-stack/components.json | 16 + examples/federation/epic-stack/docs/README.md | 35 + examples/federation/epic-stack/docs/apis.md | 21 + .../epic-stack/docs/authentication.md | 113 + .../federation/epic-stack/docs/caching.md | 84 + .../epic-stack/docs/client-hints.md | 13 + .../federation/epic-stack/docs/community.md | 21 + .../federation/epic-stack/docs/database.md | 368 + .../epic-stack/docs/decisions/000-template.md | 12 + .../docs/decisions/001-typescript-only.md | 44 + .../docs/decisions/002-email-service.md | 41 + .../epic-stack/docs/decisions/003-sqlite.md | 83 + .../docs/decisions/004-github-actions.md | 49 + .../docs/decisions/005-client-pref-cookies.md | 94 + .../docs/decisions/006-native-esm.md | 38 + .../epic-stack/docs/decisions/007-sessions.md | 44 + .../decisions/008-content-security-policy.md | 32 + .../docs/decisions/009-region-selection.md | 32 + .../docs/decisions/010-memory-swap.md | 41 + .../epic-stack/docs/decisions/011-sitemaps.md | 33 + .../epic-stack/docs/decisions/012-cuid.md | 81 + .../docs/decisions/013-email-code.md | 40 + .../epic-stack/docs/decisions/014-totp.md | 114 + .../docs/decisions/015-monitoring.md | 36 + .../docs/decisions/016-source-maps.md | 70 + .../docs/decisions/017-resend-email.md | 29 + .../epic-stack/docs/decisions/018-images.md | 61 + .../docs/decisions/019-components.md | 80 + .../epic-stack/docs/decisions/020-icons.md | 42 + .../docs/decisions/021-node-version.md | 58 + .../docs/decisions/022-report-only-csp.md | 31 + .../docs/decisions/023-route-based-dialogs.md | 45 + .../docs/decisions/024-change-email.md | 68 + .../docs/decisions/025-rate-limiting.md | 62 + .../docs/decisions/026-path-aliases.md | 36 + .../epic-stack/docs/decisions/027-toasts.md | 36 + .../docs/decisions/028-permissions-rbac.md | 84 + .../docs/decisions/029-remix-auth.md | 22 + .../docs/decisions/030-github-auth.md | 69 + .../epic-stack/docs/decisions/031-imports.md | 76 + .../epic-stack/docs/decisions/032-csrf.md | 33 + .../epic-stack/docs/decisions/033-honeypot.md | 35 + .../docs/decisions/034-source-maps.md | 24 + .../docs/decisions/035-remove-csrf.md | 43 + .../epic-stack/docs/decisions/036-vite.md | 46 + .../037-generated-internal-command.md | 44 + .../docs/decisions/038-remove-cleanup-db.md | 45 + .../epic-stack/docs/decisions/README.md | 7 + .../federation/epic-stack/docs/deployment.md | 189 + examples/federation/epic-stack/docs/email.md | 22 + .../federation/epic-stack/docs/examples.md | 146 + .../federation/epic-stack/docs/features.md | 55 + examples/federation/epic-stack/docs/fonts.md | 152 + .../epic-stack/docs/getting-started.md | 60 + .../epic-stack/docs/guiding-principles.md | 30 + examples/federation/epic-stack/docs/icons.md | 41 + .../epic-stack/docs/managing-updates.md | 178 + examples/federation/epic-stack/docs/memory.md | 17 + .../federation/epic-stack/docs/monitoring.md | 67 + .../federation/epic-stack/docs/permissions.md | 42 + .../federation/epic-stack/docs/redirects.md | 88 + .../federation/epic-stack/docs/routing.md | 145 + .../federation/epic-stack/docs/secrets.md | 37 + .../federation/epic-stack/docs/security.md | 85 + examples/federation/epic-stack/docs/seo.md | 51 + .../epic-stack/docs/server-timing.md | 89 + .../federation/epic-stack/docs/testing.md | 48 + .../federation/epic-stack/docs/timezone.md | 37 + examples/federation/epic-stack/docs/toasts.md | 62 + .../epic-stack/docs/troubleshooting.md | 76 + .../federation/epic-stack/eslint.config.js | 14 + examples/federation/epic-stack/fly.toml | 61 + examples/federation/epic-stack/index.js | 31 + .../federation/epic-stack/other/Dockerfile | 95 + .../epic-stack/other/Dockerfile.dockerignore | 9 + .../federation/epic-stack/other/README.md | 9 + .../epic-stack/other/build-icons.ts | 153 + .../epic-stack/other/build-server.ts | 50 + .../federation/epic-stack/other/litefs.yml | 43 + .../federation/epic-stack/other/sly/sly.json | 11 + .../epic-stack/other/sly/transform-icon.ts | 19 + .../epic-stack/other/svg-icons/README.md | 11 + .../epic-stack/other/svg-icons/arrow-left.svg | 11 + .../other/svg-icons/arrow-right.svg | 11 + .../epic-stack/other/svg-icons/avatar.svg | 11 + .../epic-stack/other/svg-icons/camera.svg | 11 + .../epic-stack/other/svg-icons/check.svg | 11 + .../epic-stack/other/svg-icons/clock.svg | 11 + .../epic-stack/other/svg-icons/cross-1.svg | 11 + .../other/svg-icons/dots-horizontal.svg | 13 + .../epic-stack/other/svg-icons/download.svg | 13 + .../other/svg-icons/envelope-closed.svg | 13 + .../epic-stack/other/svg-icons/exit.svg | 11 + .../epic-stack/other/svg-icons/file-text.svg | 11 + .../other/svg-icons/github-logo.svg | 13 + .../epic-stack/other/svg-icons/laptop.svg | 11 + .../epic-stack/other/svg-icons/link-2.svg | 13 + .../other/svg-icons/lock-closed.svg | 11 + .../other/svg-icons/lock-open-1.svg | 11 + .../other/svg-icons/magnifying-glass.svg | 11 + .../epic-stack/other/svg-icons/moon.svg | 11 + .../epic-stack/other/svg-icons/pencil-1.svg | 11 + .../epic-stack/other/svg-icons/pencil-2.svg | 11 + .../epic-stack/other/svg-icons/plus.svg | 11 + .../other/svg-icons/question-mark-circled.svg | 13 + .../epic-stack/other/svg-icons/reset.svg | 11 + .../epic-stack/other/svg-icons/sun.svg | 11 + .../epic-stack/other/svg-icons/trash.svg | 11 + .../epic-stack/other/svg-icons/update.svg | 11 + .../federation/epic-stack/package-lock.json | 17276 ++++++++++++++++ examples/federation/epic-stack/package.json | 172 + .../epic-stack/playwright.config.ts | 42 + .../federation/epic-stack/postcss.config.js | 7 + .../20230914194400_init/migration.sql | 258 + .../prisma/migrations/migration_lock.toml | 3 + .../epic-stack/prisma/schema.prisma | 169 + examples/federation/epic-stack/prisma/seed.ts | 230 + .../federation/epic-stack/public/favicon.ico | Bin 0 -> 15406 bytes .../epic-stack/public/favicons/README.md | 12 + .../favicons/android-chrome-192x192.png | Bin 0 -> 10041 bytes .../favicons/android-chrome-512x512.png | Bin 0 -> 27787 bytes .../federation/epic-stack/public/img/user.png | Bin 0 -> 3012 bytes .../epic-stack/public/site.webmanifest | 20 + .../epic-stack/react-router.config.ts | 9 + .../epic-stack/remix.init/gitignore | 29 + .../federation/epic-stack/remix.init/index.js | 4 + .../epic-stack/remix.init/index.mjs | 315 + .../epic-stack/remix.init/package-lock.json | 1731 ++ .../epic-stack/remix.init/package.json | 12 + .../federation/epic-stack/rsbuild.config.ts | 19 + .../federation/epic-stack/server/dev-build.js | 23 + .../epic-stack/server/dev-server.js | 7 + .../federation/epic-stack/server/index.ts | 318 + .../epic-stack/server/utils/monitoring.ts | 47 + .../federation/epic-stack/tailwind.config.ts | 22 + .../federation/epic-stack/tests/db-utils.ts | 115 + .../epic-stack/tests/e2e/2fa.test.ts | 64 + .../tests/e2e/error-boundary.test.ts | 9 + .../epic-stack/tests/e2e/note-images.test.ts | 140 + .../epic-stack/tests/e2e/notes.test.ts | 74 + .../epic-stack/tests/e2e/onboarding.test.ts | 431 + .../epic-stack/tests/e2e/search.test.ts | 26 + .../tests/e2e/settings-profile.test.ts | 115 + .../tests/fixtures/github/ghost.jpg | Bin 0 -> 16411 bytes .../fixtures/images/kody-notes/cute-koala.png | Bin 0 -> 306392 bytes .../images/kody-notes/koala-coder.png | Bin 0 -> 406767 bytes .../images/kody-notes/koala-cuddle.png | Bin 0 -> 337477 bytes .../images/kody-notes/koala-eating.png | Bin 0 -> 454917 bytes .../images/kody-notes/koala-mentor.png | Bin 0 -> 309275 bytes .../images/kody-notes/koala-soccer.png | Bin 0 -> 340830 bytes .../fixtures/images/kody-notes/mountain.png | Bin 0 -> 520758 bytes .../tests/fixtures/images/notes/0.png | Bin 0 -> 596706 bytes .../tests/fixtures/images/notes/1.png | Bin 0 -> 690425 bytes .../tests/fixtures/images/notes/2.png | Bin 0 -> 445199 bytes .../tests/fixtures/images/notes/3.png | Bin 0 -> 395815 bytes .../tests/fixtures/images/notes/4.png | Bin 0 -> 322099 bytes .../tests/fixtures/images/notes/5.png | Bin 0 -> 290108 bytes .../tests/fixtures/images/notes/6.png | Bin 0 -> 573271 bytes .../tests/fixtures/images/notes/7.png | Bin 0 -> 503933 bytes .../tests/fixtures/images/notes/8.png | Bin 0 -> 493499 bytes .../tests/fixtures/images/notes/9.png | Bin 0 -> 439449 bytes .../tests/fixtures/images/user/0.jpg | Bin 0 -> 24127 bytes .../tests/fixtures/images/user/1.jpg | Bin 0 -> 18801 bytes .../tests/fixtures/images/user/2.jpg | Bin 0 -> 20850 bytes .../tests/fixtures/images/user/3.jpg | Bin 0 -> 25106 bytes .../tests/fixtures/images/user/4.jpg | Bin 0 -> 20368 bytes .../tests/fixtures/images/user/5.jpg | Bin 0 -> 23240 bytes .../tests/fixtures/images/user/6.jpg | Bin 0 -> 33405 bytes .../tests/fixtures/images/user/7.jpg | Bin 0 -> 22600 bytes .../tests/fixtures/images/user/8.jpg | Bin 0 -> 23605 bytes .../tests/fixtures/images/user/9.jpg | Bin 0 -> 27519 bytes .../tests/fixtures/images/user/README.md | 4 + .../tests/fixtures/images/user/kody.png | Bin 0 -> 347294 bytes .../epic-stack/tests/mocks/README.md | 9 + .../epic-stack/tests/mocks/github.ts | 193 + .../epic-stack/tests/mocks/index.ts | 28 + .../epic-stack/tests/mocks/resend.ts | 22 + .../epic-stack/tests/mocks/utils.ts | 65 + .../epic-stack/tests/playwright-utils.ts | 162 + .../epic-stack/tests/setup/custom-matchers.ts | 169 + .../epic-stack/tests/setup/db-setup.ts | 20 + .../epic-stack/tests/setup/global-setup.ts | 35 + .../epic-stack/tests/setup/setup-test-env.ts | 27 + examples/federation/epic-stack/tests/utils.ts | 33 + examples/federation/epic-stack/tsconfig.json | 17 + .../federation/epic-stack/types/deps.d.ts | 6 + .../federation/epic-stack/types/env.env.d.ts | 2 + .../epic-stack/types/icon-name.d.ts | 3 + .../federation/epic-stack/types/reset.d.ts | 2 + pnpm-lock.yaml | 368 +- 683 files changed, 78920 insertions(+), 364 deletions(-) create mode 100644 examples/federation/epic-stack-remote/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 examples/federation/epic-stack-remote/.github/workflows/deploy.yml create mode 100644 examples/federation/epic-stack-remote/.github/workflows/version.yml create mode 100644 examples/federation/epic-stack-remote/.gitignore create mode 100644 examples/federation/epic-stack-remote/.prettierignore create mode 100644 examples/federation/epic-stack-remote/.vscode/extensions.json create mode 100644 examples/federation/epic-stack-remote/.vscode/remix.code-snippets create mode 100644 examples/federation/epic-stack-remote/.vscode/settings.json create mode 100644 examples/federation/epic-stack-remote/CONTRIBUTING.md create mode 100644 examples/federation/epic-stack-remote/LICENSE.md create mode 100644 examples/federation/epic-stack-remote/README.md create mode 100644 examples/federation/epic-stack-remote/app/assets/favicons/apple-touch-icon.png create mode 100644 examples/federation/epic-stack-remote/app/assets/favicons/favicon.svg create mode 100644 examples/federation/epic-stack-remote/app/components/error-boundary.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/floating-toolbar.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/forms.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/progress-bar.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/search-bar.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/spacer.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/toaster.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/README.md create mode 100644 examples/federation/epic-stack-remote/app/components/ui/button.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/checkbox.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/dropdown-menu.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/icon.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/input-otp.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/input.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/label.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/sonner.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/status-button.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/textarea.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/ui/tooltip.tsx create mode 100644 examples/federation/epic-stack-remote/app/components/user-dropdown.tsx create mode 100644 examples/federation/epic-stack-remote/app/entry.client.tsx create mode 100644 examples/federation/epic-stack-remote/app/entry.server.tsx create mode 100644 examples/federation/epic-stack-remote/app/root.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/$.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/auth.$provider.callback.test.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/auth.$provider.callback.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/auth_.$provider.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/forgot-password.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/login.server.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/login.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/logout.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/onboarding.server.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/onboarding.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/onboarding_.$provider.server.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/onboarding_.$provider.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/reset-password.server.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/reset-password.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/signup.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/verify.server.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_auth+/verify.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/about.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/index.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/docker.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/eslint.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/faker.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/fly.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/github.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/logos.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/msw.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/playwright.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/prettier.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/prisma.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/radix.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/react-email.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/remix.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/resend.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/sentry.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/shadcn-ui.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/sqlite.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/stars.jpg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/tailwind.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/testing-library.png create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/typescript.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/vitest.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/logos/zod.svg create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/privacy.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/support.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/tailwind-preset.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_marketing+/tos.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/_seo+/robots[.]txt.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/_seo+/sitemap[.]xml.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/admin+/cache.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/admin+/cache_.lru.$cacheKey.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/admin+/cache_.sqlite.$cacheKey.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/admin+/cache_.sqlite.server.ts create mode 100644 examples/federation/epic-stack-remote/app/routes/admin+/cache_.sqlite.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/me.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/resources+/download-user-data.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/resources+/healthcheck.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/resources+/note-images.$imageId.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/resources+/theme-switch.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/resources+/user-images.$imageId.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.change-email.server.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.change-email.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.connections.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.index.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.password.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.password_.create.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.photo.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.two-factor.disable.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.two-factor.index.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.two-factor.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/settings+/profile.two-factor.verify.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username.test.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username_+/__note-editor.server.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username_+/__note-editor.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username_+/notes.$noteId.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username_+/notes.$noteId_.edit.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username_+/notes.index.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username_+/notes.new.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/$username_+/notes.tsx create mode 100644 examples/federation/epic-stack-remote/app/routes/users+/index.tsx create mode 100644 examples/federation/epic-stack-remote/app/styles/tailwind.css create mode 100644 examples/federation/epic-stack-remote/app/utils/auth.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/cache.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/client-hints.tsx create mode 100644 examples/federation/epic-stack-remote/app/utils/connections.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/connections.tsx create mode 100644 examples/federation/epic-stack-remote/app/utils/db.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/email.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/env.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/extended-theme.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/file-uploads.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/headers.server.test.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/headers.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/honeypot.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/litefs.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/misc.error-message.test.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/misc.tsx create mode 100644 examples/federation/epic-stack-remote/app/utils/misc.use-double-check.test.tsx create mode 100644 examples/federation/epic-stack-remote/app/utils/monitoring.client.tsx create mode 100644 examples/federation/epic-stack-remote/app/utils/nonce-provider.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/permissions.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/providers/constants.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/providers/github.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/providers/provider.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/redirect-cookie.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/request-info.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/session.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/theme.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/timing.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/toast.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/totp.server.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/user-validation.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/user.ts create mode 100644 examples/federation/epic-stack-remote/app/utils/verification.server.ts create mode 100644 examples/federation/epic-stack-remote/components.json create mode 100644 examples/federation/epic-stack-remote/docs/README.md create mode 100644 examples/federation/epic-stack-remote/docs/apis.md create mode 100644 examples/federation/epic-stack-remote/docs/authentication.md create mode 100644 examples/federation/epic-stack-remote/docs/caching.md create mode 100644 examples/federation/epic-stack-remote/docs/client-hints.md create mode 100644 examples/federation/epic-stack-remote/docs/community.md create mode 100644 examples/federation/epic-stack-remote/docs/database.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/000-template.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/001-typescript-only.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/002-email-service.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/003-sqlite.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/004-github-actions.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/005-client-pref-cookies.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/006-native-esm.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/007-sessions.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/008-content-security-policy.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/009-region-selection.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/010-memory-swap.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/011-sitemaps.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/012-cuid.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/013-email-code.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/014-totp.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/015-monitoring.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/016-source-maps.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/017-resend-email.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/018-images.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/019-components.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/020-icons.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/021-node-version.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/022-report-only-csp.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/023-route-based-dialogs.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/024-change-email.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/025-rate-limiting.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/026-path-aliases.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/027-toasts.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/028-permissions-rbac.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/029-remix-auth.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/030-github-auth.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/031-imports.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/032-csrf.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/033-honeypot.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/034-source-maps.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/035-remove-csrf.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/036-vite.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/037-generated-internal-command.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/038-remove-cleanup-db.md create mode 100644 examples/federation/epic-stack-remote/docs/decisions/README.md create mode 100644 examples/federation/epic-stack-remote/docs/deployment.md create mode 100644 examples/federation/epic-stack-remote/docs/email.md create mode 100644 examples/federation/epic-stack-remote/docs/examples.md create mode 100644 examples/federation/epic-stack-remote/docs/features.md create mode 100644 examples/federation/epic-stack-remote/docs/fonts.md create mode 100644 examples/federation/epic-stack-remote/docs/getting-started.md create mode 100644 examples/federation/epic-stack-remote/docs/guiding-principles.md create mode 100644 examples/federation/epic-stack-remote/docs/icons.md create mode 100644 examples/federation/epic-stack-remote/docs/managing-updates.md create mode 100644 examples/federation/epic-stack-remote/docs/memory.md create mode 100644 examples/federation/epic-stack-remote/docs/monitoring.md create mode 100644 examples/federation/epic-stack-remote/docs/permissions.md create mode 100644 examples/federation/epic-stack-remote/docs/redirects.md create mode 100644 examples/federation/epic-stack-remote/docs/routing.md create mode 100644 examples/federation/epic-stack-remote/docs/secrets.md create mode 100644 examples/federation/epic-stack-remote/docs/security.md create mode 100644 examples/federation/epic-stack-remote/docs/seo.md create mode 100644 examples/federation/epic-stack-remote/docs/server-timing.md create mode 100644 examples/federation/epic-stack-remote/docs/testing.md create mode 100644 examples/federation/epic-stack-remote/docs/timezone.md create mode 100644 examples/federation/epic-stack-remote/docs/toasts.md create mode 100644 examples/federation/epic-stack-remote/docs/troubleshooting.md create mode 100644 examples/federation/epic-stack-remote/eslint.config.js create mode 100644 examples/federation/epic-stack-remote/fly.toml create mode 100644 examples/federation/epic-stack-remote/index.js create mode 100644 examples/federation/epic-stack-remote/other/Dockerfile create mode 100644 examples/federation/epic-stack-remote/other/Dockerfile.dockerignore create mode 100644 examples/federation/epic-stack-remote/other/README.md create mode 100644 examples/federation/epic-stack-remote/other/build-icons.ts create mode 100644 examples/federation/epic-stack-remote/other/build-server.ts create mode 100644 examples/federation/epic-stack-remote/other/litefs.yml create mode 100644 examples/federation/epic-stack-remote/other/sly/sly.json create mode 100644 examples/federation/epic-stack-remote/other/sly/transform-icon.ts create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/README.md create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/arrow-left.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/arrow-right.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/avatar.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/camera.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/check.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/clock.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/cross-1.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/dots-horizontal.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/download.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/envelope-closed.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/exit.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/file-text.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/github-logo.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/laptop.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/link-2.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/lock-closed.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/lock-open-1.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/magnifying-glass.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/moon.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/pencil-1.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/pencil-2.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/plus.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/question-mark-circled.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/reset.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/sun.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/trash.svg create mode 100644 examples/federation/epic-stack-remote/other/svg-icons/update.svg create mode 100644 examples/federation/epic-stack-remote/package-lock.json create mode 100644 examples/federation/epic-stack-remote/package.json create mode 100644 examples/federation/epic-stack-remote/playwright.config.ts create mode 100644 examples/federation/epic-stack-remote/postcss.config.js create mode 100644 examples/federation/epic-stack-remote/prisma/migrations/20230914194400_init/migration.sql create mode 100644 examples/federation/epic-stack-remote/prisma/migrations/migration_lock.toml create mode 100644 examples/federation/epic-stack-remote/prisma/schema.prisma create mode 100644 examples/federation/epic-stack-remote/prisma/seed.ts create mode 100644 examples/federation/epic-stack-remote/public/favicon.ico create mode 100644 examples/federation/epic-stack-remote/public/favicons/README.md create mode 100644 examples/federation/epic-stack-remote/public/favicons/android-chrome-192x192.png create mode 100644 examples/federation/epic-stack-remote/public/favicons/android-chrome-512x512.png create mode 100644 examples/federation/epic-stack-remote/public/img/user.png create mode 100644 examples/federation/epic-stack-remote/public/site.webmanifest create mode 100644 examples/federation/epic-stack-remote/react-router.config.ts create mode 100644 examples/federation/epic-stack-remote/remix.init/gitignore create mode 100644 examples/federation/epic-stack-remote/remix.init/index.js create mode 100644 examples/federation/epic-stack-remote/remix.init/index.mjs create mode 100644 examples/federation/epic-stack-remote/remix.init/package-lock.json create mode 100644 examples/federation/epic-stack-remote/remix.init/package.json create mode 100644 examples/federation/epic-stack-remote/rsbuild.config.ts create mode 100644 examples/federation/epic-stack-remote/server/dev-build.js create mode 100644 examples/federation/epic-stack-remote/server/dev-server.js create mode 100644 examples/federation/epic-stack-remote/server/index.ts create mode 100644 examples/federation/epic-stack-remote/server/utils/monitoring.ts create mode 100644 examples/federation/epic-stack-remote/tailwind.config.ts create mode 100644 examples/federation/epic-stack-remote/tests/db-utils.ts create mode 100644 examples/federation/epic-stack-remote/tests/e2e/2fa.test.ts create mode 100644 examples/federation/epic-stack-remote/tests/e2e/error-boundary.test.ts create mode 100644 examples/federation/epic-stack-remote/tests/e2e/note-images.test.ts create mode 100644 examples/federation/epic-stack-remote/tests/e2e/notes.test.ts create mode 100644 examples/federation/epic-stack-remote/tests/e2e/onboarding.test.ts create mode 100644 examples/federation/epic-stack-remote/tests/e2e/search.test.ts create mode 100644 examples/federation/epic-stack-remote/tests/e2e/settings-profile.test.ts create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/github/ghost.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/kody-notes/cute-koala.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/kody-notes/koala-coder.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/kody-notes/koala-cuddle.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/kody-notes/koala-eating.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/kody-notes/koala-mentor.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/kody-notes/koala-soccer.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/kody-notes/mountain.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/0.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/1.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/2.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/3.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/4.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/5.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/6.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/7.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/8.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/notes/9.png create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/0.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/1.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/2.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/3.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/4.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/5.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/6.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/7.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/8.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/9.jpg create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/README.md create mode 100644 examples/federation/epic-stack-remote/tests/fixtures/images/user/kody.png create mode 100644 examples/federation/epic-stack-remote/tests/mocks/README.md create mode 100644 examples/federation/epic-stack-remote/tests/mocks/github.ts create mode 100644 examples/federation/epic-stack-remote/tests/mocks/index.ts create mode 100644 examples/federation/epic-stack-remote/tests/mocks/resend.ts create mode 100644 examples/federation/epic-stack-remote/tests/mocks/utils.ts create mode 100644 examples/federation/epic-stack-remote/tests/playwright-utils.ts create mode 100644 examples/federation/epic-stack-remote/tests/setup/custom-matchers.ts create mode 100644 examples/federation/epic-stack-remote/tests/setup/db-setup.ts create mode 100644 examples/federation/epic-stack-remote/tests/setup/global-setup.ts create mode 100644 examples/federation/epic-stack-remote/tests/setup/setup-test-env.ts create mode 100644 examples/federation/epic-stack-remote/tests/utils.ts create mode 100644 examples/federation/epic-stack-remote/tsconfig.json create mode 100644 examples/federation/epic-stack-remote/types/deps.d.ts create mode 100644 examples/federation/epic-stack-remote/types/env.env.d.ts create mode 100644 examples/federation/epic-stack-remote/types/icon-name.d.ts create mode 100644 examples/federation/epic-stack-remote/types/reset.d.ts create mode 100644 examples/federation/epic-stack/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 examples/federation/epic-stack/.github/workflows/deploy.yml create mode 100644 examples/federation/epic-stack/.github/workflows/version.yml create mode 100644 examples/federation/epic-stack/.gitignore create mode 100644 examples/federation/epic-stack/.prettierignore create mode 100644 examples/federation/epic-stack/.vscode/extensions.json create mode 100644 examples/federation/epic-stack/.vscode/remix.code-snippets create mode 100644 examples/federation/epic-stack/.vscode/settings.json create mode 100644 examples/federation/epic-stack/CONTRIBUTING.md create mode 100644 examples/federation/epic-stack/LICENSE.md create mode 100644 examples/federation/epic-stack/README.md create mode 100644 examples/federation/epic-stack/app/assets/favicons/apple-touch-icon.png create mode 100644 examples/federation/epic-stack/app/assets/favicons/favicon.svg create mode 100644 examples/federation/epic-stack/app/components/error-boundary.tsx create mode 100644 examples/federation/epic-stack/app/components/floating-toolbar.tsx create mode 100644 examples/federation/epic-stack/app/components/forms.tsx create mode 100644 examples/federation/epic-stack/app/components/progress-bar.tsx create mode 100644 examples/federation/epic-stack/app/components/search-bar.tsx create mode 100644 examples/federation/epic-stack/app/components/spacer.tsx create mode 100644 examples/federation/epic-stack/app/components/toaster.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/README.md create mode 100644 examples/federation/epic-stack/app/components/ui/button.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/checkbox.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/dropdown-menu.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/icon.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/input-otp.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/input.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/label.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/sonner.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/status-button.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/textarea.tsx create mode 100644 examples/federation/epic-stack/app/components/ui/tooltip.tsx create mode 100644 examples/federation/epic-stack/app/components/user-dropdown.tsx create mode 100644 examples/federation/epic-stack/app/entry.client.tsx create mode 100644 examples/federation/epic-stack/app/entry.server.tsx create mode 100644 examples/federation/epic-stack/app/root.tsx create mode 100644 examples/federation/epic-stack/app/routes.ts create mode 100644 examples/federation/epic-stack/app/routes/$.tsx create mode 100644 examples/federation/epic-stack/app/routes/_auth+/auth.$provider.callback.test.ts create mode 100644 examples/federation/epic-stack/app/routes/_auth+/auth.$provider.callback.ts create mode 100644 examples/federation/epic-stack/app/routes/_auth+/auth_.$provider.ts create mode 100644 examples/federation/epic-stack/app/routes/_auth+/forgot-password.tsx create mode 100644 examples/federation/epic-stack/app/routes/_auth+/login.server.ts create mode 100644 examples/federation/epic-stack/app/routes/_auth+/login.tsx create mode 100644 examples/federation/epic-stack/app/routes/_auth+/logout.tsx create mode 100644 examples/federation/epic-stack/app/routes/_auth+/onboarding.server.ts create mode 100644 examples/federation/epic-stack/app/routes/_auth+/onboarding.tsx create mode 100644 examples/federation/epic-stack/app/routes/_auth+/onboarding_.$provider.server.ts create mode 100644 examples/federation/epic-stack/app/routes/_auth+/onboarding_.$provider.tsx create mode 100644 examples/federation/epic-stack/app/routes/_auth+/reset-password.server.ts create mode 100644 examples/federation/epic-stack/app/routes/_auth+/reset-password.tsx create mode 100644 examples/federation/epic-stack/app/routes/_auth+/signup.tsx create mode 100644 examples/federation/epic-stack/app/routes/_auth+/verify.server.ts create mode 100644 examples/federation/epic-stack/app/routes/_auth+/verify.tsx create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/about.tsx create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/index.tsx create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/docker.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/eslint.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/faker.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/fly.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/github.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/logos.ts create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/msw.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/playwright.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/prettier.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/prisma.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/radix.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/react-email.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/remix.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/resend.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/sentry.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/shadcn-ui.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/sqlite.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/stars.jpg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/tailwind.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/testing-library.png create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/typescript.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/vitest.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/logos/zod.svg create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/privacy.tsx create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/support.tsx create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/tailwind-preset.ts create mode 100644 examples/federation/epic-stack/app/routes/_marketing+/tos.tsx create mode 100644 examples/federation/epic-stack/app/routes/_seo+/robots[.]txt.ts create mode 100644 examples/federation/epic-stack/app/routes/_seo+/sitemap[.]xml.ts create mode 100644 examples/federation/epic-stack/app/routes/admin+/cache.tsx create mode 100644 examples/federation/epic-stack/app/routes/admin+/cache_.lru.$cacheKey.ts create mode 100644 examples/federation/epic-stack/app/routes/admin+/cache_.sqlite.$cacheKey.ts create mode 100644 examples/federation/epic-stack/app/routes/admin+/cache_.sqlite.server.ts create mode 100644 examples/federation/epic-stack/app/routes/admin+/cache_.sqlite.tsx create mode 100644 examples/federation/epic-stack/app/routes/me.tsx create mode 100644 examples/federation/epic-stack/app/routes/resources+/download-user-data.tsx create mode 100644 examples/federation/epic-stack/app/routes/resources+/healthcheck.tsx create mode 100644 examples/federation/epic-stack/app/routes/resources+/note-images.$imageId.tsx create mode 100644 examples/federation/epic-stack/app/routes/resources+/theme-switch.tsx create mode 100644 examples/federation/epic-stack/app/routes/resources+/user-images.$imageId.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.change-email.server.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.change-email.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.connections.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.index.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.password.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.password_.create.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.photo.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.two-factor.disable.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.two-factor.index.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.two-factor.tsx create mode 100644 examples/federation/epic-stack/app/routes/settings+/profile.two-factor.verify.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username.test.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username_+/__note-editor.server.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username_+/__note-editor.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username_+/notes.$noteId.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username_+/notes.$noteId_.edit.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username_+/notes.index.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username_+/notes.new.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/$username_+/notes.tsx create mode 100644 examples/federation/epic-stack/app/routes/users+/index.tsx create mode 100644 examples/federation/epic-stack/app/styles/tailwind.css create mode 100644 examples/federation/epic-stack/app/utils/auth.server.ts create mode 100644 examples/federation/epic-stack/app/utils/cache.server.ts create mode 100644 examples/federation/epic-stack/app/utils/client-hints.tsx create mode 100644 examples/federation/epic-stack/app/utils/connections.server.ts create mode 100644 examples/federation/epic-stack/app/utils/connections.tsx create mode 100644 examples/federation/epic-stack/app/utils/db.server.ts create mode 100644 examples/federation/epic-stack/app/utils/email.server.ts create mode 100644 examples/federation/epic-stack/app/utils/env.server.ts create mode 100644 examples/federation/epic-stack/app/utils/extended-theme.ts create mode 100644 examples/federation/epic-stack/app/utils/file-uploads.server.ts create mode 100644 examples/federation/epic-stack/app/utils/headers.server.test.ts create mode 100644 examples/federation/epic-stack/app/utils/headers.server.ts create mode 100644 examples/federation/epic-stack/app/utils/honeypot.server.ts create mode 100644 examples/federation/epic-stack/app/utils/litefs.server.ts create mode 100644 examples/federation/epic-stack/app/utils/misc.error-message.test.ts create mode 100644 examples/federation/epic-stack/app/utils/misc.tsx create mode 100644 examples/federation/epic-stack/app/utils/misc.use-double-check.test.tsx create mode 100644 examples/federation/epic-stack/app/utils/monitoring.client.tsx create mode 100644 examples/federation/epic-stack/app/utils/nonce-provider.ts create mode 100644 examples/federation/epic-stack/app/utils/permissions.server.ts create mode 100644 examples/federation/epic-stack/app/utils/providers/constants.ts create mode 100644 examples/federation/epic-stack/app/utils/providers/github.server.ts create mode 100644 examples/federation/epic-stack/app/utils/providers/provider.ts create mode 100644 examples/federation/epic-stack/app/utils/redirect-cookie.server.ts create mode 100644 examples/federation/epic-stack/app/utils/request-info.ts create mode 100644 examples/federation/epic-stack/app/utils/session.server.ts create mode 100644 examples/federation/epic-stack/app/utils/theme.server.ts create mode 100644 examples/federation/epic-stack/app/utils/timing.server.ts create mode 100644 examples/federation/epic-stack/app/utils/toast.server.ts create mode 100644 examples/federation/epic-stack/app/utils/totp.server.ts create mode 100644 examples/federation/epic-stack/app/utils/user-validation.ts create mode 100644 examples/federation/epic-stack/app/utils/user.ts create mode 100644 examples/federation/epic-stack/app/utils/verification.server.ts create mode 100644 examples/federation/epic-stack/components.json create mode 100644 examples/federation/epic-stack/docs/README.md create mode 100644 examples/federation/epic-stack/docs/apis.md create mode 100644 examples/federation/epic-stack/docs/authentication.md create mode 100644 examples/federation/epic-stack/docs/caching.md create mode 100644 examples/federation/epic-stack/docs/client-hints.md create mode 100644 examples/federation/epic-stack/docs/community.md create mode 100644 examples/federation/epic-stack/docs/database.md create mode 100644 examples/federation/epic-stack/docs/decisions/000-template.md create mode 100644 examples/federation/epic-stack/docs/decisions/001-typescript-only.md create mode 100644 examples/federation/epic-stack/docs/decisions/002-email-service.md create mode 100644 examples/federation/epic-stack/docs/decisions/003-sqlite.md create mode 100644 examples/federation/epic-stack/docs/decisions/004-github-actions.md create mode 100644 examples/federation/epic-stack/docs/decisions/005-client-pref-cookies.md create mode 100644 examples/federation/epic-stack/docs/decisions/006-native-esm.md create mode 100644 examples/federation/epic-stack/docs/decisions/007-sessions.md create mode 100644 examples/federation/epic-stack/docs/decisions/008-content-security-policy.md create mode 100644 examples/federation/epic-stack/docs/decisions/009-region-selection.md create mode 100644 examples/federation/epic-stack/docs/decisions/010-memory-swap.md create mode 100644 examples/federation/epic-stack/docs/decisions/011-sitemaps.md create mode 100644 examples/federation/epic-stack/docs/decisions/012-cuid.md create mode 100644 examples/federation/epic-stack/docs/decisions/013-email-code.md create mode 100644 examples/federation/epic-stack/docs/decisions/014-totp.md create mode 100644 examples/federation/epic-stack/docs/decisions/015-monitoring.md create mode 100644 examples/federation/epic-stack/docs/decisions/016-source-maps.md create mode 100644 examples/federation/epic-stack/docs/decisions/017-resend-email.md create mode 100644 examples/federation/epic-stack/docs/decisions/018-images.md create mode 100644 examples/federation/epic-stack/docs/decisions/019-components.md create mode 100644 examples/federation/epic-stack/docs/decisions/020-icons.md create mode 100644 examples/federation/epic-stack/docs/decisions/021-node-version.md create mode 100644 examples/federation/epic-stack/docs/decisions/022-report-only-csp.md create mode 100644 examples/federation/epic-stack/docs/decisions/023-route-based-dialogs.md create mode 100644 examples/federation/epic-stack/docs/decisions/024-change-email.md create mode 100644 examples/federation/epic-stack/docs/decisions/025-rate-limiting.md create mode 100644 examples/federation/epic-stack/docs/decisions/026-path-aliases.md create mode 100644 examples/federation/epic-stack/docs/decisions/027-toasts.md create mode 100644 examples/federation/epic-stack/docs/decisions/028-permissions-rbac.md create mode 100644 examples/federation/epic-stack/docs/decisions/029-remix-auth.md create mode 100644 examples/federation/epic-stack/docs/decisions/030-github-auth.md create mode 100644 examples/federation/epic-stack/docs/decisions/031-imports.md create mode 100644 examples/federation/epic-stack/docs/decisions/032-csrf.md create mode 100644 examples/federation/epic-stack/docs/decisions/033-honeypot.md create mode 100644 examples/federation/epic-stack/docs/decisions/034-source-maps.md create mode 100644 examples/federation/epic-stack/docs/decisions/035-remove-csrf.md create mode 100644 examples/federation/epic-stack/docs/decisions/036-vite.md create mode 100644 examples/federation/epic-stack/docs/decisions/037-generated-internal-command.md create mode 100644 examples/federation/epic-stack/docs/decisions/038-remove-cleanup-db.md create mode 100644 examples/federation/epic-stack/docs/decisions/README.md create mode 100644 examples/federation/epic-stack/docs/deployment.md create mode 100644 examples/federation/epic-stack/docs/email.md create mode 100644 examples/federation/epic-stack/docs/examples.md create mode 100644 examples/federation/epic-stack/docs/features.md create mode 100644 examples/federation/epic-stack/docs/fonts.md create mode 100644 examples/federation/epic-stack/docs/getting-started.md create mode 100644 examples/federation/epic-stack/docs/guiding-principles.md create mode 100644 examples/federation/epic-stack/docs/icons.md create mode 100644 examples/federation/epic-stack/docs/managing-updates.md create mode 100644 examples/federation/epic-stack/docs/memory.md create mode 100644 examples/federation/epic-stack/docs/monitoring.md create mode 100644 examples/federation/epic-stack/docs/permissions.md create mode 100644 examples/federation/epic-stack/docs/redirects.md create mode 100644 examples/federation/epic-stack/docs/routing.md create mode 100644 examples/federation/epic-stack/docs/secrets.md create mode 100644 examples/federation/epic-stack/docs/security.md create mode 100644 examples/federation/epic-stack/docs/seo.md create mode 100644 examples/federation/epic-stack/docs/server-timing.md create mode 100644 examples/federation/epic-stack/docs/testing.md create mode 100644 examples/federation/epic-stack/docs/timezone.md create mode 100644 examples/federation/epic-stack/docs/toasts.md create mode 100644 examples/federation/epic-stack/docs/troubleshooting.md create mode 100644 examples/federation/epic-stack/eslint.config.js create mode 100644 examples/federation/epic-stack/fly.toml create mode 100644 examples/federation/epic-stack/index.js create mode 100644 examples/federation/epic-stack/other/Dockerfile create mode 100644 examples/federation/epic-stack/other/Dockerfile.dockerignore create mode 100644 examples/federation/epic-stack/other/README.md create mode 100644 examples/federation/epic-stack/other/build-icons.ts create mode 100644 examples/federation/epic-stack/other/build-server.ts create mode 100644 examples/federation/epic-stack/other/litefs.yml create mode 100644 examples/federation/epic-stack/other/sly/sly.json create mode 100644 examples/federation/epic-stack/other/sly/transform-icon.ts create mode 100644 examples/federation/epic-stack/other/svg-icons/README.md create mode 100644 examples/federation/epic-stack/other/svg-icons/arrow-left.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/arrow-right.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/avatar.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/camera.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/check.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/clock.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/cross-1.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/dots-horizontal.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/download.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/envelope-closed.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/exit.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/file-text.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/github-logo.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/laptop.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/link-2.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/lock-closed.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/lock-open-1.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/magnifying-glass.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/moon.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/pencil-1.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/pencil-2.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/plus.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/question-mark-circled.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/reset.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/sun.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/trash.svg create mode 100644 examples/federation/epic-stack/other/svg-icons/update.svg create mode 100644 examples/federation/epic-stack/package-lock.json create mode 100644 examples/federation/epic-stack/package.json create mode 100644 examples/federation/epic-stack/playwright.config.ts create mode 100644 examples/federation/epic-stack/postcss.config.js create mode 100644 examples/federation/epic-stack/prisma/migrations/20230914194400_init/migration.sql create mode 100644 examples/federation/epic-stack/prisma/migrations/migration_lock.toml create mode 100644 examples/federation/epic-stack/prisma/schema.prisma create mode 100644 examples/federation/epic-stack/prisma/seed.ts create mode 100644 examples/federation/epic-stack/public/favicon.ico create mode 100644 examples/federation/epic-stack/public/favicons/README.md create mode 100644 examples/federation/epic-stack/public/favicons/android-chrome-192x192.png create mode 100644 examples/federation/epic-stack/public/favicons/android-chrome-512x512.png create mode 100644 examples/federation/epic-stack/public/img/user.png create mode 100644 examples/federation/epic-stack/public/site.webmanifest create mode 100644 examples/federation/epic-stack/react-router.config.ts create mode 100644 examples/federation/epic-stack/remix.init/gitignore create mode 100644 examples/federation/epic-stack/remix.init/index.js create mode 100644 examples/federation/epic-stack/remix.init/index.mjs create mode 100644 examples/federation/epic-stack/remix.init/package-lock.json create mode 100644 examples/federation/epic-stack/remix.init/package.json create mode 100644 examples/federation/epic-stack/rsbuild.config.ts create mode 100644 examples/federation/epic-stack/server/dev-build.js create mode 100644 examples/federation/epic-stack/server/dev-server.js create mode 100644 examples/federation/epic-stack/server/index.ts create mode 100644 examples/federation/epic-stack/server/utils/monitoring.ts create mode 100644 examples/federation/epic-stack/tailwind.config.ts create mode 100644 examples/federation/epic-stack/tests/db-utils.ts create mode 100644 examples/federation/epic-stack/tests/e2e/2fa.test.ts create mode 100644 examples/federation/epic-stack/tests/e2e/error-boundary.test.ts create mode 100644 examples/federation/epic-stack/tests/e2e/note-images.test.ts create mode 100644 examples/federation/epic-stack/tests/e2e/notes.test.ts create mode 100644 examples/federation/epic-stack/tests/e2e/onboarding.test.ts create mode 100644 examples/federation/epic-stack/tests/e2e/search.test.ts create mode 100644 examples/federation/epic-stack/tests/e2e/settings-profile.test.ts create mode 100644 examples/federation/epic-stack/tests/fixtures/github/ghost.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/kody-notes/cute-koala.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/kody-notes/koala-coder.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/kody-notes/koala-cuddle.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/kody-notes/koala-eating.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/kody-notes/koala-mentor.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/kody-notes/koala-soccer.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/kody-notes/mountain.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/0.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/1.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/2.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/3.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/4.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/5.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/6.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/7.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/8.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/notes/9.png create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/0.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/1.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/2.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/3.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/4.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/5.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/6.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/7.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/8.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/9.jpg create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/README.md create mode 100644 examples/federation/epic-stack/tests/fixtures/images/user/kody.png create mode 100644 examples/federation/epic-stack/tests/mocks/README.md create mode 100644 examples/federation/epic-stack/tests/mocks/github.ts create mode 100644 examples/federation/epic-stack/tests/mocks/index.ts create mode 100644 examples/federation/epic-stack/tests/mocks/resend.ts create mode 100644 examples/federation/epic-stack/tests/mocks/utils.ts create mode 100644 examples/federation/epic-stack/tests/playwright-utils.ts create mode 100644 examples/federation/epic-stack/tests/setup/custom-matchers.ts create mode 100644 examples/federation/epic-stack/tests/setup/db-setup.ts create mode 100644 examples/federation/epic-stack/tests/setup/global-setup.ts create mode 100644 examples/federation/epic-stack/tests/setup/setup-test-env.ts create mode 100644 examples/federation/epic-stack/tests/utils.ts create mode 100644 examples/federation/epic-stack/tsconfig.json create mode 100644 examples/federation/epic-stack/types/deps.d.ts create mode 100644 examples/federation/epic-stack/types/env.env.d.ts create mode 100644 examples/federation/epic-stack/types/icon-name.d.ts create mode 100644 examples/federation/epic-stack/types/reset.d.ts diff --git a/examples/federation/epic-stack-remote/.github/PULL_REQUEST_TEMPLATE.md b/examples/federation/epic-stack-remote/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..84a2084 --- /dev/null +++ b/examples/federation/epic-stack-remote/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,15 @@ + + +## Test Plan + + + +## Checklist + +- [ ] Tests updated +- [ ] Docs updated + +## Screenshots + + diff --git a/examples/federation/epic-stack-remote/.github/workflows/deploy.yml b/examples/federation/epic-stack-remote/.github/workflows/deploy.yml new file mode 100644 index 0000000..e0eac2b --- /dev/null +++ b/examples/federation/epic-stack-remote/.github/workflows/deploy.yml @@ -0,0 +1,174 @@ +name: 🚀 Deploy +on: + push: + branches: + - main + - dev + pull_request: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + actions: write + contents: read + +jobs: + lint: + name: ⬣ ESLint + runs-on: ubuntu-22.04 + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v4 + + - name: ⎔ Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: 📥 Download deps + uses: bahmutov/npm-install@v1 + + - name: 🖼 Build icons + run: npm run build:icons + + - name: 🔬 Lint + run: npm run lint + + typecheck: + name: ʦ TypeScript + runs-on: ubuntu-22.04 + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v4 + + - name: ⎔ Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: 📥 Download deps + uses: bahmutov/npm-install@v1 + + - name: 🖼 Build icons + run: npm run build:icons + + - name: 🔎 Type check + run: npm run typecheck --if-present + + vitest: + name: ⚡ Vitest + runs-on: ubuntu-22.04 + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v4 + + - name: ⎔ Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: 📥 Download deps + uses: bahmutov/npm-install@v1 + + - name: 🏄 Copy test env vars + run: cp .env.example .env + + - name: 🖼 Build icons + run: npm run build:icons + + - name: ⚡ Run vitest + run: npm run test -- --coverage + + playwright: + name: 🎭 Playwright + runs-on: ubuntu-22.04 + timeout-minutes: 60 + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v4 + + - name: 🏄 Copy test env vars + run: cp .env.example .env + + - name: ⎔ Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: 📥 Download deps + uses: bahmutov/npm-install@v1 + + - name: 📥 Install Playwright Browsers + run: npm run test:e2e:install + + - name: 🛠 Setup Database + run: npx prisma migrate deploy + + - name: 🏦 Cache Database + id: db-cache + uses: actions/cache@v4 + with: + path: prisma/data.db + key: + db-cache-schema_${{ hashFiles('./prisma/schema.prisma') + }}-migrations_${{ hashFiles('./prisma/migrations/*/migration.sql') + }} + + - name: 🌱 Seed Database + if: steps.db-cache.outputs.cache-hit != 'true' + run: npx prisma migrate reset --force + + - name: 🏗 Build + run: npm run build + + - name: 🎭 Playwright tests + run: npx playwright test + + - name: 📊 Upload report + uses: actions/upload-artifact@v4 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 + + deploy: + name: 🚀 Deploy + runs-on: ubuntu-22.04 + needs: [lint, typecheck, vitest, playwright] + # only build/deploy branches on pushes + if: ${{ github.event_name == 'push' }} + + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: '50' + + - name: 👀 Read app name + uses: SebRollen/toml-action@v1.2.0 + id: app_name + with: + file: 'fly.toml' + field: 'app' + + - name: 🎈 Setup Fly + uses: superfly/flyctl-actions/setup-flyctl@1.5 + + - name: 🚀 Deploy Staging + if: ${{ github.ref == 'refs/heads/dev' }} + run: + flyctl deploy --remote-only --build-arg COMMIT_SHA=${{ github.sha }} + --app ${{ steps.app_name.outputs.value }}-staging + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + + - name: 🚀 Deploy Production + if: ${{ github.ref == 'refs/heads/main' }} + run: + flyctl deploy --remote-only --build-arg COMMIT_SHA=${{ github.sha }} + --build-secret SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} diff --git a/examples/federation/epic-stack-remote/.github/workflows/version.yml b/examples/federation/epic-stack-remote/.github/workflows/version.yml new file mode 100644 index 0000000..1a7515d --- /dev/null +++ b/examples/federation/epic-stack-remote/.github/workflows/version.yml @@ -0,0 +1,54 @@ +name: 🔖 Version +on: + push: + branches: + - main + - dev + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + version: + name: 🚀 Update Version + runs-on: ubuntu-22.04 + if: ${{ github.event_name == 'push' }} + + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v4 + + - name: 🔢 Get HEAD commit hash + id: get_head_hash + run: echo "HEAD_HASH=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT + + - name: 📅 Get current date + id: get_date + run: + echo "CURRENT_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + + - name: 📝 Update package.json + run: | + jq ' + if .["epic-stack"] then + .["epic-stack"].head = "${{ steps.get_head_hash.outputs.HEAD_HASH }}" | + .["epic-stack"].date = "${{ steps.get_date.outputs.CURRENT_DATE }}" + else + .["epic-stack"] = { + "head": "${{ steps.get_head_hash.outputs.HEAD_HASH }}", + "date": "${{ steps.get_date.outputs.CURRENT_DATE }}" + } + end + ' package.json > temp.json && mv temp.json package.json + + - name: 💾 Commit changes + run: | + git config --local user.email "kody@epicweb.dev" + git config --local user.name "kody" + git add package.json + git commit -m "Update epic-stack version [skip ci]" + git push diff --git a/examples/federation/epic-stack-remote/.gitignore b/examples/federation/epic-stack-remote/.gitignore new file mode 100644 index 0000000..6ba5a4f --- /dev/null +++ b/examples/federation/epic-stack-remote/.gitignore @@ -0,0 +1,26 @@ +node_modules +.DS_store + +/build +/server-build +.env +.cache + +/prisma/data.db +/prisma/data.db-journal +/tests/prisma + +/test-results/ +/playwright-report/ +/playwright/.cache/ +/tests/fixtures/email/ +/coverage + +/other/cache.db + +# Easy way to create temporary files/folders that won't accidentally be added to git +*.local.* + +# generated files +/app/components/ui/icons +.react-router/ diff --git a/examples/federation/epic-stack-remote/.prettierignore b/examples/federation/epic-stack-remote/.prettierignore new file mode 100644 index 0000000..f022d02 --- /dev/null +++ b/examples/federation/epic-stack-remote/.prettierignore @@ -0,0 +1,15 @@ +node_modules + +/build +/public/build +/server-build +.env + +/test-results/ +/playwright-report/ +/playwright/.cache/ +/tests/fixtures/email/*.json +/coverage +/prisma/migrations + +package-lock.json diff --git a/examples/federation/epic-stack-remote/.vscode/extensions.json b/examples/federation/epic-stack-remote/.vscode/extensions.json new file mode 100644 index 0000000..3c0a690 --- /dev/null +++ b/examples/federation/epic-stack-remote/.vscode/extensions.json @@ -0,0 +1,11 @@ +{ + "recommendations": [ + "bradlc.vscode-tailwindcss", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "prisma.prisma", + "qwtel.sqlite-viewer", + "yoavbls.pretty-ts-errors", + "github.vscode-github-actions" + ] +} diff --git a/examples/federation/epic-stack-remote/.vscode/remix.code-snippets b/examples/federation/epic-stack-remote/.vscode/remix.code-snippets new file mode 100644 index 0000000..39e959f --- /dev/null +++ b/examples/federation/epic-stack-remote/.vscode/remix.code-snippets @@ -0,0 +1,80 @@ +{ + "loader": { + "prefix": "/loader", + "scope": "typescriptreact,javascriptreact,typescript,javascript", + "body": [ + "import { type Route } from \"./+types/${TM_FILENAME_BASE}.ts\"", + "", + "export async function loader({ request }: Route.LoaderArgs) {", + " return {}", + "}", + ], + }, + "action": { + "prefix": "/action", + "scope": "typescriptreact,javascriptreact,typescript,javascript", + "body": [ + "import { type Route } from \"./+types/${TM_FILENAME_BASE}.ts\"", + "", + "export async function action({ request }: Route.ActionArgs) {", + " return {}", + "}", + ], + }, + "default": { + "prefix": "/default", + "scope": "typescriptreact,javascriptreact,typescript,javascript", + "body": [ + "export default function ${TM_FILENAME_BASE/[^a-zA-Z0-9]*([a-zA-Z0-9])([a-zA-Z0-9]*)/${1:/capitalize}${2}/g}() {", + " return (", + "
", + "

Unknown Route

", + "
", + " )", + "}", + ], + }, + "headers": { + "prefix": "/headers", + "scope": "typescriptreact,javascriptreact,typescript,javascript", + "body": [ + "import { type Route } from \"./+types/${TM_FILENAME_BASE}.ts\"", + "export const headers: Route.HeadersFunction = ({ loaderHeaders }) => ({", + " 'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',", + "})", + ], + }, + "links": { + "prefix": "/links", + "scope": "typescriptreact,javascriptreact,typescript,javascript", + "body": [ + "import { type Route } from \"./+types/${TM_FILENAME_BASE}.ts\"", + "", + "export const links: Route.LinksFunction = () => {", + " return []", + "}", + ], + }, + "meta": { + "prefix": "/meta", + "scope": "typescriptreact,javascriptreact,typescript,javascript", + "body": [ + "import { type Route } from \"./+types/${TM_FILENAME_BASE}.ts\"", + "", + "export const meta: Route.MetaFunction = ({ data }) => [{", + " title: 'Title',", + "}]", + ], + }, + "shouldRevalidate": { + "prefix": "/shouldRevalidate", + "scope": "typescriptreact,javascriptreact,typescript,javascript", + "body": [ + "import { type ShouldRevalidateFunctionArgs } from 'react-router'", + "", + "export function shouldRevalidate({ defaultShouldRevalidate }: ShouldRevalidateFunctionArgs) {", + " return defaultShouldRevalidate", + "}", + ], + }, +} \ No newline at end of file diff --git a/examples/federation/epic-stack-remote/.vscode/settings.json b/examples/federation/epic-stack-remote/.vscode/settings.json new file mode 100644 index 0000000..9ec5cad --- /dev/null +++ b/examples/federation/epic-stack-remote/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "typescript.preferences.autoImportFileExcludePatterns": [ + "@remix-run/server-runtime", + "express", + "@radix-ui/**", + "@react-email/**", + "node:stream/consumers", + "node:test", + "node:console" + ], + "workbench.editorAssociations": { + "*.db": "sqlite-viewer.view" + } +} diff --git a/examples/federation/epic-stack-remote/CONTRIBUTING.md b/examples/federation/epic-stack-remote/CONTRIBUTING.md new file mode 100644 index 0000000..2a1e49f --- /dev/null +++ b/examples/federation/epic-stack-remote/CONTRIBUTING.md @@ -0,0 +1,87 @@ +# Contributing + +Thanks for your willingness to contribute! Please make sure to check with me +before doing a bunch of work on something. + +## Project setup + +If you do need to set the project up locally yourself, feel free to follow these +instructions: + +### System Requirements + +- [Node.js](https://nodejs.org/) >= 20.0.0 +- [npm](https://npmjs.com/) >= 8.18.0 +- [git](https://git-scm.com/) >= 2.38.0 + +### Setup steps + +1. Fork repo +2. clone the repo +3. Copy `.env.example` into `.env` +4. Run `npm install && npm run setup -s` to install dependencies and run + validation +5. Create a branch for your PR with `git checkout -b pr/your-branch-name` + +> Tip: Keep your `main` branch pointing at the original repository and make pull +> requests from branches on your fork. To do this, run: +> +> ``` +> git remote add upstream https://github.com/epicweb-dev/epic-stack.git +> git fetch upstream +> git branch --set-upstream-to=upstream/main main +> ``` +> +> This will add the original repository as a "remote" called "upstream," Then +> fetch the git information from that remote, then set your local `main` branch +> to use the upstream main branch whenever you run `git pull`. Then you can make +> all of your pull request branches based on this `main` branch. Whenever you +> want to update your version of `main`, do a regular `git pull`. + +If the setup script doesn't work, you can try to run the commands manually: + +```sh +git clone +cd ./epic-stack + +# copy the .env.example to .env +# everything's mocked out during development so you shouldn't need to +# change any of these values unless you want to hit real environments. +cp .env.example .env + +# Install deps +npm install + +# setup database +prisma migrate reset --force + +# Install playwright browsers +npm run test:e2e:install + +# run build, typecheck, linting +npm run validate +``` + +If that all worked without trouble, you should be able to start development +with: + +```sh +npm run dev +``` + +And open up `http://localhost:3000` and rock! + +## Help Needed + +There's something to be said for custom code and the ability that grants with +regard to tuning it to be exactly what you need. But there's also something to +be said for offloading maintenance onto external dependencies. There are likely +several bits of code in this codebase that could benefit from externalization. +There could even be some things that could be improved by existing libraries. + +Feel free to take any code from within this project and turn it into an open +source library (appropriate attribution is appreciated). Then come back and make +a PR to use your new library. + +NOTE: Actual adoption of your library is not guaranteed. Offloading maintenance +and adaptability is a delicate balance. diff --git a/examples/federation/epic-stack-remote/LICENSE.md b/examples/federation/epic-stack-remote/LICENSE.md new file mode 100644 index 0000000..7c76ba3 --- /dev/null +++ b/examples/federation/epic-stack-remote/LICENSE.md @@ -0,0 +1,18 @@ +Copyright © 2023 Kent C. Dodds + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/examples/federation/epic-stack-remote/README.md b/examples/federation/epic-stack-remote/README.md new file mode 100644 index 0000000..cc8f52f --- /dev/null +++ b/examples/federation/epic-stack-remote/README.md @@ -0,0 +1,54 @@ +
+

The Epic Stack 🚀

+ + Ditch analysis paralysis and start shipping Epic Web apps. + +

+ This is an opinionated project starter and reference that allows teams to + ship their ideas to production faster and on a more stable foundation based + on the experience of Kent C. Dodds and + contributors. +

+
+ +```sh +npx create-epic-app@latest +``` + +[![The Epic Stack](https://github-production-user-asset-6210df.s3.amazonaws.com/1500684/246885449-1b00286c-aa3d-44b2-9ef2-04f694eb3592.png)](https://www.epicweb.dev/epic-stack) + +[The Epic Stack](https://www.epicweb.dev/epic-stack) + +
+ +## Watch Kent's Introduction to The Epic Stack + +[![Epic Stack Talk slide showing Flynn Rider with knives, the text "I've been around and I've got opinions" and Kent speaking in the corner](https://github-production-user-asset-6210df.s3.amazonaws.com/1500684/277818553-47158e68-4efc-43ae-a477-9d1670d4217d.png)](https://www.epicweb.dev/talks/the-epic-stack) + +["The Epic Stack" by Kent C. Dodds](https://www.epicweb.dev/talks/the-epic-stack) + +## Docs + +[Read the docs](https://github.com/epicweb-dev/epic-stack/blob/main/docs) +(please 🙏). + +## Support + +- 🆘 Join the + [discussion on GitHub](https://github.com/epicweb-dev/epic-stack/discussions) + and the [KCD Community on Discord](https://kcd.im/discord). +- 💡 Create an + [idea discussion](https://github.com/epicweb-dev/epic-stack/discussions/new?category=ideas) + for suggestions. +- 🐛 Open a [GitHub issue](https://github.com/epicweb-dev/epic-stack/issues) to + report a bug. + +## Branding + +Want to talk about the Epic Stack in a blog post or talk? Great! Here are some +assets you can use in your material: +[EpicWeb.dev/brand](https://epicweb.dev/brand) + +## Thanks + +You rock 🪨 diff --git a/examples/federation/epic-stack-remote/app/assets/favicons/apple-touch-icon.png b/examples/federation/epic-stack-remote/app/assets/favicons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8bf4632e7f5e38c2938bf0892a18c98b21a8f1d4 GIT binary patch literal 8986 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 AU;qFB literal 0 HcmV?d00001 diff --git a/examples/federation/epic-stack-remote/app/assets/favicons/favicon.svg b/examples/federation/epic-stack-remote/app/assets/favicons/favicon.svg new file mode 100644 index 0000000..72be6f0 --- /dev/null +++ b/examples/federation/epic-stack-remote/app/assets/favicons/favicon.svg @@ -0,0 +1,13 @@ + + + + diff --git a/examples/federation/epic-stack-remote/app/components/error-boundary.tsx b/examples/federation/epic-stack-remote/app/components/error-boundary.tsx new file mode 100644 index 0000000..0aad131 --- /dev/null +++ b/examples/federation/epic-stack-remote/app/components/error-boundary.tsx @@ -0,0 +1,53 @@ +import { captureException } from '@sentry/react' +import { useEffect, type ReactElement } from 'react' +import { + type ErrorResponse, + isRouteErrorResponse, + useParams, + useRouteError, +} from 'react-router' +import { getErrorMessage } from '#app/utils/misc' + +type StatusHandler = (info: { + error: ErrorResponse + params: Record +}) => ReactElement | null + +export function GeneralErrorBoundary({ + defaultStatusHandler = ({ error }) => ( +

+ {error.status} {error.data} +

+ ), + statusHandlers, + unexpectedErrorHandler = (error) =>

{getErrorMessage(error)}

, +}: { + defaultStatusHandler?: StatusHandler + statusHandlers?: Record + unexpectedErrorHandler?: (error: unknown) => ReactElement | null +}) { + const error = useRouteError() + const params = useParams() + const isResponse = isRouteErrorResponse(error) + + if (typeof document !== 'undefined') { + console.error(error) + } + + useEffect(() => { + if (isResponse) return + + captureException(error) + }, [error, isResponse]) + + return ( +
+ {isResponse + ? (statusHandlers?.[error.status] ?? defaultStatusHandler)({ + error, + params, + }) + : unexpectedErrorHandler(error)} +
+ ) +} diff --git a/examples/federation/epic-stack-remote/app/components/floating-toolbar.tsx b/examples/federation/epic-stack-remote/app/components/floating-toolbar.tsx new file mode 100644 index 0000000..41b5be0 --- /dev/null +++ b/examples/federation/epic-stack-remote/app/components/floating-toolbar.tsx @@ -0,0 +1,2 @@ +export const floatingToolbarClassName = + 'absolute bottom-3 left-3 right-3 flex items-center gap-2 rounded-lg bg-muted/80 p-4 pl-5 shadow-xl shadow-accent backdrop-blur-sm md:gap-4 md:pl-7 justify-end' diff --git a/examples/federation/epic-stack-remote/app/components/forms.tsx b/examples/federation/epic-stack-remote/app/components/forms.tsx new file mode 100644 index 0000000..9d3644a --- /dev/null +++ b/examples/federation/epic-stack-remote/app/components/forms.tsx @@ -0,0 +1,202 @@ +import { useInputControl } from '@conform-to/react' +import { REGEXP_ONLY_DIGITS_AND_CHARS, type OTPInputProps } from 'input-otp' +import React, { useId } from 'react' +import { Checkbox, type CheckboxProps } from './ui/checkbox.tsx' +import { + InputOTP, + InputOTPGroup, + InputOTPSeparator, + InputOTPSlot, +} from './ui/input-otp.tsx' +import { Input } from './ui/input.tsx' +import { Label } from './ui/label.tsx' +import { Textarea } from './ui/textarea.tsx' + +export type ListOfErrors = Array | null | undefined + +export function ErrorList({ + id, + errors, +}: { + errors?: ListOfErrors + id?: string +}) { + const errorsToRender = errors?.filter(Boolean) + if (!errorsToRender?.length) return null + return ( +
    + {errorsToRender.map((e) => ( +
  • + {e} +
  • + ))} +
+ ) +} + +export function Field({ + labelProps, + inputProps, + errors, + className, +}: { + labelProps: React.LabelHTMLAttributes + inputProps: React.InputHTMLAttributes + errors?: ListOfErrors + className?: string +}) { + const fallbackId = useId() + const id = inputProps.id ?? fallbackId + const errorId = errors?.length ? `${id}-error` : undefined + return ( +
+
+ ) +} + +export function OTPField({ + labelProps, + inputProps, + errors, + className, +}: { + labelProps: React.LabelHTMLAttributes + inputProps: Partial + errors?: ListOfErrors + className?: string +}) { + const fallbackId = useId() + const id = inputProps.id ?? fallbackId + const errorId = errors?.length ? `${id}-error` : undefined + return ( +
+
+ ) +} + +export function TextareaField({ + labelProps, + textareaProps, + errors, + className, +}: { + labelProps: React.LabelHTMLAttributes + textareaProps: React.TextareaHTMLAttributes + errors?: ListOfErrors + className?: string +}) { + const fallbackId = useId() + const id = textareaProps.id ?? textareaProps.name ?? fallbackId + const errorId = errors?.length ? `${id}-error` : undefined + return ( +
+