@cherishxn/agent-scaffold 0.0.0-stage → 1.1.0
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/LICENSE +21 -0
- package/README.md +99 -2
- package/THIRD_PARTY_NOTICES.md +18 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +105 -0
- package/dist/diagnostics.d.ts +10 -0
- package/dist/diagnostics.js +27 -0
- package/dist/generate.d.ts +55 -0
- package/dist/generate.js +159 -0
- package/dist/model.d.ts +33 -0
- package/dist/model.js +24 -0
- package/dist/verify.d.ts +67 -0
- package/dist/verify.js +278 -0
- package/package.json +52 -4
- package/schemas/manifest.json +171 -0
- package/schemas/plan.json +164 -0
- package/schemas/result.json +97 -0
- package/schemas/spec.json +50 -0
- package/skills/scaffold-use/SKILL.md +24 -0
- package/templates/catalog.json +37 -0
- package/templates/next-fullstack-antd/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-antd/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-antd/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-antd/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-antd/.dockerignore +18 -0
- package/templates/next-fullstack-antd/.env.example +13 -0
- package/templates/next-fullstack-antd/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-antd/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-antd/.scaffold-checks.json +7 -0
- package/templates/next-fullstack-antd/AGENTS.md +11 -0
- package/templates/next-fullstack-antd/CLAUDE.md +1 -0
- package/templates/next-fullstack-antd/DESIGN.md +208 -0
- package/templates/next-fullstack-antd/LICENSE +21 -0
- package/templates/next-fullstack-antd/README.md +64 -0
- package/templates/next-fullstack-antd/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/next-fullstack-antd/compose.yaml +18 -0
- package/templates/next-fullstack-antd/design/guide.md +61 -0
- package/templates/next-fullstack-antd/design/layout.css +6 -0
- package/templates/next-fullstack-antd/design/structure.json +107 -0
- package/templates/next-fullstack-antd/design/tokens.json +171 -0
- package/templates/next-fullstack-antd/design/widgets.css +30 -0
- package/templates/next-fullstack-antd/design/widgets.json +233 -0
- package/templates/next-fullstack-antd/docs/PROJECT.md +32 -0
- package/templates/next-fullstack-antd/docs/api.d.ts +544 -0
- package/templates/next-fullstack-antd/docs/openapi.json +461 -0
- package/templates/next-fullstack-antd/gitignore.template +19 -0
- package/templates/next-fullstack-antd/licenses/fastapi.txt +21 -0
- package/templates/next-fullstack-antd/licenses/nest.txt +22 -0
- package/templates/next-fullstack-antd/licenses/next.txt +21 -0
- package/templates/next-fullstack-antd/licenses/shadcn.txt +21 -0
- package/templates/next-fullstack-antd/licenses/sources.json +27 -0
- package/templates/next-fullstack-antd/licenses/spring.txt +202 -0
- package/templates/next-fullstack-antd/package-lock.json +494 -0
- package/templates/next-fullstack-antd/package.json +26 -0
- package/templates/next-fullstack-antd/playwright.config.ts +3 -0
- package/templates/next-fullstack-antd/project.json +8 -0
- package/templates/next-fullstack-antd/scripts/api-check.mjs +18 -0
- package/templates/next-fullstack-antd/scripts/api-contract.mjs +46 -0
- package/templates/next-fullstack-antd/scripts/design-coverage.mjs +20 -0
- package/templates/next-fullstack-antd/scripts/design-next-cleanup.mjs +13 -0
- package/templates/next-fullstack-antd/scripts/design-verify.mjs +154 -0
- package/templates/next-fullstack-antd/scripts/design.mjs +108 -0
- package/templates/next-fullstack-antd/scripts/project.mjs +120 -0
- package/templates/next-fullstack-antd/tests/contract-client.ts +20 -0
- package/templates/next-fullstack-antd/tests/contract.spec.ts +49 -0
- package/templates/next-fullstack-antd/tests/design/harness.tsx +63 -0
- package/templates/next-fullstack-antd/tests/ui.spec.ts +61 -0
- package/templates/next-fullstack-antd/web/Dockerfile +12 -0
- package/templates/next-fullstack-antd/web/app/api/auth/login/route.ts +1 -0
- package/templates/next-fullstack-antd/web/app/api/auth/logout/route.ts +1 -0
- package/templates/next-fullstack-antd/web/app/api/auth/me/route.ts +1 -0
- package/templates/next-fullstack-antd/web/app/api/health/route.ts +1 -0
- package/templates/next-fullstack-antd/web/app/api/records/[id]/route.ts +5 -0
- package/templates/next-fullstack-antd/web/app/api/records/route.ts +3 -0
- package/templates/next-fullstack-antd/web/app/layout.tsx +5 -0
- package/templates/next-fullstack-antd/web/app/page.tsx +2 -0
- package/templates/next-fullstack-antd/web/eslint.config.mjs +3 -0
- package/templates/next-fullstack-antd/web/lib/api.ts +35 -0
- package/templates/next-fullstack-antd/web/lib/auth.ts +10 -0
- package/templates/next-fullstack-antd/web/lib/db.ts +3 -0
- package/templates/next-fullstack-antd/web/lib/session.test.ts +15 -0
- package/templates/next-fullstack-antd/web/lib/validation.test.ts +3 -0
- package/templates/next-fullstack-antd/web/lib/validation.ts +5 -0
- package/templates/next-fullstack-antd/web/next-env.d.ts +7 -0
- package/templates/next-fullstack-antd/web/next.config.ts +3 -0
- package/templates/next-fullstack-antd/web/package.json +35 -0
- package/templates/next-fullstack-antd/web/pnpm-lock.yaml +3756 -0
- package/templates/next-fullstack-antd/web/pnpm-workspace.yaml +7 -0
- package/templates/next-fullstack-antd/web/prisma/migrations/202610190001_initial/migration.sql +99 -0
- package/templates/next-fullstack-antd/web/prisma/migrations/migration_lock.toml +1 -0
- package/templates/next-fullstack-antd/web/prisma/schema.prisma +72 -0
- package/templates/next-fullstack-antd/web/scripts/seed.ts +4 -0
- package/templates/next-fullstack-antd/web/src/App.tsx +29 -0
- package/templates/next-fullstack-antd/web/src/design-layout.css +7 -0
- package/templates/next-fullstack-antd/web/src/design-runtime.json +511 -0
- package/templates/next-fullstack-antd/web/src/design-tokens.css +168 -0
- package/templates/next-fullstack-antd/web/src/design-widgets.css +31 -0
- package/templates/next-fullstack-antd/web/src/structure-view.tsx +16 -0
- package/templates/next-fullstack-antd/web/src/styles.css +3 -0
- package/templates/next-fullstack-antd/web/src/ui.tsx +30 -0
- package/templates/next-fullstack-antd/web/src/widget-icon.tsx +5 -0
- package/templates/next-fullstack-antd/web/src/widget-types.ts +13 -0
- package/templates/next-fullstack-antd/web/src/workspace-model.ts +85 -0
- package/templates/next-fullstack-antd/web/tsconfig.json +42 -0
- package/templates/next-fullstack-antd/web/vitest.config.ts +2 -0
- package/templates/next-fullstack-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-shadcn/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-shadcn/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-shadcn/.dockerignore +18 -0
- package/templates/next-fullstack-shadcn/.env.example +13 -0
- package/templates/next-fullstack-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/next-fullstack-shadcn/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/next-fullstack-shadcn/.scaffold-checks.json +7 -0
- package/templates/next-fullstack-shadcn/AGENTS.md +11 -0
- package/templates/next-fullstack-shadcn/CLAUDE.md +1 -0
- package/templates/next-fullstack-shadcn/DESIGN.md +208 -0
- package/templates/next-fullstack-shadcn/LICENSE +21 -0
- package/templates/next-fullstack-shadcn/README.md +64 -0
- package/templates/next-fullstack-shadcn/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/next-fullstack-shadcn/compose.yaml +18 -0
- package/templates/next-fullstack-shadcn/design/guide.md +61 -0
- package/templates/next-fullstack-shadcn/design/layout.css +6 -0
- package/templates/next-fullstack-shadcn/design/structure.json +107 -0
- package/templates/next-fullstack-shadcn/design/tokens.json +171 -0
- package/templates/next-fullstack-shadcn/design/widgets.css +30 -0
- package/templates/next-fullstack-shadcn/design/widgets.json +233 -0
- package/templates/next-fullstack-shadcn/docs/PROJECT.md +32 -0
- package/templates/next-fullstack-shadcn/docs/api.d.ts +544 -0
- package/templates/next-fullstack-shadcn/docs/openapi.json +461 -0
- package/templates/next-fullstack-shadcn/gitignore.template +19 -0
- package/templates/next-fullstack-shadcn/licenses/fastapi.txt +21 -0
- package/templates/next-fullstack-shadcn/licenses/nest.txt +22 -0
- package/templates/next-fullstack-shadcn/licenses/next.txt +21 -0
- package/templates/next-fullstack-shadcn/licenses/shadcn.txt +21 -0
- package/templates/next-fullstack-shadcn/licenses/sources.json +27 -0
- package/templates/next-fullstack-shadcn/licenses/spring.txt +202 -0
- package/templates/next-fullstack-shadcn/package-lock.json +494 -0
- package/templates/next-fullstack-shadcn/package.json +26 -0
- package/templates/next-fullstack-shadcn/playwright.config.ts +3 -0
- package/templates/next-fullstack-shadcn/project.json +8 -0
- package/templates/next-fullstack-shadcn/scripts/api-check.mjs +18 -0
- package/templates/next-fullstack-shadcn/scripts/api-contract.mjs +46 -0
- package/templates/next-fullstack-shadcn/scripts/design-coverage.mjs +20 -0
- package/templates/next-fullstack-shadcn/scripts/design-next-cleanup.mjs +13 -0
- package/templates/next-fullstack-shadcn/scripts/design-verify.mjs +154 -0
- package/templates/next-fullstack-shadcn/scripts/design.mjs +108 -0
- package/templates/next-fullstack-shadcn/scripts/project.mjs +120 -0
- package/templates/next-fullstack-shadcn/tests/contract-client.ts +20 -0
- package/templates/next-fullstack-shadcn/tests/contract.spec.ts +49 -0
- package/templates/next-fullstack-shadcn/tests/design/harness.tsx +63 -0
- package/templates/next-fullstack-shadcn/tests/ui.spec.ts +61 -0
- package/templates/next-fullstack-shadcn/web/Dockerfile +12 -0
- package/templates/next-fullstack-shadcn/web/app/api/auth/login/route.ts +1 -0
- package/templates/next-fullstack-shadcn/web/app/api/auth/logout/route.ts +1 -0
- package/templates/next-fullstack-shadcn/web/app/api/auth/me/route.ts +1 -0
- package/templates/next-fullstack-shadcn/web/app/api/health/route.ts +1 -0
- package/templates/next-fullstack-shadcn/web/app/api/records/[id]/route.ts +5 -0
- package/templates/next-fullstack-shadcn/web/app/api/records/route.ts +3 -0
- package/templates/next-fullstack-shadcn/web/app/layout.tsx +4 -0
- package/templates/next-fullstack-shadcn/web/app/page.tsx +2 -0
- package/templates/next-fullstack-shadcn/web/eslint.config.mjs +3 -0
- package/templates/next-fullstack-shadcn/web/lib/api.ts +35 -0
- package/templates/next-fullstack-shadcn/web/lib/auth.ts +10 -0
- package/templates/next-fullstack-shadcn/web/lib/db.ts +3 -0
- package/templates/next-fullstack-shadcn/web/lib/session.test.ts +15 -0
- package/templates/next-fullstack-shadcn/web/lib/validation.test.ts +3 -0
- package/templates/next-fullstack-shadcn/web/lib/validation.ts +5 -0
- package/templates/next-fullstack-shadcn/web/next-env.d.ts +7 -0
- package/templates/next-fullstack-shadcn/web/next.config.ts +3 -0
- package/templates/next-fullstack-shadcn/web/package.json +39 -0
- package/templates/next-fullstack-shadcn/web/pnpm-lock.yaml +3286 -0
- package/templates/next-fullstack-shadcn/web/pnpm-workspace.yaml +7 -0
- package/templates/next-fullstack-shadcn/web/postcss.config.mjs +1 -0
- package/templates/next-fullstack-shadcn/web/prisma/migrations/202610190001_initial/migration.sql +99 -0
- package/templates/next-fullstack-shadcn/web/prisma/migrations/migration_lock.toml +1 -0
- package/templates/next-fullstack-shadcn/web/prisma/schema.prisma +72 -0
- package/templates/next-fullstack-shadcn/web/scripts/seed.ts +4 -0
- package/templates/next-fullstack-shadcn/web/src/App.tsx +30 -0
- package/templates/next-fullstack-shadcn/web/src/design-layout.css +7 -0
- package/templates/next-fullstack-shadcn/web/src/design-runtime.json +511 -0
- package/templates/next-fullstack-shadcn/web/src/design-tokens.css +168 -0
- package/templates/next-fullstack-shadcn/web/src/design-widgets.css +31 -0
- package/templates/next-fullstack-shadcn/web/src/structure-view.tsx +16 -0
- package/templates/next-fullstack-shadcn/web/src/styles.css +3 -0
- package/templates/next-fullstack-shadcn/web/src/tailwind.css +2 -0
- package/templates/next-fullstack-shadcn/web/src/ui.tsx +13 -0
- package/templates/next-fullstack-shadcn/web/src/widget-icon.tsx +5 -0
- package/templates/next-fullstack-shadcn/web/src/widget-types.ts +13 -0
- package/templates/next-fullstack-shadcn/web/src/workspace-model.ts +85 -0
- package/templates/next-fullstack-shadcn/web/tsconfig.json +42 -0
- package/templates/next-fullstack-shadcn/web/vitest.config.ts +2 -0
- package/templates/react-fastapi-antd/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-antd/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-antd/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-antd/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-antd/.dockerignore +18 -0
- package/templates/react-fastapi-antd/.env.example +13 -0
- package/templates/react-fastapi-antd/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-antd/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-antd/.scaffold-checks.json +7 -0
- package/templates/react-fastapi-antd/AGENTS.md +11 -0
- package/templates/react-fastapi-antd/CLAUDE.md +1 -0
- package/templates/react-fastapi-antd/DESIGN.md +208 -0
- package/templates/react-fastapi-antd/LICENSE +21 -0
- package/templates/react-fastapi-antd/README.md +64 -0
- package/templates/react-fastapi-antd/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-fastapi-antd/backend/.python-version +1 -0
- package/templates/react-fastapi-antd/backend/Dockerfile +10 -0
- package/templates/react-fastapi-antd/backend/alembic.ini +3 -0
- package/templates/react-fastapi-antd/backend/app/__init__.py +0 -0
- package/templates/react-fastapi-antd/backend/app/core/__init__.py +0 -0
- package/templates/react-fastapi-antd/backend/app/core/security.py +25 -0
- package/templates/react-fastapi-antd/backend/app/db.py +11 -0
- package/templates/react-fastapi-antd/backend/app/main.py +146 -0
- package/templates/react-fastapi-antd/backend/app/models.py +21 -0
- package/templates/react-fastapi-antd/backend/app/seed.py +21 -0
- package/templates/react-fastapi-antd/backend/migrations/env.py +9 -0
- package/templates/react-fastapi-antd/backend/migrations/versions/0001_initial.py +18 -0
- package/templates/react-fastapi-antd/backend/pyproject.toml +16 -0
- package/templates/react-fastapi-antd/backend/tests/test_api.py +27 -0
- package/templates/react-fastapi-antd/backend/uv.lock +1085 -0
- package/templates/react-fastapi-antd/compose.yaml +18 -0
- package/templates/react-fastapi-antd/design/guide.md +61 -0
- package/templates/react-fastapi-antd/design/layout.css +6 -0
- package/templates/react-fastapi-antd/design/structure.json +107 -0
- package/templates/react-fastapi-antd/design/tokens.json +171 -0
- package/templates/react-fastapi-antd/design/widgets.css +30 -0
- package/templates/react-fastapi-antd/design/widgets.json +233 -0
- package/templates/react-fastapi-antd/docs/PROJECT.md +32 -0
- package/templates/react-fastapi-antd/docs/api.d.ts +544 -0
- package/templates/react-fastapi-antd/docs/openapi.json +461 -0
- package/templates/react-fastapi-antd/gitignore.template +19 -0
- package/templates/react-fastapi-antd/licenses/fastapi.txt +21 -0
- package/templates/react-fastapi-antd/licenses/nest.txt +22 -0
- package/templates/react-fastapi-antd/licenses/next.txt +21 -0
- package/templates/react-fastapi-antd/licenses/shadcn.txt +21 -0
- package/templates/react-fastapi-antd/licenses/sources.json +27 -0
- package/templates/react-fastapi-antd/licenses/spring.txt +202 -0
- package/templates/react-fastapi-antd/package-lock.json +494 -0
- package/templates/react-fastapi-antd/package.json +26 -0
- package/templates/react-fastapi-antd/playwright.config.ts +3 -0
- package/templates/react-fastapi-antd/project.json +8 -0
- package/templates/react-fastapi-antd/scripts/api-check.mjs +18 -0
- package/templates/react-fastapi-antd/scripts/api-contract.mjs +46 -0
- package/templates/react-fastapi-antd/scripts/design-coverage.mjs +20 -0
- package/templates/react-fastapi-antd/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-fastapi-antd/scripts/design-verify.mjs +154 -0
- package/templates/react-fastapi-antd/scripts/design.mjs +108 -0
- package/templates/react-fastapi-antd/scripts/project.mjs +120 -0
- package/templates/react-fastapi-antd/tests/contract-client.ts +20 -0
- package/templates/react-fastapi-antd/tests/contract.spec.ts +49 -0
- package/templates/react-fastapi-antd/tests/design/harness.tsx +63 -0
- package/templates/react-fastapi-antd/tests/ui.spec.ts +61 -0
- package/templates/react-fastapi-antd/web/bun.lock +442 -0
- package/templates/react-fastapi-antd/web/eslint.config.mjs +3 -0
- package/templates/react-fastapi-antd/web/index.html +1 -0
- package/templates/react-fastapi-antd/web/package.json +28 -0
- package/templates/react-fastapi-antd/web/src/App.tsx +29 -0
- package/templates/react-fastapi-antd/web/src/design-layout.css +7 -0
- package/templates/react-fastapi-antd/web/src/design-runtime.json +511 -0
- package/templates/react-fastapi-antd/web/src/design-tokens.css +168 -0
- package/templates/react-fastapi-antd/web/src/design-widgets.css +31 -0
- package/templates/react-fastapi-antd/web/src/main.tsx +6 -0
- package/templates/react-fastapi-antd/web/src/structure-view.tsx +16 -0
- package/templates/react-fastapi-antd/web/src/styles.css +3 -0
- package/templates/react-fastapi-antd/web/src/ui.tsx +30 -0
- package/templates/react-fastapi-antd/web/src/widget-icon.tsx +5 -0
- package/templates/react-fastapi-antd/web/src/widget-types.ts +13 -0
- package/templates/react-fastapi-antd/web/src/workspace-model.ts +85 -0
- package/templates/react-fastapi-antd/web/tsconfig.json +22 -0
- package/templates/react-fastapi-antd/web/vite.config.ts +3 -0
- package/templates/react-fastapi-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-shadcn/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-shadcn/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-shadcn/.dockerignore +18 -0
- package/templates/react-fastapi-shadcn/.env.example +13 -0
- package/templates/react-fastapi-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-fastapi-shadcn/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-fastapi-shadcn/.scaffold-checks.json +7 -0
- package/templates/react-fastapi-shadcn/AGENTS.md +11 -0
- package/templates/react-fastapi-shadcn/CLAUDE.md +1 -0
- package/templates/react-fastapi-shadcn/DESIGN.md +208 -0
- package/templates/react-fastapi-shadcn/LICENSE +21 -0
- package/templates/react-fastapi-shadcn/README.md +64 -0
- package/templates/react-fastapi-shadcn/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-fastapi-shadcn/backend/.python-version +1 -0
- package/templates/react-fastapi-shadcn/backend/Dockerfile +10 -0
- package/templates/react-fastapi-shadcn/backend/alembic.ini +3 -0
- package/templates/react-fastapi-shadcn/backend/app/__init__.py +0 -0
- package/templates/react-fastapi-shadcn/backend/app/core/__init__.py +0 -0
- package/templates/react-fastapi-shadcn/backend/app/core/security.py +25 -0
- package/templates/react-fastapi-shadcn/backend/app/db.py +11 -0
- package/templates/react-fastapi-shadcn/backend/app/main.py +146 -0
- package/templates/react-fastapi-shadcn/backend/app/models.py +21 -0
- package/templates/react-fastapi-shadcn/backend/app/seed.py +21 -0
- package/templates/react-fastapi-shadcn/backend/migrations/env.py +9 -0
- package/templates/react-fastapi-shadcn/backend/migrations/versions/0001_initial.py +18 -0
- package/templates/react-fastapi-shadcn/backend/pyproject.toml +16 -0
- package/templates/react-fastapi-shadcn/backend/tests/test_api.py +27 -0
- package/templates/react-fastapi-shadcn/backend/uv.lock +1085 -0
- package/templates/react-fastapi-shadcn/compose.yaml +18 -0
- package/templates/react-fastapi-shadcn/design/guide.md +61 -0
- package/templates/react-fastapi-shadcn/design/layout.css +6 -0
- package/templates/react-fastapi-shadcn/design/structure.json +107 -0
- package/templates/react-fastapi-shadcn/design/tokens.json +171 -0
- package/templates/react-fastapi-shadcn/design/widgets.css +30 -0
- package/templates/react-fastapi-shadcn/design/widgets.json +233 -0
- package/templates/react-fastapi-shadcn/docs/PROJECT.md +32 -0
- package/templates/react-fastapi-shadcn/docs/api.d.ts +544 -0
- package/templates/react-fastapi-shadcn/docs/openapi.json +461 -0
- package/templates/react-fastapi-shadcn/gitignore.template +19 -0
- package/templates/react-fastapi-shadcn/licenses/fastapi.txt +21 -0
- package/templates/react-fastapi-shadcn/licenses/nest.txt +22 -0
- package/templates/react-fastapi-shadcn/licenses/next.txt +21 -0
- package/templates/react-fastapi-shadcn/licenses/shadcn.txt +21 -0
- package/templates/react-fastapi-shadcn/licenses/sources.json +27 -0
- package/templates/react-fastapi-shadcn/licenses/spring.txt +202 -0
- package/templates/react-fastapi-shadcn/package-lock.json +494 -0
- package/templates/react-fastapi-shadcn/package.json +26 -0
- package/templates/react-fastapi-shadcn/playwright.config.ts +3 -0
- package/templates/react-fastapi-shadcn/project.json +8 -0
- package/templates/react-fastapi-shadcn/scripts/api-check.mjs +18 -0
- package/templates/react-fastapi-shadcn/scripts/api-contract.mjs +46 -0
- package/templates/react-fastapi-shadcn/scripts/design-coverage.mjs +20 -0
- package/templates/react-fastapi-shadcn/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-fastapi-shadcn/scripts/design-verify.mjs +154 -0
- package/templates/react-fastapi-shadcn/scripts/design.mjs +108 -0
- package/templates/react-fastapi-shadcn/scripts/project.mjs +120 -0
- package/templates/react-fastapi-shadcn/tests/contract-client.ts +20 -0
- package/templates/react-fastapi-shadcn/tests/contract.spec.ts +49 -0
- package/templates/react-fastapi-shadcn/tests/design/harness.tsx +63 -0
- package/templates/react-fastapi-shadcn/tests/ui.spec.ts +61 -0
- package/templates/react-fastapi-shadcn/web/bun.lock +413 -0
- package/templates/react-fastapi-shadcn/web/eslint.config.mjs +3 -0
- package/templates/react-fastapi-shadcn/web/index.html +1 -0
- package/templates/react-fastapi-shadcn/web/package.json +33 -0
- package/templates/react-fastapi-shadcn/web/src/App.tsx +30 -0
- package/templates/react-fastapi-shadcn/web/src/design-layout.css +7 -0
- package/templates/react-fastapi-shadcn/web/src/design-runtime.json +511 -0
- package/templates/react-fastapi-shadcn/web/src/design-tokens.css +168 -0
- package/templates/react-fastapi-shadcn/web/src/design-widgets.css +31 -0
- package/templates/react-fastapi-shadcn/web/src/main.tsx +6 -0
- package/templates/react-fastapi-shadcn/web/src/structure-view.tsx +16 -0
- package/templates/react-fastapi-shadcn/web/src/styles.css +3 -0
- package/templates/react-fastapi-shadcn/web/src/tailwind.css +2 -0
- package/templates/react-fastapi-shadcn/web/src/ui.tsx +13 -0
- package/templates/react-fastapi-shadcn/web/src/widget-icon.tsx +5 -0
- package/templates/react-fastapi-shadcn/web/src/widget-types.ts +13 -0
- package/templates/react-fastapi-shadcn/web/src/workspace-model.ts +85 -0
- package/templates/react-fastapi-shadcn/web/tsconfig.json +22 -0
- package/templates/react-fastapi-shadcn/web/vite.config.ts +4 -0
- package/templates/react-nest-antd/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-antd/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-antd/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-antd/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-antd/.dockerignore +18 -0
- package/templates/react-nest-antd/.env.example +13 -0
- package/templates/react-nest-antd/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-antd/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-antd/.scaffold-checks.json +7 -0
- package/templates/react-nest-antd/AGENTS.md +11 -0
- package/templates/react-nest-antd/CLAUDE.md +1 -0
- package/templates/react-nest-antd/DESIGN.md +208 -0
- package/templates/react-nest-antd/LICENSE +21 -0
- package/templates/react-nest-antd/README.md +64 -0
- package/templates/react-nest-antd/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-nest-antd/backend/Dockerfile +12 -0
- package/templates/react-nest-antd/backend/eslint.config.mjs +3 -0
- package/templates/react-nest-antd/backend/jest.config.cjs +1 -0
- package/templates/react-nest-antd/backend/package.json +40 -0
- package/templates/react-nest-antd/backend/pnpm-lock.yaml +5165 -0
- package/templates/react-nest-antd/backend/pnpm-workspace.yaml +6 -0
- package/templates/react-nest-antd/backend/prisma/migrations/202610190001_initial/migration.sql +3 -0
- package/templates/react-nest-antd/backend/prisma/migrations/migration_lock.toml +1 -0
- package/templates/react-nest-antd/backend/prisma/schema.prisma +25 -0
- package/templates/react-nest-antd/backend/scripts/seed.ts +4 -0
- package/templates/react-nest-antd/backend/src/app.module.ts +43 -0
- package/templates/react-nest-antd/backend/src/main.ts +6 -0
- package/templates/react-nest-antd/backend/src/password.ts +3 -0
- package/templates/react-nest-antd/backend/src/validation.ts +7 -0
- package/templates/react-nest-antd/backend/test/api.test.ts +25 -0
- package/templates/react-nest-antd/backend/tsconfig.build.json +15 -0
- package/templates/react-nest-antd/backend/tsconfig.json +17 -0
- package/templates/react-nest-antd/compose.yaml +18 -0
- package/templates/react-nest-antd/design/guide.md +61 -0
- package/templates/react-nest-antd/design/layout.css +6 -0
- package/templates/react-nest-antd/design/structure.json +107 -0
- package/templates/react-nest-antd/design/tokens.json +171 -0
- package/templates/react-nest-antd/design/widgets.css +30 -0
- package/templates/react-nest-antd/design/widgets.json +233 -0
- package/templates/react-nest-antd/docs/PROJECT.md +32 -0
- package/templates/react-nest-antd/docs/api.d.ts +544 -0
- package/templates/react-nest-antd/docs/openapi.json +461 -0
- package/templates/react-nest-antd/gitignore.template +19 -0
- package/templates/react-nest-antd/licenses/fastapi.txt +21 -0
- package/templates/react-nest-antd/licenses/nest.txt +22 -0
- package/templates/react-nest-antd/licenses/next.txt +21 -0
- package/templates/react-nest-antd/licenses/shadcn.txt +21 -0
- package/templates/react-nest-antd/licenses/sources.json +27 -0
- package/templates/react-nest-antd/licenses/spring.txt +202 -0
- package/templates/react-nest-antd/package-lock.json +494 -0
- package/templates/react-nest-antd/package.json +26 -0
- package/templates/react-nest-antd/playwright.config.ts +3 -0
- package/templates/react-nest-antd/project.json +8 -0
- package/templates/react-nest-antd/scripts/api-check.mjs +18 -0
- package/templates/react-nest-antd/scripts/api-contract.mjs +46 -0
- package/templates/react-nest-antd/scripts/design-coverage.mjs +20 -0
- package/templates/react-nest-antd/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-nest-antd/scripts/design-verify.mjs +154 -0
- package/templates/react-nest-antd/scripts/design.mjs +108 -0
- package/templates/react-nest-antd/scripts/project.mjs +120 -0
- package/templates/react-nest-antd/tests/contract-client.ts +20 -0
- package/templates/react-nest-antd/tests/contract.spec.ts +49 -0
- package/templates/react-nest-antd/tests/design/harness.tsx +63 -0
- package/templates/react-nest-antd/tests/ui.spec.ts +61 -0
- package/templates/react-nest-antd/web/eslint.config.mjs +3 -0
- package/templates/react-nest-antd/web/index.html +1 -0
- package/templates/react-nest-antd/web/package.json +28 -0
- package/templates/react-nest-antd/web/pnpm-lock.yaml +2215 -0
- package/templates/react-nest-antd/web/src/App.tsx +29 -0
- package/templates/react-nest-antd/web/src/design-layout.css +7 -0
- package/templates/react-nest-antd/web/src/design-runtime.json +511 -0
- package/templates/react-nest-antd/web/src/design-tokens.css +168 -0
- package/templates/react-nest-antd/web/src/design-widgets.css +31 -0
- package/templates/react-nest-antd/web/src/main.tsx +6 -0
- package/templates/react-nest-antd/web/src/structure-view.tsx +16 -0
- package/templates/react-nest-antd/web/src/styles.css +3 -0
- package/templates/react-nest-antd/web/src/ui.tsx +30 -0
- package/templates/react-nest-antd/web/src/widget-icon.tsx +5 -0
- package/templates/react-nest-antd/web/src/widget-types.ts +13 -0
- package/templates/react-nest-antd/web/src/workspace-model.ts +85 -0
- package/templates/react-nest-antd/web/tsconfig.json +22 -0
- package/templates/react-nest-antd/web/vite.config.ts +3 -0
- package/templates/react-nest-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-shadcn/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-shadcn/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-shadcn/.dockerignore +18 -0
- package/templates/react-nest-shadcn/.env.example +13 -0
- package/templates/react-nest-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-nest-shadcn/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-nest-shadcn/.scaffold-checks.json +7 -0
- package/templates/react-nest-shadcn/AGENTS.md +11 -0
- package/templates/react-nest-shadcn/CLAUDE.md +1 -0
- package/templates/react-nest-shadcn/DESIGN.md +208 -0
- package/templates/react-nest-shadcn/LICENSE +21 -0
- package/templates/react-nest-shadcn/README.md +64 -0
- package/templates/react-nest-shadcn/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-nest-shadcn/backend/Dockerfile +12 -0
- package/templates/react-nest-shadcn/backend/eslint.config.mjs +3 -0
- package/templates/react-nest-shadcn/backend/jest.config.cjs +1 -0
- package/templates/react-nest-shadcn/backend/package.json +40 -0
- package/templates/react-nest-shadcn/backend/pnpm-lock.yaml +5165 -0
- package/templates/react-nest-shadcn/backend/pnpm-workspace.yaml +6 -0
- package/templates/react-nest-shadcn/backend/prisma/migrations/202610190001_initial/migration.sql +3 -0
- package/templates/react-nest-shadcn/backend/prisma/migrations/migration_lock.toml +1 -0
- package/templates/react-nest-shadcn/backend/prisma/schema.prisma +25 -0
- package/templates/react-nest-shadcn/backend/scripts/seed.ts +4 -0
- package/templates/react-nest-shadcn/backend/src/app.module.ts +43 -0
- package/templates/react-nest-shadcn/backend/src/main.ts +6 -0
- package/templates/react-nest-shadcn/backend/src/password.ts +3 -0
- package/templates/react-nest-shadcn/backend/src/validation.ts +7 -0
- package/templates/react-nest-shadcn/backend/test/api.test.ts +25 -0
- package/templates/react-nest-shadcn/backend/tsconfig.build.json +15 -0
- package/templates/react-nest-shadcn/backend/tsconfig.json +17 -0
- package/templates/react-nest-shadcn/compose.yaml +18 -0
- package/templates/react-nest-shadcn/design/guide.md +61 -0
- package/templates/react-nest-shadcn/design/layout.css +6 -0
- package/templates/react-nest-shadcn/design/structure.json +107 -0
- package/templates/react-nest-shadcn/design/tokens.json +171 -0
- package/templates/react-nest-shadcn/design/widgets.css +30 -0
- package/templates/react-nest-shadcn/design/widgets.json +233 -0
- package/templates/react-nest-shadcn/docs/PROJECT.md +32 -0
- package/templates/react-nest-shadcn/docs/api.d.ts +544 -0
- package/templates/react-nest-shadcn/docs/openapi.json +461 -0
- package/templates/react-nest-shadcn/gitignore.template +19 -0
- package/templates/react-nest-shadcn/licenses/fastapi.txt +21 -0
- package/templates/react-nest-shadcn/licenses/nest.txt +22 -0
- package/templates/react-nest-shadcn/licenses/next.txt +21 -0
- package/templates/react-nest-shadcn/licenses/shadcn.txt +21 -0
- package/templates/react-nest-shadcn/licenses/sources.json +27 -0
- package/templates/react-nest-shadcn/licenses/spring.txt +202 -0
- package/templates/react-nest-shadcn/package-lock.json +494 -0
- package/templates/react-nest-shadcn/package.json +26 -0
- package/templates/react-nest-shadcn/playwright.config.ts +3 -0
- package/templates/react-nest-shadcn/project.json +8 -0
- package/templates/react-nest-shadcn/scripts/api-check.mjs +18 -0
- package/templates/react-nest-shadcn/scripts/api-contract.mjs +46 -0
- package/templates/react-nest-shadcn/scripts/design-coverage.mjs +20 -0
- package/templates/react-nest-shadcn/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-nest-shadcn/scripts/design-verify.mjs +154 -0
- package/templates/react-nest-shadcn/scripts/design.mjs +108 -0
- package/templates/react-nest-shadcn/scripts/project.mjs +120 -0
- package/templates/react-nest-shadcn/tests/contract-client.ts +20 -0
- package/templates/react-nest-shadcn/tests/contract.spec.ts +49 -0
- package/templates/react-nest-shadcn/tests/design/harness.tsx +63 -0
- package/templates/react-nest-shadcn/tests/ui.spec.ts +61 -0
- package/templates/react-nest-shadcn/web/eslint.config.mjs +3 -0
- package/templates/react-nest-shadcn/web/index.html +1 -0
- package/templates/react-nest-shadcn/web/package.json +33 -0
- package/templates/react-nest-shadcn/web/pnpm-lock.yaml +1788 -0
- package/templates/react-nest-shadcn/web/src/App.tsx +30 -0
- package/templates/react-nest-shadcn/web/src/design-layout.css +7 -0
- package/templates/react-nest-shadcn/web/src/design-runtime.json +511 -0
- package/templates/react-nest-shadcn/web/src/design-tokens.css +168 -0
- package/templates/react-nest-shadcn/web/src/design-widgets.css +31 -0
- package/templates/react-nest-shadcn/web/src/main.tsx +6 -0
- package/templates/react-nest-shadcn/web/src/structure-view.tsx +16 -0
- package/templates/react-nest-shadcn/web/src/styles.css +3 -0
- package/templates/react-nest-shadcn/web/src/tailwind.css +2 -0
- package/templates/react-nest-shadcn/web/src/ui.tsx +13 -0
- package/templates/react-nest-shadcn/web/src/widget-icon.tsx +5 -0
- package/templates/react-nest-shadcn/web/src/widget-types.ts +13 -0
- package/templates/react-nest-shadcn/web/src/workspace-model.ts +85 -0
- package/templates/react-nest-shadcn/web/tsconfig.json +22 -0
- package/templates/react-nest-shadcn/web/vite.config.ts +4 -0
- package/templates/react-spring-antd/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-antd/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-antd/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-antd/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-antd/.dockerignore +18 -0
- package/templates/react-spring-antd/.env.example +13 -0
- package/templates/react-spring-antd/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-antd/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-antd/.scaffold-checks.json +7 -0
- package/templates/react-spring-antd/AGENTS.md +11 -0
- package/templates/react-spring-antd/CLAUDE.md +1 -0
- package/templates/react-spring-antd/DESIGN.md +208 -0
- package/templates/react-spring-antd/LICENSE +21 -0
- package/templates/react-spring-antd/README.md +64 -0
- package/templates/react-spring-antd/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-spring-antd/backend/.mvn/wrapper/maven-wrapper.properties +3 -0
- package/templates/react-spring-antd/backend/Dockerfile +11 -0
- package/templates/react-spring-antd/backend/mvnw +295 -0
- package/templates/react-spring-antd/backend/pom.xml +15 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Api.java +38 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/AppUser.java +11 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Application.java +7 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Errors.java +13 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/PersonalRecord.java +15 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Records.java +14 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Security.java +28 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Seed.java +13 -0
- package/templates/react-spring-antd/backend/src/main/java/dev/scaffold/app/Users.java +5 -0
- package/templates/react-spring-antd/backend/src/main/resources/application.properties +17 -0
- package/templates/react-spring-antd/backend/src/main/resources/db/migration/V1__initial.sql +3 -0
- package/templates/react-spring-antd/backend/src/main/resources/openapi.json +461 -0
- package/templates/react-spring-antd/backend/src/test/java/dev/scaffold/app/ApiTest.java +28 -0
- package/templates/react-spring-antd/backend/src/test/java/dev/scaffold/app/SessionExpiryTest.java +37 -0
- package/templates/react-spring-antd/compose.yaml +18 -0
- package/templates/react-spring-antd/design/guide.md +61 -0
- package/templates/react-spring-antd/design/layout.css +6 -0
- package/templates/react-spring-antd/design/structure.json +107 -0
- package/templates/react-spring-antd/design/tokens.json +171 -0
- package/templates/react-spring-antd/design/widgets.css +30 -0
- package/templates/react-spring-antd/design/widgets.json +233 -0
- package/templates/react-spring-antd/docs/PROJECT.md +32 -0
- package/templates/react-spring-antd/docs/api.d.ts +544 -0
- package/templates/react-spring-antd/docs/openapi.json +461 -0
- package/templates/react-spring-antd/gitignore.template +19 -0
- package/templates/react-spring-antd/licenses/fastapi.txt +21 -0
- package/templates/react-spring-antd/licenses/nest.txt +22 -0
- package/templates/react-spring-antd/licenses/next.txt +21 -0
- package/templates/react-spring-antd/licenses/shadcn.txt +21 -0
- package/templates/react-spring-antd/licenses/sources.json +27 -0
- package/templates/react-spring-antd/licenses/spring.txt +202 -0
- package/templates/react-spring-antd/package-lock.json +494 -0
- package/templates/react-spring-antd/package.json +26 -0
- package/templates/react-spring-antd/playwright.config.ts +3 -0
- package/templates/react-spring-antd/project.json +8 -0
- package/templates/react-spring-antd/scripts/api-check.mjs +18 -0
- package/templates/react-spring-antd/scripts/api-contract.mjs +46 -0
- package/templates/react-spring-antd/scripts/design-coverage.mjs +20 -0
- package/templates/react-spring-antd/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-spring-antd/scripts/design-verify.mjs +154 -0
- package/templates/react-spring-antd/scripts/design.mjs +108 -0
- package/templates/react-spring-antd/scripts/project.mjs +120 -0
- package/templates/react-spring-antd/tests/contract-client.ts +20 -0
- package/templates/react-spring-antd/tests/contract.spec.ts +49 -0
- package/templates/react-spring-antd/tests/design/harness.tsx +63 -0
- package/templates/react-spring-antd/tests/ui.spec.ts +61 -0
- package/templates/react-spring-antd/web/eslint.config.mjs +3 -0
- package/templates/react-spring-antd/web/index.html +1 -0
- package/templates/react-spring-antd/web/package.json +28 -0
- package/templates/react-spring-antd/web/pnpm-lock.yaml +2215 -0
- package/templates/react-spring-antd/web/src/App.tsx +29 -0
- package/templates/react-spring-antd/web/src/design-layout.css +7 -0
- package/templates/react-spring-antd/web/src/design-runtime.json +511 -0
- package/templates/react-spring-antd/web/src/design-tokens.css +168 -0
- package/templates/react-spring-antd/web/src/design-widgets.css +31 -0
- package/templates/react-spring-antd/web/src/main.tsx +6 -0
- package/templates/react-spring-antd/web/src/structure-view.tsx +16 -0
- package/templates/react-spring-antd/web/src/styles.css +3 -0
- package/templates/react-spring-antd/web/src/ui.tsx +30 -0
- package/templates/react-spring-antd/web/src/widget-icon.tsx +5 -0
- package/templates/react-spring-antd/web/src/widget-types.ts +13 -0
- package/templates/react-spring-antd/web/src/workspace-model.ts +85 -0
- package/templates/react-spring-antd/web/tsconfig.json +22 -0
- package/templates/react-spring-antd/web/vite.config.ts +3 -0
- package/templates/react-spring-shadcn/.agents/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-shadcn/.agents/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-shadcn/.claude/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-shadcn/.claude/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-shadcn/.dockerignore +18 -0
- package/templates/react-spring-shadcn/.env.example +13 -0
- package/templates/react-spring-shadcn/.grok/skills/design-contract/SKILL.md +23 -0
- package/templates/react-spring-shadcn/.grok/skills/project-work/SKILL.md +10 -0
- package/templates/react-spring-shadcn/.scaffold-checks.json +7 -0
- package/templates/react-spring-shadcn/AGENTS.md +11 -0
- package/templates/react-spring-shadcn/CLAUDE.md +1 -0
- package/templates/react-spring-shadcn/DESIGN.md +208 -0
- package/templates/react-spring-shadcn/LICENSE +21 -0
- package/templates/react-spring-shadcn/README.md +64 -0
- package/templates/react-spring-shadcn/THIRD_PARTY_NOTICES.md +18 -0
- package/templates/react-spring-shadcn/backend/.mvn/wrapper/maven-wrapper.properties +3 -0
- package/templates/react-spring-shadcn/backend/Dockerfile +11 -0
- package/templates/react-spring-shadcn/backend/mvnw +295 -0
- package/templates/react-spring-shadcn/backend/pom.xml +15 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Api.java +38 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/AppUser.java +11 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Application.java +7 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Errors.java +13 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/PersonalRecord.java +15 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Records.java +14 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Security.java +28 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Seed.java +13 -0
- package/templates/react-spring-shadcn/backend/src/main/java/dev/scaffold/app/Users.java +5 -0
- package/templates/react-spring-shadcn/backend/src/main/resources/application.properties +17 -0
- package/templates/react-spring-shadcn/backend/src/main/resources/db/migration/V1__initial.sql +3 -0
- package/templates/react-spring-shadcn/backend/src/main/resources/openapi.json +461 -0
- package/templates/react-spring-shadcn/backend/src/test/java/dev/scaffold/app/ApiTest.java +28 -0
- package/templates/react-spring-shadcn/backend/src/test/java/dev/scaffold/app/SessionExpiryTest.java +37 -0
- package/templates/react-spring-shadcn/compose.yaml +18 -0
- package/templates/react-spring-shadcn/design/guide.md +61 -0
- package/templates/react-spring-shadcn/design/layout.css +6 -0
- package/templates/react-spring-shadcn/design/structure.json +107 -0
- package/templates/react-spring-shadcn/design/tokens.json +171 -0
- package/templates/react-spring-shadcn/design/widgets.css +30 -0
- package/templates/react-spring-shadcn/design/widgets.json +233 -0
- package/templates/react-spring-shadcn/docs/PROJECT.md +32 -0
- package/templates/react-spring-shadcn/docs/api.d.ts +544 -0
- package/templates/react-spring-shadcn/docs/openapi.json +461 -0
- package/templates/react-spring-shadcn/gitignore.template +19 -0
- package/templates/react-spring-shadcn/licenses/fastapi.txt +21 -0
- package/templates/react-spring-shadcn/licenses/nest.txt +22 -0
- package/templates/react-spring-shadcn/licenses/next.txt +21 -0
- package/templates/react-spring-shadcn/licenses/shadcn.txt +21 -0
- package/templates/react-spring-shadcn/licenses/sources.json +27 -0
- package/templates/react-spring-shadcn/licenses/spring.txt +202 -0
- package/templates/react-spring-shadcn/package-lock.json +494 -0
- package/templates/react-spring-shadcn/package.json +26 -0
- package/templates/react-spring-shadcn/playwright.config.ts +3 -0
- package/templates/react-spring-shadcn/project.json +8 -0
- package/templates/react-spring-shadcn/scripts/api-check.mjs +18 -0
- package/templates/react-spring-shadcn/scripts/api-contract.mjs +46 -0
- package/templates/react-spring-shadcn/scripts/design-coverage.mjs +20 -0
- package/templates/react-spring-shadcn/scripts/design-next-cleanup.mjs +13 -0
- package/templates/react-spring-shadcn/scripts/design-verify.mjs +154 -0
- package/templates/react-spring-shadcn/scripts/design.mjs +108 -0
- package/templates/react-spring-shadcn/scripts/project.mjs +120 -0
- package/templates/react-spring-shadcn/tests/contract-client.ts +20 -0
- package/templates/react-spring-shadcn/tests/contract.spec.ts +49 -0
- package/templates/react-spring-shadcn/tests/design/harness.tsx +63 -0
- package/templates/react-spring-shadcn/tests/ui.spec.ts +61 -0
- package/templates/react-spring-shadcn/web/eslint.config.mjs +3 -0
- package/templates/react-spring-shadcn/web/index.html +1 -0
- package/templates/react-spring-shadcn/web/package.json +33 -0
- package/templates/react-spring-shadcn/web/pnpm-lock.yaml +1788 -0
- package/templates/react-spring-shadcn/web/src/App.tsx +30 -0
- package/templates/react-spring-shadcn/web/src/design-layout.css +7 -0
- package/templates/react-spring-shadcn/web/src/design-runtime.json +511 -0
- package/templates/react-spring-shadcn/web/src/design-tokens.css +168 -0
- package/templates/react-spring-shadcn/web/src/design-widgets.css +31 -0
- package/templates/react-spring-shadcn/web/src/main.tsx +6 -0
- package/templates/react-spring-shadcn/web/src/structure-view.tsx +16 -0
- package/templates/react-spring-shadcn/web/src/styles.css +3 -0
- package/templates/react-spring-shadcn/web/src/tailwind.css +2 -0
- package/templates/react-spring-shadcn/web/src/ui.tsx +13 -0
- package/templates/react-spring-shadcn/web/src/widget-icon.tsx +5 -0
- package/templates/react-spring-shadcn/web/src/widget-types.ts +13 -0
- package/templates/react-spring-shadcn/web/src/workspace-model.ts +85 -0
- package/templates/react-spring-shadcn/web/tsconfig.json +22 -0
- package/templates/react-spring-shadcn/web/vite.config.ts +4 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/* Generated by design:sync. Edit design/tokens.json or design/widgets.json. */
|
|
2
|
+
:root {
|
|
3
|
+
--design-colors-primary: #8fc3ff;
|
|
4
|
+
--design-colors-primary-hover: #b5d8ff;
|
|
5
|
+
--design-colors-primary-active: #69a9f3;
|
|
6
|
+
--design-colors-primary-text: #02040a;
|
|
7
|
+
--design-colors-background: #02040a;
|
|
8
|
+
--design-colors-text: #f4f8ff;
|
|
9
|
+
--design-colors-surface: #0b111d;
|
|
10
|
+
--design-colors-focus: #8fc3ff;
|
|
11
|
+
--design-colors-border: #283547;
|
|
12
|
+
--design-colors-brand: #f4f8ff;
|
|
13
|
+
--design-colors-eyebrow: #9baecb;
|
|
14
|
+
--design-colors-muted: #a1afc3;
|
|
15
|
+
--design-colors-intro: #b5c3d7;
|
|
16
|
+
--design-colors-panel-border: #283547;
|
|
17
|
+
--design-colors-divider: #202c3e;
|
|
18
|
+
--design-colors-record-text: #f4f8ff;
|
|
19
|
+
--design-colors-record-meta: #a1afc3;
|
|
20
|
+
--design-colors-record-hover: #142237;
|
|
21
|
+
--design-colors-pagination-border: #283547;
|
|
22
|
+
--design-colors-empty: #a1afc3;
|
|
23
|
+
--design-colors-empty-heading: #e2eeff;
|
|
24
|
+
--design-colors-success-background: #102b25;
|
|
25
|
+
--design-colors-success-border: #387c69;
|
|
26
|
+
--design-colors-success-text: #a2e6cc;
|
|
27
|
+
--design-colors-error-background: #311b24;
|
|
28
|
+
--design-colors-error-border: #8f4c61;
|
|
29
|
+
--design-colors-error-text: #ffbdcd;
|
|
30
|
+
--design-colors-footer-border: #283547;
|
|
31
|
+
--design-colors-footer-text: #a1afc3;
|
|
32
|
+
--design-colors-badge-border: #435773;
|
|
33
|
+
--design-colors-badge-text: #b5c3d7;
|
|
34
|
+
--design-colors-control-focus: #8fc3ff;
|
|
35
|
+
--design-colors-control-border: #657891;
|
|
36
|
+
--design-colors-control-background: #080e18;
|
|
37
|
+
--design-colors-secondary-border: #657891;
|
|
38
|
+
--design-colors-secondary-text: #e2eeff;
|
|
39
|
+
--design-colors-secondary-hover: #19283d;
|
|
40
|
+
--design-colors-danger-border: #ad6578;
|
|
41
|
+
--design-colors-danger-background: #311b24;
|
|
42
|
+
--design-colors-danger-text: #ffbdcd;
|
|
43
|
+
--design-colors-danger-hover: #472636;
|
|
44
|
+
--design-typography-body-font-family: Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
|
|
45
|
+
--design-typography-body-font-size: 16px;
|
|
46
|
+
--design-typography-body-line-height: 1.65;
|
|
47
|
+
--design-typography-h1-font-size: 36px;
|
|
48
|
+
--design-typography-h1-line-height: 1.2;
|
|
49
|
+
--design-typography-h1-letter-spacing: -0.03em;
|
|
50
|
+
--design-typography-h1-font-weight: 560;
|
|
51
|
+
--design-typography-login-heading-font-size: 48px;
|
|
52
|
+
--design-typography-login-heading-line-height: 1.15;
|
|
53
|
+
--design-typography-login-heading-font-weight: 560;
|
|
54
|
+
--design-typography-login-heading-letter-spacing: -0.03em;
|
|
55
|
+
--design-typography-h2-font-size: 20px;
|
|
56
|
+
--design-typography-h2-line-height: 1.4;
|
|
57
|
+
--design-typography-h2-font-weight: 580;
|
|
58
|
+
--design-typography-h2-letter-spacing: -0.02em;
|
|
59
|
+
--design-typography-h3-font-size: 18px;
|
|
60
|
+
--design-typography-h3-font-weight: 600;
|
|
61
|
+
--design-typography-h3-line-height: 1.5;
|
|
62
|
+
--design-typography-label-font-size: 14px;
|
|
63
|
+
--design-typography-label-font-weight: 600;
|
|
64
|
+
--design-typography-eyebrow-font-size: 11px;
|
|
65
|
+
--design-typography-eyebrow-font-weight: 700;
|
|
66
|
+
--design-typography-eyebrow-letter-spacing: 0.22em;
|
|
67
|
+
--design-typography-eyebrow-line-height: 1.5;
|
|
68
|
+
--design-typography-button-font-size: 14px;
|
|
69
|
+
--design-typography-button-font-weight: 600;
|
|
70
|
+
--design-typography-button-line-height: 20px;
|
|
71
|
+
--design-typography-caption-font-size: 12px;
|
|
72
|
+
--design-typography-intro-font-size: 18px;
|
|
73
|
+
--design-typography-intro-line-height: 1.8;
|
|
74
|
+
--design-typography-mobile-heading-font-size: 32px;
|
|
75
|
+
--design-typography-mobile-heading-line-height: 1.2;
|
|
76
|
+
--design-typography-mobile-page-heading-font-size: 28px;
|
|
77
|
+
--design-typography-mobile-page-heading-line-height: 1.25;
|
|
78
|
+
--design-rounded-md: 0px;
|
|
79
|
+
--design-rounded-panel: 0px;
|
|
80
|
+
--design-rounded-full: 0px;
|
|
81
|
+
--design-spacing-s0: 0px;
|
|
82
|
+
--design-spacing-s1: 1px;
|
|
83
|
+
--design-spacing-s2: 2px;
|
|
84
|
+
--design-spacing-s3: 3px;
|
|
85
|
+
--design-spacing-s4: 4px;
|
|
86
|
+
--design-spacing-s6: 6px;
|
|
87
|
+
--design-spacing-s8: 8px;
|
|
88
|
+
--design-spacing-s10: 10px;
|
|
89
|
+
--design-spacing-s12: 12px;
|
|
90
|
+
--design-spacing-s14: 14px;
|
|
91
|
+
--design-spacing-s15: 15px;
|
|
92
|
+
--design-spacing-s16: 16px;
|
|
93
|
+
--design-spacing-s18: 18px;
|
|
94
|
+
--design-spacing-s20: 20px;
|
|
95
|
+
--design-spacing-s22: 22px;
|
|
96
|
+
--design-spacing-s24: 24px;
|
|
97
|
+
--design-spacing-s26: 26px;
|
|
98
|
+
--design-spacing-s28: 28px;
|
|
99
|
+
--design-spacing-s30: 30px;
|
|
100
|
+
--design-spacing-s32: 32px;
|
|
101
|
+
--design-spacing-s34: 34px;
|
|
102
|
+
--design-spacing-s38: 38px;
|
|
103
|
+
--design-spacing-s44: 44px;
|
|
104
|
+
--design-spacing-s48: 48px;
|
|
105
|
+
--design-spacing-s60: 60px;
|
|
106
|
+
--design-spacing-s80: 80px;
|
|
107
|
+
--design-spacing-s88: 88px;
|
|
108
|
+
--design-spacing-shell-max: 1240px;
|
|
109
|
+
--design-spacing-login-max: 1020px;
|
|
110
|
+
--design-spacing-intro-max: 460px;
|
|
111
|
+
--design-spacing-login-card-max: 430px;
|
|
112
|
+
--design-spacing-list-min: 260px;
|
|
113
|
+
--design-spacing-footer-reserve: 155px;
|
|
114
|
+
--design-spacing-mobile-breakpoint: 760px;
|
|
115
|
+
--design-spacing-control-min: 44px;
|
|
116
|
+
--design-components-button-primary-background-color: #8fc3ff;
|
|
117
|
+
--design-components-button-primary-text-color: #02040a;
|
|
118
|
+
--design-components-button-primary-rounded: 0px;
|
|
119
|
+
--design-components-button-primary-height: 44px;
|
|
120
|
+
--design-components-panel-background-color: #0b111d;
|
|
121
|
+
--design-components-panel-padding: 26px;
|
|
122
|
+
--design-components-panel-rounded: 0px;
|
|
123
|
+
--design-components-input-rounded: 0px;
|
|
124
|
+
--design-effects-panel-shadow: 0 16px 48px rgba(0,0,0,0.18);
|
|
125
|
+
--design-widgets-button-height: 44px;
|
|
126
|
+
--design-widgets-button-padding-x: 16px;
|
|
127
|
+
--design-widgets-button-padding-y: 8px;
|
|
128
|
+
--design-widgets-button-border-width: 1px;
|
|
129
|
+
--design-widgets-button-font-size: 14px;
|
|
130
|
+
--design-widgets-button-font-weight: 600;
|
|
131
|
+
--design-widgets-button-line-height: 20px;
|
|
132
|
+
--design-widgets-button-radius: 0px;
|
|
133
|
+
--design-widgets-input-height: 44px;
|
|
134
|
+
--design-widgets-input-padding-x: 12px;
|
|
135
|
+
--design-widgets-input-padding-y: 8px;
|
|
136
|
+
--design-widgets-input-border-width: 1px;
|
|
137
|
+
--design-widgets-input-font-size: 16px;
|
|
138
|
+
--design-widgets-input-line-height: 24px;
|
|
139
|
+
--design-widgets-input-radius: 0px;
|
|
140
|
+
--design-widgets-textarea-padding-x: 12px;
|
|
141
|
+
--design-widgets-textarea-padding-y: 8px;
|
|
142
|
+
--design-widgets-textarea-border-width: 1px;
|
|
143
|
+
--design-widgets-textarea-font-size: 16px;
|
|
144
|
+
--design-widgets-textarea-line-height: 24px;
|
|
145
|
+
--design-widgets-textarea-radius: 0px;
|
|
146
|
+
--design-widgets-alert-padding-x: 16px;
|
|
147
|
+
--design-widgets-alert-padding-y: 12px;
|
|
148
|
+
--design-widgets-alert-gap: 8px;
|
|
149
|
+
--design-widgets-alert-icon-size: 16px;
|
|
150
|
+
--design-widgets-alert-font-size: 14px;
|
|
151
|
+
--design-widgets-alert-line-height: 22px;
|
|
152
|
+
--design-widgets-alert-border-width: 1px;
|
|
153
|
+
--design-widgets-alert-radius: 0px;
|
|
154
|
+
--design-widgets-badge-padding-x: 10px;
|
|
155
|
+
--design-widgets-badge-padding-y: 3px;
|
|
156
|
+
--design-widgets-badge-font-size: 12px;
|
|
157
|
+
--design-widgets-badge-line-height: 18px;
|
|
158
|
+
--design-widgets-badge-border-width: 1px;
|
|
159
|
+
--design-widgets-badge-radius: 0px;
|
|
160
|
+
--design-widgets-panel-padding: 26px;
|
|
161
|
+
--design-widgets-panel-border-width: 1px;
|
|
162
|
+
--design-widgets-panel-radius: 0px;
|
|
163
|
+
--design-widgets-field-gap: 8px;
|
|
164
|
+
--design-widgets-field-margin-y: 22px;
|
|
165
|
+
--design-widgets-field-font-size: 14px;
|
|
166
|
+
--design-widgets-field-font-weight: 600;
|
|
167
|
+
--design-widgets-field-line-height: 22px;
|
|
168
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* Generated by design:sync. Edit design/widgets.css. */
|
|
2
|
+
/* These semantic hooks belong to the widget contract, never to a library. */
|
|
3
|
+
[data-widget]{box-sizing:border-box!important;font-family:var(--design-typography-body-font-family)!important;letter-spacing:normal!important;text-transform:none!important;box-shadow:none!important}
|
|
4
|
+
[data-widget="button"]{display:inline-flex!important;align-items:center!important;justify-content:center!important;gap:8px!important;vertical-align:middle!important;position:relative!important;min-width:0!important;height:var(--design-widgets-button-height)!important;min-height:var(--design-widgets-button-height)!important;padding:var(--design-widgets-button-padding-y) var(--design-widgets-button-padding-x)!important;margin:0!important;border:var(--design-widgets-button-border-width) solid transparent!important;border-radius:var(--design-widgets-button-radius)!important;font-size:var(--design-widgets-button-font-size)!important;font-weight:var(--design-widgets-button-font-weight)!important;line-height:var(--design-widgets-button-line-height)!important;cursor:pointer!important;text-align:center!important;white-space:nowrap!important;transition:background-color 180ms,border-color 180ms,color 180ms!important}
|
|
5
|
+
[data-widget="button"] [data-part="label"]{display:inline!important;margin:0!important;padding:0!important;font:inherit!important;line-height:inherit!important;color:inherit!important}
|
|
6
|
+
[data-widget="button"][data-variant="primary"]{background:var(--design-colors-primary)!important;color:var(--design-colors-primary-text)!important}
|
|
7
|
+
[data-widget="button"][data-variant="primary"]:hover{background:var(--design-colors-primary-hover)!important}
|
|
8
|
+
[data-widget="button"][data-variant="primary"]:active{background:var(--design-colors-primary-active)!important}
|
|
9
|
+
[data-widget="button"][data-variant="secondary"]{background:var(--design-colors-control-background)!important;color:var(--design-colors-secondary-text)!important;border-color:var(--design-colors-secondary-border)!important}
|
|
10
|
+
[data-widget="button"][data-variant="secondary"]:hover,[data-widget="button"][data-variant="secondary"]:active{background:var(--design-colors-secondary-hover)!important}
|
|
11
|
+
[data-widget="button"][data-variant="danger"]{background:var(--design-colors-danger-background)!important;color:var(--design-colors-danger-text)!important;border-color:var(--design-colors-danger-border)!important}
|
|
12
|
+
[data-widget="button"][data-variant="danger"]:hover,[data-widget="button"][data-variant="danger"]:active{background:var(--design-colors-danger-hover)!important}
|
|
13
|
+
[data-widget="button"]:disabled{opacity:.5!important;cursor:not-allowed!important;pointer-events:none!important}
|
|
14
|
+
[data-widget="input"],[data-widget="textarea"]{display:block!important;width:100%!important;min-width:0!important;margin:0!important;padding:var(--design-widgets-input-padding-y) var(--design-widgets-input-padding-x)!important;border:var(--design-widgets-input-border-width) solid var(--design-colors-control-border)!important;border-radius:var(--design-widgets-input-radius)!important;background:var(--design-colors-control-background)!important;color:var(--design-colors-text)!important;font-size:var(--design-widgets-input-font-size)!important;font-weight:400!important;line-height:var(--design-widgets-input-line-height)!important;outline:none!important;transition:border-color 180ms!important}
|
|
15
|
+
[data-widget="input"]{height:var(--design-widgets-input-height)!important;min-height:var(--design-widgets-input-height)!important}
|
|
16
|
+
[data-widget="textarea"]{padding:var(--design-widgets-textarea-padding-y) var(--design-widgets-textarea-padding-x)!important;border-width:var(--design-widgets-textarea-border-width)!important;border-radius:var(--design-widgets-textarea-radius)!important;font-size:var(--design-widgets-textarea-font-size)!important;line-height:var(--design-widgets-textarea-line-height)!important;resize:vertical!important;min-height:0!important}
|
|
17
|
+
[data-widget="input"]::placeholder,[data-widget="textarea"]::placeholder{color:var(--design-colors-muted)!important;opacity:1!important}
|
|
18
|
+
[data-widget="input"]:hover,[data-widget="textarea"]:hover{border-color:var(--design-colors-control-focus)!important}
|
|
19
|
+
[data-widget="input"][aria-invalid="true"],[data-widget="textarea"][aria-invalid="true"]{border-color:var(--design-colors-error-border)!important}
|
|
20
|
+
[data-widget="input"]:disabled,[data-widget="textarea"]:disabled{opacity:.5!important;cursor:not-allowed!important}
|
|
21
|
+
[data-widget="button"]:focus-visible,[data-widget="input"]:focus,[data-widget="textarea"]:focus{outline:2px solid var(--design-colors-control-focus)!important;outline-offset:2px!important}
|
|
22
|
+
[data-widget="alert"]{display:flex!important;align-items:flex-start!important;gap:var(--design-widgets-alert-gap)!important;margin:16px 0!important;padding:var(--design-widgets-alert-padding-y) var(--design-widgets-alert-padding-x)!important;border:var(--design-widgets-alert-border-width) solid var(--design-colors-error-border)!important;border-radius:var(--design-widgets-alert-radius)!important;background:var(--design-colors-error-background)!important;color:var(--design-colors-error-text)!important;font-size:var(--design-widgets-alert-font-size)!important;font-weight:400!important;line-height:var(--design-widgets-alert-line-height)!important}
|
|
23
|
+
[data-widget="alert"][data-variant="success"]{background:var(--design-colors-success-background)!important;color:var(--design-colors-success-text)!important;border-color:var(--design-colors-success-border)!important}
|
|
24
|
+
[data-widget="alert"] [data-part="icon"]{display:block!important;width:var(--design-widgets-alert-icon-size)!important;height:var(--design-widgets-alert-icon-size)!important;flex:none!important;margin:3px 0 0!important;color:inherit!important}
|
|
25
|
+
[data-widget="alert"] [data-part="message"]{display:block!important;margin:0!important;padding:0!important;font:inherit!important;line-height:inherit!important;color:inherit!important;overflow-wrap:anywhere}
|
|
26
|
+
[data-widget="badge"]{display:inline-flex!important;align-items:center!important;vertical-align:middle!important;white-space:nowrap!important;margin:0!important;padding:var(--design-widgets-badge-padding-y) var(--design-widgets-badge-padding-x)!important;border:var(--design-widgets-badge-border-width) solid var(--design-colors-badge-border)!important;border-radius:var(--design-widgets-badge-radius)!important;background:transparent!important;color:var(--design-colors-badge-text)!important;font-size:var(--design-widgets-badge-font-size)!important;font-weight:400!important;line-height:var(--design-widgets-badge-line-height)!important}
|
|
27
|
+
[data-widget="panel"]{background:var(--design-colors-surface)!important;border:var(--design-widgets-panel-border-width) solid var(--design-colors-panel-border)!important;border-radius:var(--design-widgets-panel-radius)!important;padding:var(--design-widgets-panel-padding)!important;box-shadow:var(--design-effects-panel-shadow)!important}
|
|
28
|
+
[data-widget="field"]{display:flex!important;flex-direction:column!important;gap:var(--design-widgets-field-gap)!important;margin:var(--design-widgets-field-margin-y) 0!important}
|
|
29
|
+
[data-widget="field"]>[data-part="label"]{font-size:var(--design-widgets-field-font-size)!important;font-weight:var(--design-widgets-field-font-weight)!important;line-height:var(--design-widgets-field-line-height)!important}
|
|
30
|
+
@media(max-width:760px){[data-widget="panel"]{padding:var(--design-spacing-s20)!important}}
|
|
31
|
+
@media(prefers-reduced-motion:reduce){[data-widget]{transition-duration:0.01ms!important}}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {createRoot} from 'react-dom/client';
|
|
3
|
+
import App from './App';
|
|
4
|
+
import project from '../../project.json';
|
|
5
|
+
document.title=project.nameZh;
|
|
6
|
+
createRoot(document.getElementById('root')!).render(<React.StrictMode><App/></React.StrictMode>);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {createElement,Fragment,type ReactNode} from 'react';
|
|
2
|
+
import design from './design-runtime.json';
|
|
3
|
+
import type {WidgetSet} from './widget-types';
|
|
4
|
+
type Node={element:string;region:string;slot?:string;children?:Node[]};
|
|
5
|
+
export function Structure({name,slots,widgets}:{widgets:WidgetSet;name:'root'|'checking'|'login'|'workspace';slots:Record<string,ReactNode>}) {
|
|
6
|
+
const {Panel}=widgets;
|
|
7
|
+
const node:Node=name==='root'?design.structure.root:design.structure.pages[name];
|
|
8
|
+
function render(item:Node):ReactNode {
|
|
9
|
+
const children=item.slot?slots[item.slot]:item.children?.map(render);
|
|
10
|
+
if(item.element==='slot')return <Fragment key={item.region}>{children}</Fragment>;
|
|
11
|
+
if(item.slot&&children==null)return null;
|
|
12
|
+
const props={className:item.region,'data-region':item.region,...(item.element==='a'?{href:'/'}:{})};
|
|
13
|
+
return item.element==='panel'?<Panel key={item.region} {...props}>{children}</Panel>:createElement(item.element,{key:item.region,...props},children);
|
|
14
|
+
}
|
|
15
|
+
return render(node);
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import {cva} from 'class-variance-authority';
|
|
3
|
+
import {WidgetIcon} from './widget-icon';
|
|
4
|
+
import type {AlertProps,ButtonProps,FieldProps,InputProps,PanelProps,TextAreaProps} from './widget-types';
|
|
5
|
+
const button=cva('inline-flex items-center justify-center');
|
|
6
|
+
export function Button({children,variant='primary',loading=false,disabled,className,type='button',...props}:ButtonProps){return <button {...props} type={type} data-widget="button" data-variant={variant} aria-busy={loading||undefined} disabled={disabled||loading} className={button({className})}><span data-part="label">{children}</span></button>;}
|
|
7
|
+
export function Input({invalid,...props}:InputProps){return <input {...props} data-widget="input" aria-invalid={invalid||undefined}/>;}
|
|
8
|
+
export function TextArea({invalid,...props}:TextAreaProps){return <textarea {...props} data-widget="textarea" aria-invalid={invalid||undefined}/>;}
|
|
9
|
+
export function Panel({children,className='',...props}:PanelProps){return <section {...props} data-widget="panel" className={`panel ${className}`}>{children}</section>;}
|
|
10
|
+
export function Field({children,label,htmlFor}:FieldProps){return <div data-widget="field" className="field"><label data-part="label" htmlFor={htmlFor}>{label}</label><div data-part="control">{children}</div></div>;}
|
|
11
|
+
export function Alert({children,variant='error'}:AlertProps){return <div data-widget="alert" data-variant={variant} role={variant==='error'?'alert':'status'}><WidgetIcon kind={variant}/><div data-part="message">{children}</div></div>;}
|
|
12
|
+
export function Badge({children}:{children:React.ReactNode}){return <span data-widget="badge" className="badge"><span data-part="label">{children}</span></span>;}
|
|
13
|
+
export function Theme({children}:{children:React.ReactNode}){return <>{children}</>;}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import design from './design-runtime.json';
|
|
2
|
+
export function WidgetIcon({kind}:{kind:'error'|'success'}) {
|
|
3
|
+
const icon=design.widgets.icons[kind];
|
|
4
|
+
return <svg data-part="icon" aria-hidden="true" viewBox={icon.viewBox} fill="none" stroke="currentColor" strokeWidth={icon.strokeWidth} strokeLinecap="round" strokeLinejoin="round">{icon.paths.map((path,index)=><path key={index} d={path}/>)}</svg>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export type ButtonProps=Omit<React.ButtonHTMLAttributes<HTMLButtonElement>,'color'>&{variant?:'primary'|'secondary'|'danger';loading?:boolean};
|
|
3
|
+
export type InputProps=Omit<React.InputHTMLAttributes<HTMLInputElement>,'size'>&{invalid?:boolean};
|
|
4
|
+
export type TextAreaProps=React.TextareaHTMLAttributes<HTMLTextAreaElement>&{invalid?:boolean};
|
|
5
|
+
export type AlertProps={children:React.ReactNode;variant?:'error'|'success'};
|
|
6
|
+
export type PanelProps=React.HTMLAttributes<HTMLElement>;
|
|
7
|
+
export type FieldProps={children:React.ReactNode;label:string;htmlFor:string};
|
|
8
|
+
|
|
9
|
+
export type WidgetSet={
|
|
10
|
+
Button:React.ComponentType<ButtonProps>;Input:React.ComponentType<InputProps>;TextArea:React.ComponentType<TextAreaProps>;
|
|
11
|
+
Alert:React.ComponentType<AlertProps>;Panel:React.ComponentType<PanelProps>;Field:React.ComponentType<FieldProps>;
|
|
12
|
+
Badge:React.ComponentType<{children:React.ReactNode}>;Theme:React.ComponentType<{children:React.ReactNode}>;
|
|
13
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type User={id:string;email:string};
|
|
2
|
+
export type RecordItem={id:string;title:string;content:string;created_at:string;updated_at:string};
|
|
3
|
+
export type RecordPage={items:RecordItem[];total:number;page:number;pageSize:number};
|
|
4
|
+
export type WorkspaceState={user:User|null;checking:boolean;email:string;password:string;list:RecordPage;page:number;selected:string|null;title:string;content:string;editing:boolean;busy:boolean;loading:boolean;error:string;notice:string};
|
|
5
|
+
const emptyList=():RecordPage=>({items:[],total:0,page:1,pageSize:10});
|
|
6
|
+
export const initialWorkspaceState=():WorkspaceState=>({user:null,checking:true,email:'',password:'',list:emptyList(),page:1,selected:null,title:'',content:'',editing:false,busy:false,loading:false,error:'',notice:''});
|
|
7
|
+
class StaleRequest extends Error {}
|
|
8
|
+
class ApiError extends Error {constructor(message:string,public status:number){super(message);}}
|
|
9
|
+
export function validateRecord(title:string,content:string):string {
|
|
10
|
+
const length=Array.from(title.trim()).length;
|
|
11
|
+
if(length<1||length>120)return '标题需为 1–120 个字符。';
|
|
12
|
+
if(Array.from(content).length>10000)return '正文最多 10,000 个字符。';
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
/** Framework-neutral business model. Views subscribe and forward user intent. */
|
|
16
|
+
export function createWorkspaceModel(request:typeof fetch=fetch) {
|
|
17
|
+
let state=initialWorkspaceState(),token:string|null=null;
|
|
18
|
+
let identityEpoch=0,refreshSequence=0,busySequence=0,lifecycle=0;
|
|
19
|
+
const requests=new Set<AbortController>(),listeners=new Set<()=>void>();
|
|
20
|
+
const patch=(value:Partial<WorkspaceState>)=>{state={...state,...value};for(const listener of listeners)listener();};
|
|
21
|
+
function cancelRequests(){for(const controller of requests)controller.abort();requests.clear();}
|
|
22
|
+
function clearIdentity(){
|
|
23
|
+
identityEpoch++;refreshSequence++;busySequence++;cancelRequests();token=null;
|
|
24
|
+
patch({user:null,list:emptyList(),page:1,selected:null,title:'',content:'',editing:false,notice:'',error:'',password:'',busy:false,loading:false});
|
|
25
|
+
}
|
|
26
|
+
async function api<T>(path:string,method='GET',body?:unknown):Promise<T> {
|
|
27
|
+
const epoch=identityEpoch,controller=new AbortController();requests.add(controller);
|
|
28
|
+
const timer=setTimeout(()=>controller.abort(),15000);
|
|
29
|
+
try{
|
|
30
|
+
const response=await request(`/api${path}`,{method,credentials:'same-origin',headers:{...(body===undefined?{}:{'Content-Type':'application/json'}),...(token?{Authorization:`Bearer ${token}`}:{})},...(body===undefined?{}:{body:JSON.stringify(body)}),signal:controller.signal});
|
|
31
|
+
if(epoch!==identityEpoch)throw new StaleRequest();
|
|
32
|
+
if(response.status===204)return undefined as T;
|
|
33
|
+
const data=await response.json();
|
|
34
|
+
if(epoch!==identityEpoch)throw new StaleRequest();
|
|
35
|
+
if(!response.ok){if(response.status===401)clearIdentity();throw new ApiError(data.error?.message||'请求失败,请检查输入后重试。',response.status);}
|
|
36
|
+
return data as T;
|
|
37
|
+
}catch(error){
|
|
38
|
+
if(error instanceof ApiError||error instanceof StaleRequest)throw error;
|
|
39
|
+
if(epoch!==identityEpoch)throw new StaleRequest();
|
|
40
|
+
throw new Error('请求失败或超时,输入已保留。请先查看记录,确认结果后再操作。',{cause:error});
|
|
41
|
+
}finally{clearTimeout(timer);requests.delete(controller);}
|
|
42
|
+
}
|
|
43
|
+
const report=(error:unknown)=>{if(!(error instanceof StaleRequest))patch({error:(error as Error).message});};
|
|
44
|
+
function busy(){const sequence=++busySequence;patch({busy:true,error:''});return ()=>{if(sequence===busySequence)patch({busy:false});};}
|
|
45
|
+
async function refresh(){
|
|
46
|
+
const sequence=++refreshSequence;patch({loading:true});
|
|
47
|
+
try{const list=await api<RecordPage>(`/records?page=${state.page}&pageSize=10`);if(sequence===refreshSequence)patch({list});}
|
|
48
|
+
catch(error){if(sequence===refreshSequence)report(error);}
|
|
49
|
+
finally{if(sequence===refreshSequence)patch({loading:false});}
|
|
50
|
+
}
|
|
51
|
+
async function start(){
|
|
52
|
+
const current=++lifecycle;patch({checking:true});
|
|
53
|
+
try{const data=await api<{user:User}>('/auth/me');if(current===lifecycle){patch({user:data.user});await refresh();}}
|
|
54
|
+
catch(error){if(current===lifecycle&&!(error instanceof ApiError&&error.status===401))report(error);}
|
|
55
|
+
finally{if(current===lifecycle)patch({checking:false});}
|
|
56
|
+
}
|
|
57
|
+
function stop(){lifecycle++;identityEpoch++;refreshSequence++;busySequence++;cancelRequests();}
|
|
58
|
+
async function login(){
|
|
59
|
+
const done=busy();
|
|
60
|
+
try{const data=await api<{user:User;token?:string}>('/auth/login','POST',{email:state.email,password:state.password});clearIdentity();token=data.token??null;patch({user:data.user,password:'',notice:''});await refresh();}
|
|
61
|
+
catch(error){report(error);}finally{done();}
|
|
62
|
+
}
|
|
63
|
+
async function logout(){const done=busy();try{await api('/auth/logout','POST',{});clearIdentity();}catch(error){report(error);}finally{done();}}
|
|
64
|
+
function create(){patch({selected:null,title:'',content:'',editing:true,error:'',notice:''});}
|
|
65
|
+
async function open(id:string){
|
|
66
|
+
const done=busy();patch({notice:''});
|
|
67
|
+
try{const data=await api<RecordItem>(`/records/${id}`);patch({selected:data.id,title:data.title,content:data.content,editing:true});}
|
|
68
|
+
catch(error){report(error);}finally{done();}
|
|
69
|
+
}
|
|
70
|
+
async function save(){
|
|
71
|
+
const error=validateRecord(state.title,state.content);patch({error,notice:''});if(error)return;
|
|
72
|
+
const done=busy();
|
|
73
|
+
try{const data=await api<RecordItem>(state.selected?`/records/${state.selected}`:'/records',state.selected?'PUT':'POST',{title:state.title,content:state.content});patch({selected:data.id,title:data.title,content:data.content,notice:'已保存'});await refresh();}
|
|
74
|
+
catch(error){report(error);}finally{done();}
|
|
75
|
+
}
|
|
76
|
+
async function remove(confirmed:boolean){
|
|
77
|
+
if(!state.selected||!confirmed)return;
|
|
78
|
+
const done=busy();patch({notice:''});
|
|
79
|
+
try{await api(`/records/${state.selected}`,'DELETE');patch({editing:false,selected:null,title:'',content:'',notice:'已删除',...(state.page>1&&state.list.items.length===1?{page:state.page-1}:{})});await refresh();}
|
|
80
|
+
catch(error){report(error);}finally{done();}
|
|
81
|
+
}
|
|
82
|
+
async function changePage(page:number){if(page<1||!Number.isInteger(page))return;patch({page});await refresh();}
|
|
83
|
+
return {getSnapshot:()=>state,subscribe:(listener:()=>void)=>{listeners.add(listener);return ()=>{listeners.delete(listener);};},start,stop,login,logout,create,open,save,remove,changePage,setField:(field:'email'|'password'|'title'|'content',value:string)=>patch({[field]:value})};
|
|
84
|
+
}
|
|
85
|
+
export type WorkspaceModel=ReturnType<typeof createWorkspaceModel>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": [
|
|
5
|
+
"ES2022",
|
|
6
|
+
"DOM",
|
|
7
|
+
"DOM.Iterable"
|
|
8
|
+
],
|
|
9
|
+
"module": "ESNext",
|
|
10
|
+
"moduleResolution": "Bundler",
|
|
11
|
+
"jsx": "react-jsx",
|
|
12
|
+
"strict": true,
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"esModuleInterop": true,
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"skipLibCheck": true
|
|
17
|
+
},
|
|
18
|
+
"include": [
|
|
19
|
+
"src",
|
|
20
|
+
"vite.config.ts"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import {defineConfig} from 'vite';
|
|
2
|
+
import react from '@vitejs/plugin-react';
|
|
3
|
+
import tailwind from '@tailwindcss/vite';
|
|
4
|
+
export default defineConfig({plugins:[react(),tailwind()],server:{proxy:{'/api':`http://127.0.0.1:${process.env.PORT||8000}`}},preview:{proxy:{'/api':`http://127.0.0.1:${process.env.PORT||8000}`}}});
|