veryfront 0.1.128 → 0.1.129
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/esm/cli/router.d.ts +0 -5
- package/esm/cli/router.d.ts.map +1 -1
- package/esm/cli/router.js +30 -2
- package/esm/cli/shared/update-check.d.ts +4 -0
- package/esm/cli/shared/update-check.d.ts.map +1 -0
- package/esm/cli/shared/update-check.js +97 -0
- package/esm/deno.d.ts +5 -0
- package/esm/deno.js +13 -8
- package/esm/src/channels/control-plane.d.ts.map +1 -1
- package/esm/src/channels/control-plane.js +5 -5
- package/esm/src/channels/invoke.d.ts +1 -1
- package/esm/src/channels/invoke.d.ts.map +1 -1
- package/esm/src/channels/invoke.js +6 -6
- package/esm/src/chat/index.d.ts +12 -24
- package/esm/src/chat/index.d.ts.map +1 -1
- package/esm/src/chat/index.js +5 -25
- package/esm/src/config/env.d.ts.map +1 -1
- package/esm/src/config/env.js +18 -10
- package/esm/src/data/static-data-fetcher.d.ts +3 -0
- package/esm/src/data/static-data-fetcher.d.ts.map +1 -1
- package/esm/src/data/static-data-fetcher.js +29 -25
- package/esm/src/data/static-paths-fetcher.d.ts.map +1 -1
- package/esm/src/data/static-paths-fetcher.js +3 -2
- package/esm/src/errors/logging.d.ts.map +1 -1
- package/esm/src/errors/logging.js +16 -7
- package/esm/src/errors/user-friendly/error-formatter.d.ts.map +1 -1
- package/esm/src/errors/user-friendly/error-formatter.js +9 -25
- package/esm/src/fs/index.d.ts +11 -12
- package/esm/src/fs/index.d.ts.map +1 -1
- package/esm/src/fs/index.js +11 -24
- package/esm/src/html/dev-scripts.d.ts.map +1 -1
- package/esm/src/html/dev-scripts.js +5 -8
- package/esm/src/html/html-escape.d.ts +1 -0
- package/esm/src/html/html-escape.d.ts.map +1 -1
- package/esm/src/html/html-escape.js +3 -0
- package/esm/src/html/html-injection.js +2 -2
- package/esm/src/html/html-shell-generator.d.ts +5 -2
- package/esm/src/html/html-shell-generator.d.ts.map +1 -1
- package/esm/src/html/html-shell-generator.js +41 -30
- package/esm/src/html/hydration-script-builder/dev-client-renderer.js +2 -2
- package/esm/src/html/hydration-script-builder/dev-component-manifest.js +2 -2
- package/esm/src/html/hydration-script-builder/dev-error-logger.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/dev-error-logger.js +2 -6
- package/esm/src/html/hydration-script-builder/dev-scripts.js +2 -2
- package/esm/src/html/hydration-script-builder/hydration-data-generator.d.ts +3 -1
- package/esm/src/html/hydration-script-builder/hydration-data-generator.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/hydration-data-generator.js +2 -2
- package/esm/src/html/hydration-script-builder/index.d.ts +1 -1
- package/esm/src/html/hydration-script-builder/index.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/index.js +1 -1
- package/esm/src/html/hydration-script-builder/prod-hydration.js +2 -2
- package/esm/src/html/hydration-script-builder/prod-scripts.d.ts +2 -0
- package/esm/src/html/hydration-script-builder/prod-scripts.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/prod-scripts.js +14 -14
- package/esm/src/html/schemas/html.schema.d.ts +2 -0
- package/esm/src/html/schemas/html.schema.d.ts.map +1 -1
- package/esm/src/html/schemas/html.schema.js +2 -0
- package/esm/src/html/styles-builder/css-pregeneration.d.ts +17 -1
- package/esm/src/html/styles-builder/css-pregeneration.d.ts.map +1 -1
- package/esm/src/html/styles-builder/css-pregeneration.js +103 -1
- package/esm/src/html/styles-builder/dev-styles.js +2 -2
- package/esm/src/html/utils.d.ts +2 -0
- package/esm/src/html/utils.d.ts.map +1 -1
- package/esm/src/html/utils.js +49 -28
- package/esm/src/integrations/remote-tools.d.ts.map +1 -1
- package/esm/src/integrations/remote-tools.js +32 -39
- package/esm/src/internal-agents/ag-ui-sse.d.ts +0 -1
- package/esm/src/internal-agents/ag-ui-sse.d.ts.map +1 -1
- package/esm/src/internal-agents/ag-ui-sse.js +2 -16
- package/esm/src/internal-agents/control-plane-auth.d.ts.map +1 -1
- package/esm/src/internal-agents/control-plane-auth.js +5 -3
- package/esm/src/internal-agents/request-body.d.ts.map +1 -1
- package/esm/src/internal-agents/request-body.js +6 -3
- package/esm/src/internal-agents/session-manager.d.ts +1 -0
- package/esm/src/internal-agents/session-manager.d.ts.map +1 -1
- package/esm/src/internal-agents/session-manager.js +12 -18
- package/esm/src/issues/core.d.ts.map +1 -1
- package/esm/src/issues/core.js +24 -23
- package/esm/src/issues/schemas/issue.schema.d.ts.map +1 -1
- package/esm/src/issues/schemas/issue.schema.js +2 -1
- package/esm/src/jobs/runtime-env.d.ts.map +1 -1
- package/esm/src/jobs/runtime-env.js +21 -44
- package/esm/src/markdown/index.d.ts +1 -2
- package/esm/src/markdown/index.d.ts.map +1 -1
- package/esm/src/markdown/index.js +1 -6
- package/esm/src/mcp/server.d.ts +0 -1
- package/esm/src/mcp/server.d.ts.map +1 -1
- package/esm/src/mcp/server.js +40 -41
- package/esm/src/mdx/index.d.ts +3 -2
- package/esm/src/mdx/index.d.ts.map +1 -1
- package/esm/src/mdx/index.js +3 -5
- package/esm/src/middleware/builtin/logger.d.ts.map +1 -1
- package/esm/src/middleware/builtin/logger.js +31 -28
- package/esm/src/middleware/builtin/security/rate-limit.d.ts.map +1 -1
- package/esm/src/middleware/builtin/security/rate-limit.js +17 -12
- package/esm/src/middleware/builtin/timeout.d.ts.map +1 -1
- package/esm/src/middleware/builtin/timeout.js +17 -10
- package/esm/src/modules/import-map/default-import-map.d.ts.map +1 -1
- package/esm/src/modules/import-map/default-import-map.js +4 -3
- package/esm/src/oauth/handlers/callback-handler.d.ts +0 -5
- package/esm/src/oauth/handlers/callback-handler.d.ts.map +1 -1
- package/esm/src/oauth/handlers/callback-handler.js +9 -14
- package/esm/src/oauth/handlers/index.d.ts +1 -1
- package/esm/src/oauth/handlers/index.js +1 -1
- package/esm/src/oauth/handlers/init-handler.d.ts.map +1 -1
- package/esm/src/oauth/handlers/init-handler.js +32 -20
- package/esm/src/oauth/providers/index.d.ts +1 -1
- package/esm/src/oauth/providers/index.js +1 -1
- package/esm/src/oauth/schemas/index.d.ts +1 -1
- package/esm/src/oauth/schemas/index.js +1 -1
- package/esm/src/oauth/token-store/index.d.ts +1 -1
- package/esm/src/oauth/token-store/index.js +1 -1
- package/esm/src/oauth/token-store/memory.d.ts +1 -1
- package/esm/src/oauth/token-store/memory.d.ts.map +1 -1
- package/esm/src/oauth/token-store/memory.js +8 -8
- package/esm/src/observability/request-profiler.d.ts +31 -0
- package/esm/src/observability/request-profiler.d.ts.map +1 -0
- package/esm/src/observability/request-profiler.js +94 -0
- package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
- package/esm/src/observability/tracing/otlp-setup.js +16 -21
- package/esm/src/prompt/factory.d.ts.map +1 -1
- package/esm/src/prompt/factory.js +10 -12
- package/esm/src/prompt/registry.d.ts.map +1 -1
- package/esm/src/prompt/registry.js +12 -10
- package/esm/src/prompt/schemas/prompt.schema.d.ts.map +1 -1
- package/esm/src/prompt/schemas/prompt.schema.js +0 -2
- package/esm/src/prompt/types.d.ts +1 -1
- package/esm/src/prompt/types.d.ts.map +1 -1
- package/esm/src/provider/local/ai-sdk-adapter.d.ts.map +1 -1
- package/esm/src/provider/local/ai-sdk-adapter.js +3 -8
- package/esm/src/provider/local/env.d.ts +4 -6
- package/esm/src/provider/local/env.d.ts.map +1 -1
- package/esm/src/provider/local/env.js +14 -1
- package/esm/src/provider/local/local-engine.d.ts.map +1 -1
- package/esm/src/provider/local/local-engine.js +2 -7
- package/esm/src/provider/model-registry.d.ts.map +1 -1
- package/esm/src/provider/model-registry.js +2 -7
- package/esm/src/provider/veryfront-cloud/provider.d.ts.map +1 -1
- package/esm/src/provider/veryfront-cloud/provider.js +1 -7
- package/esm/src/provider/veryfront-cloud/shared.d.ts.map +1 -1
- package/esm/src/provider/veryfront-cloud/shared.js +9 -11
- package/esm/src/proxy/handler.d.ts.map +1 -1
- package/esm/src/proxy/handler.js +56 -57
- package/esm/src/react/compat/hooks-adapter.d.ts +1 -7
- package/esm/src/react/compat/hooks-adapter.d.ts.map +1 -1
- package/esm/src/react/compat/hooks-adapter.js +35 -40
- package/esm/src/react/components/Head.d.ts +1 -26
- package/esm/src/react/components/Head.d.ts.map +1 -1
- package/esm/src/react/components/Head.js +1 -172
- package/esm/src/react/context/index.d.ts +2 -46
- package/esm/src/react/context/index.d.ts.map +1 -1
- package/esm/src/react/context/index.js +1 -44
- package/esm/src/react/head-collector.d.ts +1 -10
- package/esm/src/react/head-collector.d.ts.map +1 -1
- package/esm/src/react/head-collector.js +4 -0
- package/esm/src/react/router/index.d.ts +2 -45
- package/esm/src/react/router/index.d.ts.map +1 -1
- package/esm/src/react/router/index.js +1 -49
- package/esm/src/react/runtime/core.d.ts +49 -0
- package/esm/src/react/runtime/core.d.ts.map +1 -0
- package/esm/src/react/runtime/core.js +200 -0
- package/esm/src/rendering/orchestrator/html.d.ts +2 -0
- package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/html.js +69 -12
- package/esm/src/rendering/orchestrator/ssr-orchestrator.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/ssr-orchestrator.js +4 -0
- package/esm/src/rendering/orchestrator/types.d.ts +4 -0
- package/esm/src/rendering/orchestrator/types.d.ts.map +1 -1
- package/esm/src/repositories/types.d.ts.map +1 -1
- package/esm/src/resource/factory.d.ts.map +1 -1
- package/esm/src/resource/factory.js +12 -9
- package/esm/src/resource/registry.d.ts +3 -3
- package/esm/src/resource/registry.d.ts.map +1 -1
- package/esm/src/resource/registry.js +7 -7
- package/esm/src/schemas/common.d.ts.map +1 -1
- package/esm/src/schemas/common.js +7 -4
- package/esm/src/security/http/config.d.ts +0 -1
- package/esm/src/security/http/config.d.ts.map +1 -1
- package/esm/src/security/http/config.js +3 -16
- package/esm/src/security/http/response/security-handler.d.ts +1 -0
- package/esm/src/security/http/response/security-handler.d.ts.map +1 -1
- package/esm/src/security/http/response/security-handler.js +17 -12
- package/esm/src/security/index.d.ts +4 -2
- package/esm/src/security/index.d.ts.map +1 -1
- package/esm/src/security/index.js +3 -1
- package/esm/src/server/handlers/dev/styles-css.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/styles-css.handler.js +8 -7
- package/esm/src/server/handlers/monitoring/metrics.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/monitoring/metrics.handler.js +3 -1
- package/esm/src/server/handlers/request/module/module-server-handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/module/module-server-handler.js +18 -15
- package/esm/src/server/handlers/request/prod-hydration-module.handler.d.ts +8 -0
- package/esm/src/server/handlers/request/prod-hydration-module.handler.d.ts.map +1 -0
- package/esm/src/server/handlers/request/prod-hydration-module.handler.js +41 -0
- package/esm/src/server/handlers/request/ssr/ssr.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/ssr/ssr.handler.js +3 -0
- package/esm/src/server/production-server.d.ts.map +1 -1
- package/esm/src/server/production-server.js +65 -0
- package/esm/src/server/runtime-handler/handler-context-builder.d.ts +1 -1
- package/esm/src/server/runtime-handler/handler-context-builder.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.d.ts +1 -1
- package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.js +36 -11
- package/esm/src/server/runtime-handler/request-utils.d.ts +7 -0
- package/esm/src/server/runtime-handler/request-utils.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/request-utils.js +10 -0
- package/esm/src/server/services/rendering/ssr.service.d.ts +1 -0
- package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
- package/esm/src/server/services/rendering/ssr.service.js +12 -5
- package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +1 -1
- package/esm/src/skill/allowed-tools.d.ts +3 -8
- package/esm/src/skill/allowed-tools.d.ts.map +1 -1
- package/esm/src/skill/executor.js +2 -2
- package/esm/src/skill/parser.d.ts.map +1 -1
- package/esm/src/skill/parser.js +12 -12
- package/esm/src/skill/path-safety.js +1 -1
- package/esm/src/skill/tools.d.ts.map +1 -1
- package/esm/src/skill/tools.js +18 -11
- package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
- package/esm/src/studio/bridge/bridge-bundle.generated.js +1 -1
- package/esm/src/task/discovery.d.ts.map +1 -1
- package/esm/src/task/discovery.js +73 -95
- package/esm/src/tool/executor.d.ts.map +1 -1
- package/esm/src/tool/executor.js +8 -7
- package/esm/src/tool/factory.d.ts.map +1 -1
- package/esm/src/tool/factory.js +13 -16
- package/esm/src/transforms/esm/package-registry.d.ts +4 -0
- package/esm/src/transforms/esm/package-registry.d.ts.map +1 -1
- package/esm/src/transforms/esm/package-registry.js +34 -17
- package/esm/src/transforms/import-rewriter/strategies/veryfront-strategy.d.ts.map +1 -1
- package/esm/src/transforms/import-rewriter/strategies/veryfront-strategy.js +2 -1
- package/esm/src/transforms/mdx/esm-module-loader/cache-format.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/cache-format.js +26 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.js +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts +1 -0
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.js +3 -0
- package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.d.ts +1 -1
- package/esm/src/transforms/pipeline/stages/ssr-vf-modules/index.js +1 -1
- package/esm/src/transforms/veryfront-module-urls.d.ts.map +1 -1
- package/esm/src/transforms/veryfront-module-urls.js +7 -3
- package/esm/src/types/entities/getEntityInfo.d.ts.map +1 -1
- package/esm/src/types/entities/getEntityInfo.js +79 -127
- package/esm/src/utils/path-utils.d.ts +1 -1
- package/esm/src/utils/path-utils.d.ts.map +1 -1
- package/esm/src/utils/path-utils.js +16 -7
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/esm/src/utils/version.d.ts.map +1 -1
- package/esm/src/utils/version.js +0 -1
- package/esm/src/workflow/worker/dynamic-job-entrypoint.d.ts.map +1 -1
- package/esm/src/workflow/worker/dynamic-job-entrypoint.js +5 -72
- package/esm/src/workflow/worker/job-entrypoint.d.ts.map +1 -1
- package/esm/src/workflow/worker/job-entrypoint.js +5 -72
- package/esm/src/workflow/worker/shared.d.ts +18 -0
- package/esm/src/workflow/worker/shared.d.ts.map +1 -0
- package/esm/src/workflow/worker/shared.js +77 -0
- package/package.json +1 -1
- package/src/cli/router.ts +41 -2
- package/src/cli/shared/update-check.ts +110 -0
- package/src/deno.js +13 -8
- package/src/src/channels/control-plane.ts +6 -10
- package/src/src/channels/invoke.ts +7 -7
- package/src/src/chat/index.ts +96 -132
- package/src/src/config/env.ts +24 -11
- package/src/src/data/static-data-fetcher.ts +59 -34
- package/src/src/data/static-paths-fetcher.ts +4 -2
- package/src/src/errors/logging.ts +21 -7
- package/src/src/errors/user-friendly/error-formatter.ts +14 -29
- package/src/src/fs/index.ts +21 -30
- package/src/src/html/dev-scripts.ts +5 -9
- package/src/src/html/html-escape.ts +4 -0
- package/src/src/html/html-injection.ts +2 -2
- package/src/src/html/html-shell-generator.ts +60 -26
- package/src/src/html/hydration-script-builder/dev-client-renderer.ts +2 -2
- package/src/src/html/hydration-script-builder/dev-component-manifest.ts +2 -2
- package/src/src/html/hydration-script-builder/dev-error-logger.ts +2 -8
- package/src/src/html/hydration-script-builder/dev-scripts.ts +2 -2
- package/src/src/html/hydration-script-builder/hydration-data-generator.ts +2 -1
- package/src/src/html/hydration-script-builder/index.ts +5 -1
- package/src/src/html/hydration-script-builder/prod-hydration.ts +2 -2
- package/src/src/html/hydration-script-builder/prod-scripts.ts +16 -15
- package/src/src/html/schemas/html.schema.ts +2 -0
- package/src/src/html/styles-builder/css-pregeneration.ts +133 -1
- package/src/src/html/styles-builder/dev-styles.ts +2 -2
- package/src/src/html/utils.ts +62 -29
- package/src/src/integrations/remote-tools.ts +39 -37
- package/src/src/internal-agents/ag-ui-sse.ts +2 -17
- package/src/src/internal-agents/control-plane-auth.ts +8 -6
- package/src/src/internal-agents/request-body.ts +7 -5
- package/src/src/internal-agents/session-manager.ts +16 -20
- package/src/src/issues/core.ts +24 -27
- package/src/src/issues/schemas/issue.schema.ts +3 -1
- package/src/src/jobs/runtime-env.ts +24 -50
- package/src/src/markdown/index.ts +5 -8
- package/src/src/mcp/server.ts +50 -53
- package/src/src/mdx/index.ts +7 -8
- package/src/src/middleware/builtin/logger.ts +44 -29
- package/src/src/middleware/builtin/security/rate-limit.ts +20 -11
- package/src/src/middleware/builtin/timeout.ts +22 -13
- package/src/src/modules/import-map/default-import-map.ts +4 -3
- package/src/src/oauth/handlers/callback-handler.ts +9 -16
- package/src/src/oauth/handlers/index.ts +1 -1
- package/src/src/oauth/handlers/init-handler.ts +56 -27
- package/src/src/oauth/providers/index.ts +1 -1
- package/src/src/oauth/schemas/index.ts +1 -1
- package/src/src/oauth/token-store/index.ts +1 -1
- package/src/src/oauth/token-store/memory.ts +8 -8
- package/src/src/observability/request-profiler.ts +140 -0
- package/src/src/observability/tracing/otlp-setup.ts +16 -22
- package/src/src/prompt/factory.ts +16 -14
- package/src/src/prompt/registry.ts +14 -13
- package/src/src/prompt/schemas/prompt.schema.ts +0 -4
- package/src/src/prompt/types.ts +1 -2
- package/src/src/provider/local/ai-sdk-adapter.ts +3 -10
- package/src/src/provider/local/env.ts +22 -2
- package/src/src/provider/local/local-engine.ts +2 -9
- package/src/src/provider/model-registry.ts +2 -9
- package/src/src/provider/veryfront-cloud/provider.ts +1 -8
- package/src/src/provider/veryfront-cloud/shared.ts +12 -15
- package/src/src/proxy/handler.ts +90 -74
- package/src/src/react/compat/hooks-adapter.ts +43 -44
- package/src/src/react/components/Head.tsx +1 -181
- package/src/src/react/context/index.tsx +2 -83
- package/src/src/react/head-collector.ts +9 -0
- package/src/src/react/router/index.tsx +2 -100
- package/src/src/react/runtime/core.ts +303 -0
- package/src/src/rendering/orchestrator/html.ts +122 -18
- package/src/src/rendering/orchestrator/ssr-orchestrator.ts +8 -0
- package/src/src/rendering/orchestrator/types.ts +4 -0
- package/src/src/repositories/types.ts +0 -4
- package/src/src/resource/factory.ts +15 -11
- package/src/src/resource/registry.ts +7 -7
- package/src/src/schemas/common.ts +8 -5
- package/src/src/security/http/config.ts +3 -19
- package/src/src/security/http/response/security-handler.ts +22 -13
- package/src/src/security/index.ts +4 -7
- package/src/src/server/handlers/dev/styles-css.handler.ts +32 -14
- package/src/src/server/handlers/monitoring/metrics.handler.ts +3 -1
- package/src/src/server/handlers/request/module/module-server-handler.ts +24 -17
- package/src/src/server/handlers/request/prod-hydration-module.handler.ts +61 -0
- package/src/src/server/handlers/request/ssr/ssr.handler.ts +3 -0
- package/src/src/server/production-server.ts +84 -0
- package/src/src/server/runtime-handler/handler-context-builder.ts +1 -1
- package/src/src/server/runtime-handler/index.ts +44 -13
- package/src/src/server/runtime-handler/request-utils.ts +11 -0
- package/src/src/server/services/rendering/ssr.service.ts +31 -18
- package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +1 -1
- package/src/src/skill/allowed-tools.ts +1 -8
- package/src/src/skill/executor.ts +2 -2
- package/src/src/skill/parser.ts +13 -20
- package/src/src/skill/path-safety.ts +1 -1
- package/src/src/skill/tools.ts +27 -20
- package/src/src/studio/bridge/bridge-bundle.generated.ts +1 -1
- package/src/src/task/discovery.ts +97 -97
- package/src/src/tool/executor.ts +10 -8
- package/src/src/tool/factory.ts +21 -22
- package/src/src/tool/types.ts +0 -17
- package/src/src/transforms/esm/package-registry.ts +52 -20
- package/src/src/transforms/import-rewriter/strategies/veryfront-strategy.ts +2 -1
- package/src/src/transforms/mdx/esm-module-loader/cache-format.ts +34 -1
- package/src/src/transforms/mdx/esm-module-loader/module-fetcher/index.ts +1 -1
- package/src/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.ts +4 -0
- package/src/src/transforms/pipeline/stages/ssr-vf-modules/index.ts +1 -1
- package/src/src/transforms/veryfront-module-urls.ts +6 -2
- package/src/src/types/entities/getEntityInfo.ts +131 -152
- package/src/src/utils/path-utils.ts +16 -7
- package/src/src/utils/version-constant.ts +1 -1
- package/src/src/utils/version.ts +0 -1
- package/src/src/workflow/worker/dynamic-job-entrypoint.ts +18 -84
- package/src/src/workflow/worker/job-entrypoint.ts +18 -85
- package/src/src/workflow/worker/shared.ts +127 -0
- package/esm/src/prompt/schemas/index.d.ts +0 -7
- package/esm/src/prompt/schemas/index.d.ts.map +0 -1
- package/esm/src/prompt/schemas/index.js +0 -6
- package/esm/src/security/http/handlers-index.d.ts +0 -5
- package/esm/src/security/http/handlers-index.d.ts.map +0 -1
- package/esm/src/security/http/handlers-index.js +0 -3
- package/src/src/prompt/schemas/index.ts +0 -7
- package/src/src/security/http/handlers-index.ts +0 -4
|
@@ -26,16 +26,20 @@ import { computeSourceHash } from "../../studio/hash-utils.js";
|
|
|
26
26
|
import { extractRelativePath } from "../../utils/route-path-utils.js";
|
|
27
27
|
import { resolveAppComponentPath } from "../layouts/utils/app-resolver.js";
|
|
28
28
|
import { StreamTimeoutError, streamToString } from "../utils/stream-utils.js";
|
|
29
|
+
import { profilePhase, profileSyncPhase } from "../../observability/request-profiler.js";
|
|
29
30
|
import {
|
|
30
31
|
normalizeCssModuleKey,
|
|
31
32
|
rewriteCssModuleContent,
|
|
32
33
|
} from "../../transforms/css-modules/naming.js";
|
|
34
|
+
import { getProjectCSS } from "../../html/styles-builder/index.js";
|
|
35
|
+
import { warmPreparedCSSArtifactFromFiles } from "../../html/styles-builder/css-pregeneration.js";
|
|
33
36
|
import { getRouteCandidates } from "./css-candidate-manifest.js";
|
|
34
37
|
import { resolveStyleContentVersion } from "../../html/styles-builder/content-version.js";
|
|
35
38
|
import { createStyleScopeProfile } from "../../html/styles-builder/style-scope-profile.js";
|
|
36
39
|
import type { ResolvedContentContext } from "../../platform/adapters/fs/veryfront/types.js";
|
|
37
40
|
|
|
38
41
|
const logger = rendererLogger.component("html-generator");
|
|
42
|
+
type ProjectCSSResult = Awaited<ReturnType<typeof getProjectCSS>> | null;
|
|
39
43
|
|
|
40
44
|
function findTagEnd(html: string, start: number): number {
|
|
41
45
|
let activeQuote: '"' | "'" | null = null;
|
|
@@ -187,7 +191,12 @@ export class HTMLGenerator {
|
|
|
187
191
|
): Promise<ReadableStream> {
|
|
188
192
|
const fullContext = context as HTMLGenerationContext;
|
|
189
193
|
const mergedFrontmatter = this.mergeFrontmatter(fullContext);
|
|
190
|
-
const htmlOptions = await
|
|
194
|
+
const htmlOptions = await profilePhase(
|
|
195
|
+
"html.build_options",
|
|
196
|
+
() => this.buildHTMLOptions(fullContext, mergedFrontmatter),
|
|
197
|
+
);
|
|
198
|
+
const projectCSSPromise = this.startProjectCSSPreparation(fullContext, htmlOptions);
|
|
199
|
+
this.startPreparedCSSWarmup(fullContext, htmlOptions);
|
|
191
200
|
|
|
192
201
|
let reactContent: string;
|
|
193
202
|
try {
|
|
@@ -201,11 +210,16 @@ export class HTMLGenerator {
|
|
|
201
210
|
reactContent = error.partialContent.trim();
|
|
202
211
|
}
|
|
203
212
|
|
|
204
|
-
const { start, end } = await
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
213
|
+
const { start, end } = await profilePhase(
|
|
214
|
+
"html.generate_shell_parts",
|
|
215
|
+
() =>
|
|
216
|
+
this.generateShellParts(
|
|
217
|
+
fullContext,
|
|
218
|
+
mergedFrontmatter,
|
|
219
|
+
htmlOptions,
|
|
220
|
+
reactContent,
|
|
221
|
+
projectCSSPromise,
|
|
222
|
+
),
|
|
209
223
|
);
|
|
210
224
|
|
|
211
225
|
const encoder = new TextEncoder();
|
|
@@ -276,14 +290,24 @@ export class HTMLGenerator {
|
|
|
276
290
|
|
|
277
291
|
private async wrapHTMLFragment(context: HTMLGenerationContext): Promise<string> {
|
|
278
292
|
const mergedFrontmatter = this.mergeFrontmatter(context);
|
|
279
|
-
const htmlOptions = await
|
|
293
|
+
const htmlOptions = await profilePhase(
|
|
294
|
+
"html.build_options",
|
|
295
|
+
() => this.buildHTMLOptions(context, mergedFrontmatter),
|
|
296
|
+
);
|
|
297
|
+
const projectCSSPromise = this.startProjectCSSPreparation(context, htmlOptions);
|
|
298
|
+
this.startPreparedCSSWarmup(context, htmlOptions);
|
|
280
299
|
const reactContent = context.html.trim();
|
|
281
300
|
|
|
282
|
-
const { start, end } = await
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
301
|
+
const { start, end } = await profilePhase(
|
|
302
|
+
"html.generate_shell_parts",
|
|
303
|
+
() =>
|
|
304
|
+
this.generateShellParts(
|
|
305
|
+
context,
|
|
306
|
+
mergedFrontmatter,
|
|
307
|
+
htmlOptions,
|
|
308
|
+
reactContent,
|
|
309
|
+
projectCSSPromise,
|
|
310
|
+
),
|
|
287
311
|
);
|
|
288
312
|
|
|
289
313
|
return `${start}${reactContent}${end}`;
|
|
@@ -294,6 +318,7 @@ export class HTMLGenerator {
|
|
|
294
318
|
mergedFrontmatter: MDXFrontmatter,
|
|
295
319
|
htmlOptions: HTMLGenerationOptions,
|
|
296
320
|
reactContent: string,
|
|
321
|
+
projectCSSPromise?: Promise<ProjectCSSResult>,
|
|
297
322
|
): Promise<{ start: string; end: string }> {
|
|
298
323
|
const head = context.collectedHead;
|
|
299
324
|
const effectiveTitle = head?.title || mergedFrontmatter.title || "Veryfront App";
|
|
@@ -317,6 +342,7 @@ export class HTMLGenerator {
|
|
|
317
342
|
context.options?.params,
|
|
318
343
|
context.options?.props,
|
|
319
344
|
reactContent,
|
|
345
|
+
projectCSSPromise,
|
|
320
346
|
);
|
|
321
347
|
|
|
322
348
|
const { scripts, other } = this.buildHeadElements(head);
|
|
@@ -343,6 +369,76 @@ export class HTMLGenerator {
|
|
|
343
369
|
return { start: modifiedStart, end };
|
|
344
370
|
}
|
|
345
371
|
|
|
372
|
+
private startProjectCSSPreparation(
|
|
373
|
+
context: HTMLGenerationContext,
|
|
374
|
+
htmlOptions: HTMLGenerationOptions,
|
|
375
|
+
): Promise<ProjectCSSResult> | undefined {
|
|
376
|
+
const isLocalProject = htmlOptions.isLocalProject ?? false;
|
|
377
|
+
if (isLocalProject || htmlOptions.environment !== "production") return undefined;
|
|
378
|
+
|
|
379
|
+
const projectScope = htmlOptions.projectSlug || htmlOptions.projectId || context.slug;
|
|
380
|
+
if (!projectScope || projectScope === "default") return undefined;
|
|
381
|
+
|
|
382
|
+
return getProjectCSS(
|
|
383
|
+
projectScope,
|
|
384
|
+
htmlOptions.globalCSS,
|
|
385
|
+
new Set([...(htmlOptions.projectClasses ?? [])]),
|
|
386
|
+
{
|
|
387
|
+
minify: true,
|
|
388
|
+
environment: htmlOptions.environment,
|
|
389
|
+
buildMode: htmlOptions.mode,
|
|
390
|
+
},
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
private startPreparedCSSWarmup(
|
|
395
|
+
context: HTMLGenerationContext,
|
|
396
|
+
htmlOptions: HTMLGenerationOptions,
|
|
397
|
+
): void {
|
|
398
|
+
const isLocalProject = htmlOptions.isLocalProject ?? false;
|
|
399
|
+
const usesPreviewStylesheet = isLocalProject || htmlOptions.environment !== "production";
|
|
400
|
+
if (!usesPreviewStylesheet) return;
|
|
401
|
+
|
|
402
|
+
const wrappedFs = this.config.adapter.fs as unknown as {
|
|
403
|
+
getUnderlyingAdapter?: () => unknown;
|
|
404
|
+
};
|
|
405
|
+
if (typeof wrappedFs.getUnderlyingAdapter !== "function") return;
|
|
406
|
+
|
|
407
|
+
const fsAdapter = wrappedFs.getUnderlyingAdapter() as {
|
|
408
|
+
getAllSourceFiles?: () =>
|
|
409
|
+
| Array<{ path: string; content?: string }>
|
|
410
|
+
| Promise<Array<{ path: string; content?: string }>>;
|
|
411
|
+
};
|
|
412
|
+
if (typeof fsAdapter.getAllSourceFiles !== "function") return;
|
|
413
|
+
|
|
414
|
+
const projectScope = htmlOptions.projectSlug || htmlOptions.projectId || context.slug;
|
|
415
|
+
if (!projectScope || projectScope === "default") return;
|
|
416
|
+
|
|
417
|
+
const projectVersion = this.getProjectContentVersion() ??
|
|
418
|
+
(this.config.mode === "development" ? "dev" : "unknown");
|
|
419
|
+
const styleProfile = createStyleScopeProfile(this.config.config);
|
|
420
|
+
const stylesheetPath = this.config.config?.tailwind?.stylesheet;
|
|
421
|
+
|
|
422
|
+
Promise.resolve(fsAdapter.getAllSourceFiles()).then((files) =>
|
|
423
|
+
warmPreparedCSSArtifactFromFiles({
|
|
424
|
+
projectSlug: projectScope,
|
|
425
|
+
projectVersion,
|
|
426
|
+
projectDir: this.config.projectDir,
|
|
427
|
+
files,
|
|
428
|
+
styleProfile,
|
|
429
|
+
stylesheetPath,
|
|
430
|
+
minify: true,
|
|
431
|
+
environment: "preview",
|
|
432
|
+
buildMode: "production",
|
|
433
|
+
})
|
|
434
|
+
).catch((error) => {
|
|
435
|
+
logger.debug("Prepared CSS warmup skipped after source scan failure", {
|
|
436
|
+
projectScope,
|
|
437
|
+
error: error instanceof Error ? error.message : String(error),
|
|
438
|
+
});
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
346
442
|
private buildHeadElements(head?: CollectedHead): { scripts: string; other: string } {
|
|
347
443
|
if (!head) return { scripts: "", other: "" };
|
|
348
444
|
|
|
@@ -438,15 +534,21 @@ export class HTMLGenerator {
|
|
|
438
534
|
): Promise<HTMLGenerationOptions> {
|
|
439
535
|
const stylesheetPath = this.config.config?.tailwind?.stylesheet || "globals.css";
|
|
440
536
|
const [appComponentPathOrNull, globalCSS] = await Promise.all([
|
|
441
|
-
this.resolveAppPath(),
|
|
442
|
-
this.loadProjectFile(stylesheetPath),
|
|
537
|
+
profilePhase("html.resolve_app_path", () => this.resolveAppPath()),
|
|
538
|
+
profilePhase("html.load_global_css", () => this.loadProjectFile(stylesheetPath)),
|
|
443
539
|
]);
|
|
444
540
|
const appComponentPath = appComponentPathOrNull ?? undefined;
|
|
445
|
-
const projectClasses = await
|
|
541
|
+
const projectClasses = await profilePhase(
|
|
542
|
+
"html.route_candidates",
|
|
543
|
+
() => this.extractProjectClassesForRoute(context, appComponentPath),
|
|
544
|
+
);
|
|
446
545
|
|
|
447
546
|
// Load CSS imported by components and merge with globalCSS.
|
|
448
547
|
// Deduplicate against the configured stylesheet to avoid double-loading.
|
|
449
|
-
const combinedCSS = await
|
|
548
|
+
const combinedCSS = await profilePhase(
|
|
549
|
+
"html.merge_imported_css",
|
|
550
|
+
() => this.mergeImportedCSS(globalCSS, context.cssImports, stylesheetPath),
|
|
551
|
+
);
|
|
450
552
|
|
|
451
553
|
logger.debug("App component resolution", {
|
|
452
554
|
appComponentPath,
|
|
@@ -474,7 +576,7 @@ export class HTMLGenerator {
|
|
|
474
576
|
? computeSourceHash(context.pageInfo.entity.content)
|
|
475
577
|
: undefined;
|
|
476
578
|
|
|
477
|
-
return {
|
|
579
|
+
return profileSyncPhase("html.build_options.finalize", () => ({
|
|
478
580
|
mode: this.config.mode,
|
|
479
581
|
config: this.config.config,
|
|
480
582
|
projectDir: this.config.projectDir,
|
|
@@ -491,6 +593,7 @@ export class HTMLGenerator {
|
|
|
491
593
|
frontmatter: mergedFrontmatter,
|
|
492
594
|
studioEmbed: context.options?.studioEmbed,
|
|
493
595
|
projectId: context.options?.projectId,
|
|
596
|
+
projectSlug: context.options?.projectSlug,
|
|
494
597
|
pageId: context.options?.pageId,
|
|
495
598
|
sourceHash,
|
|
496
599
|
colorScheme: context.options?.colorScheme,
|
|
@@ -501,7 +604,8 @@ export class HTMLGenerator {
|
|
|
501
604
|
projectClasses,
|
|
502
605
|
isLocalProject: this.config.mode === "development",
|
|
503
606
|
noHmr: context.options?.noHmr,
|
|
504
|
-
|
|
607
|
+
forceProductionScripts: context.options?.forceProductionScripts,
|
|
608
|
+
}));
|
|
505
609
|
}
|
|
506
610
|
|
|
507
611
|
/**
|
|
@@ -12,6 +12,10 @@ import type { RenderOptions } from "./types.js";
|
|
|
12
12
|
import { runWithHeadCollector } from "../../react/head-collector.js";
|
|
13
13
|
import { getWorkerPool, isSSRIsolationEnabled } from "../../security/sandbox/worker-pool.js";
|
|
14
14
|
import type { WorkerResponse } from "../../security/sandbox/worker-types.js";
|
|
15
|
+
import {
|
|
16
|
+
endRenderSession,
|
|
17
|
+
hasRenderSession,
|
|
18
|
+
} from "../../transforms/mdx/esm-module-loader/module-fetcher/index.js";
|
|
15
19
|
|
|
16
20
|
const logger = rendererLogger.component("ssr-orchestrator");
|
|
17
21
|
|
|
@@ -113,6 +117,10 @@ export class SSROrchestrator {
|
|
|
113
117
|
|
|
114
118
|
const { html, stream } = renderResult;
|
|
115
119
|
|
|
120
|
+
if (options?.renderSessionId && hasRenderSession(options.renderSessionId)) {
|
|
121
|
+
endRenderSession(options.renderSessionId);
|
|
122
|
+
}
|
|
123
|
+
|
|
116
124
|
const mergedOptions = {
|
|
117
125
|
...generationContext.options,
|
|
118
126
|
...options,
|
|
@@ -55,6 +55,10 @@ export interface RenderOptions {
|
|
|
55
55
|
skipCachePersist?: boolean;
|
|
56
56
|
/** Disable HMR scripts (for embedded iframes where WebSocket is unwanted) */
|
|
57
57
|
noHmr?: boolean;
|
|
58
|
+
/** Force production client scripts even when rendering a local project */
|
|
59
|
+
forceProductionScripts?: boolean;
|
|
60
|
+
/** Internal SSR module-tracking session id for first-response manifest preloads */
|
|
61
|
+
renderSessionId?: string;
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
export interface RenderContext {
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import type { DirEntry, FileInfo } from "../platform/adapters/base.js";
|
|
2
|
-
|
|
3
|
-
// Re-export schema-based types
|
|
4
2
|
export type { CacheRepositoryOptions, CacheStats, RepositoryContext } from "./schemas/index.js";
|
|
5
|
-
|
|
6
|
-
// Import for use in interface definitions
|
|
7
3
|
import type { CacheStats, RepositoryContext } from "./schemas/index.js";
|
|
8
4
|
|
|
9
5
|
export interface FileSystemRepository {
|
|
@@ -12,8 +12,8 @@ import { createError, toError } from "../errors/veryfront-error.js";
|
|
|
12
12
|
export function resource<TParams = unknown, TData = unknown>(
|
|
13
13
|
config: ResourceConfig<TParams, TData>,
|
|
14
14
|
): Resource<TParams, TData> {
|
|
15
|
-
const pattern = config.pattern ??
|
|
16
|
-
const id =
|
|
15
|
+
const pattern = config.pattern ?? generateFallbackPattern();
|
|
16
|
+
const id = resourcePatternToId(pattern);
|
|
17
17
|
|
|
18
18
|
return {
|
|
19
19
|
id,
|
|
@@ -24,13 +24,7 @@ export function resource<TParams = unknown, TData = unknown>(
|
|
|
24
24
|
try {
|
|
25
25
|
config.paramsSchema.parse(params);
|
|
26
26
|
} catch (error) {
|
|
27
|
-
|
|
28
|
-
throw toError(
|
|
29
|
-
createError({
|
|
30
|
-
type: "agent",
|
|
31
|
-
message: `Resource "${id}" params validation failed: ${message}`,
|
|
32
|
-
}),
|
|
33
|
-
);
|
|
27
|
+
throw createParamsValidationError(id, error);
|
|
34
28
|
}
|
|
35
29
|
|
|
36
30
|
return config.load(params);
|
|
@@ -46,7 +40,7 @@ export function resource<TParams = unknown, TData = unknown>(
|
|
|
46
40
|
* Auto-discovery is handled by the discovery module which scans
|
|
47
41
|
* the filesystem and extracts patterns from resource definitions.
|
|
48
42
|
*/
|
|
49
|
-
function
|
|
43
|
+
function generateFallbackPattern(): string {
|
|
50
44
|
return `/resource_${Date.now()}`;
|
|
51
45
|
}
|
|
52
46
|
|
|
@@ -54,6 +48,16 @@ function generateResourcePattern(): string {
|
|
|
54
48
|
* Convert path pattern to ID
|
|
55
49
|
* Example: "/users/:userId/profile" -> "users_userId_profile"
|
|
56
50
|
*/
|
|
57
|
-
function
|
|
51
|
+
function resourcePatternToId(pattern: string): string {
|
|
58
52
|
return pattern.replace(/^\//, "").replace(/\//g, "_").replace(/:/g, "");
|
|
59
53
|
}
|
|
54
|
+
|
|
55
|
+
function createParamsValidationError(resourceId: string, cause: unknown): Error {
|
|
56
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
57
|
+
return toError(
|
|
58
|
+
createError({
|
|
59
|
+
type: "agent",
|
|
60
|
+
message: `Resource "${resourceId}" params validation failed: ${message}`,
|
|
61
|
+
}),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -11,12 +11,12 @@ import type { Resource } from "./types.js";
|
|
|
11
11
|
import { ProjectScopedRegistryManager } from "../ai/registry-manager.js";
|
|
12
12
|
import { ScopedRegistryFacade } from "../ai/registry-facade.js";
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const resourceRegistryManager = new ProjectScopedRegistryManager<Resource>("resource");
|
|
15
15
|
|
|
16
|
-
class
|
|
16
|
+
class ResourceRegistry extends ScopedRegistryFacade<Resource> {
|
|
17
17
|
findByPattern(uri: string): Resource | undefined {
|
|
18
18
|
for (const resource of this.getAll().values()) {
|
|
19
|
-
if (this.
|
|
19
|
+
if (this.matchPattern(uri, resource.pattern)) return resource;
|
|
20
20
|
}
|
|
21
21
|
return undefined;
|
|
22
22
|
}
|
|
@@ -25,12 +25,12 @@ class ResourceRegistryClass extends ScopedRegistryFacade<Resource> {
|
|
|
25
25
|
return new RegExp(`^${pattern.replace(/:(\w+)/g, "(?<$1>[^/]+)")}$`);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
private
|
|
29
|
-
return this.patternToRegex(pattern)
|
|
28
|
+
private matchPattern(uri: string, pattern: string): RegExpMatchArray | null {
|
|
29
|
+
return uri.match(this.patternToRegex(pattern));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
extractParams(uri: string, pattern: string): Record<string, string> {
|
|
33
|
-
return
|
|
33
|
+
return this.matchPattern(uri, pattern)?.groups ?? {};
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
list(): string[] {
|
|
@@ -38,4 +38,4 @@ class ResourceRegistryClass extends ScopedRegistryFacade<Resource> {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export const resourceRegistry = new
|
|
41
|
+
export const resourceRegistry = new ResourceRegistry(resourceRegistryManager);
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { MAX_URL_LENGTH_FOR_VALIDATION } from "../utils/constants/index.js";
|
|
3
|
+
import { timestamp } from "./primitives.js";
|
|
4
|
+
|
|
5
|
+
const SLUG_PATTERN = /^[a-z0-9-]+$/;
|
|
6
|
+
const E164_PHONE_NUMBER_PATTERN = /^\+?[1-9]\d{1,14}$/;
|
|
3
7
|
|
|
4
8
|
export const CommonSchemas = {
|
|
5
9
|
email: z.string().email().max(255),
|
|
6
10
|
uuid: z.string().uuid(),
|
|
7
|
-
slug: z.string().regex(
|
|
11
|
+
slug: z.string().regex(SLUG_PATTERN).min(1).max(100),
|
|
8
12
|
url: z.string().url().max(MAX_URL_LENGTH_FOR_VALIDATION),
|
|
9
|
-
phoneNumber: z.string().regex(
|
|
13
|
+
phoneNumber: z.string().regex(E164_PHONE_NUMBER_PATTERN),
|
|
10
14
|
|
|
11
15
|
pagination: z.object({
|
|
12
16
|
page: z.coerce.number().int().positive().default(1),
|
|
@@ -17,8 +21,8 @@ export const CommonSchemas = {
|
|
|
17
21
|
|
|
18
22
|
dateRange: z
|
|
19
23
|
.object({
|
|
20
|
-
from:
|
|
21
|
-
to:
|
|
24
|
+
from: timestamp,
|
|
25
|
+
to: timestamp,
|
|
22
26
|
})
|
|
23
27
|
.refine(({ from, to }) => new Date(from) <= new Date(to), {
|
|
24
28
|
message: "From date must be before or equal to To date",
|
|
@@ -33,7 +37,6 @@ export const CommonSchemas = {
|
|
|
33
37
|
.regex(/[^A-Za-z0-9]/, "Password must contain at least one special character"),
|
|
34
38
|
};
|
|
35
39
|
|
|
36
|
-
// Export inferred types for convenience
|
|
37
40
|
export type Email = z.infer<typeof CommonSchemas.email>;
|
|
38
41
|
export type Uuid = z.infer<typeof CommonSchemas.uuid>;
|
|
39
42
|
export type Slug = z.infer<typeof CommonSchemas.slug>;
|
|
@@ -3,7 +3,7 @@ import type { SecurityConfig } from "../../types/index.js";
|
|
|
3
3
|
import type { VeryfrontConfig } from "../../config/index.js";
|
|
4
4
|
import { getConfig } from "../../config/index.js";
|
|
5
5
|
import { serverLogger } from "../../utils/index.js";
|
|
6
|
-
import { buildCSP, generateNonce } from "./response/security-handler.js";
|
|
6
|
+
import { buildCSP, generateNonce, serializeCSPDirectives } from "./response/security-handler.js";
|
|
7
7
|
|
|
8
8
|
const logger = serverLogger.component("security-config-loader");
|
|
9
9
|
|
|
@@ -33,7 +33,7 @@ export class SecurityConfigLoader {
|
|
|
33
33
|
this.applyConfig(cfg);
|
|
34
34
|
} catch (error) {
|
|
35
35
|
// Config is optional, so we don't throw
|
|
36
|
-
logger.debug("Failed to load config
|
|
36
|
+
logger.debug("Failed to load config", { error });
|
|
37
37
|
this.isLoaded = true; // Mark as loaded even on error to prevent retry
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -54,26 +54,10 @@ export class SecurityConfigLoader {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
this.securityConfig = security;
|
|
57
|
-
this.cspUserHeader =
|
|
57
|
+
this.cspUserHeader = serializeCSPDirectives(security.csp);
|
|
58
58
|
this.isLoaded = true;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
private parseCspUserHeader(csp: SecurityConfig["csp"]): string | null {
|
|
62
|
-
if (!csp || typeof csp !== "object") return null;
|
|
63
|
-
|
|
64
|
-
const pieces: string[] = [];
|
|
65
|
-
|
|
66
|
-
for (const [k, v] of Object.entries(csp)) {
|
|
67
|
-
if (v === undefined) continue;
|
|
68
|
-
|
|
69
|
-
const key = k.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
70
|
-
const val = Array.isArray(v) ? v.join(" ") : String(v);
|
|
71
|
-
pieces.push(`${key} ${val}`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return pieces.length ? pieces.join("; ") : null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
61
|
getSecurityConfig(): SecurityConfig | null {
|
|
78
62
|
return this.securityConfig;
|
|
79
63
|
}
|
|
@@ -56,6 +56,26 @@ function buildDefaultCSP(nonce: string): string {
|
|
|
56
56
|
].join("; ");
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
export function serializeCSPDirectives(
|
|
60
|
+
csp: SecurityConfig["csp"],
|
|
61
|
+
nonce?: string,
|
|
62
|
+
): string | null {
|
|
63
|
+
if (!csp || typeof csp !== "object") return null;
|
|
64
|
+
|
|
65
|
+
const pieces: string[] = [];
|
|
66
|
+
|
|
67
|
+
for (const [key, value] of Object.entries(csp)) {
|
|
68
|
+
if (value === undefined) continue;
|
|
69
|
+
|
|
70
|
+
const directive = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
71
|
+
const sources = Array.isArray(value) ? value.join(" ") : String(value);
|
|
72
|
+
const serialized = `${directive} ${sources}`;
|
|
73
|
+
pieces.push(nonce ? serialized.replace(/{NONCE}/g, nonce) : serialized);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return pieces.length ? pieces.join("; ") : null;
|
|
77
|
+
}
|
|
78
|
+
|
|
59
79
|
export function buildCSP(
|
|
60
80
|
isDev: boolean,
|
|
61
81
|
nonce: string,
|
|
@@ -69,19 +89,8 @@ export function buildCSP(
|
|
|
69
89
|
if (cspUserHeader?.trim()) return cspUserHeader.replace(/{NONCE}/g, nonce);
|
|
70
90
|
|
|
71
91
|
const cfgCsp = config?.csp;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
for (const [k, v] of Object.entries(cfgCsp)) {
|
|
76
|
-
if (v === undefined) continue;
|
|
77
|
-
|
|
78
|
-
const key = k.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
79
|
-
const val = Array.isArray(v) ? v.join(" ") : String(v);
|
|
80
|
-
pieces.push(`${key} ${val}`.replace(/{NONCE}/g, nonce));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (pieces.length) return pieces.join("; ");
|
|
84
|
-
}
|
|
92
|
+
const serializedConfigCsp = serializeCSPDirectives(cfgCsp, nonce);
|
|
93
|
+
if (serializedConfigCsp) return serializedConfigCsp;
|
|
85
94
|
|
|
86
95
|
// No explicit CSP configured — apply a secure default in production.
|
|
87
96
|
// Dev mode skips the default to avoid blocking HMR and dev tooling.
|
|
@@ -30,13 +30,10 @@ export type {
|
|
|
30
30
|
ValidatedHandlerFunction,
|
|
31
31
|
} from "./input-validation/index.js";
|
|
32
32
|
|
|
33
|
-
export {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
setCors,
|
|
38
|
-
} from "./http/handlers-index.js";
|
|
39
|
-
export type { CORSConfig, CSPDirectives, SecurityConfig } from "./http/handlers-index.js";
|
|
33
|
+
export { AuthHandler } from "./http/auth.js";
|
|
34
|
+
export { SecurityConfigLoader } from "./http/config.js";
|
|
35
|
+
export { loadSecurityConfig, setCors } from "./http/middleware/index.js";
|
|
36
|
+
export type { CORSConfig, CSPDirectives, SecurityConfig } from "./http/middleware/index.js";
|
|
40
37
|
|
|
41
38
|
export { CsrfHandler } from "./http/csrf/index.js";
|
|
42
39
|
export { applyCsrfCookie, generateCsrfToken, validateCsrf } from "./csrf/index.js";
|
|
@@ -34,6 +34,7 @@ import type {
|
|
|
34
34
|
VeryfrontApiClient,
|
|
35
35
|
} from "../../../platform/adapters/veryfront-api-client/index.js";
|
|
36
36
|
import { extractProjectCandidates } from "./styles-candidate-scanner.js";
|
|
37
|
+
import { profilePhase } from "../../../observability/request-profiler.js";
|
|
37
38
|
|
|
38
39
|
const logger = serverLogger.component("styles-css-handler");
|
|
39
40
|
|
|
@@ -59,7 +60,7 @@ export class StylesCSSHandler extends BaseHandler {
|
|
|
59
60
|
const contentContext = this.getContentContext(ctx);
|
|
60
61
|
let rawCss: string;
|
|
61
62
|
try {
|
|
62
|
-
rawCss = await this.loadStylesheet(ctx);
|
|
63
|
+
rawCss = await profilePhase("css.load_stylesheet", () => this.loadStylesheet(ctx));
|
|
63
64
|
} catch (error) {
|
|
64
65
|
logger.error("Failed to load stylesheet", {
|
|
65
66
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -75,7 +76,10 @@ export class StylesCSSHandler extends BaseHandler {
|
|
|
75
76
|
);
|
|
76
77
|
|
|
77
78
|
if (preparedContext) {
|
|
78
|
-
const prepared = await
|
|
79
|
+
const prepared = await profilePhase(
|
|
80
|
+
"css.prepared_cache_lookup",
|
|
81
|
+
() => tryGetPreparedProjectCSS(preparedContext),
|
|
82
|
+
);
|
|
79
83
|
if (prepared) {
|
|
80
84
|
logger.debug("Prepared CSS cache hit", {
|
|
81
85
|
projectScope,
|
|
@@ -90,12 +94,16 @@ export class StylesCSSHandler extends BaseHandler {
|
|
|
90
94
|
}
|
|
91
95
|
}
|
|
92
96
|
|
|
93
|
-
const remotePrepared = await
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
const remotePrepared = await profilePhase(
|
|
98
|
+
"css.remote_artifact_lookup",
|
|
99
|
+
() =>
|
|
100
|
+
this.tryResolveRemotePreparedCSS(
|
|
101
|
+
ctx,
|
|
102
|
+
projectScope,
|
|
103
|
+
styleProfile.hash,
|
|
104
|
+
contentContext,
|
|
105
|
+
preparedContext,
|
|
106
|
+
),
|
|
99
107
|
);
|
|
100
108
|
if (remotePrepared) {
|
|
101
109
|
logger.debug("Prepared CSS resolved via style artifact metadata", {
|
|
@@ -111,7 +119,10 @@ export class StylesCSSHandler extends BaseHandler {
|
|
|
111
119
|
|
|
112
120
|
let candidates: Set<string>;
|
|
113
121
|
try {
|
|
114
|
-
candidates = await
|
|
122
|
+
candidates = await profilePhase(
|
|
123
|
+
"css.extract_candidates",
|
|
124
|
+
() => extractProjectCandidates(ctx),
|
|
125
|
+
);
|
|
115
126
|
} catch (error) {
|
|
116
127
|
logger.error("Failed to extract candidates", {
|
|
117
128
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -120,7 +131,10 @@ export class StylesCSSHandler extends BaseHandler {
|
|
|
120
131
|
}
|
|
121
132
|
let result: GeneratedStylesResult;
|
|
122
133
|
try {
|
|
123
|
-
result = await
|
|
134
|
+
result = await profilePhase(
|
|
135
|
+
"css.generate_stylesheet",
|
|
136
|
+
() => this.generateStylesheet(ctx, rawCss, candidates),
|
|
137
|
+
);
|
|
124
138
|
} catch (error) {
|
|
125
139
|
const formatted = formatCSSError(error instanceof Error ? error : String(error));
|
|
126
140
|
logger.error("Tailwind error", {
|
|
@@ -173,10 +187,14 @@ body::before {
|
|
|
173
187
|
});
|
|
174
188
|
|
|
175
189
|
if (preparedContext && "hash" in result) {
|
|
176
|
-
await
|
|
177
|
-
css
|
|
178
|
-
|
|
179
|
-
|
|
190
|
+
await profilePhase(
|
|
191
|
+
"css.store_prepared",
|
|
192
|
+
() =>
|
|
193
|
+
storePreparedProjectCSS(preparedContext, {
|
|
194
|
+
css: result.css,
|
|
195
|
+
hash: result.hash,
|
|
196
|
+
}),
|
|
197
|
+
);
|
|
180
198
|
}
|
|
181
199
|
|
|
182
200
|
if ("hash" in result) {
|
|
@@ -2,6 +2,7 @@ import * as dntShim from "../../../../_dnt.shims.js";
|
|
|
2
2
|
import { BaseHandler } from "../response/base.js";
|
|
3
3
|
import type { HandlerContext, HandlerMetadata, HandlerPriority, HandlerResult } from "../types.js";
|
|
4
4
|
import { metrics } from "../../../observability/simple-metrics/index.js";
|
|
5
|
+
import { snapshotRequestProfiles } from "../../../observability/request-profiler.js";
|
|
5
6
|
import { ResponseBuilder } from "../../../security/index.js";
|
|
6
7
|
import {
|
|
7
8
|
HTTP_INTERNAL_SERVER_ERROR,
|
|
@@ -29,11 +30,12 @@ export class MetricsHandler extends BaseHandler {
|
|
|
29
30
|
|
|
30
31
|
try {
|
|
31
32
|
const snap = metrics.snapshot();
|
|
33
|
+
const profiling = snapshotRequestProfiles();
|
|
32
34
|
const memory = this.safeCall(memoryUsage);
|
|
33
35
|
const uptimeValue = this.safeCall(uptime);
|
|
34
36
|
|
|
35
37
|
const response = ResponseBuilder.json(
|
|
36
|
-
{ counters: snap, memory, uptime: uptimeValue },
|
|
38
|
+
{ counters: snap, profiling, memory, uptime: uptimeValue },
|
|
37
39
|
req,
|
|
38
40
|
{ securityConfig, corsConfig, status: HTTP_OK },
|
|
39
41
|
);
|