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,501 @@
|
|
|
1
|
+
import { Elysia } from "elysia"
|
|
2
|
+
import type { FluxStackConfig, FluxStackContext } from "../types"
|
|
3
|
+
import type { Plugin, PluginContext, PluginUtils } from "../plugins/types"
|
|
4
|
+
import { PluginRegistry } from "../plugins/registry"
|
|
5
|
+
import { getConfigSync, getEnvironmentInfo } from "../config"
|
|
6
|
+
import { logger } from "../utils/logger"
|
|
7
|
+
import { createErrorHandler } from "../utils/errors/handlers"
|
|
8
|
+
import { createTimer, formatBytes, isProduction, isDevelopment } from "../utils/helpers"
|
|
9
|
+
|
|
10
|
+
export class FluxStackFramework {
|
|
11
|
+
private app: Elysia
|
|
12
|
+
private context: FluxStackContext
|
|
13
|
+
private pluginRegistry: PluginRegistry
|
|
14
|
+
private pluginContext: PluginContext
|
|
15
|
+
private isStarted: boolean = false
|
|
16
|
+
|
|
17
|
+
constructor(config?: Partial<FluxStackConfig>) {
|
|
18
|
+
// Load the full configuration
|
|
19
|
+
const fullConfig = config ? { ...getConfigSync(), ...config } : getConfigSync()
|
|
20
|
+
const envInfo = getEnvironmentInfo()
|
|
21
|
+
|
|
22
|
+
this.context = {
|
|
23
|
+
config: fullConfig,
|
|
24
|
+
isDevelopment: envInfo.isDevelopment,
|
|
25
|
+
isProduction: envInfo.isProduction,
|
|
26
|
+
isTest: envInfo.isTest,
|
|
27
|
+
environment: envInfo.name
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
this.app = new Elysia()
|
|
31
|
+
this.pluginRegistry = new PluginRegistry()
|
|
32
|
+
|
|
33
|
+
// Create plugin utilities
|
|
34
|
+
const pluginUtils: PluginUtils = {
|
|
35
|
+
createTimer,
|
|
36
|
+
formatBytes,
|
|
37
|
+
isProduction,
|
|
38
|
+
isDevelopment,
|
|
39
|
+
getEnvironment: () => envInfo.name,
|
|
40
|
+
createHash: (data: string) => {
|
|
41
|
+
const crypto = require('crypto')
|
|
42
|
+
return crypto.createHash('sha256').update(data).digest('hex')
|
|
43
|
+
},
|
|
44
|
+
deepMerge: (target: any, source: any) => {
|
|
45
|
+
const result = { ...target }
|
|
46
|
+
for (const key in source) {
|
|
47
|
+
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
48
|
+
result[key] = pluginUtils.deepMerge(result[key] || {}, source[key])
|
|
49
|
+
} else {
|
|
50
|
+
result[key] = source[key]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return result
|
|
54
|
+
},
|
|
55
|
+
validateSchema: (_data: any, _schema: any) => {
|
|
56
|
+
// Simple validation - in a real implementation you'd use a proper schema validator
|
|
57
|
+
try {
|
|
58
|
+
// Basic validation logic
|
|
59
|
+
return { valid: true, errors: [] }
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return { valid: false, errors: [error instanceof Error ? error.message : 'Validation failed'] }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Create a logger wrapper that implements the full Logger interface
|
|
67
|
+
const pluginLogger = {
|
|
68
|
+
debug: (message: string, meta?: any) => logger.debug(message, meta),
|
|
69
|
+
info: (message: string, meta?: any) => logger.info(message, meta),
|
|
70
|
+
warn: (message: string, meta?: any) => logger.warn(message, meta),
|
|
71
|
+
error: (message: string, meta?: any) => logger.error(message, meta),
|
|
72
|
+
child: (context: any) => (logger as any).child(context),
|
|
73
|
+
time: (label: string) => (logger as any).time(label),
|
|
74
|
+
timeEnd: (label: string) => (logger as any).timeEnd(label),
|
|
75
|
+
request: (method: string, path: string, status?: number, duration?: number) =>
|
|
76
|
+
logger.request(method, path, status, duration)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.pluginContext = {
|
|
80
|
+
config: fullConfig,
|
|
81
|
+
logger: pluginLogger,
|
|
82
|
+
app: this.app,
|
|
83
|
+
utils: pluginUtils
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.setupCors()
|
|
87
|
+
this.setupHooks()
|
|
88
|
+
this.setupErrorHandling()
|
|
89
|
+
|
|
90
|
+
logger.framework('FluxStack framework initialized', {
|
|
91
|
+
environment: envInfo.name,
|
|
92
|
+
port: fullConfig.server.port
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private setupCors() {
|
|
97
|
+
const { cors } = this.context.config.server
|
|
98
|
+
|
|
99
|
+
this.app
|
|
100
|
+
.onRequest(({ set }) => {
|
|
101
|
+
set.headers["Access-Control-Allow-Origin"] = cors.origins.join(", ") || "*"
|
|
102
|
+
set.headers["Access-Control-Allow-Methods"] = cors.methods.join(", ") || "*"
|
|
103
|
+
set.headers["Access-Control-Allow-Headers"] = cors.headers.join(", ") || "*"
|
|
104
|
+
if (cors.credentials) {
|
|
105
|
+
set.headers["Access-Control-Allow-Credentials"] = "true"
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
.options("*", ({ set }) => {
|
|
109
|
+
set.status = 200
|
|
110
|
+
return ""
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private setupHooks() {
|
|
115
|
+
// Setup onRequest hook and onBeforeRoute hook
|
|
116
|
+
this.app.onRequest(async ({ request, set }) => {
|
|
117
|
+
const startTime = Date.now()
|
|
118
|
+
const url = new URL(request.url)
|
|
119
|
+
|
|
120
|
+
const requestContext = {
|
|
121
|
+
request,
|
|
122
|
+
path: url.pathname,
|
|
123
|
+
method: request.method,
|
|
124
|
+
headers: (() => {
|
|
125
|
+
const headers: Record<string, string> = {}
|
|
126
|
+
request.headers.forEach((value: string, key: string) => {
|
|
127
|
+
headers[key] = value
|
|
128
|
+
})
|
|
129
|
+
return headers
|
|
130
|
+
})(),
|
|
131
|
+
query: Object.fromEntries(url.searchParams.entries()),
|
|
132
|
+
params: {},
|
|
133
|
+
startTime,
|
|
134
|
+
handled: false,
|
|
135
|
+
response: undefined
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Execute onRequest hooks for all plugins first (logging, auth, etc.)
|
|
139
|
+
await this.executePluginHooks('onRequest', requestContext)
|
|
140
|
+
|
|
141
|
+
// Execute onBeforeRoute hooks - allow plugins to handle requests before routing
|
|
142
|
+
const handledResponse = await this.executePluginBeforeRouteHooks(requestContext)
|
|
143
|
+
|
|
144
|
+
// If a plugin handled the request, return the response
|
|
145
|
+
if (handledResponse) {
|
|
146
|
+
return handledResponse
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// Setup onResponse hook
|
|
151
|
+
this.app.onAfterHandle(async ({ request, response, set }) => {
|
|
152
|
+
const startTime = Date.now()
|
|
153
|
+
const url = new URL(request.url)
|
|
154
|
+
|
|
155
|
+
const responseContext = {
|
|
156
|
+
request,
|
|
157
|
+
path: url.pathname,
|
|
158
|
+
method: request.method,
|
|
159
|
+
headers: (() => {
|
|
160
|
+
const headers: Record<string, string> = {}
|
|
161
|
+
request.headers.forEach((value: string, key: string) => {
|
|
162
|
+
headers[key] = value
|
|
163
|
+
})
|
|
164
|
+
return headers
|
|
165
|
+
})(),
|
|
166
|
+
query: Object.fromEntries(url.searchParams.entries()),
|
|
167
|
+
params: {},
|
|
168
|
+
response,
|
|
169
|
+
statusCode: (response as any)?.status || set.status || 200,
|
|
170
|
+
duration: Date.now() - startTime,
|
|
171
|
+
startTime
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Execute onResponse hooks for all plugins
|
|
175
|
+
await this.executePluginHooks('onResponse', responseContext)
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private setupErrorHandling() {
|
|
180
|
+
const errorHandler = createErrorHandler({
|
|
181
|
+
logger: this.pluginContext.logger,
|
|
182
|
+
isDevelopment: this.context.isDevelopment
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
this.app.onError(async ({ error, request, path, set }) => {
|
|
186
|
+
const startTime = Date.now()
|
|
187
|
+
const url = new URL(request.url)
|
|
188
|
+
|
|
189
|
+
const errorContext = {
|
|
190
|
+
request,
|
|
191
|
+
path: url.pathname,
|
|
192
|
+
method: request.method,
|
|
193
|
+
headers: (() => {
|
|
194
|
+
const headers: Record<string, string> = {}
|
|
195
|
+
request.headers.forEach((value: string, key: string) => {
|
|
196
|
+
headers[key] = value
|
|
197
|
+
})
|
|
198
|
+
return headers
|
|
199
|
+
})(),
|
|
200
|
+
query: Object.fromEntries(url.searchParams.entries()),
|
|
201
|
+
params: {},
|
|
202
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
203
|
+
duration: Date.now() - startTime,
|
|
204
|
+
handled: false,
|
|
205
|
+
startTime
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Execute onError hooks for all plugins - allow them to handle the error
|
|
209
|
+
const handledResponse = await this.executePluginErrorHooks(errorContext)
|
|
210
|
+
|
|
211
|
+
// If a plugin handled the error, return the response
|
|
212
|
+
if (handledResponse) {
|
|
213
|
+
return handledResponse
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Vite proxy logic is now handled by the Vite plugin via onBeforeRoute hook
|
|
217
|
+
|
|
218
|
+
// Convert Elysia error to standard Error if needed
|
|
219
|
+
const standardError = error instanceof Error ? error : new Error(String(error))
|
|
220
|
+
return errorHandler(standardError, request, path)
|
|
221
|
+
})
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private async executePluginHooks(hookName: string, context: any): Promise<void> {
|
|
225
|
+
const loadOrder = this.pluginRegistry.getLoadOrder()
|
|
226
|
+
|
|
227
|
+
for (const pluginName of loadOrder) {
|
|
228
|
+
const plugin = this.pluginRegistry.get(pluginName)
|
|
229
|
+
if (!plugin) continue
|
|
230
|
+
|
|
231
|
+
const hookFn = (plugin as any)[hookName]
|
|
232
|
+
if (typeof hookFn === 'function') {
|
|
233
|
+
try {
|
|
234
|
+
await hookFn(context)
|
|
235
|
+
} catch (error) {
|
|
236
|
+
logger.error(`Plugin '${pluginName}' ${hookName} hook failed`, {
|
|
237
|
+
error: (error as Error).message
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private async executePluginBeforeRouteHooks(requestContext: any): Promise<Response | null> {
|
|
245
|
+
const loadOrder = this.pluginRegistry.getLoadOrder()
|
|
246
|
+
|
|
247
|
+
for (const pluginName of loadOrder) {
|
|
248
|
+
const plugin = this.pluginRegistry.get(pluginName)
|
|
249
|
+
if (!plugin) continue
|
|
250
|
+
|
|
251
|
+
const onBeforeRouteFn = (plugin as any).onBeforeRoute
|
|
252
|
+
if (typeof onBeforeRouteFn === 'function') {
|
|
253
|
+
try {
|
|
254
|
+
await onBeforeRouteFn(requestContext)
|
|
255
|
+
|
|
256
|
+
// If this plugin handled the request, return the response
|
|
257
|
+
if (requestContext.handled && requestContext.response) {
|
|
258
|
+
return requestContext.response
|
|
259
|
+
}
|
|
260
|
+
} catch (error) {
|
|
261
|
+
logger.error(`Plugin '${pluginName}' onBeforeRoute hook failed`, {
|
|
262
|
+
error: (error as Error).message
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return null
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private async executePluginErrorHooks(errorContext: any): Promise<Response | null> {
|
|
272
|
+
const loadOrder = this.pluginRegistry.getLoadOrder()
|
|
273
|
+
|
|
274
|
+
for (const pluginName of loadOrder) {
|
|
275
|
+
const plugin = this.pluginRegistry.get(pluginName)
|
|
276
|
+
if (!plugin) continue
|
|
277
|
+
|
|
278
|
+
const onErrorFn = (plugin as any).onError
|
|
279
|
+
if (typeof onErrorFn === 'function') {
|
|
280
|
+
try {
|
|
281
|
+
await onErrorFn(errorContext)
|
|
282
|
+
|
|
283
|
+
// If this plugin handled the error, check if it provides a response
|
|
284
|
+
if (errorContext.handled) {
|
|
285
|
+
// For Vite plugin, we'll handle the proxy here
|
|
286
|
+
if (pluginName === 'vite' && errorContext.error.constructor.name === 'NotFoundError') {
|
|
287
|
+
return await this.handleViteProxy(errorContext)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// For other plugins, return a basic success response
|
|
291
|
+
return new Response('OK', { status: 200 })
|
|
292
|
+
}
|
|
293
|
+
} catch (error) {
|
|
294
|
+
logger.error(`Plugin '${pluginName}' onError hook failed`, {
|
|
295
|
+
error: (error as Error).message
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return null
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private async handleViteProxy(errorContext: any): Promise<Response> {
|
|
305
|
+
const vitePort = this.context.config.client?.port || 5173
|
|
306
|
+
const url = new URL(errorContext.request.url)
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
const viteUrl = `http://localhost:${vitePort}${url.pathname}${url.search}`
|
|
310
|
+
|
|
311
|
+
// Forward request to Vite
|
|
312
|
+
const response = await fetch(viteUrl, {
|
|
313
|
+
method: errorContext.method,
|
|
314
|
+
headers: errorContext.headers
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
// Return a proper Response object with all headers and status
|
|
318
|
+
const body = await response.arrayBuffer()
|
|
319
|
+
|
|
320
|
+
return new Response(body, {
|
|
321
|
+
status: response.status,
|
|
322
|
+
statusText: response.statusText,
|
|
323
|
+
headers: response.headers
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
} catch (viteError) {
|
|
327
|
+
// If Vite fails, return error response
|
|
328
|
+
return new Response(`Vite server not ready on port ${vitePort}. Error: ${viteError}`, {
|
|
329
|
+
status: 503,
|
|
330
|
+
headers: { 'Content-Type': 'text/plain' }
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
use(plugin: Plugin) {
|
|
336
|
+
try {
|
|
337
|
+
// Use the registry's public register method, but don't await it since we need sync operation
|
|
338
|
+
if (this.pluginRegistry.has(plugin.name)) {
|
|
339
|
+
throw new Error(`Plugin '${plugin.name}' is already registered`)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Store plugin without calling setup - setup will be called in start()
|
|
343
|
+
// We need to manually set the plugin since register() is async but we need sync
|
|
344
|
+
(this.pluginRegistry as any).plugins.set(plugin.name, plugin)
|
|
345
|
+
|
|
346
|
+
// Update dependencies tracking
|
|
347
|
+
if (plugin.dependencies) {
|
|
348
|
+
(this.pluginRegistry as any).dependencies.set(plugin.name, plugin.dependencies)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Update load order by calling the private method
|
|
352
|
+
try {
|
|
353
|
+
(this.pluginRegistry as any).updateLoadOrder()
|
|
354
|
+
} catch (error) {
|
|
355
|
+
// Fallback: create basic load order
|
|
356
|
+
const plugins = (this.pluginRegistry as any).plugins as Map<string, Plugin>
|
|
357
|
+
const loadOrder = Array.from(plugins.keys())
|
|
358
|
+
;(this.pluginRegistry as any).loadOrder = loadOrder
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
logger.framework(`Plugin '${plugin.name}' registered`, {
|
|
362
|
+
version: plugin.version,
|
|
363
|
+
dependencies: plugin.dependencies
|
|
364
|
+
})
|
|
365
|
+
return this
|
|
366
|
+
} catch (error) {
|
|
367
|
+
logger.error(`Failed to register plugin '${plugin.name}'`, { error: (error as Error).message })
|
|
368
|
+
throw error
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
routes(routeModule: any) {
|
|
373
|
+
this.app.use(routeModule)
|
|
374
|
+
return this
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
async start(): Promise<void> {
|
|
378
|
+
if (this.isStarted) {
|
|
379
|
+
logger.warn('Framework is already started')
|
|
380
|
+
return
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
// Validate plugin dependencies before starting
|
|
385
|
+
const plugins = (this.pluginRegistry as any).plugins as Map<string, Plugin>
|
|
386
|
+
for (const [pluginName, plugin] of plugins) {
|
|
387
|
+
if (plugin.dependencies) {
|
|
388
|
+
for (const depName of plugin.dependencies) {
|
|
389
|
+
if (!plugins.has(depName)) {
|
|
390
|
+
throw new Error(`Plugin '${pluginName}' depends on '${depName}' which is not registered`)
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Get load order
|
|
397
|
+
const loadOrder = this.pluginRegistry.getLoadOrder()
|
|
398
|
+
|
|
399
|
+
// Call setup hooks for all plugins
|
|
400
|
+
for (const pluginName of loadOrder) {
|
|
401
|
+
const plugin = this.pluginRegistry.get(pluginName)!
|
|
402
|
+
|
|
403
|
+
// Call setup hook if it exists and hasn't been called
|
|
404
|
+
if (plugin.setup) {
|
|
405
|
+
await plugin.setup(this.pluginContext)
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Call onServerStart hooks
|
|
410
|
+
for (const pluginName of loadOrder) {
|
|
411
|
+
const plugin = this.pluginRegistry.get(pluginName)!
|
|
412
|
+
|
|
413
|
+
if (plugin.onServerStart) {
|
|
414
|
+
await plugin.onServerStart(this.pluginContext)
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
this.isStarted = true
|
|
419
|
+
logger.framework('All plugins loaded successfully', {
|
|
420
|
+
pluginCount: loadOrder.length
|
|
421
|
+
})
|
|
422
|
+
|
|
423
|
+
} catch (error) {
|
|
424
|
+
logger.error('Failed to start framework', { error: (error as Error).message })
|
|
425
|
+
throw error
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
async stop(): Promise<void> {
|
|
430
|
+
if (!this.isStarted) {
|
|
431
|
+
return
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
try {
|
|
435
|
+
// Call onServerStop hooks in reverse order
|
|
436
|
+
const loadOrder = this.pluginRegistry.getLoadOrder().reverse()
|
|
437
|
+
|
|
438
|
+
for (const pluginName of loadOrder) {
|
|
439
|
+
const plugin = this.pluginRegistry.get(pluginName)!
|
|
440
|
+
|
|
441
|
+
if (plugin.onServerStop) {
|
|
442
|
+
await plugin.onServerStop(this.pluginContext)
|
|
443
|
+
logger.framework(`Plugin '${pluginName}' server stop hook completed`)
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
this.isStarted = false
|
|
448
|
+
logger.framework('Framework stopped successfully')
|
|
449
|
+
|
|
450
|
+
} catch (error) {
|
|
451
|
+
logger.error('Error during framework shutdown', { error: (error as Error).message })
|
|
452
|
+
throw error
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
getApp() {
|
|
457
|
+
return this.app
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
getContext() {
|
|
461
|
+
return this.context
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
getPluginRegistry() {
|
|
465
|
+
return this.pluginRegistry
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
async listen(callback?: () => void) {
|
|
469
|
+
// Start the framework (load plugins)
|
|
470
|
+
await this.start()
|
|
471
|
+
|
|
472
|
+
const port = this.context.config.server.port
|
|
473
|
+
const apiPrefix = this.context.config.server.apiPrefix
|
|
474
|
+
|
|
475
|
+
this.app.listen(port, () => {
|
|
476
|
+
logger.framework(`Server started on port ${port}`, {
|
|
477
|
+
apiPrefix,
|
|
478
|
+
environment: this.context.environment,
|
|
479
|
+
pluginCount: this.pluginRegistry.getAll().length
|
|
480
|
+
})
|
|
481
|
+
|
|
482
|
+
console.log(`🚀 API ready at http://localhost:${port}${apiPrefix}`)
|
|
483
|
+
console.log(`📋 Health check: http://localhost:${port}${apiPrefix}/health`)
|
|
484
|
+
console.log()
|
|
485
|
+
callback?.()
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
// Handle graceful shutdown
|
|
489
|
+
process.on('SIGTERM', async () => {
|
|
490
|
+
logger.framework('Received SIGTERM, shutting down gracefully')
|
|
491
|
+
await this.stop()
|
|
492
|
+
process.exit(0)
|
|
493
|
+
})
|
|
494
|
+
|
|
495
|
+
process.on('SIGINT', async () => {
|
|
496
|
+
logger.framework('Received SIGINT, shutting down gracefully')
|
|
497
|
+
await this.stop()
|
|
498
|
+
process.exit(0)
|
|
499
|
+
})
|
|
500
|
+
}
|
|
501
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Framework Types
|
|
3
|
+
* Defines the main interfaces and types for the FluxStack framework
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { FluxStackConfig } from "../types"
|
|
7
|
+
import type { Logger } from "../utils/logger/index"
|
|
8
|
+
|
|
9
|
+
export interface FluxStackFrameworkOptions {
|
|
10
|
+
config?: Partial<FluxStackConfig>
|
|
11
|
+
plugins?: string[]
|
|
12
|
+
autoStart?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface FrameworkContext {
|
|
16
|
+
config: FluxStackConfig
|
|
17
|
+
isDevelopment: boolean
|
|
18
|
+
isProduction: boolean
|
|
19
|
+
isTest: boolean
|
|
20
|
+
environment: string
|
|
21
|
+
logger: Logger
|
|
22
|
+
startTime: Date
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface FrameworkStats {
|
|
26
|
+
uptime: number
|
|
27
|
+
pluginCount: number
|
|
28
|
+
requestCount: number
|
|
29
|
+
errorCount: number
|
|
30
|
+
memoryUsage: NodeJS.MemoryUsage
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface FrameworkHooks {
|
|
34
|
+
beforeStart?: () => void | Promise<void>
|
|
35
|
+
afterStart?: () => void | Promise<void>
|
|
36
|
+
beforeStop?: () => void | Promise<void>
|
|
37
|
+
afterStop?: () => void | Promise<void>
|
|
38
|
+
onError?: (error: Error) => void | Promise<void>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface RouteDefinition {
|
|
42
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD'
|
|
43
|
+
path: string
|
|
44
|
+
handler: Function
|
|
45
|
+
schema?: any
|
|
46
|
+
middleware?: Function[]
|
|
47
|
+
description?: string
|
|
48
|
+
tags?: string[]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface MiddlewareDefinition {
|
|
52
|
+
name: string
|
|
53
|
+
handler: Function
|
|
54
|
+
priority?: number
|
|
55
|
+
routes?: string[]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ServiceDefinition {
|
|
59
|
+
name: string
|
|
60
|
+
instance: any
|
|
61
|
+
dependencies?: string[]
|
|
62
|
+
singleton?: boolean
|
|
63
|
+
}
|