@mars-stack/cli 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/template/.cursor/rules/composition-patterns.mdc +186 -0
- package/template/.cursor/rules/data-access.mdc +29 -0
- package/template/.cursor/rules/project-structure.mdc +34 -0
- package/template/.cursor/rules/security.mdc +25 -0
- package/template/.cursor/rules/testing.mdc +24 -0
- package/template/.cursor/rules/ui-conventions.mdc +29 -0
- package/template/.cursor/skills/add-api-route/SKILL.md +122 -0
- package/template/.cursor/skills/add-audit-log/SKILL.md +373 -0
- package/template/.cursor/skills/add-blog/SKILL.md +447 -0
- package/template/.cursor/skills/add-command-palette/SKILL.md +438 -0
- package/template/.cursor/skills/add-component/SKILL.md +158 -0
- package/template/.cursor/skills/add-crud-routes/SKILL.md +221 -0
- package/template/.cursor/skills/add-e2e-test/SKILL.md +227 -0
- package/template/.cursor/skills/add-error-boundary/SKILL.md +472 -0
- package/template/.cursor/skills/add-feature/SKILL.md +174 -0
- package/template/.cursor/skills/add-middleware/SKILL.md +135 -0
- package/template/.cursor/skills/add-page/SKILL.md +151 -0
- package/template/.cursor/skills/add-prisma-model/SKILL.md +148 -0
- package/template/.cursor/skills/add-protected-resource/SKILL.md +192 -0
- package/template/.cursor/skills/add-role/SKILL.md +156 -0
- package/template/.cursor/skills/add-server-action/SKILL.md +167 -0
- package/template/.cursor/skills/add-webhook/SKILL.md +192 -0
- package/template/.cursor/skills/build-complete-feature/SKILL.md +227 -0
- package/template/.cursor/skills/build-dashboard/SKILL.md +211 -0
- package/template/.cursor/skills/build-data-table/SKILL.md +283 -0
- package/template/.cursor/skills/build-form/SKILL.md +231 -0
- package/template/.cursor/skills/build-landing-page/SKILL.md +248 -0
- package/template/.cursor/skills/configure-ai/SKILL.md +617 -0
- package/template/.cursor/skills/configure-analytics/SKILL.md +413 -0
- package/template/.cursor/skills/configure-dark-mode/SKILL.md +309 -0
- package/template/.cursor/skills/configure-email/SKILL.md +170 -0
- package/template/.cursor/skills/configure-email-verification/SKILL.md +333 -0
- package/template/.cursor/skills/configure-feature-flags/SKILL.md +361 -0
- package/template/.cursor/skills/configure-i18n/SKILL.md +518 -0
- package/template/.cursor/skills/configure-jobs/SKILL.md +500 -0
- package/template/.cursor/skills/configure-magic-links/SKILL.md +385 -0
- package/template/.cursor/skills/configure-multi-tenancy/SKILL.md +611 -0
- package/template/.cursor/skills/configure-notifications/SKILL.md +569 -0
- package/template/.cursor/skills/configure-oauth/SKILL.md +217 -0
- package/template/.cursor/skills/configure-onboarding/SKILL.md +483 -0
- package/template/.cursor/skills/configure-payments/SKILL.md +243 -0
- package/template/.cursor/skills/configure-realtime/SKILL.md +733 -0
- package/template/.cursor/skills/configure-search/SKILL.md +581 -0
- package/template/.cursor/skills/configure-storage/SKILL.md +273 -0
- package/template/.cursor/skills/configure-two-factor/SKILL.md +518 -0
- package/template/.cursor/skills/create-execution-plan/SKILL.md +204 -0
- package/template/.cursor/skills/create-seed/SKILL.md +191 -0
- package/template/.cursor/skills/deploy-to-vercel/SKILL.md +300 -0
- package/template/.cursor/skills/design-tokens/SKILL.md +138 -0
- package/template/.cursor/skills/mars-capture-conversation-context/SKILL.md +119 -0
- package/template/.cursor/skills/setup-billing/SKILL.md +322 -0
- package/template/.cursor/skills/setup-project/SKILL.md +104 -0
- package/template/.cursor/skills/setup-teams/SKILL.md +682 -0
- package/template/.cursor/skills/test-api-route/SKILL.md +219 -0
- package/template/.cursor/skills/update-architecture-docs/SKILL.md +99 -0
- package/template/AGENTS.md +104 -0
- package/template/ARCHITECTURE.md +102 -0
- package/template/docs/QUALITY_SCORE.md +20 -0
- package/template/docs/design-docs/conversation-as-system-record.md +70 -0
- package/template/docs/design-docs/core-beliefs.md +43 -0
- package/template/docs/design-docs/index.md +8 -0
- package/template/docs/exec-plans/active/.gitkeep +0 -0
- package/template/docs/exec-plans/completed/.gitkeep +0 -0
- package/template/docs/exec-plans/tech-debt.md +7 -0
- package/template/docs/generated/.gitkeep +0 -0
- package/template/docs/product-specs/index.md +7 -0
- package/template/docs/references/index.md +18 -0
- package/template/e2e/api.spec.ts +20 -0
- package/template/e2e/auth.spec.ts +24 -0
- package/template/e2e/public.spec.ts +25 -0
- package/template/eslint.config.mjs +24 -0
- package/template/next-env.d.ts +6 -0
- package/template/next.config.ts +45 -0
- package/template/package.json +80 -0
- package/template/playwright.config.ts +31 -0
- package/template/postcss.config.mjs +8 -0
- package/template/prisma/generated/prisma/browser.ts +49 -0
- package/template/prisma/generated/prisma/client.ts +73 -0
- package/template/prisma/generated/prisma/commonInputTypes.ts +406 -0
- package/template/prisma/generated/prisma/enums.ts +15 -0
- package/template/prisma/generated/prisma/internal/class.ts +254 -0
- package/template/prisma/generated/prisma/internal/prismaNamespace.ts +1240 -0
- package/template/prisma/generated/prisma/internal/prismaNamespaceBrowser.ts +190 -0
- package/template/prisma/generated/prisma/models/Account.ts +1543 -0
- package/template/prisma/generated/prisma/models/File.ts +1529 -0
- package/template/prisma/generated/prisma/models/Session.ts +1415 -0
- package/template/prisma/generated/prisma/models/Subscription.ts +1455 -0
- package/template/prisma/generated/prisma/models/User.ts +2235 -0
- package/template/prisma/generated/prisma/models/VerificationToken.ts +1099 -0
- package/template/prisma/generated/prisma/models.ts +17 -0
- package/template/prisma/schema/auth.prisma +69 -0
- package/template/prisma/schema/base.prisma +8 -0
- package/template/prisma/schema/file.prisma +15 -0
- package/template/prisma/schema/subscription.prisma +17 -0
- package/template/prisma.config.ts +13 -0
- package/template/scripts/check-architecture.ts +221 -0
- package/template/scripts/check-doc-freshness.ts +242 -0
- package/template/scripts/ensure-db.mjs +291 -0
- package/template/scripts/generate-docs.ts +143 -0
- package/template/scripts/generate-env-example.ts +89 -0
- package/template/scripts/seed.ts +56 -0
- package/template/scripts/update-quality-score.ts +263 -0
- package/template/src/__tests__/architecture.test.ts +114 -0
- package/template/src/app/(auth)/forgotten-password/page.tsx +92 -0
- package/template/src/app/(auth)/layout.tsx +11 -0
- package/template/src/app/(auth)/register/page.tsx +162 -0
- package/template/src/app/(auth)/reset-password/page.tsx +109 -0
- package/template/src/app/(auth)/sign-in/page.tsx +122 -0
- package/template/src/app/(auth)/verify/[token]/page.tsx +87 -0
- package/template/src/app/(auth)/verify/page.tsx +56 -0
- package/template/src/app/(protected)/admin/page.tsx +108 -0
- package/template/src/app/(protected)/dashboard/loading.tsx +20 -0
- package/template/src/app/(protected)/dashboard/page.tsx +22 -0
- package/template/src/app/(protected)/layout.tsx +262 -0
- package/template/src/app/(protected)/settings/page.tsx +370 -0
- package/template/src/app/api/auth/forgot/route.ts +63 -0
- package/template/src/app/api/auth/login/route.ts +121 -0
- package/template/src/app/api/auth/logout/route.ts +19 -0
- package/template/src/app/api/auth/me/route.ts +30 -0
- package/template/src/app/api/auth/reset/route.ts +45 -0
- package/template/src/app/api/auth/signup/route.ts +85 -0
- package/template/src/app/api/auth/verify/route.ts +46 -0
- package/template/src/app/api/csrf/route.ts +12 -0
- package/template/src/app/api/health/route.ts +10 -0
- package/template/src/app/api/protected/admin/users/route.ts +24 -0
- package/template/src/app/api/protected/billing/checkout/route.ts +83 -0
- package/template/src/app/api/protected/billing/portal/route.ts +39 -0
- package/template/src/app/api/protected/files/[fileId]/route.ts +86 -0
- package/template/src/app/api/protected/files/upload/route.ts +64 -0
- package/template/src/app/api/protected/user/password/route.ts +63 -0
- package/template/src/app/api/protected/user/profile/route.ts +35 -0
- package/template/src/app/api/protected/user/sessions/[sessionId]/route.ts +33 -0
- package/template/src/app/api/protected/user/sessions/route.ts +22 -0
- package/template/src/app/api/readiness/route.ts +15 -0
- package/template/src/app/api/webhooks/stripe/route.ts +166 -0
- package/template/src/app/error.tsx +33 -0
- package/template/src/app/layout.tsx +29 -0
- package/template/src/app/not-found.tsx +20 -0
- package/template/src/app/page.tsx +136 -0
- package/template/src/app/privacy/page.tsx +178 -0
- package/template/src/app/providers.tsx +8 -0
- package/template/src/app/terms/page.tsx +139 -0
- package/template/src/config/app.config.ts +70 -0
- package/template/src/config/routes.ts +17 -0
- package/template/src/features/admin/index.ts +11 -0
- package/template/src/features/admin/permissions.ts +64 -0
- package/template/src/features/auth/context/AuthContext.tsx +96 -0
- package/template/src/features/auth/context/index.ts +2 -0
- package/template/src/features/auth/index.ts +3 -0
- package/template/src/features/auth/server/consent.ts +66 -0
- package/template/src/features/auth/server/session-revocation.ts +20 -0
- package/template/src/features/auth/server/sessions.ts +66 -0
- package/template/src/features/auth/server/user.ts +166 -0
- package/template/src/features/auth/types.ts +19 -0
- package/template/src/features/auth/validators.ts +29 -0
- package/template/src/features/billing/server/index.ts +66 -0
- package/template/src/features/billing/types.ts +43 -0
- package/template/src/features/uploads/server/index.ts +49 -0
- package/template/src/features/uploads/types.ts +26 -0
- package/template/src/lib/core/email/templates/base-layout.ts +122 -0
- package/template/src/lib/core/email/templates/index.ts +4 -0
- package/template/src/lib/core/email/templates/password-reset-email.ts +42 -0
- package/template/src/lib/core/email/templates/verification-email.ts +41 -0
- package/template/src/lib/core/email/templates/welcome-email.ts +40 -0
- package/template/src/lib/mars.ts +56 -0
- package/template/src/lib/prisma.ts +19 -0
- package/template/src/proxy.ts +92 -0
- package/template/src/styles/brand.css +17 -0
- package/template/src/styles/globals.css +6 -0
- package/template/tsconfig.json +59 -0
- package/template/vitest.config.ts +41 -0
- package/template/vitest.setup.ts +24 -0
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# References
|
|
2
|
+
|
|
3
|
+
External documents, articles, and open-source projects that influenced the architecture and conventions of this project. Track influences here so future agents (and humans) can trace *why* things are structured the way they are.
|
|
4
|
+
|
|
5
|
+
| Reference | Type | Key Influence |
|
|
6
|
+
|-----------|------|---------------|
|
|
7
|
+
| [Mars Product Roadmap](../exec-plans/completed/) | Execution Plan | The blueprint that generated this project's architecture |
|
|
8
|
+
| [Harness Engineering](https://openai.com/index/harness-engineering/) | Article | Agent-first development model: AGENTS.md, docs/ knowledge base, plans as artifacts |
|
|
9
|
+
| [UI Design Brain](https://github.com/carmahhawwari/ui-design-brain) | Cursor Skill | Component knowledge model for UI generation |
|
|
10
|
+
| [Vercel React Best Practices](https://github.com/vercel-labs/agent-skills/tree/main/skills/react-best-practices) | Agent Skill | Structured rules with impact levels for React/Next.js performance |
|
|
11
|
+
|
|
12
|
+
## Adding References
|
|
13
|
+
|
|
14
|
+
When a conversation, article, or external project significantly influences an architectural decision:
|
|
15
|
+
|
|
16
|
+
1. Add an entry to this table with the source, type, and key influence
|
|
17
|
+
2. If the influence is substantial, create a dedicated reference file explaining what was adopted and why
|
|
18
|
+
3. Update `docs/design-docs/` if the influence resulted in a new design decision
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
test.describe('API endpoints', () => {
|
|
4
|
+
test('CSRF endpoint returns token', async ({ request }) => {
|
|
5
|
+
const response = await request.get('/api/csrf');
|
|
6
|
+
expect(response.ok()).toBeTruthy();
|
|
7
|
+
const body = await response.json();
|
|
8
|
+
expect(body.csrfToken).toBeDefined();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('readiness endpoint returns ok', async ({ request }) => {
|
|
12
|
+
const response = await request.get('/api/readiness');
|
|
13
|
+
expect(response.status()).toBeLessThan(600);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('protected endpoints return 401 without auth', async ({ request }) => {
|
|
17
|
+
const response = await request.get('/api/protected/admin/users');
|
|
18
|
+
expect(response.status()).toBe(401);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
test.describe('Authentication flow', () => {
|
|
4
|
+
test('signup page loads', async ({ page }) => {
|
|
5
|
+
await page.goto('/register');
|
|
6
|
+
await expect(page).toHaveTitle(/register|sign up/i);
|
|
7
|
+
await expect(page.locator('form')).toBeVisible();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('login page loads', async ({ page }) => {
|
|
11
|
+
await page.goto('/sign-in');
|
|
12
|
+
await expect(page.locator('form')).toBeVisible();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('unauthenticated user is redirected from protected routes', async ({ page }) => {
|
|
16
|
+
await page.goto('/dashboard');
|
|
17
|
+
await expect(page).toHaveURL(/sign-in/);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('forgot password page loads', async ({ page }) => {
|
|
21
|
+
await page.goto('/forgotten-password');
|
|
22
|
+
await expect(page.locator('form')).toBeVisible();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
test.describe('Public pages', () => {
|
|
4
|
+
test('landing page loads', async ({ page }) => {
|
|
5
|
+
await page.goto('/');
|
|
6
|
+
await expect(page.locator('h1')).toBeVisible();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test('terms page loads', async ({ page }) => {
|
|
10
|
+
await page.goto('/terms');
|
|
11
|
+
await expect(page.locator('h1')).toBeVisible();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('privacy page loads', async ({ page }) => {
|
|
15
|
+
await page.goto('/privacy');
|
|
16
|
+
await expect(page.locator('h1')).toBeVisible();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('health endpoint returns ok', async ({ request }) => {
|
|
20
|
+
const response = await request.get('/api/health');
|
|
21
|
+
expect(response.ok()).toBeTruthy();
|
|
22
|
+
const body = await response.json();
|
|
23
|
+
expect(body.status).toBe('ok');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import nextVitals from 'eslint-config-next/core-web-vitals';
|
|
2
|
+
import tsConfig from 'eslint-config-next/typescript';
|
|
3
|
+
|
|
4
|
+
const eslintConfig = [
|
|
5
|
+
...nextVitals,
|
|
6
|
+
...tsConfig,
|
|
7
|
+
{
|
|
8
|
+
ignores: ['.next/**', 'out/**', 'build/**', 'node_modules/**'],
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
rules: {
|
|
12
|
+
'@typescript-eslint/no-unused-vars': [
|
|
13
|
+
'error',
|
|
14
|
+
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
|
|
15
|
+
],
|
|
16
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
17
|
+
'prefer-const': 'error',
|
|
18
|
+
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
|
19
|
+
'react-hooks/set-state-in-effect': 'off',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
export default eslintConfig;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { NextConfig } from 'next';
|
|
2
|
+
|
|
3
|
+
const cspDirectives = [
|
|
4
|
+
"default-src 'self'",
|
|
5
|
+
"script-src 'self' 'unsafe-eval' 'unsafe-inline'",
|
|
6
|
+
"style-src 'self' 'unsafe-inline'",
|
|
7
|
+
"img-src 'self' blob: data: https:",
|
|
8
|
+
"font-src 'self' https://fonts.gstatic.com",
|
|
9
|
+
"connect-src 'self' https:",
|
|
10
|
+
"frame-ancestors 'none'",
|
|
11
|
+
"base-uri 'self'",
|
|
12
|
+
"form-action 'self'",
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const cspHeader = cspDirectives.join('; ');
|
|
16
|
+
|
|
17
|
+
const securityHeaders = [
|
|
18
|
+
{ key: 'X-Frame-Options', value: 'DENY' },
|
|
19
|
+
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
|
20
|
+
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
|
|
21
|
+
{ key: 'X-DNS-Prefetch-Control', value: 'on' },
|
|
22
|
+
{
|
|
23
|
+
key: 'Strict-Transport-Security',
|
|
24
|
+
value: 'max-age=63072000; includeSubDomains; preload',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
key: 'Permissions-Policy',
|
|
28
|
+
value: 'camera=(), microphone=(), geolocation=()',
|
|
29
|
+
},
|
|
30
|
+
{ key: 'Content-Security-Policy', value: cspHeader },
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const nextConfig: NextConfig = {
|
|
34
|
+
transpilePackages: ['@mars-stack/core', '@mars-stack/ui'],
|
|
35
|
+
async headers() {
|
|
36
|
+
return [
|
|
37
|
+
{
|
|
38
|
+
source: '/(.*)',
|
|
39
|
+
headers: securityHeaders,
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default nextConfig;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mars-stack/template",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "node scripts/ensure-db.mjs && next dev --turbopack",
|
|
8
|
+
"dev:no-db": "next dev --turbopack",
|
|
9
|
+
"db:local": "npx prisma dev --detach",
|
|
10
|
+
"db:local:stop": "npx prisma dev stop",
|
|
11
|
+
"db:local:ls": "npx prisma dev ls",
|
|
12
|
+
"build": "prisma generate && next build",
|
|
13
|
+
"start": "next start",
|
|
14
|
+
"lint": "eslint .",
|
|
15
|
+
"test": "vitest run",
|
|
16
|
+
"test:watch": "vitest",
|
|
17
|
+
"test:coverage": "vitest run --coverage",
|
|
18
|
+
"test:e2e": "playwright test",
|
|
19
|
+
"test:e2e:ui": "playwright test --ui",
|
|
20
|
+
"db:generate": "prisma generate",
|
|
21
|
+
"db:push": "prisma generate && prisma db push",
|
|
22
|
+
"db:migrate": "prisma generate && prisma migrate dev",
|
|
23
|
+
"db:seed": "prisma db seed",
|
|
24
|
+
"db:studio": "prisma studio",
|
|
25
|
+
"generate:env": "tsx scripts/generate-env-example.ts",
|
|
26
|
+
"check:architecture": "tsx scripts/check-architecture.ts",
|
|
27
|
+
"check:docs": "tsx scripts/check-doc-freshness.ts",
|
|
28
|
+
"update:quality": "tsx scripts/update-quality-score.ts"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@mars-stack/core": "*",
|
|
32
|
+
"@mars-stack/ui": "*",
|
|
33
|
+
"@prisma/adapter-pg": "^7.5.0",
|
|
34
|
+
"@prisma/client": "^7.5.0",
|
|
35
|
+
"dotenv": "^16.4.0",
|
|
36
|
+
"@react-email/components": "^1.0.8",
|
|
37
|
+
"@sendgrid/mail": "^8.1.0",
|
|
38
|
+
"@upstash/ratelimit": "^2.0.0",
|
|
39
|
+
"@upstash/redis": "^1.36.4",
|
|
40
|
+
"bcryptjs": "^2.4.3",
|
|
41
|
+
"clsx": "^2.1.1",
|
|
42
|
+
"jose": "^6.2.1",
|
|
43
|
+
"next": "^16.0.0",
|
|
44
|
+
"pino": "^9.6.0",
|
|
45
|
+
"pino-pretty": "^13.0.0",
|
|
46
|
+
"react": "^19.0.0",
|
|
47
|
+
"react-dom": "^19.0.0",
|
|
48
|
+
"react-email": "^5.2.9",
|
|
49
|
+
"server-only": "^0.0.1",
|
|
50
|
+
"stripe": "^17.0.0",
|
|
51
|
+
"zod": "^4.3.6"
|
|
52
|
+
},
|
|
53
|
+
"prisma": {
|
|
54
|
+
"schema": "prisma/schema",
|
|
55
|
+
"seed": "npx tsx scripts/seed.ts"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@eslint/eslintrc": "^3.3.5",
|
|
59
|
+
"@playwright/test": "^1.50.0",
|
|
60
|
+
"@tailwindcss/postcss": "^4.0.0",
|
|
61
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
62
|
+
"@testing-library/react": "^16.0.0",
|
|
63
|
+
"@types/bcryptjs": "^2.4.0",
|
|
64
|
+
"@types/node": "^25.4.0",
|
|
65
|
+
"@types/react": "^19.0.0",
|
|
66
|
+
"@types/react-dom": "^19.0.0",
|
|
67
|
+
"@vitejs/plugin-react": "^5.1.4",
|
|
68
|
+
"eslint": "^9.0.0",
|
|
69
|
+
"eslint-config-next": "^16.0.0",
|
|
70
|
+
"jsdom": "^28.1.0",
|
|
71
|
+
"postcss": "^8.5.0",
|
|
72
|
+
"prettier": "^3.5.0",
|
|
73
|
+
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
74
|
+
"prisma": "^7.5.0",
|
|
75
|
+
"tailwindcss": "^4.0.0",
|
|
76
|
+
"tsx": "^4.0.0",
|
|
77
|
+
"typescript": "^5.7.0",
|
|
78
|
+
"vitest": "^3.0.0"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './e2e',
|
|
5
|
+
fullyParallel: true,
|
|
6
|
+
forbidOnly: !!process.env.CI,
|
|
7
|
+
retries: process.env.CI ? 2 : 0,
|
|
8
|
+
workers: process.env.CI ? 1 : undefined,
|
|
9
|
+
reporter: 'html',
|
|
10
|
+
use: {
|
|
11
|
+
baseURL: 'http://localhost:3000',
|
|
12
|
+
trace: 'on-first-retry',
|
|
13
|
+
screenshot: 'only-on-failure',
|
|
14
|
+
},
|
|
15
|
+
projects: [
|
|
16
|
+
{
|
|
17
|
+
name: 'chromium',
|
|
18
|
+
use: { ...devices['Desktop Chrome'] },
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'mobile',
|
|
22
|
+
use: { ...devices['iPhone 14'] },
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
webServer: {
|
|
26
|
+
command: 'yarn build && yarn start',
|
|
27
|
+
url: 'http://localhost:3000',
|
|
28
|
+
reuseExistingServer: !process.env.CI,
|
|
29
|
+
timeout: 120_000,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
// biome-ignore-all lint: generated file
|
|
5
|
+
// @ts-nocheck
|
|
6
|
+
/*
|
|
7
|
+
* This file should be your main import to use Prisma-related types and utilities in a browser.
|
|
8
|
+
* Use it to get access to models, enums, and input types.
|
|
9
|
+
*
|
|
10
|
+
* This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
|
|
11
|
+
* See `client.ts` for the standard, server-side entry point.
|
|
12
|
+
*
|
|
13
|
+
* 🟢 You can import this file directly.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import * as Prisma from './internal/prismaNamespaceBrowser'
|
|
17
|
+
export { Prisma }
|
|
18
|
+
export * as $Enums from './enums'
|
|
19
|
+
export * from './enums';
|
|
20
|
+
/**
|
|
21
|
+
* Model User
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
export type User = Prisma.UserModel
|
|
25
|
+
/**
|
|
26
|
+
* Model Account
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
export type Account = Prisma.AccountModel
|
|
30
|
+
/**
|
|
31
|
+
* Model Session
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
34
|
+
export type Session = Prisma.SessionModel
|
|
35
|
+
/**
|
|
36
|
+
* Model VerificationToken
|
|
37
|
+
*
|
|
38
|
+
*/
|
|
39
|
+
export type VerificationToken = Prisma.VerificationTokenModel
|
|
40
|
+
/**
|
|
41
|
+
* Model File
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
export type File = Prisma.FileModel
|
|
45
|
+
/**
|
|
46
|
+
* Model Subscription
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
export type Subscription = Prisma.SubscriptionModel
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
// biome-ignore-all lint: generated file
|
|
5
|
+
// @ts-nocheck
|
|
6
|
+
/*
|
|
7
|
+
* This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
|
|
8
|
+
* If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
|
|
9
|
+
*
|
|
10
|
+
* 🟢 You can import this file directly.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import * as process from 'node:process'
|
|
14
|
+
import * as path from 'node:path'
|
|
15
|
+
import { fileURLToPath } from 'node:url'
|
|
16
|
+
globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url))
|
|
17
|
+
|
|
18
|
+
import * as runtime from "@prisma/client/runtime/client"
|
|
19
|
+
import * as $Enums from "./enums"
|
|
20
|
+
import * as $Class from "./internal/class"
|
|
21
|
+
import * as Prisma from "./internal/prismaNamespace"
|
|
22
|
+
|
|
23
|
+
export * as $Enums from './enums'
|
|
24
|
+
export * from "./enums"
|
|
25
|
+
/**
|
|
26
|
+
* ## Prisma Client
|
|
27
|
+
*
|
|
28
|
+
* Type-safe database client for TypeScript
|
|
29
|
+
* @example
|
|
30
|
+
* ```
|
|
31
|
+
* const prisma = new PrismaClient({
|
|
32
|
+
* adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL })
|
|
33
|
+
* })
|
|
34
|
+
* // Fetch zero or more Users
|
|
35
|
+
* const users = await prisma.user.findMany()
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Read more in our [docs](https://pris.ly/d/client).
|
|
39
|
+
*/
|
|
40
|
+
export const PrismaClient = $Class.getPrismaClientClass()
|
|
41
|
+
export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>
|
|
42
|
+
export { Prisma }
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Model User
|
|
46
|
+
*
|
|
47
|
+
*/
|
|
48
|
+
export type User = Prisma.UserModel
|
|
49
|
+
/**
|
|
50
|
+
* Model Account
|
|
51
|
+
*
|
|
52
|
+
*/
|
|
53
|
+
export type Account = Prisma.AccountModel
|
|
54
|
+
/**
|
|
55
|
+
* Model Session
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
export type Session = Prisma.SessionModel
|
|
59
|
+
/**
|
|
60
|
+
* Model VerificationToken
|
|
61
|
+
*
|
|
62
|
+
*/
|
|
63
|
+
export type VerificationToken = Prisma.VerificationTokenModel
|
|
64
|
+
/**
|
|
65
|
+
* Model File
|
|
66
|
+
*
|
|
67
|
+
*/
|
|
68
|
+
export type File = Prisma.FileModel
|
|
69
|
+
/**
|
|
70
|
+
* Model Subscription
|
|
71
|
+
*
|
|
72
|
+
*/
|
|
73
|
+
export type Subscription = Prisma.SubscriptionModel
|