create-win-project 1.3.0 → 2.0.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 +1 -1
- package/README.md +58 -160
- package/checks/check-compatibility.js +95 -0
- package/{scripts/verify-generated.mjs → checks/check-generated-project.js} +28 -4
- package/{scripts/validate-content.mjs → checks/check-library.js} +17 -7
- package/checks/check-package.js +15 -0
- package/checks/classify-changes.js +29 -0
- package/checks/run-compatibility-shard.js +21 -0
- package/docs/README.md +20 -0
- package/docs/capabilities.md +13 -0
- package/docs/compatibility.md +13 -0
- package/docs/generated-project.md +12 -0
- package/docs/getting-started.md +26 -0
- package/docs/maintainers/architecture.md +161 -0
- package/docs/maintainers/ci-strategy.md +46 -0
- package/docs/{CONTENT_MODEL.md → maintainers/content-model.md} +3 -3
- package/docs/maintainers/contributing.md +154 -0
- package/docs/{DEPENDENCY_MAINTENANCE.md → maintainers/dependencies.md} +1 -1
- package/docs/migration-v2.md +13 -0
- package/docs/production-contract.md +24 -0
- package/index.js +2 -429
- package/{playbooks → library}/INDEX.md +5 -5
- package/library/compatibility-impact.json +14 -0
- package/{playbooks/capabilities/ci/github-actions.manifest.json → library/development-tools/ci/definition.json} +1 -0
- package/library/development-tools/devops/makefile/commands.md +11 -0
- package/library/development-tools/devops/makefile/definition.json +11 -0
- package/library/development-tools/devops/makefile/docker.md +9 -0
- package/library/development-tools/devops/makefile/validation.md +5 -0
- package/{playbooks/devops/pr-template.manifest.json → library/development-tools/devops/pr-template/definition.json} +1 -0
- package/library/features/sqlalchemy-alembic.md +17 -0
- package/library/optional-features/concerns/zod/errors.md +5 -0
- package/library/optional-features/concerns/zod/testing.md +5 -0
- package/library/optional-features/concerns/zod/validation.md +21 -0
- package/library/optional-features/styling/css-modules/definition.json +12 -0
- package/library/optional-features/styling/css-modules/responsive.md +5 -0
- package/library/optional-features/styling/css-modules/theme.md +7 -0
- package/{playbooks/platform/mobile.manifest.json → library/platforms/mobile/definition.json} +1 -0
- package/{playbooks/platform/web.manifest.json → library/platforms/web/definition.json} +1 -0
- package/{playbooks/stack/react-native.manifest.json → library/stacks/expo/definition.json} +2 -2
- package/library/stacks/fastapi/architecture.md +40 -0
- package/library/stacks/fastapi/definition.json +39 -0
- package/library/stacks/fastapi/runtime.md +25 -0
- package/library/stacks/fastapi/security.md +26 -0
- package/library/stacks/fastapi/structure.md +27 -0
- package/library/stacks/fastapi/testing.md +23 -0
- package/{playbooks/stack/nextjs.manifest.json → library/stacks/nextjs/definition.json} +2 -2
- package/{playbooks/stack/no-frontend.manifest.json → library/stacks/no-frontend/definition.json} +1 -1
- package/{playbooks/stack/react-vite.manifest.json → library/stacks/react-vite/definition.json} +2 -2
- package/{compatibility/profiles.json → library/tested-versions.json} +46 -2
- package/{playbooks/universal/accessibility.manifest.json → library/universal/accessibility/definition.json} +1 -1
- package/library/universal/coding-rules/definition.json +13 -0
- package/library/universal/coding-rules/hygiene.md +9 -0
- package/library/universal/coding-rules/naming.md +17 -0
- package/{playbooks/universal/error-handling.manifest.json → library/universal/error-handling/definition.json} +1 -0
- package/library/universal/git-conventions/branches.md +5 -0
- package/library/universal/git-conventions/commits.md +7 -0
- package/library/universal/git-conventions/definition.json +13 -0
- package/library/universal/git-conventions/workflow.md +5 -0
- package/{playbooks/universal/observability.manifest.json → library/universal/observability/definition.json} +1 -0
- package/{playbooks/universal/security.manifest.json → library/universal/security/definition.json} +1 -0
- package/library/universal/typescript/boundaries.md +13 -0
- package/library/universal/typescript/definition.json +12 -0
- package/library/universal/typescript/errors.md +5 -0
- package/library/universal/typescript/patterns.md +7 -0
- package/package.json +14 -15
- package/public/logo.svg +19 -0
- package/src/cli/arguments.js +63 -0
- package/src/cli/display.js +220 -0
- package/src/cli/main.js +203 -0
- package/src/cli/navigation.js +156 -0
- package/src/cli/questions.js +188 -0
- package/src/cli/system-check.js +158 -0
- package/src/engine/create-project.js +10 -0
- package/src/engine/install-dependencies.js +13 -0
- package/{lib/catalog.js → src/engine/load-library.js} +8 -8
- package/{lib/files.js → src/engine/project-files.js} +10 -1
- package/{lib/playbooks.js → src/engine/project-guidance.js} +26 -3
- package/{lib/application-shapes.js → src/engine/project-shapes.js} +4 -4
- package/{lib/template.js → src/engine/render-templates.js} +11 -0
- package/{lib/compatibility.js → src/engine/tested-versions.js} +21 -2
- package/src/engine/upgrade-report.js +20 -0
- package/src/engine/write-files.js +34 -0
- package/{lib/stacks/registry.js → src/stacks/available-stacks.js} +25 -1
- package/src/stacks/backends/README.md +5 -0
- package/src/stacks/backends/fastapi/ci.js +3 -0
- package/src/stacks/backends/fastapi/create-files.js +874 -0
- package/src/stacks/backends/fastapi/docker.js +75 -0
- package/src/stacks/backends/fastapi/environment.js +3 -0
- package/src/stacks/backends/fastapi/index.js +32 -0
- package/{lib/stacks → src/stacks/backends}/laravel/architecture.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/auth/oidc.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/auth/public.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/auth/sanctum.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/auth/session.js +1 -0
- package/src/stacks/backends/laravel/ci.js +3 -0
- package/{lib/stacks → src/stacks/backends}/laravel/composer.js +1 -1
- package/{lib/stacks/laravel/generate.js → src/stacks/backends/laravel/create-files.js} +1 -0
- package/src/stacks/backends/laravel/docker.js +14 -0
- package/src/stacks/backends/laravel/environment.js +5 -0
- package/{lib/stacks → src/stacks/backends}/laravel/index.js +11 -3
- package/{lib/stacks → src/stacks/backends}/laravel/ui/blade.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/ui/index.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/ui/inertia-react.js +4 -2
- package/{lib/stacks → src/stacks/backends}/laravel/ui/livewire.js +1 -0
- package/{lib/stacks → src/stacks/backends}/laravel/ui/shared.js +1 -0
- package/src/stacks/backends/none/index.js +23 -0
- package/src/stacks/backends/postgres/ci.js +3 -0
- package/src/stacks/backends/postgres/create-files.js +21 -0
- package/src/stacks/backends/postgres/docker.js +3 -0
- package/src/stacks/backends/postgres/environment.js +3 -0
- package/src/stacks/backends/postgres/index.js +30 -0
- package/src/stacks/backends/springboot/ci.js +3 -0
- package/src/stacks/backends/springboot/create-files.js +91 -0
- package/src/stacks/backends/springboot/docker.js +3 -0
- package/src/stacks/backends/springboot/environment.js +3 -0
- package/src/stacks/backends/springboot/index.js +31 -0
- package/src/stacks/backends/supabase/ci.js +3 -0
- package/src/stacks/backends/supabase/create-files.js +52 -0
- package/src/stacks/backends/supabase/docker.js +3 -0
- package/src/stacks/backends/supabase/environment.js +3 -0
- package/src/stacks/backends/supabase/index.js +31 -0
- package/src/stacks/backends/supabase/native.js +14 -0
- package/src/stacks/compose-files.js +259 -0
- package/{lib/generator.js → src/stacks/create-project.js} +206 -57
- package/src/stacks/frontends/README.md +4 -0
- package/src/stacks/frontends/nextjs/ci.js +3 -0
- package/src/stacks/frontends/nextjs/create-files.js +46 -0
- package/src/stacks/frontends/nextjs/dependencies.js +5 -0
- package/src/stacks/frontends/nextjs/docker.js +3 -0
- package/src/stacks/frontends/nextjs/environment.js +7 -0
- package/src/stacks/frontends/nextjs/index.js +35 -0
- package/src/stacks/frontends/react-native/ci.js +3 -0
- package/src/stacks/frontends/react-native/create-files.js +28 -0
- package/src/stacks/frontends/react-native/dependencies.js +5 -0
- package/src/stacks/frontends/react-native/docker.js +5 -0
- package/src/stacks/frontends/react-native/environment.js +7 -0
- package/src/stacks/frontends/react-native/index.js +30 -0
- package/src/stacks/frontends/react-vite/ci.js +3 -0
- package/src/stacks/frontends/react-vite/create-files.js +27 -0
- package/src/stacks/frontends/react-vite/dependencies.js +5 -0
- package/src/stacks/frontends/react-vite/docker.js +3 -0
- package/src/stacks/frontends/react-vite/environment.js +8 -0
- package/src/stacks/frontends/react-vite/index.js +32 -0
- package/src/stacks/shared/capability-packs.js +31 -0
- package/{lib → src}/stacks/shared/contributions.js +1 -1
- package/src/stacks/shared/environment.js +38 -0
- package/src/stacks/shared/javascript-package.js +117 -0
- package/src/stacks/shared/testing-files.js +16 -0
- package/templates/ci/fastapi.yml +62 -0
- package/templates/docker/compose/postgres.yml +1 -1
- package/templates/docker/compose/springboot.yml +3 -3
- package/templates/docker/compose/supabase.yml +1 -1
- package/templates/docker/compose-prod/fastapi.yml +52 -0
- package/templates/docker/compose-prod/springboot.yml +20 -2
- package/templates/docker/dockerfile/fastapi.dev.dockerfile +9 -0
- package/templates/docker/dockerfile/fastapi.prod.dockerfile +11 -0
- package/templates/docker/dockerfile/nextjs.prod.dockerfile +1 -0
- package/templates/docker/dockerfile/springboot.prod.dockerfile +4 -1
- package/templates/docker/dockerfile/vite.prod.dockerfile +2 -1
- package/templates/makefile/fastapi.mk +97 -0
- package/docs/ARCHITECTURE.md +0 -118
- package/lib/banner.js +0 -45
- package/lib/constants.js +0 -3
- package/lib/doctor.js +0 -45
- package/lib/interview.js +0 -77
- package/lib/laravel-scaffold.js +0 -3
- package/lib/scaffold.js +0 -467
- package/lib/stacks/index.js +0 -8
- package/playbooks/concerns/zod.md +0 -174
- package/playbooks/devops/makefile.manifest.json +0 -10
- package/playbooks/devops/makefile.md +0 -556
- package/playbooks/styling/css-modules-extensions.md +0 -267
- package/playbooks/styling/css-modules.manifest.json +0 -11
- package/playbooks/universal/coding-rules.manifest.json +0 -12
- package/playbooks/universal/coding-rules.md +0 -281
- package/playbooks/universal/git-conventions.manifest.json +0 -10
- package/playbooks/universal/git-conventions.md +0 -186
- package/playbooks/universal/typescript.manifest.json +0 -11
- package/playbooks/universal/typescript.md +0 -272
- package/scripts/compatibility-matrix.mjs +0 -48
- /package/{playbooks/capabilities → library/development-tools}/ci/github-actions.md +0 -0
- /package/{playbooks/devops → library/development-tools/devops/pr-template}/pr-template.md +0 -0
- /package/{playbooks/capabilities/docker/docker.manifest.json → library/development-tools/docker/definition.json} +0 -0
- /package/{playbooks/capabilities → library/development-tools}/docker/overview.md +0 -0
- /package/{playbooks/capabilities → library/features}/auth/oidc-resource-server.md +0 -0
- /package/{playbooks/capabilities → library/features}/auth/spring-session.md +0 -0
- /package/{playbooks/capabilities/flyway/flyway.manifest.json → library/features/flyway/definition.json} +0 -0
- /package/{playbooks/capabilities → library/features}/flyway/environments.md +0 -0
- /package/{playbooks/capabilities → library/features}/flyway/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/flyway/testing.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/database.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/observability.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/oidc-resource-server.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/queues.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/sanctum-spa.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/scheduler.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/session-auth.md +0 -0
- /package/{playbooks/capabilities → library/features}/laravel/storage-uploads.md +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/architecture.md +0 -0
- /package/{playbooks/capabilities/postgresql/postgresql.manifest.json → library/features/postgresql/definition.json} +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/schema-design.md +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/security.md +0 -0
- /package/{playbooks/capabilities → library/features}/postgresql/testing.md +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/architecture.md +0 -0
- /package/{playbooks/capabilities/prisma/prisma.manifest.json → library/features/prisma/definition.json} +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/runtime.md +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/schema.md +0 -0
- /package/{playbooks/capabilities → library/features}/prisma/testing.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/architecture.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/authentication.md +0 -0
- /package/{playbooks/capabilities/supabase/supabase.manifest.json → library/features/supabase/definition.json} +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/expo.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/migrations.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/nextjs.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/rls.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/testing.md +0 -0
- /package/{playbooks/capabilities → library/features}/supabase/vite.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/axios.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/next-safe-action.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/next-themes.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/nuqs.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/t3-env.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/tanstack-query.md +0 -0
- /package/{playbooks → library/optional-features}/concerns/zustand.md +0 -0
- /package/{playbooks/styling/native-styles.manifest.json → library/optional-features/styling/native-styles/definition.json} +0 -0
- /package/{playbooks/styling → library/optional-features/styling/native-styles}/native-styles.md +0 -0
- /package/{playbooks/styling/tailwind.manifest.json → library/optional-features/styling/tailwind/definition.json} +0 -0
- /package/{playbooks/styling → library/optional-features/styling/tailwind}/tailwind-extensions.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/architecture.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/runtime.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/security.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/structure.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/blade/testing.md +0 -0
- /package/{playbooks/stack/laravel-ui.manifest.json → library/platforms/laravel-ui/definition.json} +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/architecture.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/runtime.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/security.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/structure.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/inertia-react/testing.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/architecture.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/runtime.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/security.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/structure.md +0 -0
- /package/{playbooks/platform → library/platforms}/laravel-ui/livewire/testing.md +0 -0
- /package/{playbooks/platform → library/platforms/mobile}/mobile.md +0 -0
- /package/{playbooks/platform → library/platforms/web}/web.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/architecture.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/expo/testing.md +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/architecture.md +0 -0
- /package/{playbooks/stack/laravel.manifest.json → library/stacks/laravel/definition.json} +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/laravel/testing.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/architecture.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/nextjs/testing.md +0 -0
- /package/{playbooks/stack/none.manifest.json → library/stacks/none/definition.json} +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/architecture.md +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/react-vite/testing.md +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/architecture.md +0 -0
- /package/{playbooks/stack/springboot.manifest.json → library/stacks/springboot/definition.json} +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/runtime.md +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/security.md +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/structure.md +0 -0
- /package/{playbooks/stack → library/stacks}/springboot/testing.md +0 -0
- /package/{playbooks/universal → library/universal/accessibility}/accessibility.md +0 -0
- /package/{playbooks/universal → library/universal/error-handling}/error-handling.md +0 -0
- /package/{playbooks/universal → library/universal/observability}/observability.md +0 -0
- /package/{playbooks/universal → library/universal/security}/security.md +0 -0
- /package/{lib → src/engine}/project-location.js +0 -0
- /package/{lib → src}/stacks/context.js +0 -0
- /package/{lib/stacks/contract.js → src/stacks/rules.js} +0 -0
- /package/{ci → templates/ci}/expo.yml +0 -0
- /package/{ci → templates/ci}/laravel.yml +0 -0
- /package/{ci → templates/ci}/nextjs.yml +0 -0
- /package/{ci → templates/ci}/springboot.yml +0 -0
- /package/{ci → templates/ci}/vite.yml +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Makefile — {{PROJECT_NAME}}
|
|
3
|
+
# =============================================================================
|
|
4
|
+
|
|
5
|
+
# Variables
|
|
6
|
+
COMPOSE := docker compose
|
|
7
|
+
BACKEND := $(COMPOSE) exec backend
|
|
8
|
+
DB := $(COMPOSE) exec db
|
|
9
|
+
WORKDIR := $(PWD)
|
|
10
|
+
|
|
11
|
+
# =============================================================================
|
|
12
|
+
# Default
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
.DEFAULT_GOAL := help
|
|
16
|
+
|
|
17
|
+
.PHONY: help
|
|
18
|
+
help: ## Show all available commands
|
|
19
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
|
|
20
|
+
| awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
|
|
21
|
+
|
|
22
|
+
# =============================================================================
|
|
23
|
+
# Project Lifecycle
|
|
24
|
+
# =============================================================================
|
|
25
|
+
|
|
26
|
+
.PHONY: dev up down restart logs logs-back clean
|
|
27
|
+
|
|
28
|
+
dev: ## Start all containers and follow logs
|
|
29
|
+
$(COMPOSE) up --build
|
|
30
|
+
|
|
31
|
+
up: ## Start all containers in background
|
|
32
|
+
$(COMPOSE) up -d --build
|
|
33
|
+
|
|
34
|
+
down: ## Stop and remove all containers
|
|
35
|
+
$(COMPOSE) down
|
|
36
|
+
|
|
37
|
+
restart: down up ## Stop then start all containers
|
|
38
|
+
|
|
39
|
+
logs: ## Follow logs from all containers
|
|
40
|
+
$(COMPOSE) logs -f
|
|
41
|
+
|
|
42
|
+
logs-back: ## Follow backend logs only
|
|
43
|
+
$(COMPOSE) logs -f backend
|
|
44
|
+
|
|
45
|
+
clean: ## Remove containers, volumes, orphans (full reset)
|
|
46
|
+
$(COMPOSE) down -v --remove-orphans
|
|
47
|
+
|
|
48
|
+
# =============================================================================
|
|
49
|
+
# Database
|
|
50
|
+
# =============================================================================
|
|
51
|
+
|
|
52
|
+
.PHONY: migrate db-shell
|
|
53
|
+
|
|
54
|
+
migrate: ## Run pending Alembic migrations
|
|
55
|
+
$(BACKEND) uv run alembic upgrade head
|
|
56
|
+
|
|
57
|
+
db-shell: ## Open psql shell inside DB container
|
|
58
|
+
$(DB) psql -U $${POSTGRES_USER} -d $${POSTGRES_DB}
|
|
59
|
+
|
|
60
|
+
# =============================================================================
|
|
61
|
+
# Shells
|
|
62
|
+
# =============================================================================
|
|
63
|
+
|
|
64
|
+
.PHONY: shell-back
|
|
65
|
+
|
|
66
|
+
shell-back: ## Open shell inside backend container
|
|
67
|
+
$(BACKEND) sh
|
|
68
|
+
|
|
69
|
+
# =============================================================================
|
|
70
|
+
# Quality
|
|
71
|
+
# =============================================================================
|
|
72
|
+
|
|
73
|
+
.PHONY: lint test test-back
|
|
74
|
+
|
|
75
|
+
lint: ## Run Ruff check and format check (backend)
|
|
76
|
+
$(BACKEND) uv run ruff check .
|
|
77
|
+
$(BACKEND) uv run ruff format --check .
|
|
78
|
+
|
|
79
|
+
test: test-back ## Run all tests
|
|
80
|
+
|
|
81
|
+
test-back: ## Run pytest (backend)
|
|
82
|
+
$(BACKEND) uv run pytest
|
|
83
|
+
|
|
84
|
+
# =============================================================================
|
|
85
|
+
# Production
|
|
86
|
+
# =============================================================================
|
|
87
|
+
|
|
88
|
+
.PHONY: build prod-up prod-down
|
|
89
|
+
|
|
90
|
+
build: ## Build production Docker images
|
|
91
|
+
$(COMPOSE) -f docker-compose.prod.yml build
|
|
92
|
+
|
|
93
|
+
prod-up: ## Start production stack
|
|
94
|
+
$(COMPOSE) -f docker-compose.prod.yml up -d --build
|
|
95
|
+
|
|
96
|
+
prod-down: ## Stop production stack
|
|
97
|
+
$(COMPOSE) -f docker-compose.prod.yml down
|
package/docs/ARCHITECTURE.md
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# Architecture
|
|
2
|
-
|
|
3
|
-
`create-win-project` composes a validated project specification into two coordinated outputs:
|
|
4
|
-
|
|
5
|
-
1. a small executable application that establishes the stack's real conventions;
|
|
6
|
-
2. a task-routed documentation layer for humans and coding agents.
|
|
7
|
-
|
|
8
|
-
Executable behavior, tests, and framework configuration are the source of truth. Playbooks explain and extend that behavior; they must not contradict it.
|
|
9
|
-
|
|
10
|
-
## Generation pipeline
|
|
11
|
-
|
|
12
|
-
```text
|
|
13
|
-
CLI interview
|
|
14
|
-
↓
|
|
15
|
-
validated answers
|
|
16
|
-
↓
|
|
17
|
-
manifest catalog + compatibility resolver
|
|
18
|
-
↓
|
|
19
|
-
resolved stack descriptor
|
|
20
|
-
├── runnable framework files
|
|
21
|
-
├── optional CI / Docker / Makefile files
|
|
22
|
-
├── project context and documentation
|
|
23
|
-
└── selected playbooks + RULES.md router
|
|
24
|
-
↓
|
|
25
|
-
generated-project contract tests
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### CLI boundary
|
|
29
|
-
|
|
30
|
-
`index.js` owns interaction and presentation. It gathers project identity, frontend, optional backend, styling, one Small/Medium/Large architecture profile, login intent, client audience when relevant, testing depth, and optional operational tooling. Medium is shown first and is the default. It does not contain stack dependency tables.
|
|
31
|
-
|
|
32
|
-
`generateProject()` validates the same answers again because it is also an exported programmatic API. A caller cannot bypass destination-name, Java-package, or testing-profile validation by skipping the CLI.
|
|
33
|
-
|
|
34
|
-
### Catalog and resolution
|
|
35
|
-
|
|
36
|
-
`lib/catalog.js` loads co-located `*.manifest.json` files and merges selected capabilities into one stack descriptor. `lib/compatibility.js` validates `compatibility/profiles.json` and resolves every package name to an exact version for the selected profile.
|
|
37
|
-
|
|
38
|
-
Stack-specific behavior crosses into core orchestration through the contract in `lib/stacks/contract.js`. Every frontend, backend, or data adapter has a stable identity, declares compatible adapters and supported application/authentication/architecture models, and is added to the explicit registry. Registration is deliberate; adapters are never discovered by scanning directories.
|
|
39
|
-
|
|
40
|
-
Adapters may contribute data in these areas:
|
|
41
|
-
|
|
42
|
-
- questions in a core-defined prompt slot;
|
|
43
|
-
- authentication models;
|
|
44
|
-
- generated file descriptions;
|
|
45
|
-
- environment declarations;
|
|
46
|
-
- install steps;
|
|
47
|
-
- Docker and CI fragments;
|
|
48
|
-
- verification cases.
|
|
49
|
-
|
|
50
|
-
Core code owns prompt order, compatibility-profile resolution, atomic writes, process execution, and final composition. An adapter receives a read-only stack context and returns contributions; it cannot write arbitrary paths or install global tools. Adapter definitions do not accept dependency tables or version fields. Exact versions remain exclusively owned by `compatibility/profiles.json`.
|
|
51
|
-
|
|
52
|
-
Manifests declare:
|
|
53
|
-
|
|
54
|
-
- identity and compatibility (`id`, `kind`, `appliesTo`);
|
|
55
|
-
- dependency names and scripts (never dependency versions);
|
|
56
|
-
- semantic environment names and which ones are client-visible;
|
|
57
|
-
- supported architecture profiles, conditional playbooks, and optional templates;
|
|
58
|
-
- constraints shown to the agent;
|
|
59
|
-
- concerns and their playbook sections.
|
|
60
|
-
|
|
61
|
-
Client environment variables are semantic in manifests (`API_URL`) and receive exactly one framework prefix during resolution (`NEXT_PUBLIC_API_URL`, `VITE_API_URL`, or `EXPO_PUBLIC_API_URL`). Public prefixes always mean the value is shipped to the client.
|
|
62
|
-
|
|
63
|
-
### Runnable scaffold
|
|
64
|
-
|
|
65
|
-
`lib/scaffold.js` owns the minimum executable vertical slice:
|
|
66
|
-
|
|
67
|
-
- Next.js: route-oriented Small; familiar feature services/actions/queries and owned repositories or remote API clients in Medium; public feature APIs and enforced boundaries in Large.
|
|
68
|
-
- React + Vite: thin browser features in Small, feature modules in Medium, and public feature APIs plus boundary checks in Large.
|
|
69
|
-
- Expo: screens/data in Small, feature modules in Medium, and boundaries ready for offline sync, background work, and platform adapters in Large.
|
|
70
|
-
- Spring Boot: conventional package-by-feature in Small, explicit API/service/repository ownership in Medium, and a verified Spring Modulith modular monolith in Large.
|
|
71
|
-
|
|
72
|
-
Authentication is selected during generation. Supabase emits Supabase Auth clients and login examples; website-only Spring uses a secure server-managed session; multi-client Spring emits an OIDC Resource Server and delegates issuance, refresh, and revocation to the identity provider. `Not yet` is fail-closed for Spring and never emits pretend authentication. Existing projects are never told to rerun the generator to add auth.
|
|
73
|
-
|
|
74
|
-
This module intentionally generates a small working example. Domain-specific features are added after product context is known; the generator does not invent business entities.
|
|
75
|
-
|
|
76
|
-
### Repository and operational files
|
|
77
|
-
|
|
78
|
-
`lib/generator.js` coordinates writes and refuses to merge into a non-empty destination. It adds documentation, selected playbooks, CI, Docker, Makefile, environment examples, and repository conventions around the runnable foundation.
|
|
79
|
-
|
|
80
|
-
The first `npm install` creates the lockfile. Generated CI uses `npm ci`, so the lockfile must be committed before CI is enabled. `create-win-project.profile.json` separately records the compatibility profile, architecture profile, and authentication intent/model/audience; after generation, that project owns its own upgrade lifecycle.
|
|
81
|
-
|
|
82
|
-
### Compatibility profile lifecycle
|
|
83
|
-
|
|
84
|
-
Exactly one profile is `current` and one is `previous`. The current profile is the default. A profile owns exact npm, Spring Boot, runtime, and container versions; manifests and scaffold code may only request names or capabilities. Promotion copies the candidate into a new dated profile, marks the former current profile previous, and happens only after the generated-project matrix passes. Major changes also require migration notes. See `DEPENDENCY_MAINTENANCE.md`.
|
|
85
|
-
|
|
86
|
-
## Documentation model
|
|
87
|
-
|
|
88
|
-
| File | Responsibility |
|
|
89
|
-
|------|----------------|
|
|
90
|
-
| `AGENTS.md` | Small always-on command, workflow, safety, and definition-of-done contract. |
|
|
91
|
-
| `CONTEXT.md` | Product goals, boundaries, decisions, and project-specific facts. |
|
|
92
|
-
| `RULES.md` | Generated concern-to-playbook section router. |
|
|
93
|
-
| `playbooks/` | Reusable standards, recipes, rationale, and stack guidance. |
|
|
94
|
-
| `docs/` | Documentation for the generated product, not generic framework teaching. |
|
|
95
|
-
|
|
96
|
-
Manifest section names are checked against Markdown headings. Numbered headings are normalized for matching, and generated contract tests reject unresolved `RULES.md` entries.
|
|
97
|
-
|
|
98
|
-
## Testing strategy
|
|
99
|
-
|
|
100
|
-
The generator itself has three verification levels:
|
|
101
|
-
|
|
102
|
-
1. unit tests for catalog composition and template rendering;
|
|
103
|
-
2. generated-output contract tests for required files, environment naming, playbook routing, profile-specific boundaries, auth metadata/code, testing profiles, and overwrite safety;
|
|
104
|
-
3. a current-and-previous matrix across every supported stack combination, all three architecture profiles, and every applicable authentication model. It installs and runs lint, typecheck, tests, builds, Expo compatibility checks/web export, Spring MVC/security/Modulith tests and Maven packaging, Compose validation, and current-profile container builds.
|
|
105
|
-
|
|
106
|
-
Canonical Markdown code examples should progressively move into extracted fixtures so examples compile against the versions they teach.
|
|
107
|
-
|
|
108
|
-
## Extension workflow
|
|
109
|
-
|
|
110
|
-
When adding a stack or capability:
|
|
111
|
-
|
|
112
|
-
1. Add its manifest, all five stack facets, and any platform/capability routes.
|
|
113
|
-
2. Add the smallest runnable files needed in `lib/scaffold.js` or a focused scaffold module.
|
|
114
|
-
3. Add every supported architecture/authentication combination to the generated-output matrix.
|
|
115
|
-
4. Run install, lint/typecheck, tests, and production build for the new fixture.
|
|
116
|
-
5. Update this architecture document if ownership or the generation pipeline changed.
|
|
117
|
-
|
|
118
|
-
Do not advertise a capability solely because a playbook mentions it. A generated capability must have executable configuration and contract coverage.
|
package/lib/banner.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
|
|
3
|
-
const W1N = [
|
|
4
|
-
' ██╗ ██╗ ██╗ ███╗ ██╗',
|
|
5
|
-
' ██║ ██║ ███║ ████╗ ██║',
|
|
6
|
-
' ██║ █╗ ██║ ╚██║ ██╔██╗██║',
|
|
7
|
-
' ██║███╗██║ ██║ ██║╚████║',
|
|
8
|
-
' ╚███╔███╔╝ ██║ ██║ ╚███║',
|
|
9
|
-
' ╚══╝╚══╝ ╚═╝ ╚═╝ ╚══╝',
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
const PROJECT = [
|
|
13
|
-
' █▀█ █▀█ █▀█ █ █▀▀ █▀▀ ▀█▀',
|
|
14
|
-
' █▀▀ █▀█ █ █ █ █▀ █ █ ',
|
|
15
|
-
' █ █ █ █▄█ █▄█ █▄▄ █▄▄ █ ',
|
|
16
|
-
]
|
|
17
|
-
|
|
18
|
-
function plain() {
|
|
19
|
-
return [...W1N, '', ...PROJECT].join('\n')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function colored() {
|
|
23
|
-
const w1n = W1N.map((l) => chalk.bold.cyan(l)).join('\n')
|
|
24
|
-
const proj = PROJECT.map((l) => chalk.bold.white(l)).join('\n')
|
|
25
|
-
return `${w1n}\n${proj}`
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function w1nBanner() {
|
|
29
|
-
const noColor = process.env.NO_COLOR !== undefined || process.env.FORCE_COLOR === '0'
|
|
30
|
-
const isTTY = process.stdout.isTTY
|
|
31
|
-
const width = process.stdout.columns || 80
|
|
32
|
-
|
|
33
|
-
// Fallback for narrow terminals or non-TTY (CI/logs): plain single-line wordmark
|
|
34
|
-
if (!isTTY || width < 80 || noColor) {
|
|
35
|
-
// Keep stacked plain for README consistency, but without colors
|
|
36
|
-
if (width < 60) return 'W1N PROJECT'
|
|
37
|
-
return plain()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return colored()
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export const bannerRaw = plain()
|
|
44
|
-
export const W1N_ART = W1N.join('\n')
|
|
45
|
-
export const PROJECT_ART = PROJECT.join('\n')
|
package/lib/constants.js
DELETED
package/lib/doctor.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from 'node:child_process'
|
|
2
|
-
import { existsSync } from 'node:fs'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
|
|
5
|
-
function isOnPath(command) {
|
|
6
|
-
const suffixes = process.platform === 'win32' ? ['', '.cmd', '.exe', '.bat'] : ['']
|
|
7
|
-
return (process.env.PATH || '').split(path.delimiter).some((directory) =>
|
|
8
|
-
suffixes.some((suffix) => existsSync(path.join(directory, `${command}${suffix}`)))
|
|
9
|
-
)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function probe(command, args = ['--version']) {
|
|
13
|
-
const result = spawnSync(command, args, { encoding: 'utf8', shell: false })
|
|
14
|
-
const version = `${result.stdout || result.stderr || ''}`.trim().split('\n')[0]
|
|
15
|
-
if (!version) return isOnPath(command) ? 'available (version unavailable)' : null
|
|
16
|
-
if (result.status !== 0) return null
|
|
17
|
-
return version
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function collectDiagnostics(profile) {
|
|
21
|
-
const nodeVersion = process.versions.node
|
|
22
|
-
const npmVersion = probe('npm')
|
|
23
|
-
const dockerVersion = probe('docker')
|
|
24
|
-
const composeVersion = dockerVersion ? probe('docker', ['compose', 'version']) : null
|
|
25
|
-
const javaVersion = probe('java', ['-version'])
|
|
26
|
-
return [
|
|
27
|
-
{ name: 'Node.js', found: nodeVersion, expected: profile.runtimes.node, required: false },
|
|
28
|
-
{ name: 'npm', found: npmVersion, required: false },
|
|
29
|
-
{ name: 'Docker', found: dockerVersion, required: false },
|
|
30
|
-
{ name: 'Docker Compose', found: composeVersion, required: false },
|
|
31
|
-
{ name: 'Java', found: javaVersion, expected: profile.runtimes.java, required: false },
|
|
32
|
-
]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function printDoctor(profile, output = console.log) {
|
|
36
|
-
output(`create-win-project doctor (profile ${profile.id})`)
|
|
37
|
-
output('Use either the Node/npm lane or the Docker/Compose lane; Java is only needed for host-run Spring projects.')
|
|
38
|
-
for (const item of collectDiagnostics(profile)) {
|
|
39
|
-
const expectation = item.expected ? ` (tested: ${item.expected})` : ''
|
|
40
|
-
output(`${item.found ? '✓' : '○'} ${item.name}: ${item.found || 'not found'}${expectation}`)
|
|
41
|
-
}
|
|
42
|
-
output('')
|
|
43
|
-
output('Node lane: npm ci && npm start')
|
|
44
|
-
output('Docker lane: docker compose build && docker compose run --rm app')
|
|
45
|
-
}
|
package/lib/interview.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
const BACK = Symbol('back')
|
|
2
|
-
|
|
3
|
-
function enabled(question, answers) {
|
|
4
|
-
return typeof question.when === 'function' ? question.when(answers) : question.when !== false
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
async function resolved(value, answers) {
|
|
8
|
-
return typeof value === 'function' ? value(answers) : value
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function clearFrom(questions, answers, index) {
|
|
12
|
-
for (let cursor = index; cursor < questions.length; cursor += 1) {
|
|
13
|
-
delete answers[questions[cursor].name]
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Runs Inquirer questions one at a time so users can safely revisit earlier answers.
|
|
19
|
-
* List/checkbox/confirm prompts expose a visible Back choice; text prompts accept `:back`.
|
|
20
|
-
*/
|
|
21
|
-
export async function promptWithBack(inquirer, questions, initialAnswers = {}) {
|
|
22
|
-
const answers = { ...initialAnswers }
|
|
23
|
-
const history = []
|
|
24
|
-
let index = 0
|
|
25
|
-
|
|
26
|
-
while (index < questions.length) {
|
|
27
|
-
const source = questions[index]
|
|
28
|
-
if (!enabled(source, answers)) { index += 1; continue }
|
|
29
|
-
|
|
30
|
-
const canGoBack = history.length > 0
|
|
31
|
-
const question = { ...source, when: undefined }
|
|
32
|
-
if (answers[source.name] !== undefined && question.default === undefined) {
|
|
33
|
-
question.default = answers[source.name]
|
|
34
|
-
}
|
|
35
|
-
if (question.type === 'input' && canGoBack) {
|
|
36
|
-
question.message = `${question.message} (type :back to return)`
|
|
37
|
-
} else if (question.type === 'confirm') {
|
|
38
|
-
const defaultValue = await resolved(question.default, answers)
|
|
39
|
-
question.type = 'list'
|
|
40
|
-
question.choices = [
|
|
41
|
-
{ name: 'Yes', value: true },
|
|
42
|
-
{ name: 'No', value: false },
|
|
43
|
-
...(canGoBack ? [{ name: '← Back', value: BACK }] : []),
|
|
44
|
-
]
|
|
45
|
-
question.default = defaultValue ? 0 : 1
|
|
46
|
-
} else if (['list', 'checkbox'].includes(question.type) && canGoBack) {
|
|
47
|
-
const choices = await resolved(question.choices, answers)
|
|
48
|
-
question.choices = [...choices, new inquirer.Separator(), { name: '← Back', value: BACK }]
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (typeof question.default === 'function') question.default = await question.default(answers)
|
|
52
|
-
const result = await inquirer.prompt([question], answers)
|
|
53
|
-
const value = result[source.name]
|
|
54
|
-
const requestedBack = value === BACK || value === ':back' || (Array.isArray(value) && value.includes(BACK))
|
|
55
|
-
if (requestedBack) {
|
|
56
|
-
const target = history.pop()
|
|
57
|
-
if (target === undefined) continue
|
|
58
|
-
clearFrom(questions, answers, target)
|
|
59
|
-
index = target
|
|
60
|
-
continue
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
answers[source.name] = value
|
|
64
|
-
history.push(index)
|
|
65
|
-
index += 1
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return answers
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function configurationDecisionChoices() {
|
|
72
|
-
return [
|
|
73
|
-
{ name: 'Create project', value: 'create' },
|
|
74
|
-
{ name: '← Back and edit', value: 'back' },
|
|
75
|
-
{ name: 'Cancel', value: 'cancel' },
|
|
76
|
-
]
|
|
77
|
-
}
|
package/lib/laravel-scaffold.js
DELETED