create-fluxstack 1.0.1 → 1.0.3
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/.claude/settings.local.json +63 -0
- package/.dockerignore +50 -0
- package/.env.example +53 -0
- package/.gitattributes +2 -0
- package/.github/workflows/ci-build-tests.yml +480 -0
- package/.github/workflows/dependency-management.yml +324 -0
- package/.github/workflows/release-validation.yml +355 -0
- package/.kiro/specs/fluxstack-architecture-optimization/design.md +700 -0
- package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +127 -0
- package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +330 -0
- package/CLAUDE.md +200 -0
- package/Dockerfile +58 -0
- package/Dockerfile.backend +52 -0
- package/Dockerfile.frontend +54 -0
- package/ENV_TESTING_REPORT.md +292 -0
- package/FRAMEWORK_ROADMAP.md +183 -0
- package/FRONTEND_TESTS_README.md +287 -0
- package/README-Docker.md +85 -0
- package/TEST_RESULTS.md +130 -0
- package/ai-context/00-QUICK-START.md +86 -0
- package/ai-context/README.md +88 -0
- package/ai-context/development/eden-treaty-guide.md +362 -0
- package/ai-context/development/patterns.md +382 -0
- package/ai-context/examples/crud-complete.md +626 -0
- package/ai-context/project/architecture.md +399 -0
- package/ai-context/project/overview.md +213 -0
- package/ai-context/recent-changes/eden-treaty-refactor.md +281 -0
- package/ai-context/recent-changes/type-inference-fix.md +223 -0
- package/ai-context/reference/environment-vars.md +384 -0
- package/ai-context/reference/troubleshooting.md +407 -0
- package/bun.lock +21 -11
- package/bunfig.toml +16 -0
- package/config/fluxstack.config.ts +48 -0
- package/create-fluxstack.ts +2 -3
- package/create-test-app.ts +156 -0
- package/docker-compose.microservices.yml +75 -0
- package/docker-compose.simple.yml +57 -0
- package/docker-compose.yml +71 -0
- package/docs/dynamic-environment-variables.md +380 -0
- package/eslint.config.js +23 -0
- package/examples/dynamic-env-usage.ts +283 -0
- package/examples/hybrid-env-strategy.ts +212 -0
- package/examples/simplified-env-usage.ts +251 -0
- package/flux-cli.ts +214 -0
- package/fluxstack.config.ts +318 -0
- package/meu-app-teste/README.md +44 -0
- package/meu-app-teste/app/client/README.md +69 -0
- package/meu-app-teste/app/client/frontend-only.ts +12 -0
- package/meu-app-teste/app/client/index.html +13 -0
- package/meu-app-teste/app/client/public/vite.svg +1 -0
- package/meu-app-teste/app/client/src/App.css +883 -0
- package/meu-app-teste/app/client/src/App.tsx +669 -0
- package/meu-app-teste/app/client/src/assets/react.svg +1 -0
- package/meu-app-teste/app/client/src/components/TestPage.tsx +453 -0
- package/meu-app-teste/app/client/src/index.css +51 -0
- package/meu-app-teste/app/client/src/lib/eden-api.ts +110 -0
- package/meu-app-teste/app/client/src/main.tsx +10 -0
- package/meu-app-teste/app/client/src/vite-env.d.ts +1 -0
- package/meu-app-teste/app/client/tsconfig.app.json +43 -0
- package/meu-app-teste/app/client/tsconfig.json +7 -0
- package/meu-app-teste/app/client/tsconfig.node.json +25 -0
- package/meu-app-teste/app/server/app.ts +10 -0
- package/meu-app-teste/app/server/backend-only.ts +15 -0
- package/meu-app-teste/app/server/controllers/users.controller.ts +69 -0
- package/meu-app-teste/app/server/index.ts +104 -0
- package/meu-app-teste/app/server/routes/index.ts +25 -0
- package/meu-app-teste/app/server/routes/users.routes.ts +121 -0
- package/meu-app-teste/app/server/types/index.ts +1 -0
- package/meu-app-teste/app/shared/types/index.ts +18 -0
- package/meu-app-teste/bun.lock +1053 -0
- package/meu-app-teste/core/__tests__/integration.test.ts +227 -0
- package/meu-app-teste/core/build/index.ts +186 -0
- package/meu-app-teste/core/cli/command-registry.ts +334 -0
- package/meu-app-teste/core/cli/index.ts +394 -0
- package/meu-app-teste/core/cli/plugin-discovery.ts +200 -0
- package/meu-app-teste/core/client/standalone.ts +57 -0
- package/meu-app-teste/core/config/__tests__/config-loader.test.ts +591 -0
- package/meu-app-teste/core/config/__tests__/config-merger.test.ts +657 -0
- package/meu-app-teste/core/config/__tests__/env-converter.test.ts +372 -0
- package/meu-app-teste/core/config/__tests__/env-processor.test.ts +431 -0
- package/meu-app-teste/core/config/__tests__/env.test.ts +452 -0
- package/meu-app-teste/core/config/__tests__/integration.test.ts +418 -0
- package/meu-app-teste/core/config/__tests__/loader.test.ts +331 -0
- package/meu-app-teste/core/config/__tests__/schema.test.ts +129 -0
- package/meu-app-teste/core/config/__tests__/validator.test.ts +318 -0
- package/meu-app-teste/core/config/env-dynamic.ts +326 -0
- package/meu-app-teste/core/config/env.ts +597 -0
- package/meu-app-teste/core/config/index.ts +317 -0
- package/meu-app-teste/core/config/loader.ts +546 -0
- package/meu-app-teste/core/config/runtime-config.ts +322 -0
- package/meu-app-teste/core/config/schema.ts +694 -0
- package/meu-app-teste/core/config/validator.ts +540 -0
- package/meu-app-teste/core/framework/__tests__/server.test.ts +233 -0
- package/meu-app-teste/core/framework/client.ts +132 -0
- package/meu-app-teste/core/framework/index.ts +8 -0
- package/meu-app-teste/core/framework/server.ts +501 -0
- package/meu-app-teste/core/framework/types.ts +63 -0
- package/meu-app-teste/core/plugins/__tests__/built-in.test.ts.disabled +366 -0
- package/meu-app-teste/core/plugins/__tests__/manager.test.ts +398 -0
- package/meu-app-teste/core/plugins/__tests__/monitoring.test.ts +401 -0
- package/meu-app-teste/core/plugins/__tests__/registry.test.ts +335 -0
- package/meu-app-teste/core/plugins/built-in/index.ts +142 -0
- package/meu-app-teste/core/plugins/built-in/logger/index.ts +180 -0
- package/meu-app-teste/core/plugins/built-in/monitoring/README.md +193 -0
- package/meu-app-teste/core/plugins/built-in/monitoring/index.ts +912 -0
- package/meu-app-teste/core/plugins/built-in/static/index.ts +289 -0
- package/meu-app-teste/core/plugins/built-in/swagger/index.ts +229 -0
- package/meu-app-teste/core/plugins/built-in/vite/index.ts +316 -0
- package/meu-app-teste/core/plugins/config.ts +348 -0
- package/meu-app-teste/core/plugins/discovery.ts +350 -0
- package/meu-app-teste/core/plugins/executor.ts +351 -0
- package/meu-app-teste/core/plugins/index.ts +195 -0
- package/meu-app-teste/core/plugins/manager.ts +583 -0
- package/meu-app-teste/core/plugins/registry.ts +424 -0
- package/meu-app-teste/core/plugins/types.ts +254 -0
- package/meu-app-teste/core/server/framework.ts +123 -0
- package/meu-app-teste/core/server/index.ts +8 -0
- package/meu-app-teste/core/server/plugins/database.ts +182 -0
- package/meu-app-teste/core/server/plugins/logger.ts +47 -0
- package/meu-app-teste/core/server/plugins/swagger.ts +34 -0
- package/meu-app-teste/core/server/standalone.ts +91 -0
- package/meu-app-teste/core/templates/create-project.ts +455 -0
- package/meu-app-teste/core/types/api.ts +169 -0
- package/meu-app-teste/core/types/build.ts +174 -0
- package/meu-app-teste/core/types/config.ts +68 -0
- package/meu-app-teste/core/types/index.ts +127 -0
- package/meu-app-teste/core/types/plugin.ts +94 -0
- package/meu-app-teste/core/utils/__tests__/errors.test.ts +139 -0
- package/meu-app-teste/core/utils/__tests__/helpers.test.ts +297 -0
- package/meu-app-teste/core/utils/__tests__/logger.test.ts +141 -0
- package/meu-app-teste/core/utils/env-runtime-v2.ts +232 -0
- package/meu-app-teste/core/utils/env-runtime.ts +252 -0
- package/meu-app-teste/core/utils/errors/codes.ts +115 -0
- package/meu-app-teste/core/utils/errors/handlers.ts +63 -0
- package/meu-app-teste/core/utils/errors/index.ts +81 -0
- package/meu-app-teste/core/utils/helpers.ts +180 -0
- package/meu-app-teste/core/utils/index.ts +18 -0
- package/meu-app-teste/core/utils/logger/index.ts +161 -0
- package/meu-app-teste/core/utils/logger.ts +106 -0
- package/meu-app-teste/core/utils/monitoring/index.ts +212 -0
- package/meu-app-teste/package.json +92 -0
- package/meu-app-teste/tsconfig.json +51 -0
- package/meu-app-teste/vite.config.ts +42 -0
- package/my-final-test/README.md +44 -0
- package/my-final-test/app/client/README.md +69 -0
- package/my-final-test/app/client/frontend-only.ts +12 -0
- package/my-final-test/app/client/index.html +13 -0
- package/my-final-test/app/client/public/vite.svg +1 -0
- package/my-final-test/app/client/src/App.css +883 -0
- package/my-final-test/app/client/src/App.tsx +669 -0
- package/my-final-test/app/client/src/assets/react.svg +1 -0
- package/my-final-test/app/client/src/components/TestPage.tsx +453 -0
- package/my-final-test/app/client/src/index.css +51 -0
- package/my-final-test/app/client/src/lib/eden-api.ts +110 -0
- package/my-final-test/app/client/src/main.tsx +10 -0
- package/my-final-test/app/client/src/vite-env.d.ts +1 -0
- package/my-final-test/app/client/tsconfig.app.json +43 -0
- package/my-final-test/app/client/tsconfig.json +7 -0
- package/my-final-test/app/client/tsconfig.node.json +25 -0
- package/my-final-test/app/server/app.ts +10 -0
- package/my-final-test/app/server/backend-only.ts +15 -0
- package/my-final-test/app/server/controllers/users.controller.ts +69 -0
- package/my-final-test/app/server/index.ts +104 -0
- package/my-final-test/app/server/routes/index.ts +25 -0
- package/my-final-test/app/server/routes/users.routes.ts +121 -0
- package/my-final-test/app/server/types/index.ts +1 -0
- package/my-final-test/app/shared/types/index.ts +18 -0
- package/my-final-test/bun.lock +993 -0
- package/my-final-test/core/__tests__/integration.test.ts +227 -0
- package/my-final-test/core/build/index.ts +186 -0
- package/my-final-test/core/cli/command-registry.ts +334 -0
- package/my-final-test/core/cli/index.ts +394 -0
- package/my-final-test/core/cli/plugin-discovery.ts +200 -0
- package/my-final-test/core/client/standalone.ts +57 -0
- package/my-final-test/core/config/__tests__/config-loader.test.ts +591 -0
- package/my-final-test/core/config/__tests__/config-merger.test.ts +657 -0
- package/my-final-test/core/config/__tests__/env-converter.test.ts +372 -0
- package/my-final-test/core/config/__tests__/env-processor.test.ts +431 -0
- package/my-final-test/core/config/__tests__/env.test.ts +452 -0
- package/my-final-test/core/config/__tests__/integration.test.ts +418 -0
- package/my-final-test/core/config/__tests__/loader.test.ts +331 -0
- package/my-final-test/core/config/__tests__/schema.test.ts +129 -0
- package/my-final-test/core/config/__tests__/validator.test.ts +318 -0
- package/my-final-test/core/config/env-dynamic.ts +326 -0
- package/my-final-test/core/config/env.ts +597 -0
- package/my-final-test/core/config/index.ts +317 -0
- package/my-final-test/core/config/loader.ts +546 -0
- package/my-final-test/core/config/runtime-config.ts +322 -0
- package/my-final-test/core/config/schema.ts +694 -0
- package/my-final-test/core/config/validator.ts +540 -0
- package/my-final-test/core/framework/__tests__/server.test.ts +233 -0
- package/my-final-test/core/framework/client.ts +132 -0
- package/my-final-test/core/framework/index.ts +8 -0
- package/my-final-test/core/framework/server.ts +501 -0
- package/my-final-test/core/framework/types.ts +63 -0
- package/my-final-test/core/plugins/__tests__/built-in.test.ts.disabled +366 -0
- package/my-final-test/core/plugins/__tests__/manager.test.ts +398 -0
- package/my-final-test/core/plugins/__tests__/monitoring.test.ts +401 -0
- package/my-final-test/core/plugins/__tests__/registry.test.ts +335 -0
- package/my-final-test/core/plugins/built-in/index.ts +142 -0
- package/my-final-test/core/plugins/built-in/logger/index.ts +180 -0
- package/my-final-test/core/plugins/built-in/monitoring/README.md +193 -0
- package/my-final-test/core/plugins/built-in/monitoring/index.ts +912 -0
- package/my-final-test/core/plugins/built-in/static/index.ts +289 -0
- package/my-final-test/core/plugins/built-in/swagger/index.ts +229 -0
- package/my-final-test/core/plugins/built-in/vite/index.ts +316 -0
- package/my-final-test/core/plugins/config.ts +348 -0
- package/my-final-test/core/plugins/discovery.ts +350 -0
- package/my-final-test/core/plugins/executor.ts +351 -0
- package/my-final-test/core/plugins/index.ts +195 -0
- package/my-final-test/core/plugins/manager.ts +583 -0
- package/my-final-test/core/plugins/registry.ts +424 -0
- package/my-final-test/core/plugins/types.ts +254 -0
- package/my-final-test/core/server/framework.ts +123 -0
- package/my-final-test/core/server/index.ts +8 -0
- package/my-final-test/core/server/plugins/database.ts +182 -0
- package/my-final-test/core/server/plugins/logger.ts +47 -0
- package/my-final-test/core/server/plugins/swagger.ts +34 -0
- package/my-final-test/core/server/standalone.ts +91 -0
- package/my-final-test/core/templates/create-project.ts +455 -0
- package/my-final-test/core/types/api.ts +169 -0
- package/my-final-test/core/types/build.ts +174 -0
- package/my-final-test/core/types/config.ts +68 -0
- package/my-final-test/core/types/index.ts +127 -0
- package/my-final-test/core/types/plugin.ts +94 -0
- package/my-final-test/core/utils/__tests__/errors.test.ts +139 -0
- package/my-final-test/core/utils/__tests__/helpers.test.ts +297 -0
- package/my-final-test/core/utils/__tests__/logger.test.ts +141 -0
- package/my-final-test/core/utils/env-runtime-v2.ts +232 -0
- package/my-final-test/core/utils/env-runtime.ts +252 -0
- package/my-final-test/core/utils/errors/codes.ts +115 -0
- package/my-final-test/core/utils/errors/handlers.ts +63 -0
- package/my-final-test/core/utils/errors/index.ts +81 -0
- package/my-final-test/core/utils/helpers.ts +180 -0
- package/my-final-test/core/utils/index.ts +18 -0
- package/my-final-test/core/utils/logger/index.ts +161 -0
- package/my-final-test/core/utils/logger.ts +106 -0
- package/my-final-test/core/utils/monitoring/index.ts +212 -0
- package/my-final-test/package.json +68 -0
- package/my-final-test/tsconfig.json +51 -0
- package/my-final-test/vite.config.ts +42 -0
- package/nginx-lb.conf +37 -0
- package/package-template.json +32 -15
- package/package.json +71 -30
- package/publish-setup.md +111 -0
- package/publish.sh +63 -0
- package/run-clean.ts +26 -0
- package/run-env-tests.ts +313 -0
- package/tailwind.config.js +34 -0
- package/teste-corrigido/README.md +44 -0
- package/teste-corrigido/app/client/README.md +69 -0
- package/teste-corrigido/app/client/frontend-only.ts +12 -0
- package/teste-corrigido/app/client/index.html +13 -0
- package/teste-corrigido/app/client/public/vite.svg +1 -0
- package/teste-corrigido/app/client/src/App.css +883 -0
- package/teste-corrigido/app/client/src/App.tsx +669 -0
- package/teste-corrigido/app/client/src/assets/react.svg +1 -0
- package/teste-corrigido/app/client/src/components/TestPage.tsx +453 -0
- package/teste-corrigido/app/client/src/index.css +51 -0
- package/teste-corrigido/app/client/src/lib/eden-api.ts +110 -0
- package/teste-corrigido/app/client/src/main.tsx +10 -0
- package/teste-corrigido/app/client/src/vite-env.d.ts +1 -0
- package/teste-corrigido/app/client/tsconfig.app.json +43 -0
- package/teste-corrigido/app/client/tsconfig.json +7 -0
- package/teste-corrigido/app/client/tsconfig.node.json +25 -0
- package/teste-corrigido/app/server/app.ts +10 -0
- package/teste-corrigido/app/server/backend-only.ts +15 -0
- package/teste-corrigido/app/server/controllers/users.controller.ts +69 -0
- package/teste-corrigido/app/server/index.ts +104 -0
- package/teste-corrigido/app/server/routes/index.ts +25 -0
- package/teste-corrigido/app/server/routes/users.routes.ts +121 -0
- package/teste-corrigido/app/server/types/index.ts +1 -0
- package/teste-corrigido/app/shared/types/index.ts +18 -0
- package/teste-corrigido/bun.lock +1053 -0
- package/teste-corrigido/core/__tests__/integration.test.ts +227 -0
- package/teste-corrigido/core/build/index.ts +186 -0
- package/teste-corrigido/core/cli/command-registry.ts +334 -0
- package/teste-corrigido/core/cli/index.ts +394 -0
- package/teste-corrigido/core/cli/plugin-discovery.ts +200 -0
- package/teste-corrigido/core/client/standalone.ts +57 -0
- package/teste-corrigido/core/config/__tests__/config-loader.test.ts +591 -0
- package/teste-corrigido/core/config/__tests__/config-merger.test.ts +657 -0
- package/teste-corrigido/core/config/__tests__/env-converter.test.ts +372 -0
- package/teste-corrigido/core/config/__tests__/env-processor.test.ts +431 -0
- package/teste-corrigido/core/config/__tests__/env.test.ts +452 -0
- package/teste-corrigido/core/config/__tests__/integration.test.ts +418 -0
- package/teste-corrigido/core/config/__tests__/loader.test.ts +331 -0
- package/teste-corrigido/core/config/__tests__/schema.test.ts +129 -0
- package/teste-corrigido/core/config/__tests__/validator.test.ts +318 -0
- package/teste-corrigido/core/config/env-dynamic.ts +326 -0
- package/teste-corrigido/core/config/env.ts +597 -0
- package/teste-corrigido/core/config/index.ts +317 -0
- package/teste-corrigido/core/config/loader.ts +546 -0
- package/teste-corrigido/core/config/runtime-config.ts +322 -0
- package/teste-corrigido/core/config/schema.ts +694 -0
- package/teste-corrigido/core/config/validator.ts +540 -0
- package/teste-corrigido/core/framework/__tests__/server.test.ts +233 -0
- package/teste-corrigido/core/framework/client.ts +132 -0
- package/teste-corrigido/core/framework/index.ts +8 -0
- package/teste-corrigido/core/framework/server.ts +501 -0
- package/teste-corrigido/core/framework/types.ts +63 -0
- package/teste-corrigido/core/plugins/__tests__/built-in.test.ts.disabled +366 -0
- package/teste-corrigido/core/plugins/__tests__/manager.test.ts +398 -0
- package/teste-corrigido/core/plugins/__tests__/monitoring.test.ts +401 -0
- package/teste-corrigido/core/plugins/__tests__/registry.test.ts +335 -0
- package/teste-corrigido/core/plugins/built-in/index.ts +142 -0
- package/teste-corrigido/core/plugins/built-in/logger/index.ts +180 -0
- package/teste-corrigido/core/plugins/built-in/monitoring/README.md +193 -0
- package/teste-corrigido/core/plugins/built-in/monitoring/index.ts +912 -0
- package/teste-corrigido/core/plugins/built-in/static/index.ts +289 -0
- package/teste-corrigido/core/plugins/built-in/swagger/index.ts +229 -0
- package/teste-corrigido/core/plugins/built-in/vite/index.ts +316 -0
- package/teste-corrigido/core/plugins/config.ts +348 -0
- package/teste-corrigido/core/plugins/discovery.ts +350 -0
- package/teste-corrigido/core/plugins/executor.ts +351 -0
- package/teste-corrigido/core/plugins/index.ts +195 -0
- package/teste-corrigido/core/plugins/manager.ts +583 -0
- package/teste-corrigido/core/plugins/registry.ts +424 -0
- package/teste-corrigido/core/plugins/types.ts +254 -0
- package/teste-corrigido/core/server/framework.ts +123 -0
- package/teste-corrigido/core/server/index.ts +8 -0
- package/teste-corrigido/core/server/plugins/database.ts +182 -0
- package/teste-corrigido/core/server/plugins/logger.ts +47 -0
- package/teste-corrigido/core/server/plugins/swagger.ts +34 -0
- package/teste-corrigido/core/server/standalone.ts +91 -0
- package/teste-corrigido/core/templates/create-project.ts +455 -0
- package/teste-corrigido/core/types/api.ts +169 -0
- package/teste-corrigido/core/types/build.ts +174 -0
- package/teste-corrigido/core/types/config.ts +68 -0
- package/teste-corrigido/core/types/index.ts +127 -0
- package/teste-corrigido/core/types/plugin.ts +94 -0
- package/teste-corrigido/core/utils/__tests__/errors.test.ts +139 -0
- package/teste-corrigido/core/utils/__tests__/helpers.test.ts +297 -0
- package/teste-corrigido/core/utils/__tests__/logger.test.ts +141 -0
- package/teste-corrigido/core/utils/env-runtime-v2.ts +232 -0
- package/teste-corrigido/core/utils/env-runtime.ts +252 -0
- package/teste-corrigido/core/utils/errors/codes.ts +115 -0
- package/teste-corrigido/core/utils/errors/handlers.ts +63 -0
- package/teste-corrigido/core/utils/errors/index.ts +81 -0
- package/teste-corrigido/core/utils/helpers.ts +180 -0
- package/teste-corrigido/core/utils/index.ts +18 -0
- package/teste-corrigido/core/utils/logger/index.ts +161 -0
- package/teste-corrigido/core/utils/logger.ts +106 -0
- package/teste-corrigido/core/utils/monitoring/index.ts +212 -0
- package/teste-corrigido/package-template.json +51 -0
- package/teste-corrigido/package.json +51 -0
- package/teste-corrigido/tsconfig.json +51 -0
- package/teste-corrigido/vite.config.ts +42 -0
- package/teste-final-npm/README.md +44 -0
- package/teste-final-npm/app/client/README.md +69 -0
- package/teste-final-npm/app/client/frontend-only.ts +12 -0
- package/teste-final-npm/app/client/index.html +13 -0
- package/teste-final-npm/app/client/public/vite.svg +1 -0
- package/teste-final-npm/app/client/src/App.css +883 -0
- package/teste-final-npm/app/client/src/App.tsx +669 -0
- package/teste-final-npm/app/client/src/assets/react.svg +1 -0
- package/teste-final-npm/app/client/src/components/TestPage.tsx +453 -0
- package/teste-final-npm/app/client/src/index.css +51 -0
- package/teste-final-npm/app/client/src/lib/eden-api.ts +110 -0
- package/teste-final-npm/app/client/src/main.tsx +10 -0
- package/teste-final-npm/app/client/src/vite-env.d.ts +1 -0
- package/teste-final-npm/app/client/tsconfig.app.json +43 -0
- package/teste-final-npm/app/client/tsconfig.json +7 -0
- package/teste-final-npm/app/client/tsconfig.node.json +25 -0
- package/teste-final-npm/app/server/app.ts +10 -0
- package/teste-final-npm/app/server/backend-only.ts +15 -0
- package/teste-final-npm/app/server/controllers/users.controller.ts +69 -0
- package/teste-final-npm/app/server/index.ts +104 -0
- package/teste-final-npm/app/server/routes/index.ts +25 -0
- package/teste-final-npm/app/server/routes/users.routes.ts +121 -0
- package/teste-final-npm/app/server/types/index.ts +1 -0
- package/teste-final-npm/app/shared/types/index.ts +18 -0
- package/teste-final-npm/bun.lock +1053 -0
- package/teste-final-npm/core/__tests__/integration.test.ts +227 -0
- package/teste-final-npm/core/build/index.ts +186 -0
- package/teste-final-npm/core/cli/command-registry.ts +334 -0
- package/teste-final-npm/core/cli/index.ts +394 -0
- package/teste-final-npm/core/cli/plugin-discovery.ts +200 -0
- package/teste-final-npm/core/client/standalone.ts +57 -0
- package/teste-final-npm/core/config/__tests__/config-loader.test.ts +591 -0
- package/teste-final-npm/core/config/__tests__/config-merger.test.ts +657 -0
- package/teste-final-npm/core/config/__tests__/env-converter.test.ts +372 -0
- package/teste-final-npm/core/config/__tests__/env-processor.test.ts +431 -0
- package/teste-final-npm/core/config/__tests__/env.test.ts +452 -0
- package/teste-final-npm/core/config/__tests__/integration.test.ts +418 -0
- package/teste-final-npm/core/config/__tests__/loader.test.ts +331 -0
- package/teste-final-npm/core/config/__tests__/schema.test.ts +129 -0
- package/teste-final-npm/core/config/__tests__/validator.test.ts +318 -0
- package/teste-final-npm/core/config/env-dynamic.ts +326 -0
- package/teste-final-npm/core/config/env.ts +597 -0
- package/teste-final-npm/core/config/index.ts +317 -0
- package/teste-final-npm/core/config/loader.ts +546 -0
- package/teste-final-npm/core/config/runtime-config.ts +322 -0
- package/teste-final-npm/core/config/schema.ts +694 -0
- package/teste-final-npm/core/config/validator.ts +540 -0
- package/teste-final-npm/core/framework/__tests__/server.test.ts +233 -0
- package/teste-final-npm/core/framework/client.ts +132 -0
- package/teste-final-npm/core/framework/index.ts +8 -0
- package/teste-final-npm/core/framework/server.ts +501 -0
- package/teste-final-npm/core/framework/types.ts +63 -0
- package/teste-final-npm/core/plugins/__tests__/built-in.test.ts.disabled +366 -0
- package/teste-final-npm/core/plugins/__tests__/manager.test.ts +398 -0
- package/teste-final-npm/core/plugins/__tests__/monitoring.test.ts +401 -0
- package/teste-final-npm/core/plugins/__tests__/registry.test.ts +335 -0
- package/teste-final-npm/core/plugins/built-in/index.ts +142 -0
- package/teste-final-npm/core/plugins/built-in/logger/index.ts +180 -0
- package/teste-final-npm/core/plugins/built-in/monitoring/README.md +193 -0
- package/teste-final-npm/core/plugins/built-in/monitoring/index.ts +912 -0
- package/teste-final-npm/core/plugins/built-in/static/index.ts +289 -0
- package/teste-final-npm/core/plugins/built-in/swagger/index.ts +229 -0
- package/teste-final-npm/core/plugins/built-in/vite/index.ts +316 -0
- package/teste-final-npm/core/plugins/config.ts +348 -0
- package/teste-final-npm/core/plugins/discovery.ts +350 -0
- package/teste-final-npm/core/plugins/executor.ts +351 -0
- package/teste-final-npm/core/plugins/index.ts +195 -0
- package/teste-final-npm/core/plugins/manager.ts +583 -0
- package/teste-final-npm/core/plugins/registry.ts +424 -0
- package/teste-final-npm/core/plugins/types.ts +254 -0
- package/teste-final-npm/core/server/framework.ts +123 -0
- package/teste-final-npm/core/server/index.ts +8 -0
- package/teste-final-npm/core/server/plugins/database.ts +182 -0
- package/teste-final-npm/core/server/plugins/logger.ts +47 -0
- package/teste-final-npm/core/server/plugins/swagger.ts +34 -0
- package/teste-final-npm/core/server/standalone.ts +91 -0
- package/teste-final-npm/core/templates/create-project.ts +455 -0
- package/teste-final-npm/core/types/api.ts +169 -0
- package/teste-final-npm/core/types/build.ts +174 -0
- package/teste-final-npm/core/types/config.ts +68 -0
- package/teste-final-npm/core/types/index.ts +127 -0
- package/teste-final-npm/core/types/plugin.ts +94 -0
- package/teste-final-npm/core/utils/__tests__/errors.test.ts +139 -0
- package/teste-final-npm/core/utils/__tests__/helpers.test.ts +297 -0
- package/teste-final-npm/core/utils/__tests__/logger.test.ts +141 -0
- package/teste-final-npm/core/utils/env-runtime-v2.ts +232 -0
- package/teste-final-npm/core/utils/env-runtime.ts +252 -0
- package/teste-final-npm/core/utils/errors/codes.ts +115 -0
- package/teste-final-npm/core/utils/errors/handlers.ts +63 -0
- package/teste-final-npm/core/utils/errors/index.ts +81 -0
- package/teste-final-npm/core/utils/helpers.ts +180 -0
- package/teste-final-npm/core/utils/index.ts +18 -0
- package/teste-final-npm/core/utils/logger/index.ts +161 -0
- package/teste-final-npm/core/utils/logger.ts +106 -0
- package/teste-final-npm/core/utils/monitoring/index.ts +212 -0
- package/teste-final-npm/package-template.json +51 -0
- package/teste-final-npm/package.json +51 -0
- package/teste-final-npm/tsconfig.json +51 -0
- package/teste-final-npm/vite.config.ts +42 -0
- package/tests/__mocks__/api.ts +56 -0
- package/tests/fixtures/users.ts +69 -0
- package/tests/integration/api/users.routes.test.ts +221 -0
- package/tests/setup.ts +29 -0
- package/tests/unit/app/client/App-simple.test.tsx +56 -0
- package/tests/unit/app/client/App.test.tsx.skip +237 -0
- package/tests/unit/app/client/eden-api.test.ts +186 -0
- package/tests/unit/app/client/simple.test.tsx +23 -0
- package/tests/unit/app/controllers/users.controller.test.ts +150 -0
- package/tests/unit/core/create-project.test.ts.skip +95 -0
- package/tests/unit/core/framework.test.ts +144 -0
- package/tests/unit/core/plugins/logger.test.ts.skip +268 -0
- package/tests/unit/core/plugins/vite.test.ts.disabled +188 -0
- package/tests/utils/test-helpers.ts +61 -0
- package/types/global.d.ts +30 -0
- package/types/vitest.d.ts +9 -0
- package/vitest.config.ts +50 -0
- package/workspace.json +6 -0
- package/.env +0 -30
|
@@ -0,0 +1,669 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react'
|
|
2
|
+
import { api, getErrorMessage } from './lib/eden-api'
|
|
3
|
+
import TestPage from './components/TestPage'
|
|
4
|
+
|
|
5
|
+
type TabType = 'overview' | 'demo' | 'api-docs' | 'tests'
|
|
6
|
+
|
|
7
|
+
interface User {
|
|
8
|
+
id: number
|
|
9
|
+
name: string
|
|
10
|
+
email: string
|
|
11
|
+
createdAt: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function App() {
|
|
15
|
+
const [activeTab, setActiveTab] = useState<TabType>('overview')
|
|
16
|
+
const [users, setUsers] = useState<User[]>([])
|
|
17
|
+
const [loading, setLoading] = useState(false)
|
|
18
|
+
const [apiStatus, setApiStatus] = useState<'online' | 'offline'>('offline')
|
|
19
|
+
const [name, setName] = useState('')
|
|
20
|
+
const [email, setEmail] = useState('')
|
|
21
|
+
const [submitting, setSubmitting] = useState(false)
|
|
22
|
+
const [message, setMessage] = useState<{ type: 'success' | 'error', text: string } | null>(null)
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
checkApiStatus()
|
|
26
|
+
loadUsers()
|
|
27
|
+
}, []) // eslint-disable-line react-hooks/exhaustive-deps
|
|
28
|
+
|
|
29
|
+
const checkApiStatus = async () => {
|
|
30
|
+
try {
|
|
31
|
+
const { data, error } = await api.health.get()
|
|
32
|
+
if (error) {
|
|
33
|
+
setApiStatus('offline')
|
|
34
|
+
} else {
|
|
35
|
+
setApiStatus('online')
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
setApiStatus('offline')
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const loadUsers = async () => {
|
|
43
|
+
try {
|
|
44
|
+
setLoading(true)
|
|
45
|
+
const { data, error } = await api.users.get()
|
|
46
|
+
|
|
47
|
+
if (error) {
|
|
48
|
+
showMessage('error', `Erro ao carregar usuários: ${error.status}`)
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ✨ Eden Treaty infere automaticamente que data.users é User[]
|
|
53
|
+
setUsers(data.users || [])
|
|
54
|
+
} catch (error) {
|
|
55
|
+
showMessage('error', getErrorMessage(error))
|
|
56
|
+
} finally {
|
|
57
|
+
setLoading(false)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
62
|
+
e.preventDefault()
|
|
63
|
+
if (!name.trim() || !email.trim()) return
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
setSubmitting(true)
|
|
67
|
+
const { data: result, error } = await api.users.post({
|
|
68
|
+
name: name.trim(),
|
|
69
|
+
email: email.trim()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
if (error) {
|
|
73
|
+
showMessage('error', `Erro ao criar usuário: ${error.status}`)
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ✨ Eden Treaty infere que result é UserResponse
|
|
78
|
+
if (result.success && result.user) {
|
|
79
|
+
setUsers(prev => [...prev, result.user])
|
|
80
|
+
setName('')
|
|
81
|
+
setEmail('')
|
|
82
|
+
showMessage('success', `Usuário ${name} adicionado com sucesso!`)
|
|
83
|
+
} else {
|
|
84
|
+
showMessage('error', result.message || 'Erro ao criar usuário')
|
|
85
|
+
}
|
|
86
|
+
} catch (error) {
|
|
87
|
+
showMessage('error', getErrorMessage(error))
|
|
88
|
+
} finally {
|
|
89
|
+
setSubmitting(false)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const handleDelete = async (userId: number, userName: string) => {
|
|
94
|
+
if (!confirm(`Tem certeza que deseja remover ${userName}?`)) return
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
// ✨ Chamar API de delete via Eden Treaty nativo
|
|
98
|
+
const { data: result, error } = await api.users({ id: userId }).delete()
|
|
99
|
+
|
|
100
|
+
if (error) {
|
|
101
|
+
showMessage('error', `Erro ao deletar usuário: ${error.status}`)
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ✨ Eden Treaty infere que result é UserResponse
|
|
106
|
+
if (result.success) {
|
|
107
|
+
// Remover da lista local após sucesso da API
|
|
108
|
+
setUsers(prev => prev.filter(user => user.id !== userId))
|
|
109
|
+
showMessage('success', `Usuário ${userName} removido com sucesso!`)
|
|
110
|
+
} else {
|
|
111
|
+
showMessage('error', result.message || 'Erro ao deletar usuário')
|
|
112
|
+
}
|
|
113
|
+
} catch (error) {
|
|
114
|
+
showMessage('error', getErrorMessage(error))
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const showMessage = (type: 'success' | 'error', text: string) => {
|
|
119
|
+
setMessage({ type, text })
|
|
120
|
+
setTimeout(() => setMessage(null), 5000)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const getInitials = (name: string) => {
|
|
124
|
+
return name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const renderOverview = () => (
|
|
128
|
+
<div className="relative">
|
|
129
|
+
{/* Hero Section with gradient background */}
|
|
130
|
+
<div className="relative overflow-hidden bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 rounded-3xl mb-12">
|
|
131
|
+
<div className="absolute inset-0 bg-gradient-to-r from-blue-900/20 to-purple-900/20"></div>
|
|
132
|
+
<div className="relative px-8 py-16 text-center">
|
|
133
|
+
<div className="mx-auto max-w-4xl">
|
|
134
|
+
<h1 className="text-5xl font-bold text-white mb-6 bg-gradient-to-r from-blue-400 via-purple-400 to-emerald-400 bg-clip-text text-transparent">
|
|
135
|
+
🔥 FluxStack v1.4.0 ⚡
|
|
136
|
+
</h1>
|
|
137
|
+
<p className="text-xl text-slate-300 mb-8 max-w-2xl mx-auto leading-relaxed">
|
|
138
|
+
Framework full-stack TypeScript moderno com hot reload coordenado e Tailwind CSS 4! 🚀
|
|
139
|
+
</p>
|
|
140
|
+
<div className="flex flex-wrap justify-center gap-3 mb-8">
|
|
141
|
+
<span className="px-4 py-2 bg-blue-500/20 text-blue-300 rounded-full text-sm font-medium border border-blue-500/30">
|
|
142
|
+
TypeScript
|
|
143
|
+
</span>
|
|
144
|
+
<span className="px-4 py-2 bg-purple-500/20 text-purple-300 rounded-full text-sm font-medium border border-purple-500/30">
|
|
145
|
+
Elysia.js
|
|
146
|
+
</span>
|
|
147
|
+
<span className="px-4 py-2 bg-emerald-500/20 text-emerald-300 rounded-full text-sm font-medium border border-emerald-500/30">
|
|
148
|
+
React 19
|
|
149
|
+
</span>
|
|
150
|
+
<span className="px-4 py-2 bg-orange-500/20 text-orange-300 rounded-full text-sm font-medium border border-orange-500/30">
|
|
151
|
+
Tailwind CSS 4
|
|
152
|
+
</span>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
{/* Features Grid */}
|
|
159
|
+
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 mb-12">
|
|
160
|
+
{[
|
|
161
|
+
{
|
|
162
|
+
icon: "🚀",
|
|
163
|
+
title: "Elysia.js",
|
|
164
|
+
description: "Backend rápido e type-safe com Bun runtime",
|
|
165
|
+
color: "from-blue-500 to-cyan-500"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
icon: "⚛️",
|
|
169
|
+
title: "React + Vite",
|
|
170
|
+
description: "Frontend moderno com hot-reload ultrarrápido",
|
|
171
|
+
color: "from-purple-500 to-pink-500"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
icon: "🔗",
|
|
175
|
+
title: "Eden Treaty",
|
|
176
|
+
description: "API type-safe com inferência automática de tipos",
|
|
177
|
+
color: "from-emerald-500 to-teal-500"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
icon: "🐳",
|
|
181
|
+
title: "Docker Ready",
|
|
182
|
+
description: "Deploy fácil com configurações otimizadas",
|
|
183
|
+
color: "from-indigo-500 to-purple-500"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
icon: "🧪",
|
|
187
|
+
title: "Testing",
|
|
188
|
+
description: "Vitest + Testing Library configurados",
|
|
189
|
+
color: "from-orange-500 to-red-500"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
icon: "🎨",
|
|
193
|
+
title: "Tailwind CSS 4",
|
|
194
|
+
description: "Styling moderno e responsivo",
|
|
195
|
+
color: "from-teal-500 to-green-500"
|
|
196
|
+
}
|
|
197
|
+
].map((feature, index) => (
|
|
198
|
+
<div
|
|
199
|
+
key={index}
|
|
200
|
+
className="group relative bg-white rounded-2xl p-6 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 border border-gray-200"
|
|
201
|
+
>
|
|
202
|
+
<div className={`absolute inset-0 bg-gradient-to-r ${feature.color} opacity-0 group-hover:opacity-5 rounded-2xl transition-opacity duration-300`}></div>
|
|
203
|
+
<div className="relative">
|
|
204
|
+
<div className="text-4xl mb-4">{feature.icon}</div>
|
|
205
|
+
<h3 className="text-xl font-semibold text-gray-900 mb-2">{feature.title}</h3>
|
|
206
|
+
<p className="text-gray-600 leading-relaxed">{feature.description}</p>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
))}
|
|
210
|
+
</div>
|
|
211
|
+
|
|
212
|
+
{/* Tech Stack Section */}
|
|
213
|
+
<div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
|
|
214
|
+
<div className="bg-gradient-to-r from-gray-50 to-slate-100 px-8 py-6 border-b border-gray-200">
|
|
215
|
+
<h2 className="text-2xl font-bold text-gray-900 text-center">Stack Tecnológica</h2>
|
|
216
|
+
</div>
|
|
217
|
+
<div className="p-8">
|
|
218
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
219
|
+
{[
|
|
220
|
+
{
|
|
221
|
+
title: "Backend",
|
|
222
|
+
color: "blue",
|
|
223
|
+
items: [
|
|
224
|
+
"Elysia.js - Web framework",
|
|
225
|
+
"Bun - Runtime & package manager",
|
|
226
|
+
"TypeScript - Type safety"
|
|
227
|
+
]
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
title: "Frontend",
|
|
231
|
+
color: "purple",
|
|
232
|
+
items: [
|
|
233
|
+
"React 19 - UI library",
|
|
234
|
+
"Vite - Build tool",
|
|
235
|
+
"Tailwind CSS 4 - Styling"
|
|
236
|
+
]
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
title: "Comunicação",
|
|
240
|
+
color: "emerald",
|
|
241
|
+
items: [
|
|
242
|
+
"Eden Treaty - Type-safe API",
|
|
243
|
+
"End-to-end TypeScript",
|
|
244
|
+
"Automatic type inference"
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
].map((category, index) => (
|
|
248
|
+
<div key={index} className="space-y-4">
|
|
249
|
+
<h3 className={`text-lg font-semibold text-${category.color}-600 pb-2 border-b-2 border-${category.color}-100`}>
|
|
250
|
+
{category.title}
|
|
251
|
+
</h3>
|
|
252
|
+
<ul className="space-y-3">
|
|
253
|
+
{category.items.map((item, itemIndex) => (
|
|
254
|
+
<li key={itemIndex} className="flex items-start gap-3 text-gray-600">
|
|
255
|
+
<div className={`w-2 h-2 rounded-full bg-${category.color}-400 flex-shrink-0 mt-2`}></div>
|
|
256
|
+
<span>{item}</span>
|
|
257
|
+
</li>
|
|
258
|
+
))}
|
|
259
|
+
</ul>
|
|
260
|
+
</div>
|
|
261
|
+
))}
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
const renderDemo = () => (
|
|
269
|
+
<div className="space-y-8">
|
|
270
|
+
{/* Header */}
|
|
271
|
+
<div className="text-center">
|
|
272
|
+
<h2 className="text-3xl font-bold text-gray-900 mb-4">🔥 Demo Interativo</h2>
|
|
273
|
+
<p className="text-lg text-gray-600 max-w-2xl mx-auto">
|
|
274
|
+
Teste a API em tempo real com hot reload coordenado e Eden Treaty 🚀
|
|
275
|
+
</p>
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
{/* Stats Cards */}
|
|
279
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
280
|
+
<div className="bg-gradient-to-br from-blue-50 to-blue-100 border border-blue-200 rounded-2xl p-6 text-center">
|
|
281
|
+
<div className="text-4xl font-bold text-blue-600 mb-2">{users.length}</div>
|
|
282
|
+
<div className="text-sm font-medium text-blue-700 uppercase tracking-wide">Usuários</div>
|
|
283
|
+
</div>
|
|
284
|
+
<div className={`bg-gradient-to-br ${apiStatus === 'online' ? 'from-emerald-50 to-emerald-100 border-emerald-200' : 'from-red-50 to-red-100 border-red-200'} border rounded-2xl p-6 text-center`}>
|
|
285
|
+
<div className="text-4xl mb-2">{apiStatus === 'online' ? '✅' : '❌'}</div>
|
|
286
|
+
<div className={`text-sm font-medium uppercase tracking-wide ${apiStatus === 'online' ? 'text-emerald-700' : 'text-red-700'}`}>
|
|
287
|
+
API {apiStatus === 'online' ? 'Online' : 'Offline'}
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
<div className="bg-gradient-to-br from-purple-50 to-purple-100 border border-purple-200 rounded-2xl p-6 text-center">
|
|
291
|
+
<div className="text-4xl mb-2">🚀</div>
|
|
292
|
+
<div className="text-sm font-medium text-purple-700 uppercase tracking-wide">Eden Treaty</div>
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
|
|
296
|
+
{/* Add User Form */}
|
|
297
|
+
<div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
|
|
298
|
+
<div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200">
|
|
299
|
+
<h3 className="text-lg font-semibold text-gray-900">Adicionar Usuário</h3>
|
|
300
|
+
</div>
|
|
301
|
+
<div className="p-6">
|
|
302
|
+
<form onSubmit={handleSubmit} className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-6">
|
|
303
|
+
<div className="space-y-2">
|
|
304
|
+
<label className="block text-sm font-medium text-gray-700">Nome</label>
|
|
305
|
+
<input
|
|
306
|
+
type="text"
|
|
307
|
+
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 placeholder-gray-400"
|
|
308
|
+
value={name}
|
|
309
|
+
onChange={(e) => setName(e.target.value)}
|
|
310
|
+
placeholder="Nome completo"
|
|
311
|
+
required
|
|
312
|
+
/>
|
|
313
|
+
</div>
|
|
314
|
+
<div className="space-y-2">
|
|
315
|
+
<label className="block text-sm font-medium text-gray-700">Email</label>
|
|
316
|
+
<input
|
|
317
|
+
type="email"
|
|
318
|
+
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 placeholder-gray-400"
|
|
319
|
+
value={email}
|
|
320
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
321
|
+
placeholder="email@exemplo.com"
|
|
322
|
+
required
|
|
323
|
+
/>
|
|
324
|
+
</div>
|
|
325
|
+
<div className="md:col-span-2">
|
|
326
|
+
<button
|
|
327
|
+
type="submit"
|
|
328
|
+
className="w-full md:w-auto px-8 py-3 bg-gradient-to-r from-blue-600 to-blue-700 text-white font-medium rounded-xl hover:from-blue-700 hover:to-blue-800 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 shadow-lg hover:shadow-xl"
|
|
329
|
+
disabled={submitting || !name.trim() || !email.trim()}
|
|
330
|
+
>
|
|
331
|
+
{submitting ? (
|
|
332
|
+
<span className="flex items-center gap-2">
|
|
333
|
+
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
|
|
334
|
+
Adicionando...
|
|
335
|
+
</span>
|
|
336
|
+
) : (
|
|
337
|
+
'Adicionar Usuário'
|
|
338
|
+
)}
|
|
339
|
+
</button>
|
|
340
|
+
</div>
|
|
341
|
+
</form>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
|
|
345
|
+
{/* Users List */}
|
|
346
|
+
<div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
|
|
347
|
+
<div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200 flex justify-between items-center">
|
|
348
|
+
<h3 className="text-lg font-semibold text-gray-900">Usuários ({users.length})</h3>
|
|
349
|
+
<button
|
|
350
|
+
className="flex items-center gap-2 px-4 py-2 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 transition-all duration-200"
|
|
351
|
+
onClick={loadUsers}
|
|
352
|
+
disabled={loading}
|
|
353
|
+
>
|
|
354
|
+
{loading ? (
|
|
355
|
+
<div className="w-4 h-4 border-2 border-gray-400 border-t-transparent rounded-full animate-spin"></div>
|
|
356
|
+
) : (
|
|
357
|
+
<span className="text-lg">↻</span>
|
|
358
|
+
)}
|
|
359
|
+
Atualizar
|
|
360
|
+
</button>
|
|
361
|
+
</div>
|
|
362
|
+
|
|
363
|
+
<div className="p-6">
|
|
364
|
+
{loading ? (
|
|
365
|
+
<div className="text-center py-12">
|
|
366
|
+
<div className="w-8 h-8 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin mx-auto mb-4"></div>
|
|
367
|
+
<p className="text-gray-600">Carregando usuários...</p>
|
|
368
|
+
</div>
|
|
369
|
+
) : users.length === 0 ? (
|
|
370
|
+
<div className="text-center py-12">
|
|
371
|
+
<div className="text-6xl mb-4 opacity-50">👥</div>
|
|
372
|
+
<h4 className="text-lg font-medium text-gray-900 mb-2">Nenhum usuário encontrado</h4>
|
|
373
|
+
<p className="text-gray-600">Adicione o primeiro usuário usando o formulário acima</p>
|
|
374
|
+
</div>
|
|
375
|
+
) : (
|
|
376
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
377
|
+
{users.map(user => (
|
|
378
|
+
<div key={user.id} className="group bg-gray-50 border border-gray-200 rounded-xl p-4 hover:shadow-lg hover:border-blue-300 transition-all duration-200">
|
|
379
|
+
<div className="flex items-start gap-3">
|
|
380
|
+
<div className="w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center text-white font-bold text-sm flex-shrink-0">
|
|
381
|
+
{getInitials(user.name)}
|
|
382
|
+
</div>
|
|
383
|
+
<div className="flex-1 min-w-0">
|
|
384
|
+
<h4 className="font-medium text-gray-900 truncate">{user.name}</h4>
|
|
385
|
+
<p className="text-sm text-gray-600 truncate">{user.email}</p>
|
|
386
|
+
<button
|
|
387
|
+
className="mt-3 w-full px-3 py-2 bg-red-50 text-red-700 border border-red-200 rounded-lg hover:bg-red-100 hover:border-red-300 focus:ring-2 focus:ring-red-500 focus:ring-offset-2 transition-all duration-200 text-sm font-medium"
|
|
388
|
+
onClick={() => handleDelete(user.id, user.name)}
|
|
389
|
+
>
|
|
390
|
+
Remover
|
|
391
|
+
</button>
|
|
392
|
+
</div>
|
|
393
|
+
</div>
|
|
394
|
+
</div>
|
|
395
|
+
))}
|
|
396
|
+
</div>
|
|
397
|
+
)}
|
|
398
|
+
</div>
|
|
399
|
+
</div>
|
|
400
|
+
</div>
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
const renderApiDocs = () => (
|
|
404
|
+
<div className="space-y-8">
|
|
405
|
+
{/* Header */}
|
|
406
|
+
<div className="text-center">
|
|
407
|
+
<h2 className="text-3xl font-bold text-gray-900 mb-4">📚 Documentação da API</h2>
|
|
408
|
+
<p className="text-lg text-gray-600 max-w-2xl mx-auto">
|
|
409
|
+
Documentação interativa gerada automaticamente com Swagger UI
|
|
410
|
+
</p>
|
|
411
|
+
</div>
|
|
412
|
+
|
|
413
|
+
{/* Quick Links */}
|
|
414
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
415
|
+
<div className="group bg-white rounded-2xl p-6 shadow-lg border border-gray-200 hover:shadow-xl hover:border-blue-300 transition-all duration-300">
|
|
416
|
+
<div className="text-center">
|
|
417
|
+
<div className="text-4xl mb-4">📋</div>
|
|
418
|
+
<h3 className="text-xl font-semibold text-gray-900 mb-2">Swagger UI Interativo</h3>
|
|
419
|
+
<p className="text-gray-600 mb-6">Interface completa para testar todos os endpoints da API</p>
|
|
420
|
+
<a
|
|
421
|
+
href="/swagger"
|
|
422
|
+
target="_blank"
|
|
423
|
+
rel="noopener noreferrer"
|
|
424
|
+
className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-600 to-blue-700 text-white font-medium rounded-xl hover:from-blue-700 hover:to-blue-800 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-all duration-200 shadow-lg hover:shadow-xl"
|
|
425
|
+
>
|
|
426
|
+
🚀 Abrir em Nova Aba
|
|
427
|
+
</a>
|
|
428
|
+
</div>
|
|
429
|
+
</div>
|
|
430
|
+
|
|
431
|
+
<div className="group bg-white rounded-2xl p-6 shadow-lg border border-gray-200 hover:shadow-xl hover:border-purple-300 transition-all duration-300">
|
|
432
|
+
<div className="text-center">
|
|
433
|
+
<div className="text-4xl mb-4">📄</div>
|
|
434
|
+
<h3 className="text-xl font-semibold text-gray-900 mb-2">OpenAPI Spec (JSON)</h3>
|
|
435
|
+
<p className="text-gray-600 mb-6">Especificação OpenAPI em formato JSON para integração</p>
|
|
436
|
+
<a
|
|
437
|
+
href="/swagger/json"
|
|
438
|
+
target="_blank"
|
|
439
|
+
rel="noopener noreferrer"
|
|
440
|
+
className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-purple-600 to-purple-700 text-white font-medium rounded-xl hover:from-purple-700 hover:to-purple-800 focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 transition-all duration-200 shadow-lg hover:shadow-xl"
|
|
441
|
+
>
|
|
442
|
+
📋 Ver JSON
|
|
443
|
+
</a>
|
|
444
|
+
</div>
|
|
445
|
+
</div>
|
|
446
|
+
</div>
|
|
447
|
+
|
|
448
|
+
{/* Embedded Swagger */}
|
|
449
|
+
<div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
|
|
450
|
+
<div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200">
|
|
451
|
+
<h3 className="text-lg font-semibold text-gray-900">🔧 Documentação Integrada</h3>
|
|
452
|
+
</div>
|
|
453
|
+
<iframe
|
|
454
|
+
src="/swagger"
|
|
455
|
+
className="w-full h-[600px] border-0"
|
|
456
|
+
title="Swagger UI"
|
|
457
|
+
/>
|
|
458
|
+
</div>
|
|
459
|
+
|
|
460
|
+
{/* Eden Treaty Guide */}
|
|
461
|
+
<div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
|
|
462
|
+
<div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200">
|
|
463
|
+
<h3 className="text-lg font-semibold text-gray-900">🔧 Como usar Eden Treaty</h3>
|
|
464
|
+
</div>
|
|
465
|
+
<div className="p-6 space-y-6">
|
|
466
|
+
<div>
|
|
467
|
+
<h4 className="text-base font-semibold text-gray-900 mb-3">Configuração do Cliente:</h4>
|
|
468
|
+
<pre className="bg-gray-900 text-gray-100 p-4 rounded-xl overflow-x-auto text-sm border border-gray-700">
|
|
469
|
+
{`import { treaty } from '@elysiajs/eden'
|
|
470
|
+
import type { App } from './server'
|
|
471
|
+
|
|
472
|
+
const client = treaty<App>('http://localhost:3000')
|
|
473
|
+
export const api = client.api`}
|
|
474
|
+
</pre>
|
|
475
|
+
</div>
|
|
476
|
+
|
|
477
|
+
<div>
|
|
478
|
+
<h4 className="text-base font-semibold text-gray-900 mb-3">Exemplos de Uso:</h4>
|
|
479
|
+
<pre className="bg-gray-900 text-gray-100 p-4 rounded-xl overflow-x-auto text-sm border border-gray-700">
|
|
480
|
+
{`// Listar usuários
|
|
481
|
+
const users = await api.users.get()
|
|
482
|
+
|
|
483
|
+
// Criar usuário
|
|
484
|
+
const newUser = await api.users.post({
|
|
485
|
+
name: "João Silva",
|
|
486
|
+
email: "joao@example.com"
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
// Deletar usuário
|
|
490
|
+
await api.users["1"].delete()
|
|
491
|
+
|
|
492
|
+
// Health check
|
|
493
|
+
const health = await api.health.get()`}
|
|
494
|
+
</pre>
|
|
495
|
+
</div>
|
|
496
|
+
|
|
497
|
+
<div>
|
|
498
|
+
<h4 className="text-base font-semibold text-gray-900 mb-3">Com tratamento de erros:</h4>
|
|
499
|
+
<pre className="bg-gray-900 text-gray-100 p-4 rounded-xl overflow-x-auto text-sm border border-gray-700">
|
|
500
|
+
{`try {
|
|
501
|
+
const result = await apiCall(api.users.post({
|
|
502
|
+
name: "Maria Silva",
|
|
503
|
+
email: "maria@example.com"
|
|
504
|
+
}))
|
|
505
|
+
|
|
506
|
+
if (result.success) {
|
|
507
|
+
console.log('Usuário criado:', result.user)
|
|
508
|
+
}
|
|
509
|
+
} catch (error) {
|
|
510
|
+
console.error('Erro:', getErrorMessage(error))
|
|
511
|
+
}`}
|
|
512
|
+
</pre>
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
</div>
|
|
516
|
+
|
|
517
|
+
{/* Features */}
|
|
518
|
+
<div className="bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
|
|
519
|
+
<div className="bg-gradient-to-r from-gray-50 to-slate-100 px-6 py-4 border-b border-gray-200">
|
|
520
|
+
<h3 className="text-lg font-semibold text-gray-900 text-center">✨ Funcionalidades</h3>
|
|
521
|
+
</div>
|
|
522
|
+
<div className="p-6">
|
|
523
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
524
|
+
{[
|
|
525
|
+
{
|
|
526
|
+
icon: "🔒",
|
|
527
|
+
title: "Type Safety",
|
|
528
|
+
description: "Tipos TypeScript inferidos automaticamente"
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
icon: "⚡",
|
|
532
|
+
title: "Auto-complete",
|
|
533
|
+
description: "IntelliSense completo no editor"
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
icon: "🔄",
|
|
537
|
+
title: "Sincronização",
|
|
538
|
+
description: "Mudanças no backend refletem automaticamente no frontend"
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
icon: "🐛",
|
|
542
|
+
title: "Debugging",
|
|
543
|
+
description: "Erros de tipo detectados em tempo de compilação"
|
|
544
|
+
}
|
|
545
|
+
].map((feature, index) => (
|
|
546
|
+
<div key={index} className="flex items-start gap-4 p-4 rounded-xl bg-gray-50 hover:bg-gray-100 transition-colors duration-200">
|
|
547
|
+
<div className="text-2xl">{feature.icon}</div>
|
|
548
|
+
<div>
|
|
549
|
+
<h4 className="font-semibold text-gray-900 mb-1">{feature.title}</h4>
|
|
550
|
+
<p className="text-gray-600 text-sm">{feature.description}</p>
|
|
551
|
+
</div>
|
|
552
|
+
</div>
|
|
553
|
+
))}
|
|
554
|
+
</div>
|
|
555
|
+
</div>
|
|
556
|
+
</div>
|
|
557
|
+
</div>
|
|
558
|
+
)
|
|
559
|
+
|
|
560
|
+
return (
|
|
561
|
+
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-100">
|
|
562
|
+
{/* Header */}
|
|
563
|
+
<header className="bg-white/80 backdrop-blur-sm border-b border-gray-200 sticky top-0 z-50">
|
|
564
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
565
|
+
<div className="flex justify-between items-center h-16">
|
|
566
|
+
{/* Logo and Navigation */}
|
|
567
|
+
<div className="flex items-center space-x-8">
|
|
568
|
+
<div className="flex items-center space-x-3">
|
|
569
|
+
<div className="text-2xl font-bold bg-gradient-to-r from-blue-600 via-purple-600 to-indigo-600 bg-clip-text text-transparent">
|
|
570
|
+
🔥 FluxStack
|
|
571
|
+
</div>
|
|
572
|
+
<span className="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">
|
|
573
|
+
v1.4.0
|
|
574
|
+
</span>
|
|
575
|
+
</div>
|
|
576
|
+
|
|
577
|
+
{/* Navigation Tabs */}
|
|
578
|
+
<nav className="hidden md:flex space-x-1">
|
|
579
|
+
{[
|
|
580
|
+
{ id: 'overview', label: '📋 Visão Geral', icon: '📋' },
|
|
581
|
+
{ id: 'demo', label: '🚀 Demo', icon: '🚀' },
|
|
582
|
+
{ id: 'api-docs', label: '📚 API Docs', icon: '📚' },
|
|
583
|
+
{ id: 'tests', label: '🧪 Testes', icon: '🧪' }
|
|
584
|
+
].map(tab => (
|
|
585
|
+
<button
|
|
586
|
+
key={tab.id}
|
|
587
|
+
className={`px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200 ${
|
|
588
|
+
activeTab === tab.id
|
|
589
|
+
? 'bg-blue-100 text-blue-700 shadow-sm'
|
|
590
|
+
: 'text-gray-600 hover:text-gray-900 hover:bg-gray-100'
|
|
591
|
+
}`}
|
|
592
|
+
onClick={() => setActiveTab(tab.id as TabType)}
|
|
593
|
+
>
|
|
594
|
+
{tab.label}
|
|
595
|
+
</button>
|
|
596
|
+
))}
|
|
597
|
+
</nav>
|
|
598
|
+
</div>
|
|
599
|
+
|
|
600
|
+
{/* Status Badge */}
|
|
601
|
+
<div className={`flex items-center space-x-2 px-3 py-2 rounded-full text-sm font-medium ${
|
|
602
|
+
apiStatus === 'online'
|
|
603
|
+
? 'bg-emerald-100 text-emerald-700'
|
|
604
|
+
: 'bg-red-100 text-red-700'
|
|
605
|
+
}`}>
|
|
606
|
+
<div className={`w-2 h-2 rounded-full ${
|
|
607
|
+
apiStatus === 'online' ? 'bg-emerald-400' : 'bg-red-400'
|
|
608
|
+
}`}></div>
|
|
609
|
+
<span>API {apiStatus === 'online' ? 'Online' : 'Offline'}</span>
|
|
610
|
+
</div>
|
|
611
|
+
</div>
|
|
612
|
+
|
|
613
|
+
{/* Mobile Navigation */}
|
|
614
|
+
<div className="md:hidden pb-3">
|
|
615
|
+
<nav className="flex space-x-1">
|
|
616
|
+
{[
|
|
617
|
+
{ id: 'overview', label: '📋 Visão Geral' },
|
|
618
|
+
{ id: 'demo', label: '🚀 Demo' },
|
|
619
|
+
{ id: 'api-docs', label: '📚 Docs' },
|
|
620
|
+
{ id: 'tests', label: '🧪 Testes' }
|
|
621
|
+
].map(tab => (
|
|
622
|
+
<button
|
|
623
|
+
key={tab.id}
|
|
624
|
+
className={`flex-1 px-3 py-2 text-xs font-medium rounded-lg transition-all duration-200 ${
|
|
625
|
+
activeTab === tab.id
|
|
626
|
+
? 'bg-blue-100 text-blue-700'
|
|
627
|
+
: 'text-gray-600 hover:text-gray-900 hover:bg-gray-100'
|
|
628
|
+
}`}
|
|
629
|
+
onClick={() => setActiveTab(tab.id as TabType)}
|
|
630
|
+
>
|
|
631
|
+
{tab.label}
|
|
632
|
+
</button>
|
|
633
|
+
))}
|
|
634
|
+
</nav>
|
|
635
|
+
</div>
|
|
636
|
+
</div>
|
|
637
|
+
</header>
|
|
638
|
+
|
|
639
|
+
{/* Main Content */}
|
|
640
|
+
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
641
|
+
{activeTab === 'overview' && renderOverview()}
|
|
642
|
+
{activeTab === 'demo' && renderDemo()}
|
|
643
|
+
{activeTab === 'api-docs' && renderApiDocs()}
|
|
644
|
+
{activeTab === 'tests' && <TestPage />}
|
|
645
|
+
</main>
|
|
646
|
+
|
|
647
|
+
{/* Toast Notification */}
|
|
648
|
+
{message && (
|
|
649
|
+
<div
|
|
650
|
+
className={`fixed top-4 right-4 z-50 px-6 py-4 rounded-xl shadow-lg cursor-pointer transform transition-all duration-300 max-w-sm ${
|
|
651
|
+
message.type === 'success'
|
|
652
|
+
? 'bg-emerald-500 text-white'
|
|
653
|
+
: 'bg-red-500 text-white'
|
|
654
|
+
}`}
|
|
655
|
+
onClick={() => setMessage(null)}
|
|
656
|
+
>
|
|
657
|
+
<div className="flex items-center space-x-2">
|
|
658
|
+
<span className="text-lg">
|
|
659
|
+
{message.type === 'success' ? '✅' : '❌'}
|
|
660
|
+
</span>
|
|
661
|
+
<span className="font-medium">{message.text}</span>
|
|
662
|
+
</div>
|
|
663
|
+
</div>
|
|
664
|
+
)}
|
|
665
|
+
</div>
|
|
666
|
+
)
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
export default App
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|