@warlock.js/core 5.29.0 → 5.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/esm/application/app.d.mts +1 -1
- package/esm/application/app.d.mts.map +1 -1
- package/esm/application/app.mjs +1 -1
- package/esm/application/app.mjs.map +1 -1
- package/esm/application/application-config-types.d.mts +1 -1
- package/esm/application/application-config-types.d.mts.map +1 -1
- package/esm/application/application.d.mts +1 -1
- package/esm/application/application.d.mts.map +1 -1
- package/esm/application/application.mjs +1 -1
- package/esm/application/application.mjs.map +1 -1
- package/esm/application/boot-signal.d.mts +1 -1
- package/esm/application/boot-signal.d.mts.map +1 -1
- package/esm/application/boot-signal.mjs +1 -1
- package/esm/application/boot-signal.mjs.map +1 -1
- package/esm/application/public-url.d.mts +1 -1
- package/esm/application/public-url.d.mts.map +1 -1
- package/esm/application/public-url.mjs +1 -1
- package/esm/application/public-url.mjs.map +1 -1
- package/esm/application/roles.d.mts +1 -1
- package/esm/application/roles.d.mts.map +1 -1
- package/esm/application/roles.mjs +1 -1
- package/esm/application/roles.mjs.map +1 -1
- package/esm/benchmark/benchmark-snapshots.d.mts +1 -1
- package/esm/benchmark/benchmark-snapshots.d.mts.map +1 -1
- package/esm/benchmark/benchmark-snapshots.mjs +1 -1
- package/esm/benchmark/benchmark-snapshots.mjs.map +1 -1
- package/esm/benchmark/benchmark.d.mts +1 -1
- package/esm/benchmark/benchmark.d.mts.map +1 -1
- package/esm/benchmark/benchmark.mjs +1 -1
- package/esm/benchmark/benchmark.mjs.map +1 -1
- package/esm/benchmark/channels/console.channel.d.mts +1 -1
- package/esm/benchmark/channels/console.channel.d.mts.map +1 -1
- package/esm/benchmark/channels/console.channel.mjs +1 -1
- package/esm/benchmark/channels/console.channel.mjs.map +1 -1
- package/esm/benchmark/channels/noop.channel.d.mts +1 -1
- package/esm/benchmark/channels/noop.channel.d.mts.map +1 -1
- package/esm/benchmark/channels/noop.channel.mjs +1 -1
- package/esm/benchmark/channels/noop.channel.mjs.map +1 -1
- package/esm/benchmark/profiler.d.mts +1 -1
- package/esm/benchmark/profiler.d.mts.map +1 -1
- package/esm/benchmark/profiler.mjs +1 -1
- package/esm/benchmark/profiler.mjs.map +1 -1
- package/esm/benchmark/types.d.mts +1 -1
- package/esm/benchmark/types.d.mts.map +1 -1
- package/esm/bootstrap/setup.d.mts +1 -1
- package/esm/bootstrap/setup.d.mts.map +1 -1
- package/esm/bootstrap/setup.mjs +1 -1
- package/esm/bootstrap/setup.mjs.map +1 -1
- package/esm/bootstrap.d.mts +1 -1
- package/esm/bootstrap.d.mts.map +1 -1
- package/esm/bootstrap.mjs +1 -1
- package/esm/bootstrap.mjs.map +1 -1
- package/esm/cache/database-cache-driver.d.mts +1 -1
- package/esm/cache/database-cache-driver.d.mts.map +1 -1
- package/esm/cache/database-cache-driver.mjs +1 -1
- package/esm/cache/database-cache-driver.mjs.map +1 -1
- package/esm/cache/index.mjs +1 -1
- package/esm/cache/index.mjs.map +1 -1
- package/esm/cli/cli-commands.manager.mjs +1 -1
- package/esm/cli/cli-commands.manager.mjs.map +1 -1
- package/esm/cli/cli-commands.utils.mjs +1 -1
- package/esm/cli/cli-commands.utils.mjs.map +1 -1
- package/esm/cli/commands/add.command.mjs +1 -1
- package/esm/cli/commands/add.command.mjs.map +1 -1
- package/esm/cli/commands/build.command.mjs +1 -1
- package/esm/cli/commands/build.command.mjs.map +1 -1
- package/esm/cli/commands/create-database.command.mjs +1 -1
- package/esm/cli/commands/create-database.command.mjs.map +1 -1
- package/esm/cli/commands/dev-server.command.mjs +1 -1
- package/esm/cli/commands/dev-server.command.mjs.map +1 -1
- package/esm/cli/commands/doctor/boot-for-diagnostics.mjs +1 -1
- package/esm/cli/commands/doctor/boot-for-diagnostics.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/config.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/config.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/connectors.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/connectors.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/handler-signature.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/handler-signature.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/health.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/health.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/index.mjs +1 -1
- package/esm/cli/commands/doctor/checks/index.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/routes.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/routes.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/doctor-command.action.mjs +1 -1
- package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
- package/esm/cli/commands/doctor/format-report.mjs +1 -1
- package/esm/cli/commands/doctor/format-report.mjs.map +1 -1
- package/esm/cli/commands/doctor/run-checks.mjs +1 -1
- package/esm/cli/commands/doctor/run-checks.mjs.map +1 -1
- package/esm/cli/commands/doctor.command.mjs +1 -1
- package/esm/cli/commands/doctor.command.mjs.map +1 -1
- package/esm/cli/commands/drop-tables.command.mjs +1 -1
- package/esm/cli/commands/drop-tables.command.mjs.map +1 -1
- package/esm/cli/commands/generate/generate.command.mjs +1 -1
- package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/column-dsl-parser.mjs +1 -1
- package/esm/cli/commands/generate/generators/column-dsl-parser.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/controller.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/controller.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/migration.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/migration.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/model.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/model.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/module.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/module.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/repository.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/repository.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/resource.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/resource.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/service.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/service.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/use-case.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/use-case.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/templates/stubs.mjs +1 -1
- package/esm/cli/commands/generate/templates/stubs.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
- package/esm/cli/commands/generate/utils/name-parser.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/path-resolver.mjs +1 -1
- package/esm/cli/commands/generate/utils/path-resolver.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/prompt.mjs +1 -1
- package/esm/cli/commands/generate/utils/prompt.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/writer.mjs +1 -1
- package/esm/cli/commands/generate/utils/writer.mjs.map +1 -1
- package/esm/cli/commands/migrate.command.mjs +1 -1
- package/esm/cli/commands/migrate.command.mjs.map +1 -1
- package/esm/cli/commands/openapi-generator.action.mjs +1 -1
- package/esm/cli/commands/openapi-generator.action.mjs.map +1 -1
- package/esm/cli/commands/openapi-generator.command.mjs +1 -1
- package/esm/cli/commands/openapi-generator.command.mjs.map +1 -1
- package/esm/cli/commands/postman-generator.action.mjs +1 -1
- package/esm/cli/commands/postman-generator.action.mjs.map +1 -1
- package/esm/cli/commands/postman-generator.command.mjs +1 -1
- package/esm/cli/commands/postman-generator.command.mjs.map +1 -1
- package/esm/cli/commands/routes/diff-page-routes.mjs +1 -1
- package/esm/cli/commands/routes/diff-page-routes.mjs.map +1 -1
- package/esm/cli/commands/routes/format-routes-table.mjs +1 -1
- package/esm/cli/commands/routes/format-routes-table.mjs.map +1 -1
- package/esm/cli/commands/routes/route-row.mjs +1 -1
- package/esm/cli/commands/routes/route-row.mjs.map +1 -1
- package/esm/cli/commands/routes/routes-command.action.mjs +1 -1
- package/esm/cli/commands/routes/routes-command.action.mjs.map +1 -1
- package/esm/cli/commands/routes/routes-diff.action.mjs +1 -1
- package/esm/cli/commands/routes/routes-diff.action.mjs.map +1 -1
- package/esm/cli/commands/routes/with-console-on-stderr.mjs +1 -1
- package/esm/cli/commands/routes/with-console-on-stderr.mjs.map +1 -1
- package/esm/cli/commands/routes.command.mjs +1 -1
- package/esm/cli/commands/routes.command.mjs.map +1 -1
- package/esm/cli/commands/seed.command.mjs +1 -1
- package/esm/cli/commands/seed.command.mjs.map +1 -1
- package/esm/cli/commands/start-production.command.mjs +1 -1
- package/esm/cli/commands/start-production.command.mjs.map +1 -1
- package/esm/cli/commands/storage-put.action.mjs +1 -1
- package/esm/cli/commands/storage-put.action.mjs.map +1 -1
- package/esm/cli/commands/storage-put.command.mjs +1 -1
- package/esm/cli/commands/storage-put.command.mjs.map +1 -1
- package/esm/cli/commands/typings-generator.command.mjs +1 -1
- package/esm/cli/commands/typings-generator.command.mjs.map +1 -1
- package/esm/cli/commands/update.command.mjs +1 -1
- package/esm/cli/commands/update.command.mjs.map +1 -1
- package/esm/cli/commands-loader.mjs +1 -1
- package/esm/cli/commands-loader.mjs.map +1 -1
- package/esm/cli/framework-cli-commands.mjs +1 -1
- package/esm/cli/framework-cli-commands.mjs.map +1 -1
- package/esm/cli/parse-cli-args.mjs +1 -1
- package/esm/cli/parse-cli-args.mjs.map +1 -1
- package/esm/cli/start.mjs +1 -1
- package/esm/cli/start.mjs.map +1 -1
- package/esm/cli/string-similarity.mjs +1 -1
- package/esm/cli/string-similarity.mjs.map +1 -1
- package/esm/commands/cli-command.d.mts +1 -1
- package/esm/commands/cli-command.d.mts.map +1 -1
- package/esm/commands/cli-command.mjs +1 -1
- package/esm/commands/cli-command.mjs.map +1 -1
- package/esm/commands/types.d.mts +1 -1
- package/esm/commands/types.d.mts.map +1 -1
- package/esm/config/config-getter.d.mts +1 -1
- package/esm/config/config-getter.d.mts.map +1 -1
- package/esm/config/config-getter.mjs +1 -1
- package/esm/config/config-getter.mjs.map +1 -1
- package/esm/config/config-handlers.d.mts +1 -1
- package/esm/config/config-handlers.d.mts.map +1 -1
- package/esm/config/config-handlers.mjs +1 -1
- package/esm/config/config-handlers.mjs.map +1 -1
- package/esm/config/config-key-from-path.mjs +1 -1
- package/esm/config/config-key-from-path.mjs.map +1 -1
- package/esm/config/config-loader.d.mts +1 -1
- package/esm/config/config-loader.d.mts.map +1 -1
- package/esm/config/config-loader.mjs +1 -1
- package/esm/config/config-loader.mjs.map +1 -1
- package/esm/config/config-manager.mjs +1 -1
- package/esm/config/config-manager.mjs.map +1 -1
- package/esm/config/config-setter.d.mts +1 -1
- package/esm/config/config-setter.d.mts.map +1 -1
- package/esm/config/config-setter.mjs +1 -1
- package/esm/config/config-setter.mjs.map +1 -1
- package/esm/config/config-special-handlers.d.mts +1 -1
- package/esm/config/config-special-handlers.d.mts.map +1 -1
- package/esm/config/config-special-handlers.mjs +1 -1
- package/esm/config/config-special-handlers.mjs.map +1 -1
- package/esm/config/load-config-files.mjs +1 -1
- package/esm/config/load-config-files.mjs.map +1 -1
- package/esm/config/locale-configuration.mjs +1 -1
- package/esm/config/locale-configuration.mjs.map +1 -1
- package/esm/config/types.d.mts +1 -1
- package/esm/config/types.d.mts.map +1 -1
- package/esm/connectors/access-connector.d.mts +1 -1
- package/esm/connectors/access-connector.d.mts.map +1 -1
- package/esm/connectors/access-connector.mjs +1 -1
- package/esm/connectors/access-connector.mjs.map +1 -1
- package/esm/connectors/ai-connector.d.mts +1 -1
- package/esm/connectors/ai-connector.d.mts.map +1 -1
- package/esm/connectors/ai-connector.mjs +1 -1
- package/esm/connectors/ai-connector.mjs.map +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.d.mts +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.mjs +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.mjs.map +1 -1
- package/esm/connectors/assert-unique-connector-names.d.mts +1 -1
- package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-unique-connector-names.mjs +1 -1
- package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
- package/esm/connectors/base-connector.d.mts +1 -1
- package/esm/connectors/base-connector.d.mts.map +1 -1
- package/esm/connectors/base-connector.mjs +1 -1
- package/esm/connectors/base-connector.mjs.map +1 -1
- package/esm/connectors/cache-connector.d.mts +1 -1
- package/esm/connectors/cache-connector.d.mts.map +1 -1
- package/esm/connectors/cache-connector.mjs +1 -1
- package/esm/connectors/cache-connector.mjs.map +1 -1
- package/esm/connectors/connectors-manager.d.mts +1 -1
- package/esm/connectors/connectors-manager.d.mts.map +1 -1
- package/esm/connectors/connectors-manager.mjs +2 -2
- package/esm/connectors/connectors-manager.mjs.map +1 -1
- package/esm/connectors/database-connector.d.mts +1 -1
- package/esm/connectors/database-connector.d.mts.map +1 -1
- package/esm/connectors/database-connector.mjs +1 -1
- package/esm/connectors/database-connector.mjs.map +1 -1
- package/esm/connectors/describe-server-address.mjs +1 -1
- package/esm/connectors/describe-server-address.mjs.map +1 -1
- package/esm/connectors/herald-connector.d.mts +1 -1
- package/esm/connectors/herald-connector.d.mts.map +1 -1
- package/esm/connectors/herald-connector.mjs +1 -1
- package/esm/connectors/herald-connector.mjs.map +1 -1
- package/esm/connectors/http-connector.d.mts +1 -1
- package/esm/connectors/http-connector.d.mts.map +1 -1
- package/esm/connectors/http-connector.mjs +1 -1
- package/esm/connectors/http-connector.mjs.map +1 -1
- package/esm/connectors/logger-connector.d.mts +1 -1
- package/esm/connectors/logger-connector.d.mts.map +1 -1
- package/esm/connectors/logger-connector.mjs +1 -1
- package/esm/connectors/logger-connector.mjs.map +1 -1
- package/esm/connectors/mail-connector.d.mts +1 -1
- package/esm/connectors/mail-connector.d.mts.map +1 -1
- package/esm/connectors/mail-connector.mjs +1 -1
- package/esm/connectors/mail-connector.mjs.map +1 -1
- package/esm/connectors/notifications-connector.d.mts +1 -1
- package/esm/connectors/notifications-connector.d.mts.map +1 -1
- package/esm/connectors/notifications-connector.mjs +1 -1
- package/esm/connectors/notifications-connector.mjs.map +1 -1
- package/esm/connectors/read-bound-port.mjs +1 -1
- package/esm/connectors/read-bound-port.mjs.map +1 -1
- package/esm/connectors/register-configured-connectors.d.mts +1 -1
- package/esm/connectors/register-configured-connectors.d.mts.map +1 -1
- package/esm/connectors/register-configured-connectors.mjs +1 -1
- package/esm/connectors/register-configured-connectors.mjs.map +1 -1
- package/esm/connectors/single-server-warnings.mjs +1 -1
- package/esm/connectors/single-server-warnings.mjs.map +1 -1
- package/esm/connectors/socket-connector.d.mts +1 -1
- package/esm/connectors/socket-connector.d.mts.map +1 -1
- package/esm/connectors/socket-connector.mjs +1 -1
- package/esm/connectors/socket-connector.mjs.map +1 -1
- package/esm/connectors/storage.connector.d.mts +1 -1
- package/esm/connectors/storage.connector.d.mts.map +1 -1
- package/esm/connectors/storage.connector.mjs +1 -1
- package/esm/connectors/storage.connector.mjs.map +1 -1
- package/esm/connectors/types.d.mts +1 -1
- package/esm/connectors/types.d.mts.map +1 -1
- package/esm/connectors/types.mjs +1 -1
- package/esm/connectors/types.mjs.map +1 -1
- package/esm/container/container-instance-registry.mjs +1 -1
- package/esm/container/container-instance-registry.mjs.map +1 -1
- package/esm/container/development-app-modules.d.mts +1 -1
- package/esm/container/development-app-modules.d.mts.map +1 -1
- package/esm/container/development-model-modules.d.mts +1 -1
- package/esm/container/development-model-modules.d.mts.map +1 -1
- package/esm/container/index.d.mts +1 -1
- package/esm/container/index.d.mts.map +1 -1
- package/esm/container/index.mjs +1 -1
- package/esm/container/index.mjs.map +1 -1
- package/esm/database/create-database-action.mjs +1 -1
- package/esm/database/create-database-action.mjs.map +1 -1
- package/esm/database/drop-tables-action.mjs +1 -1
- package/esm/database/drop-tables-action.mjs.map +1 -1
- package/esm/database/migrate-action.mjs +1 -1
- package/esm/database/migrate-action.mjs.map +1 -1
- package/esm/database/models/database-log/database-log.d.mts +31 -39
- package/esm/database/models/database-log/database-log.d.mts.map +1 -1
- package/esm/database/models/database-log/database-log.mjs +1 -1
- package/esm/database/models/database-log/database-log.mjs.map +1 -1
- package/esm/database/pending-exit-code.mjs +1 -1
- package/esm/database/pending-exit-code.mjs.map +1 -1
- package/esm/database/resolve-pending-migrations.mjs +1 -1
- package/esm/database/resolve-pending-migrations.mjs.map +1 -1
- package/esm/database/seed-command-action.mjs +1 -1
- package/esm/database/seed-command-action.mjs.map +1 -1
- package/esm/database/seeds/seed-records-table-migration.mjs +1 -1
- package/esm/database/seeds/seed-records-table-migration.mjs.map +1 -1
- package/esm/database/seeds/seeder.d.mts +1 -1
- package/esm/database/seeds/seeder.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.d.mts +1 -1
- package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.mjs +1 -1
- package/esm/database/seeds/seeder.errors.mjs.map +1 -1
- package/esm/database/seeds/seeder.mjs +1 -1
- package/esm/database/seeds/seeder.mjs.map +1 -1
- package/esm/database/seeds/seeders.manager.mjs +1 -1
- package/esm/database/seeds/seeders.manager.mjs.map +1 -1
- package/esm/database/seeds/seeds-table-migration.mjs +1 -1
- package/esm/database/seeds/seeds-table-migration.mjs.map +1 -1
- package/esm/database/seeds/types.d.mts +1 -1
- package/esm/database/seeds/types.d.mts.map +1 -1
- package/esm/database/seeds/utils.mjs +1 -1
- package/esm/database/seeds/utils.mjs.map +1 -1
- package/esm/database/utils.d.mts +1 -1
- package/esm/database/utils.d.mts.map +1 -1
- package/esm/database/utils.mjs +1 -1
- package/esm/database/utils.mjs.map +1 -1
- package/esm/dev-server/app-module-registry.mjs +1 -1
- package/esm/dev-server/app-module-registry.mjs.map +1 -1
- package/esm/dev-server/boot-precondition-error.mjs +1 -1
- package/esm/dev-server/boot-precondition-error.mjs.map +1 -1
- package/esm/dev-server/build-development-openapi-document.mjs +1 -1
- package/esm/dev-server/build-development-openapi-document.mjs.map +1 -1
- package/esm/dev-server/check-for-updates.mjs +1 -1
- package/esm/dev-server/check-for-updates.mjs.map +1 -1
- package/esm/dev-server/collect-development-api-routes.mjs +1 -1
- package/esm/dev-server/collect-development-api-routes.mjs.map +1 -1
- package/esm/dev-server/create-worker.mjs +1 -1
- package/esm/dev-server/create-worker.mjs.map +1 -1
- package/esm/dev-server/dependency-graph.d.mts +1 -1
- package/esm/dev-server/dependency-graph.d.mts.map +1 -1
- package/esm/dev-server/dependency-graph.mjs +1 -1
- package/esm/dev-server/dependency-graph.mjs.map +1 -1
- package/esm/dev-server/dev-logger.mjs +1 -1
- package/esm/dev-server/dev-logger.mjs.map +1 -1
- package/esm/dev-server/development-server.mjs +1 -1
- package/esm/dev-server/development-server.mjs.map +1 -1
- package/esm/dev-server/events.mjs +1 -1
- package/esm/dev-server/events.mjs.map +1 -1
- package/esm/dev-server/extract-translation-keys.mjs +1 -1
- package/esm/dev-server/extract-translation-keys.mjs.map +1 -1
- package/esm/dev-server/file-event-handler.mjs +1 -1
- package/esm/dev-server/file-event-handler.mjs.map +1 -1
- package/esm/dev-server/file-manager.d.mts +1 -1
- package/esm/dev-server/file-manager.d.mts.map +1 -1
- package/esm/dev-server/file-manager.mjs +1 -1
- package/esm/dev-server/file-manager.mjs.map +1 -1
- package/esm/dev-server/file-operations.d.mts +1 -1
- package/esm/dev-server/file-operations.d.mts.map +1 -1
- package/esm/dev-server/file-operations.mjs +1 -1
- package/esm/dev-server/file-operations.mjs.map +1 -1
- package/esm/dev-server/files-orchestrator.mjs +20 -17
- package/esm/dev-server/files-orchestrator.mjs.map +1 -1
- package/esm/dev-server/files-watcher.mjs +1 -1
- package/esm/dev-server/files-watcher.mjs.map +1 -1
- package/esm/dev-server/flags.mjs +1 -1
- package/esm/dev-server/flags.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/base-health-checker.mjs +1 -1
- package/esm/dev-server/health-checker/checkers/base-health-checker.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +1 -1
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs +1 -1
- package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs.map +1 -1
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +1 -1
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
- package/esm/dev-server/health-checker/file-health-result.d.mts +1 -1
- package/esm/dev-server/health-checker/file-health-result.d.mts.map +1 -1
- package/esm/dev-server/health-checker/file-health-result.mjs +1 -1
- package/esm/dev-server/health-checker/file-health-result.mjs.map +1 -1
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs +1 -1
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
- package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs +1 -1
- package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs.map +1 -1
- package/esm/dev-server/health-checker/workers/ts-health.worker.mjs +1 -1
- package/esm/dev-server/health-checker/workers/ts-health.worker.mjs.map +1 -1
- package/esm/dev-server/layer-executor.mjs +1 -1
- package/esm/dev-server/layer-executor.mjs.map +1 -1
- package/esm/dev-server/legacy-locales-warning.mjs +1 -1
- package/esm/dev-server/legacy-locales-warning.mjs.map +1 -1
- package/esm/dev-server/loader/build-transpile-init.mjs +1 -1
- package/esm/dev-server/loader/build-transpile-init.mjs.map +1 -1
- package/esm/dev-server/loader/hook-thread.d.mts +1 -1
- package/esm/dev-server/loader/hook-thread.d.mts.map +1 -1
- package/esm/dev-server/loader/hook-thread.mjs +1 -1
- package/esm/dev-server/loader/hook-thread.mjs.map +1 -1
- package/esm/dev-server/loader/load-hook.d.mts +1 -1
- package/esm/dev-server/loader/load-hook.d.mts.map +1 -1
- package/esm/dev-server/loader/load-hook.mjs +1 -1
- package/esm/dev-server/loader/load-hook.mjs.map +1 -1
- package/esm/dev-server/loader/loader-port-acks.mjs +34 -0
- package/esm/dev-server/loader/loader-port-acks.mjs.map +1 -0
- package/esm/dev-server/loader/own-resolver.mjs +1 -1
- package/esm/dev-server/loader/own-resolver.mjs.map +1 -1
- package/esm/dev-server/loader/register-loader.mjs +1 -1
- package/esm/dev-server/loader/register-loader.mjs.map +1 -1
- package/esm/dev-server/loader/resolve-capture.mjs +1 -1
- package/esm/dev-server/loader/resolve-capture.mjs.map +1 -1
- package/esm/dev-server/loader/resolve-hook.d.mts +1 -1
- package/esm/dev-server/loader/resolve-hook.d.mts.map +1 -1
- package/esm/dev-server/loader/resolve-hook.mjs +2 -2
- package/esm/dev-server/loader/resolve-hook.mjs.map +1 -1
- package/esm/dev-server/loader/source-slug.mjs +1 -1
- package/esm/dev-server/loader/source-slug.mjs.map +1 -1
- package/esm/dev-server/loader/transpile-cache.mjs +1 -1
- package/esm/dev-server/loader/transpile-cache.mjs.map +1 -1
- package/esm/dev-server/loader/version-registry.mjs +1 -1
- package/esm/dev-server/loader/version-registry.mjs.map +1 -1
- package/esm/dev-server/manifest-manager.d.mts +1 -1
- package/esm/dev-server/manifest-manager.d.mts.map +1 -1
- package/esm/dev-server/manifest-manager.mjs +1 -1
- package/esm/dev-server/manifest-manager.mjs.map +1 -1
- package/esm/dev-server/model-module-registry.mjs +1 -1
- package/esm/dev-server/model-module-registry.mjs.map +1 -1
- package/esm/dev-server/model-resource-typings.mjs +1 -1
- package/esm/dev-server/model-resource-typings.mjs.map +1 -1
- package/esm/dev-server/module-loader.mjs +1 -1
- package/esm/dev-server/module-loader.mjs.map +1 -1
- package/esm/dev-server/package-json-manager.mjs +1 -1
- package/esm/dev-server/package-json-manager.mjs.map +1 -1
- package/esm/dev-server/parse-imports.mjs +73 -6
- package/esm/dev-server/parse-imports.mjs.map +1 -1
- package/esm/dev-server/read-config-ast.mjs +1 -1
- package/esm/dev-server/read-config-ast.mjs.map +1 -1
- package/esm/dev-server/ready-block.mjs +1 -1
- package/esm/dev-server/ready-block.mjs.map +1 -1
- package/esm/dev-server/register-dev-shortcuts.mjs +1 -1
- package/esm/dev-server/register-dev-shortcuts.mjs.map +1 -1
- package/esm/dev-server/register-installed-devtools.mjs +1 -1
- package/esm/dev-server/register-installed-devtools.mjs.map +1 -1
- package/esm/dev-server/restart-dev-server.mjs +1 -1
- package/esm/dev-server/restart-dev-server.mjs.map +1 -1
- package/esm/dev-server/route-types-publisher.mjs +1 -1
- package/esm/dev-server/route-types-publisher.mjs.map +1 -1
- package/esm/dev-server/run-connector-typings.mjs +1 -1
- package/esm/dev-server/run-connector-typings.mjs.map +1 -1
- package/esm/dev-server/run-typings-generation.mjs +1 -1
- package/esm/dev-server/run-typings-generation.mjs.map +1 -1
- package/esm/dev-server/shortcuts.mjs +1 -1
- package/esm/dev-server/shortcuts.mjs.map +1 -1
- package/esm/dev-server/special-file-patterns.mjs +1 -1
- package/esm/dev-server/special-file-patterns.mjs.map +1 -1
- package/esm/dev-server/special-files-collector.d.mts +1 -1
- package/esm/dev-server/special-files-collector.d.mts.map +1 -1
- package/esm/dev-server/special-files-collector.mjs +1 -1
- package/esm/dev-server/special-files-collector.mjs.map +1 -1
- package/esm/dev-server/start-development-server.mjs +1 -1
- package/esm/dev-server/start-development-server.mjs.map +1 -1
- package/esm/dev-server/supervisor.mjs +1 -1
- package/esm/dev-server/supervisor.mjs.map +1 -1
- package/esm/dev-server/translation-keys-sources.mjs +1 -1
- package/esm/dev-server/translation-keys-sources.mjs.map +1 -1
- package/esm/dev-server/tsconfig-manager.mjs +1 -1
- package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
- package/esm/dev-server/type-generator.mjs +32 -11
- package/esm/dev-server/type-generator.mjs.map +1 -1
- package/esm/dev-server/types.d.mts +1 -1
- package/esm/dev-server/types.d.mts.map +1 -1
- package/esm/dev-server/update-check-cache.mjs +1 -1
- package/esm/dev-server/update-check-cache.mjs.map +1 -1
- package/esm/dev-server/utils.mjs +1 -1
- package/esm/dev-server/utils.mjs.map +1 -1
- package/esm/encryption/encrypt.d.mts +1 -1
- package/esm/encryption/encrypt.d.mts.map +1 -1
- package/esm/encryption/encrypt.mjs +1 -1
- package/esm/encryption/encrypt.mjs.map +1 -1
- package/esm/encryption/hash.d.mts +1 -1
- package/esm/encryption/hash.d.mts.map +1 -1
- package/esm/encryption/hash.mjs +1 -1
- package/esm/encryption/hash.mjs.map +1 -1
- package/esm/encryption/password.d.mts +1 -1
- package/esm/encryption/password.d.mts.map +1 -1
- package/esm/encryption/password.mjs +1 -1
- package/esm/encryption/password.mjs.map +1 -1
- package/esm/encryption/types.d.mts +1 -1
- package/esm/encryption/types.d.mts.map +1 -1
- package/esm/errors/container-key-missing-error.mjs +1 -1
- package/esm/errors/container-key-missing-error.mjs.map +1 -1
- package/esm/errors/esbuild-binary-missing-error.mjs +1 -1
- package/esm/errors/esbuild-binary-missing-error.mjs.map +1 -1
- package/esm/errors/index.d.mts +2 -0
- package/esm/errors/index.mjs +3 -0
- package/esm/errors/unknown-locale-error.mjs +1 -1
- package/esm/errors/unknown-locale-error.mjs.map +1 -1
- package/esm/generations/add-command.action.mjs +29 -6
- package/esm/generations/add-command.action.mjs.map +1 -1
- package/esm/generations/features/access.feature.mjs +1 -1
- package/esm/generations/features/access.feature.mjs.map +1 -1
- package/esm/generations/features/ai-anthropic.feature.mjs +1 -1
- package/esm/generations/features/ai-anthropic.feature.mjs.map +1 -1
- package/esm/generations/features/ai-bedrock.feature.mjs +1 -1
- package/esm/generations/features/ai-bedrock.feature.mjs.map +1 -1
- package/esm/generations/features/ai-google.feature.mjs +1 -1
- package/esm/generations/features/ai-google.feature.mjs.map +1 -1
- package/esm/generations/features/ai-ollama.feature.mjs +1 -1
- package/esm/generations/features/ai-ollama.feature.mjs.map +1 -1
- package/esm/generations/features/ai-openai.feature.mjs +1 -1
- package/esm/generations/features/ai-openai.feature.mjs.map +1 -1
- package/esm/generations/features/ai-panoptic.feature.mjs +1 -1
- package/esm/generations/features/ai-panoptic.feature.mjs.map +1 -1
- package/esm/generations/features/ai-tools.feature.mjs +1 -1
- package/esm/generations/features/ai-tools.feature.mjs.map +1 -1
- package/esm/generations/features/ai-workspace.feature.mjs +1 -1
- package/esm/generations/features/ai-workspace.feature.mjs.map +1 -1
- package/esm/generations/features/ai.feature.mjs +1 -1
- package/esm/generations/features/ai.feature.mjs.map +1 -1
- package/esm/generations/features/auth-google.feature.mjs +1 -1
- package/esm/generations/features/auth-google.feature.mjs.map +1 -1
- package/esm/generations/features/auth-passkeys.feature.mjs +1 -1
- package/esm/generations/features/auth-passkeys.feature.mjs.map +1 -1
- package/esm/generations/features/bull-board.feature.mjs +1 -1
- package/esm/generations/features/bull-board.feature.mjs.map +1 -1
- package/esm/generations/features/devtools.feature.mjs +1 -1
- package/esm/generations/features/devtools.feature.mjs.map +1 -1
- package/esm/generations/features/herald.feature.mjs +1 -1
- package/esm/generations/features/herald.feature.mjs.map +1 -1
- package/esm/generations/features/image.feature.mjs +1 -1
- package/esm/generations/features/image.feature.mjs.map +1 -1
- package/esm/generations/features/index.mjs +1 -1
- package/esm/generations/features/index.mjs.map +1 -1
- package/esm/generations/features/mail.feature.mjs +1 -1
- package/esm/generations/features/mail.feature.mjs.map +1 -1
- package/esm/generations/features/mongodb.feature.mjs +1 -1
- package/esm/generations/features/mongodb.feature.mjs.map +1 -1
- package/esm/generations/features/mysql.feature.mjs +1 -1
- package/esm/generations/features/mysql.feature.mjs.map +1 -1
- package/esm/generations/features/notifications.feature.mjs +121 -17
- package/esm/generations/features/notifications.feature.mjs.map +1 -1
- package/esm/generations/features/postgres.feature.mjs +1 -1
- package/esm/generations/features/postgres.feature.mjs.map +1 -1
- package/esm/generations/features/queue.feature.mjs +1 -1
- package/esm/generations/features/queue.feature.mjs.map +1 -1
- package/esm/generations/features/react-email.feature.mjs +1 -1
- package/esm/generations/features/react-email.feature.mjs.map +1 -1
- package/esm/generations/features/react.feature.mjs +1 -1
- package/esm/generations/features/react.feature.mjs.map +1 -1
- package/esm/generations/features/redis.feature.mjs +1 -1
- package/esm/generations/features/redis.feature.mjs.map +1 -1
- package/esm/generations/features/s3.feature.mjs +1 -1
- package/esm/generations/features/s3.feature.mjs.map +1 -1
- package/esm/generations/features/scheduler.feature.mjs +1 -1
- package/esm/generations/features/scheduler.feature.mjs.map +1 -1
- package/esm/generations/features/ses.feature.mjs +1 -1
- package/esm/generations/features/ses.feature.mjs.map +1 -1
- package/esm/generations/features/shadcn.feature.mjs +1 -1
- package/esm/generations/features/shadcn.feature.mjs.map +1 -1
- package/esm/generations/features/shared/insert-connector-entry.mjs +1 -1
- package/esm/generations/features/shared/insert-connector-entry.mjs.map +1 -1
- package/esm/generations/features/shared/insert-queue-dashboard-block.mjs +1 -1
- package/esm/generations/features/shared/insert-queue-dashboard-block.mjs.map +1 -1
- package/esm/generations/features/shared/link-ai-package-import.mjs +1 -1
- package/esm/generations/features/shared/link-ai-package-import.mjs.map +1 -1
- package/esm/generations/features/shared/merge-web-sitemap-config.mjs +1 -1
- package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
- package/esm/generations/features/shared/migration-timestamp.mjs +1 -1
- package/esm/generations/features/shared/migration-timestamp.mjs.map +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs.map +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs.map +1 -1
- package/esm/generations/features/shared/resolve-contact-scaffold.mjs +1 -1
- package/esm/generations/features/shared/resolve-contact-scaffold.mjs.map +1 -1
- package/esm/generations/features/sitemap.feature.mjs +1 -1
- package/esm/generations/features/sitemap.feature.mjs.map +1 -1
- package/esm/generations/features/socket.feature.mjs +1 -1
- package/esm/generations/features/socket.feature.mjs.map +1 -1
- package/esm/generations/features/tailwind.feature.mjs +1 -1
- package/esm/generations/features/tailwind.feature.mjs.map +1 -1
- package/esm/generations/features/test.feature.mjs +1 -1
- package/esm/generations/features/test.feature.mjs.map +1 -1
- package/esm/generations/features/types.mjs +1 -1
- package/esm/generations/features/types.mjs.map +1 -1
- package/esm/generations/features/web.feature.mjs +1 -1
- package/esm/generations/features/web.feature.mjs.map +1 -1
- package/esm/generations/pnpm-build-approvals.mjs +89 -3
- package/esm/generations/pnpm-build-approvals.mjs.map +1 -1
- package/esm/generations/stubs.mjs +184 -78
- package/esm/generations/stubs.mjs.map +1 -1
- package/esm/http/boot-port-preflight.d.mts +1 -1
- package/esm/http/boot-port-preflight.d.mts.map +1 -1
- package/esm/http/boot-port-preflight.mjs +1 -1
- package/esm/http/boot-port-preflight.mjs.map +1 -1
- package/esm/http/build-cors-options.mjs +1 -1
- package/esm/http/build-cors-options.mjs.map +1 -1
- package/esm/http/build-rate-limit-options.d.mts +22 -1
- package/esm/http/build-rate-limit-options.d.mts.map +1 -1
- package/esm/http/build-rate-limit-options.mjs +7 -1
- package/esm/http/build-rate-limit-options.mjs.map +1 -1
- package/esm/http/config.d.mts +1 -1
- package/esm/http/config.d.mts.map +1 -1
- package/esm/http/config.mjs +1 -1
- package/esm/http/config.mjs.map +1 -1
- package/esm/http/context/request-context.d.mts +1 -1
- package/esm/http/context/request-context.d.mts.map +1 -1
- package/esm/http/context/request-context.mjs +1 -1
- package/esm/http/context/request-context.mjs.map +1 -1
- package/esm/http/context/request-memo.d.mts +1 -1
- package/esm/http/context/request-memo.d.mts.map +1 -1
- package/esm/http/context/request-memo.mjs +1 -1
- package/esm/http/context/request-memo.mjs.map +1 -1
- package/esm/http/createHttpApplication.d.mts +1 -1
- package/esm/http/createHttpApplication.d.mts.map +1 -1
- package/esm/http/createHttpApplication.mjs +1 -1
- package/esm/http/createHttpApplication.mjs.map +1 -1
- package/esm/http/csp.d.mts +1 -1
- package/esm/http/csp.d.mts.map +1 -1
- package/esm/http/csp.mjs +1 -1
- package/esm/http/csp.mjs.map +1 -1
- package/esm/http/csrf-default-guard.d.mts +1 -1
- package/esm/http/csrf-default-guard.d.mts.map +1 -1
- package/esm/http/csrf-default-guard.mjs +1 -1
- package/esm/http/csrf-default-guard.mjs.map +1 -1
- package/esm/http/csrf-origin-policy.d.mts +1 -1
- package/esm/http/csrf-origin-policy.d.mts.map +1 -1
- package/esm/http/csrf-origin-policy.mjs +1 -1
- package/esm/http/csrf-origin-policy.mjs.map +1 -1
- package/esm/http/database/RequestLog.d.mts +63 -111
- package/esm/http/database/RequestLog.d.mts.map +1 -1
- package/esm/http/database/RequestLog.mjs +1 -1
- package/esm/http/database/RequestLog.mjs.map +1 -1
- package/esm/http/error-codes.d.mts +1 -1
- package/esm/http/error-codes.d.mts.map +1 -1
- package/esm/http/error-codes.mjs +1 -1
- package/esm/http/error-codes.mjs.map +1 -1
- package/esm/http/error-mapper.d.mts +48 -0
- package/esm/http/error-mapper.d.mts.map +1 -0
- package/esm/http/error-mapper.mjs +48 -0
- package/esm/http/error-mapper.mjs.map +1 -0
- package/esm/http/errors/errors.d.mts +1 -1
- package/esm/http/errors/errors.d.mts.map +1 -1
- package/esm/http/errors/errors.mjs +1 -1
- package/esm/http/errors/errors.mjs.map +1 -1
- package/esm/http/events.d.mts +1 -1
- package/esm/http/events.d.mts.map +1 -1
- package/esm/http/events.mjs +1 -1
- package/esm/http/events.mjs.map +1 -1
- package/esm/http/flush-pending-cookies.mjs +1 -1
- package/esm/http/flush-pending-cookies.mjs.map +1 -1
- package/esm/http/health.d.mts +1 -1
- package/esm/http/health.d.mts.map +1 -1
- package/esm/http/health.mjs +1 -1
- package/esm/http/health.mjs.map +1 -1
- package/esm/http/index.d.mts +10 -6
- package/esm/http/index.mjs +8 -5
- package/esm/http/middleware/cache-response-middleware.d.mts +1 -1
- package/esm/http/middleware/cache-response-middleware.d.mts.map +1 -1
- package/esm/http/middleware/cache-response-middleware.mjs +1 -1
- package/esm/http/middleware/cache-response-middleware.mjs.map +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.d.mts +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.d.mts.map +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.mjs +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.mjs.map +1 -1
- package/esm/http/middleware/idempotency.middleware.d.mts +1 -1
- package/esm/http/middleware/idempotency.middleware.d.mts.map +1 -1
- package/esm/http/middleware/idempotency.middleware.mjs +1 -1
- package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
- package/esm/http/middleware/inject-request-context.d.mts +1 -1
- package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
- package/esm/http/middleware/inject-request-context.mjs +4 -2
- package/esm/http/middleware/inject-request-context.mjs.map +1 -1
- package/esm/http/middleware/ip-filter.middleware.d.mts +1 -1
- package/esm/http/middleware/ip-filter.middleware.d.mts.map +1 -1
- package/esm/http/middleware/ip-filter.middleware.mjs +1 -1
- package/esm/http/middleware/ip-filter.middleware.mjs.map +1 -1
- package/esm/http/middleware/maintenance.middleware.d.mts +1 -1
- package/esm/http/middleware/maintenance.middleware.d.mts.map +1 -1
- package/esm/http/middleware/maintenance.middleware.mjs +1 -1
- package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
- package/esm/http/middleware/max-body-size.middleware.d.mts +1 -1
- package/esm/http/middleware/max-body-size.middleware.d.mts.map +1 -1
- package/esm/http/middleware/max-body-size.middleware.mjs +1 -1
- package/esm/http/middleware/max-body-size.middleware.mjs.map +1 -1
- package/esm/http/middleware/middleware-list.d.mts +1 -1
- package/esm/http/middleware/middleware-list.d.mts.map +1 -1
- package/esm/http/middleware/middleware-list.mjs +1 -1
- package/esm/http/middleware/middleware-list.mjs.map +1 -1
- package/esm/http/middleware/rate-limit.middleware.d.mts +20 -5
- package/esm/http/middleware/rate-limit.middleware.d.mts.map +1 -1
- package/esm/http/middleware/rate-limit.middleware.mjs +34 -12
- package/esm/http/middleware/rate-limit.middleware.mjs.map +1 -1
- package/esm/http/middleware/utils/cidr-match.d.mts +1 -1
- package/esm/http/middleware/utils/cidr-match.d.mts.map +1 -1
- package/esm/http/middleware/utils/cidr-match.mjs +1 -1
- package/esm/http/middleware/utils/cidr-match.mjs.map +1 -1
- package/esm/http/middleware/utils/idempotency-key.d.mts +1 -1
- package/esm/http/middleware/utils/idempotency-key.d.mts.map +1 -1
- package/esm/http/middleware/utils/idempotency-key.mjs +1 -1
- package/esm/http/middleware/utils/idempotency-key.mjs.map +1 -1
- package/esm/http/middleware/utils/parse-size.d.mts +1 -1
- package/esm/http/middleware/utils/parse-size.d.mts.map +1 -1
- package/esm/http/middleware/utils/parse-size.mjs +1 -1
- package/esm/http/middleware/utils/parse-size.mjs.map +1 -1
- package/esm/http/parse-urlencoded-body.mjs +1 -1
- package/esm/http/parse-urlencoded-body.mjs.map +1 -1
- package/esm/http/plugins.d.mts +9 -2
- package/esm/http/plugins.d.mts.map +1 -1
- package/esm/http/plugins.mjs +18 -4
- package/esm/http/plugins.mjs.map +1 -1
- package/esm/http/port-preflight.d.mts +1 -1
- package/esm/http/port-preflight.d.mts.map +1 -1
- package/esm/http/port-preflight.mjs +1 -1
- package/esm/http/port-preflight.mjs.map +1 -1
- package/esm/http/rate-limit-cache-store.mjs +155 -0
- package/esm/http/rate-limit-cache-store.mjs.map +1 -0
- package/esm/http/ready-report.d.mts +1 -1
- package/esm/http/ready-report.d.mts.map +1 -1
- package/esm/http/ready-report.mjs +1 -1
- package/esm/http/ready-report.mjs.map +1 -1
- package/esm/http/request-controller.d.mts +1 -1
- package/esm/http/request-controller.d.mts.map +1 -1
- package/esm/http/request-controller.mjs +1 -1
- package/esm/http/request-controller.mjs.map +1 -1
- package/esm/http/request-log-snapshot.d.mts +123 -0
- package/esm/http/request-log-snapshot.d.mts.map +1 -0
- package/esm/http/request-log-snapshot.mjs +141 -0
- package/esm/http/request-log-snapshot.mjs.map +1 -0
- package/esm/http/request.d.mts +41 -2
- package/esm/http/request.d.mts.map +1 -1
- package/esm/http/request.mjs +65 -2
- package/esm/http/request.mjs.map +1 -1
- package/esm/http/resolve-bind-port.mjs +1 -1
- package/esm/http/resolve-bind-port.mjs.map +1 -1
- package/esm/http/response.d.mts +40 -8
- package/esm/http/response.d.mts.map +1 -1
- package/esm/http/response.mjs +173 -61
- package/esm/http/response.mjs.map +1 -1
- package/esm/http/serialized.d.mts +1 -1
- package/esm/http/serialized.d.mts.map +1 -1
- package/esm/http/server-rebuilt.d.mts +1 -1
- package/esm/http/server-rebuilt.d.mts.map +1 -1
- package/esm/http/server-rebuilt.mjs +1 -1
- package/esm/http/server-rebuilt.mjs.map +1 -1
- package/esm/http/server.d.mts +34 -6
- package/esm/http/server.d.mts.map +1 -1
- package/esm/http/server.mjs +70 -5
- package/esm/http/server.mjs.map +1 -1
- package/esm/http/stream-react-response.d.mts +1 -1
- package/esm/http/stream-react-response.d.mts.map +1 -1
- package/esm/http/stream-react-response.mjs +1 -1
- package/esm/http/stream-react-response.mjs.map +1 -1
- package/esm/http/stream-transport.mjs +75 -0
- package/esm/http/stream-transport.mjs.map +1 -0
- package/esm/http/tracing/trace-id.d.mts +1 -1
- package/esm/http/tracing/trace-id.d.mts.map +1 -1
- package/esm/http/tracing/trace-id.mjs +1 -1
- package/esm/http/tracing/trace-id.mjs.map +1 -1
- package/esm/http/tracing/tracing-dispatcher.d.mts +1 -1
- package/esm/http/tracing/tracing-dispatcher.d.mts.map +1 -1
- package/esm/http/tracing/tracing-dispatcher.mjs +1 -1
- package/esm/http/tracing/tracing-dispatcher.mjs.map +1 -1
- package/esm/http/tracing/tracing.type.d.mts +1 -1
- package/esm/http/tracing/tracing.type.d.mts.map +1 -1
- package/esm/http/types.d.mts +131 -6
- package/esm/http/types.d.mts.map +1 -1
- package/esm/http/uploaded-file.d.mts +2 -2
- package/esm/http/uploaded-file.d.mts.map +1 -1
- package/esm/http/uploaded-file.mjs +2 -2
- package/esm/http/uploaded-file.mjs.map +1 -1
- package/esm/http/uploads/detect-image-format.mjs +1 -1
- package/esm/http/uploads/detect-image-format.mjs.map +1 -1
- package/esm/http/uploads/generate-image-variant.mjs +1 -1
- package/esm/http/uploads/generate-image-variant.mjs.map +1 -1
- package/esm/http/uploads/generate-image-variants.d.mts +1 -1
- package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
- package/esm/http/uploads/generate-image-variants.mjs +15 -7
- package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
- package/esm/http/uploads/image-variant-cache.mjs +143 -0
- package/esm/http/uploads/image-variant-cache.mjs.map +1 -0
- package/esm/http/uploads/image-variant-types.d.mts +1 -1
- package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.d.mts +1 -1
- package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.mjs +1 -1
- package/esm/http/uploads/image-variants-config-error.mjs.map +1 -1
- package/esm/http/uploads/index.d.mts +3 -1
- package/esm/http/uploads/index.mjs +3 -1
- package/esm/http/uploads/is-path-inside.mjs +1 -1
- package/esm/http/uploads/is-path-inside.mjs.map +1 -1
- package/esm/http/uploads/load-variant-source.mjs +1 -1
- package/esm/http/uploads/load-variant-source.mjs.map +1 -1
- package/esm/http/uploads/local-disk-root.mjs +24 -0
- package/esm/http/uploads/local-disk-root.mjs.map +1 -0
- package/esm/http/uploads/matches-if-none-match.mjs +1 -1
- package/esm/http/uploads/matches-if-none-match.mjs.map +1 -1
- package/esm/http/uploads/parse-uploaded-file-query.mjs +1 -1
- package/esm/http/uploads/parse-uploaded-file-query.mjs.map +1 -1
- package/esm/http/uploads/purge-image-variants.d.mts +32 -0
- package/esm/http/uploads/purge-image-variants.d.mts.map +1 -0
- package/esm/http/uploads/purge-image-variants.mjs +46 -0
- package/esm/http/uploads/purge-image-variants.mjs.map +1 -0
- package/esm/http/uploads/read-file-head.mjs +1 -1
- package/esm/http/uploads/read-file-head.mjs.map +1 -1
- package/esm/http/uploads/resolve-image-variant.d.mts +73 -0
- package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -0
- package/esm/http/uploads/resolve-image-variant.mjs +107 -0
- package/esm/http/uploads/resolve-image-variant.mjs.map +1 -0
- package/esm/http/uploads/resolve-image-variants-config.mjs +1 -1
- package/esm/http/uploads/resolve-image-variants-config.mjs.map +1 -1
- package/esm/http/uploads/resolve-inline-image-content-type.mjs +1 -1
- package/esm/http/uploads/resolve-inline-image-content-type.mjs.map +1 -1
- package/esm/http/uploads/resolve-original-content-type.mjs +1 -1
- package/esm/http/uploads/resolve-original-content-type.mjs.map +1 -1
- package/esm/http/uploads/resolve-upload-path.mjs +3 -2
- package/esm/http/uploads/resolve-upload-path.mjs.map +1 -1
- package/esm/http/uploads/resolve-variant-candidate.mjs +1 -1
- package/esm/http/uploads/resolve-variant-candidate.mjs.map +1 -1
- package/esm/http/uploads/single-flight.mjs +1 -1
- package/esm/http/uploads/single-flight.mjs.map +1 -1
- package/esm/http/uploads/uploaded-file.controller.d.mts +24 -6
- package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
- package/esm/http/uploads/uploaded-file.controller.mjs +63 -91
- package/esm/http/uploads/uploaded-file.controller.mjs.map +1 -1
- package/esm/http/uploads/variant-cache-key.mjs +30 -5
- package/esm/http/uploads/variant-cache-key.mjs.map +1 -1
- package/esm/http/uploads/variant-generations.mjs +1 -1
- package/esm/http/uploads/variant-generations.mjs.map +1 -1
- package/esm/http/uploads-config.d.mts +1 -1
- package/esm/http/uploads-config.d.mts.map +1 -1
- package/esm/http/uploads-config.mjs +1 -1
- package/esm/http/uploads-config.mjs.map +1 -1
- package/esm/http/uploads-types.d.mts +1 -1
- package/esm/http/uploads-types.d.mts.map +1 -1
- package/esm/http/xmlable.d.mts +1 -1
- package/esm/http/xmlable.d.mts.map +1 -1
- package/esm/image/image.d.mts +1 -1
- package/esm/image/image.d.mts.map +1 -1
- package/esm/image/image.mjs +1 -1
- package/esm/image/image.mjs.map +1 -1
- package/esm/index.d.mts +13 -9
- package/esm/index.mjs +10 -7
- package/esm/loader/app-module-importer.d.mts +1 -1
- package/esm/loader/app-module-importer.d.mts.map +1 -1
- package/esm/loader/app-module-importer.mjs +1 -1
- package/esm/loader/app-module-importer.mjs.map +1 -1
- package/esm/localization/parse-locale-dictionary.d.mts +1 -1
- package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
- package/esm/localization/parse-locale-dictionary.mjs +1 -1
- package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
- package/esm/localization/register-locale-dictionary.d.mts +1 -1
- package/esm/localization/register-locale-dictionary.d.mts.map +1 -1
- package/esm/localization/register-locale-dictionary.mjs +1 -1
- package/esm/localization/register-locale-dictionary.mjs.map +1 -1
- package/esm/logger/fatal-visibility.d.mts +1 -1
- package/esm/logger/fatal-visibility.d.mts.map +1 -1
- package/esm/logger/fatal-visibility.mjs +1 -1
- package/esm/logger/fatal-visibility.mjs.map +1 -1
- package/esm/logger/logger.d.mts +1 -1
- package/esm/logger/logger.d.mts.map +1 -1
- package/esm/logger/logger.mjs +1 -1
- package/esm/logger/logger.mjs.map +1 -1
- package/esm/logger/types.d.mts +1 -1
- package/esm/logger/types.d.mts.map +1 -1
- package/esm/mail/config.d.mts +1 -1
- package/esm/mail/config.d.mts.map +1 -1
- package/esm/mail/config.mjs +1 -1
- package/esm/mail/config.mjs.map +1 -1
- package/esm/mail/events.d.mts +1 -1
- package/esm/mail/events.d.mts.map +1 -1
- package/esm/mail/events.mjs +1 -1
- package/esm/mail/events.mjs.map +1 -1
- package/esm/mail/mail.d.mts +1 -1
- package/esm/mail/mail.d.mts.map +1 -1
- package/esm/mail/mail.mjs +1 -1
- package/esm/mail/mail.mjs.map +1 -1
- package/esm/mail/mailer-pool.d.mts +1 -1
- package/esm/mail/mailer-pool.d.mts.map +1 -1
- package/esm/mail/mailer-pool.mjs +1 -1
- package/esm/mail/mailer-pool.mjs.map +1 -1
- package/esm/mail/react-mail.d.mts +1 -1
- package/esm/mail/react-mail.d.mts.map +1 -1
- package/esm/mail/react-mail.mjs +1 -1
- package/esm/mail/react-mail.mjs.map +1 -1
- package/esm/mail/send-mail.d.mts +1 -1
- package/esm/mail/send-mail.d.mts.map +1 -1
- package/esm/mail/send-mail.mjs +7 -7
- package/esm/mail/send-mail.mjs.map +1 -1
- package/esm/mail/test-mailbox.d.mts +1 -1
- package/esm/mail/test-mailbox.d.mts.map +1 -1
- package/esm/mail/test-mailbox.mjs +1 -1
- package/esm/mail/test-mailbox.mjs.map +1 -1
- package/esm/mail/types.d.mts +1 -1
- package/esm/mail/types.d.mts.map +1 -1
- package/esm/mail/types.mjs +1 -1
- package/esm/mail/types.mjs.map +1 -1
- package/esm/manifest/manifest-manager.mjs +1 -1
- package/esm/manifest/manifest-manager.mjs.map +1 -1
- package/esm/openapi/build-openapi-document.d.mts +1 -1
- package/esm/openapi/build-openapi-document.d.mts.map +1 -1
- package/esm/openapi/build-openapi-document.mjs +1 -1
- package/esm/openapi/build-openapi-document.mjs.map +1 -1
- package/esm/openapi/cast-schema.mjs +1 -1
- package/esm/openapi/cast-schema.mjs.map +1 -1
- package/esm/openapi/collect-openapi-document.mjs +1 -1
- package/esm/openapi/collect-openapi-document.mjs.map +1 -1
- package/esm/openapi/development-openapi-provider.d.mts +1 -1
- package/esm/openapi/development-openapi-provider.d.mts.map +1 -1
- package/esm/openapi/development-openapi-provider.mjs +1 -1
- package/esm/openapi/development-openapi-provider.mjs.map +1 -1
- package/esm/openapi/error-responses.mjs +1 -1
- package/esm/openapi/error-responses.mjs.map +1 -1
- package/esm/openapi/openapi-child-output.mjs +1 -1
- package/esm/openapi/openapi-child-output.mjs.map +1 -1
- package/esm/openapi/openapi-protocol.mjs +1 -1
- package/esm/openapi/openapi-protocol.mjs.map +1 -1
- package/esm/openapi/paths.mjs +1 -1
- package/esm/openapi/paths.mjs.map +1 -1
- package/esm/openapi/postman/build-request-body.mjs +1 -1
- package/esm/openapi/postman/build-request-body.mjs.map +1 -1
- package/esm/openapi/postman/build-request-url.mjs +1 -1
- package/esm/openapi/postman/build-request-url.mjs.map +1 -1
- package/esm/openapi/postman/build-saved-responses.mjs +1 -1
- package/esm/openapi/postman/build-saved-responses.mjs.map +1 -1
- package/esm/openapi/postman/example-from-schema.d.mts +1 -1
- package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
- package/esm/openapi/postman/example-from-schema.mjs +1 -1
- package/esm/openapi/postman/example-from-schema.mjs.map +1 -1
- package/esm/openapi/postman/http-status-text.mjs +1 -1
- package/esm/openapi/postman/http-status-text.mjs.map +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.d.mts +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.mjs +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.mjs.map +1 -1
- package/esm/openapi/postman/postman-types.d.mts +1 -1
- package/esm/openapi/postman/postman-types.d.mts.map +1 -1
- package/esm/openapi/postman/resolve-operation-auth.mjs +1 -1
- package/esm/openapi/postman/resolve-operation-auth.mjs.map +1 -1
- package/esm/openapi/postman/schema-refs.d.mts +1 -1
- package/esm/openapi/postman/schema-refs.d.mts.map +1 -1
- package/esm/openapi/postman/schema-refs.mjs +1 -1
- package/esm/openapi/postman/schema-refs.mjs.map +1 -1
- package/esm/openapi/postman/uuid-v5.mjs +1 -1
- package/esm/openapi/postman/uuid-v5.mjs.map +1 -1
- package/esm/openapi/request-schemas.mjs +1 -1
- package/esm/openapi/request-schemas.mjs.map +1 -1
- package/esm/openapi/response-schemas.mjs +1 -1
- package/esm/openapi/response-schemas.mjs.map +1 -1
- package/esm/openapi/schema-registry.mjs +1 -1
- package/esm/openapi/schema-registry.mjs.map +1 -1
- package/esm/openapi/security.mjs +1 -1
- package/esm/openapi/security.mjs.map +1 -1
- package/esm/openapi/types.d.mts +1 -1
- package/esm/openapi/types.d.mts.map +1 -1
- package/esm/production/assert-dist-ready-to-start.mjs +1 -1
- package/esm/production/assert-dist-ready-to-start.mjs.map +1 -1
- package/esm/production/assert-generated-imports.mjs +1 -1
- package/esm/production/assert-generated-imports.mjs.map +1 -1
- package/esm/production/build-app-production.mjs +1 -1
- package/esm/production/build-app-production.mjs.map +1 -1
- package/esm/production/build-contributions.mjs +1 -1
- package/esm/production/build-contributions.mjs.map +1 -1
- package/esm/production/bundle-framework-dependencies.mjs +1 -1
- package/esm/production/bundle-framework-dependencies.mjs.map +1 -1
- package/esm/production/dist-build-manifest.mjs +1 -1
- package/esm/production/dist-build-manifest.mjs.map +1 -1
- package/esm/production/esbuild-plugins.mjs +1 -1
- package/esm/production/esbuild-plugins.mjs.map +1 -1
- package/esm/production/esbuild-preflight.mjs +1 -1
- package/esm/production/esbuild-preflight.mjs.map +1 -1
- package/esm/production/production-builder.mjs +1 -1
- package/esm/production/production-builder.mjs.map +1 -1
- package/esm/production/production-supervisor.mjs +1 -1
- package/esm/production/production-supervisor.mjs.map +1 -1
- package/esm/production/promote-dist.mjs +1 -1
- package/esm/production/promote-dist.mjs.map +1 -1
- package/esm/production/registration-child-runner.mjs +1 -1
- package/esm/production/registration-child-runner.mjs.map +1 -1
- package/esm/production/resolve-build-config.d.mts +1 -1
- package/esm/production/resolve-build-config.d.mts.map +1 -1
- package/esm/production/resolve-build-config.mjs +1 -1
- package/esm/production/resolve-build-config.mjs.map +1 -1
- package/esm/production/route-registration-child.mjs +1 -1
- package/esm/production/route-registration-child.mjs.map +1 -1
- package/esm/production/route-registration-snapshot.mjs +1 -1
- package/esm/production/route-registration-snapshot.mjs.map +1 -1
- package/esm/production/tsconfig-path-aliases.mjs +1 -1
- package/esm/production/tsconfig-path-aliases.mjs.map +1 -1
- package/esm/react/index.d.mts +1 -1
- package/esm/react/index.d.mts.map +1 -1
- package/esm/react/index.mjs +1 -1
- package/esm/react/index.mjs.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.d.mts +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.d.mts.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.mjs +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.mjs.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.mjs +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.mjs.map +1 -1
- package/esm/repositories/adapters/cascade/filter-applicator.mjs +1 -1
- package/esm/repositories/adapters/cascade/filter-applicator.mjs.map +1 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts +1 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
- package/esm/repositories/contracts/repository-adapter.contract.d.mts +1 -1
- package/esm/repositories/contracts/repository-adapter.contract.d.mts.map +1 -1
- package/esm/repositories/contracts/types.d.mts +1 -1
- package/esm/repositories/contracts/types.d.mts.map +1 -1
- package/esm/repositories/repository.manager.d.mts +1 -1
- package/esm/repositories/repository.manager.d.mts.map +1 -1
- package/esm/repositories/repository.manager.mjs +1 -1
- package/esm/repositories/repository.manager.mjs.map +1 -1
- package/esm/resource/define-resource.d.mts +1 -1
- package/esm/resource/define-resource.d.mts.map +1 -1
- package/esm/resource/define-resource.mjs +1 -1
- package/esm/resource/define-resource.mjs.map +1 -1
- package/esm/resource/nullable-resource.d.mts +1 -1
- package/esm/resource/nullable-resource.d.mts.map +1 -1
- package/esm/resource/nullable-resource.mjs +1 -1
- package/esm/resource/nullable-resource.mjs.map +1 -1
- package/esm/resource/register-resource.d.mts +1 -1
- package/esm/resource/register-resource.d.mts.map +1 -1
- package/esm/resource/register-resource.mjs +1 -1
- package/esm/resource/register-resource.mjs.map +1 -1
- package/esm/resource/resource-field-builder.d.mts +1 -1
- package/esm/resource/resource-field-builder.d.mts.map +1 -1
- package/esm/resource/resource-field-builder.mjs +1 -1
- package/esm/resource/resource-field-builder.mjs.map +1 -1
- package/esm/resource/resource.d.mts +1 -1
- package/esm/resource/resource.d.mts.map +1 -1
- package/esm/resource/resource.mjs +1 -1
- package/esm/resource/resource.mjs.map +1 -1
- package/esm/resource/types.d.mts +1 -1
- package/esm/resource/types.d.mts.map +1 -1
- package/esm/restful/restful.d.mts +1 -1
- package/esm/restful/restful.d.mts.map +1 -1
- package/esm/restful/restful.mjs +1 -1
- package/esm/restful/restful.mjs.map +1 -1
- package/esm/router/build-route-rate-limit.mjs +1 -1
- package/esm/router/build-route-rate-limit.mjs.map +1 -1
- package/esm/router/describe-route-for-log.mjs +1 -1
- package/esm/router/describe-route-for-log.mjs.map +1 -1
- package/esm/router/dev-dispatch.mjs +1 -1
- package/esm/router/dev-dispatch.mjs.map +1 -1
- package/esm/router/log-request-lifecycle.mjs +1 -1
- package/esm/router/log-request-lifecycle.mjs.map +1 -1
- package/esm/router/named-api-routes-with-responses.mjs +1 -1
- package/esm/router/named-api-routes-with-responses.mjs.map +1 -1
- package/esm/router/normalize-request-path.d.mts +1 -1
- package/esm/router/normalize-request-path.d.mts.map +1 -1
- package/esm/router/normalize-request-path.mjs +1 -1
- package/esm/router/normalize-request-path.mjs.map +1 -1
- package/esm/router/normalize-route-path.d.mts +1 -1
- package/esm/router/normalize-route-path.d.mts.map +1 -1
- package/esm/router/normalize-route-path.mjs +1 -1
- package/esm/router/normalize-route-path.mjs.map +1 -1
- package/esm/router/positional-handler-diagnostics.d.mts +1 -1
- package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
- package/esm/router/positional-handler-diagnostics.mjs +1 -1
- package/esm/router/positional-handler-diagnostics.mjs.map +1 -1
- package/esm/router/response-schema-types.mjs +1 -1
- package/esm/router/response-schema-types.mjs.map +1 -1
- package/esm/router/route-builder.d.mts +1 -1
- package/esm/router/route-builder.d.mts.map +1 -1
- package/esm/router/route-builder.mjs +1 -1
- package/esm/router/route-builder.mjs.map +1 -1
- package/esm/router/route-name-method-suffix.d.mts +1 -1
- package/esm/router/route-name-method-suffix.d.mts.map +1 -1
- package/esm/router/route-name-method-suffix.mjs +1 -1
- package/esm/router/route-name-method-suffix.mjs.map +1 -1
- package/esm/router/route-registry.d.mts +1 -1
- package/esm/router/route-registry.d.mts.map +1 -1
- package/esm/router/route-registry.mjs +1 -1
- package/esm/router/route-registry.mjs.map +1 -1
- package/esm/router/router.d.mts +8 -1
- package/esm/router/router.d.mts.map +1 -1
- package/esm/router/router.mjs +20 -15
- package/esm/router/router.mjs.map +1 -1
- package/esm/router/types.d.mts +13 -1
- package/esm/router/types.d.mts.map +1 -1
- package/esm/socket/types.d.mts +1 -1
- package/esm/socket/types.d.mts.map +1 -1
- package/esm/socket/utils.d.mts +1 -1
- package/esm/socket/utils.d.mts.map +1 -1
- package/esm/socket/utils.mjs +1 -1
- package/esm/socket/utils.mjs.map +1 -1
- package/esm/storage/config.d.mts +1 -1
- package/esm/storage/config.d.mts.map +1 -1
- package/esm/storage/config.mjs +1 -1
- package/esm/storage/config.mjs.map +1 -1
- package/esm/storage/context/storage-driver-context.d.mts +1 -1
- package/esm/storage/context/storage-driver-context.d.mts.map +1 -1
- package/esm/storage/context/storage-driver-context.mjs +1 -1
- package/esm/storage/context/storage-driver-context.mjs.map +1 -1
- package/esm/storage/drivers/cloud-driver.d.mts +1 -1
- package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
- package/esm/storage/drivers/cloud-driver.mjs +1 -1
- package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
- package/esm/storage/drivers/do-spaces-driver.d.mts +1 -1
- package/esm/storage/drivers/do-spaces-driver.d.mts.map +1 -1
- package/esm/storage/drivers/do-spaces-driver.mjs +1 -1
- package/esm/storage/drivers/do-spaces-driver.mjs.map +1 -1
- package/esm/storage/drivers/local-driver.d.mts +12 -1
- package/esm/storage/drivers/local-driver.d.mts.map +1 -1
- package/esm/storage/drivers/local-driver.mjs +33 -1
- package/esm/storage/drivers/local-driver.mjs.map +1 -1
- package/esm/storage/drivers/r2-driver.d.mts +1 -1
- package/esm/storage/drivers/r2-driver.d.mts.map +1 -1
- package/esm/storage/drivers/r2-driver.mjs +1 -1
- package/esm/storage/drivers/r2-driver.mjs.map +1 -1
- package/esm/storage/drivers/s3-driver.d.mts +1 -1
- package/esm/storage/drivers/s3-driver.d.mts.map +1 -1
- package/esm/storage/drivers/s3-driver.mjs +1 -1
- package/esm/storage/drivers/s3-driver.mjs.map +1 -1
- package/esm/storage/index.d.mts +1 -1
- package/esm/storage/scoped-storage.d.mts +1 -1
- package/esm/storage/scoped-storage.d.mts.map +1 -1
- package/esm/storage/scoped-storage.mjs +1 -1
- package/esm/storage/scoped-storage.mjs.map +1 -1
- package/esm/storage/storage-file.d.mts +1 -1
- package/esm/storage/storage-file.d.mts.map +1 -1
- package/esm/storage/storage-file.mjs +1 -1
- package/esm/storage/storage-file.mjs.map +1 -1
- package/esm/storage/storage.d.mts +3 -3
- package/esm/storage/storage.d.mts.map +1 -1
- package/esm/storage/storage.mjs +1 -1
- package/esm/storage/storage.mjs.map +1 -1
- package/esm/storage/types.d.mts +3 -2
- package/esm/storage/types.d.mts.map +1 -1
- package/esm/storage/utils/classify-ip-address.d.mts +1 -1
- package/esm/storage/utils/classify-ip-address.d.mts.map +1 -1
- package/esm/storage/utils/classify-ip-address.mjs +1 -1
- package/esm/storage/utils/classify-ip-address.mjs.map +1 -1
- package/esm/storage/utils/contain-path.d.mts +1 -1
- package/esm/storage/utils/contain-path.d.mts.map +1 -1
- package/esm/storage/utils/contain-path.mjs +1 -1
- package/esm/storage/utils/contain-path.mjs.map +1 -1
- package/esm/storage/utils/mime.d.mts +1 -1
- package/esm/storage/utils/mime.d.mts.map +1 -1
- package/esm/storage/utils/mime.mjs +1 -1
- package/esm/storage/utils/mime.mjs.map +1 -1
- package/esm/storage/utils/safe-fetch.d.mts +1 -1
- package/esm/storage/utils/safe-fetch.d.mts.map +1 -1
- package/esm/storage/utils/safe-fetch.mjs +1 -1
- package/esm/storage/utils/safe-fetch.mjs.map +1 -1
- package/esm/storage/utils/storage-capability-error.d.mts +1 -1
- package/esm/storage/utils/storage-capability-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-capability-error.mjs +1 -1
- package/esm/storage/utils/storage-capability-error.mjs.map +1 -1
- package/esm/storage/utils/storage-error.d.mts +1 -1
- package/esm/storage/utils/storage-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-error.mjs +1 -1
- package/esm/storage/utils/storage-error.mjs.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.d.mts +1 -1
- package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.mjs +1 -1
- package/esm/storage/utils/storage-not-initialized-error.mjs.map +1 -1
- package/esm/tests/start-http-development-server.d.mts +1 -1
- package/esm/tests/start-http-development-server.d.mts.map +1 -1
- package/esm/tests/start-http-development-server.mjs +1 -1
- package/esm/tests/start-http-development-server.mjs.map +1 -1
- package/esm/tests/test-connectors-selection.d.mts +1 -1
- package/esm/tests/test-connectors-selection.d.mts.map +1 -1
- package/esm/tests/test-connectors-selection.mjs +1 -1
- package/esm/tests/test-connectors-selection.mjs.map +1 -1
- package/esm/tests/test-helpers.d.mts +1 -1
- package/esm/tests/test-helpers.d.mts.map +1 -1
- package/esm/tests/test-helpers.mjs +1 -1
- package/esm/tests/test-helpers.mjs.map +1 -1
- package/esm/tests/test-lifecycle-state.mjs +1 -1
- package/esm/tests/test-lifecycle-state.mjs.map +1 -1
- package/esm/tests/test-server-port-channel.mjs +1 -1
- package/esm/tests/test-server-port-channel.mjs.map +1 -1
- package/esm/tests/test-setup-timeout.mjs +1 -1
- package/esm/tests/test-setup-timeout.mjs.map +1 -1
- package/esm/tests/vitest-setup.d.mts +1 -1
- package/esm/tests/vitest-setup.d.mts.map +1 -1
- package/esm/tests/vitest-setup.mjs +1 -1
- package/esm/tests/vitest-setup.mjs.map +1 -1
- package/esm/updater/package-manager.mjs +1 -1
- package/esm/updater/package-manager.mjs.map +1 -1
- package/esm/updater/update-warlock-packages.mjs +1 -1
- package/esm/updater/update-warlock-packages.mjs.map +1 -1
- package/esm/use-cases/types.d.mts +1 -1
- package/esm/use-cases/types.d.mts.map +1 -1
- package/esm/use-cases/use-case-broadcast.d.mts +1 -1
- package/esm/use-cases/use-case-broadcast.d.mts.map +1 -1
- package/esm/use-cases/use-case-broadcast.mjs +1 -1
- package/esm/use-cases/use-case-broadcast.mjs.map +1 -1
- package/esm/use-cases/use-case-events.d.mts +1 -1
- package/esm/use-cases/use-case-events.d.mts.map +1 -1
- package/esm/use-cases/use-case-events.mjs +1 -1
- package/esm/use-cases/use-case-events.mjs.map +1 -1
- package/esm/use-cases/use-case-pipeline.d.mts +1 -1
- package/esm/use-cases/use-case-pipeline.d.mts.map +1 -1
- package/esm/use-cases/use-case-pipeline.mjs +1 -1
- package/esm/use-cases/use-case-pipeline.mjs.map +1 -1
- package/esm/use-cases/use-case.d.mts +1 -1
- package/esm/use-cases/use-case.d.mts.map +1 -1
- package/esm/use-cases/use-case.errors.d.mts +1 -1
- package/esm/use-cases/use-case.errors.d.mts.map +1 -1
- package/esm/use-cases/use-case.errors.mjs +1 -1
- package/esm/use-cases/use-case.errors.mjs.map +1 -1
- package/esm/use-cases/use-case.mjs +1 -1
- package/esm/use-cases/use-case.mjs.map +1 -1
- package/esm/use-cases/use-cases-registry.d.mts +1 -1
- package/esm/use-cases/use-cases-registry.d.mts.map +1 -1
- package/esm/use-cases/use-cases-registry.mjs +1 -1
- package/esm/use-cases/use-cases-registry.mjs.map +1 -1
- package/esm/utils/app-log.d.mts +6 -6
- package/esm/utils/app-log.d.mts.map +1 -1
- package/esm/utils/app-log.mjs +1 -1
- package/esm/utils/app-log.mjs.map +1 -1
- package/esm/utils/database-log.d.mts +1 -1
- package/esm/utils/database-log.d.mts.map +1 -1
- package/esm/utils/database-log.mjs +1 -1
- package/esm/utils/database-log.mjs.map +1 -1
- package/esm/utils/detect-environment-overrides.mjs +1 -1
- package/esm/utils/detect-environment-overrides.mjs.map +1 -1
- package/esm/utils/environment.d.mts +1 -1
- package/esm/utils/environment.d.mts.map +1 -1
- package/esm/utils/environment.mjs +1 -1
- package/esm/utils/environment.mjs.map +1 -1
- package/esm/utils/framework-vesion.mjs +1 -1
- package/esm/utils/framework-vesion.mjs.map +1 -1
- package/esm/utils/get-localized.d.mts +1 -1
- package/esm/utils/get-localized.d.mts.map +1 -1
- package/esm/utils/get-localized.mjs +1 -1
- package/esm/utils/get-localized.mjs.map +1 -1
- package/esm/utils/is-test-file.mjs +1 -1
- package/esm/utils/is-test-file.mjs.map +1 -1
- package/esm/utils/load-environment.mjs +1 -1
- package/esm/utils/load-environment.mjs.map +1 -1
- package/esm/utils/normalized-path.d.mts +1 -1
- package/esm/utils/normalized-path.d.mts.map +1 -1
- package/esm/utils/normalized-path.mjs +1 -1
- package/esm/utils/normalized-path.mjs.map +1 -1
- package/esm/utils/npm-registry.d.mts +1 -1
- package/esm/utils/npm-registry.d.mts.map +1 -1
- package/esm/utils/npm-registry.mjs +1 -1
- package/esm/utils/npm-registry.mjs.map +1 -1
- package/esm/utils/paths.d.mts +1 -1
- package/esm/utils/paths.d.mts.map +1 -1
- package/esm/utils/paths.mjs +1 -1
- package/esm/utils/paths.mjs.map +1 -1
- package/esm/utils/promise-all-object.d.mts +1 -1
- package/esm/utils/promise-all-object.d.mts.map +1 -1
- package/esm/utils/promise-all-object.mjs +1 -1
- package/esm/utils/promise-all-object.mjs.map +1 -1
- package/esm/utils/queue.d.mts +1 -1
- package/esm/utils/queue.d.mts.map +1 -1
- package/esm/utils/queue.mjs +1 -1
- package/esm/utils/queue.mjs.map +1 -1
- package/esm/utils/recorded-environment-overrides.mjs +1 -1
- package/esm/utils/recorded-environment-overrides.mjs.map +1 -1
- package/esm/utils/report-environment-overrides.mjs +1 -1
- package/esm/utils/report-environment-overrides.mjs.map +1 -1
- package/esm/utils/sleep.d.mts +1 -1
- package/esm/utils/sleep.d.mts.map +1 -1
- package/esm/utils/sleep.mjs +1 -1
- package/esm/utils/sleep.mjs.map +1 -1
- package/esm/utils/sluggable.d.mts +1 -1
- package/esm/utils/sluggable.d.mts.map +1 -1
- package/esm/utils/sluggable.mjs +1 -1
- package/esm/utils/sluggable.mjs.map +1 -1
- package/esm/utils/to-json.d.mts +1 -1
- package/esm/utils/to-json.d.mts.map +1 -1
- package/esm/utils/to-json.mjs +1 -1
- package/esm/utils/to-json.mjs.map +1 -1
- package/esm/utils/types.d.mts +1 -1
- package/esm/utils/types.d.mts.map +1 -1
- package/esm/utils/urls.d.mts +1 -1
- package/esm/utils/urls.d.mts.map +1 -1
- package/esm/utils/urls.mjs +1 -1
- package/esm/utils/urls.mjs.map +1 -1
- package/esm/utils/version-compare.d.mts +1 -1
- package/esm/utils/version-compare.d.mts.map +1 -1
- package/esm/utils/version-compare.mjs +1 -1
- package/esm/utils/version-compare.mjs.map +1 -1
- package/esm/validation/database/exists-except-current-id.d.mts +1 -1
- package/esm/validation/database/exists-except-current-id.d.mts.map +1 -1
- package/esm/validation/database/exists-except-current-id.mjs +1 -1
- package/esm/validation/database/exists-except-current-id.mjs.map +1 -1
- package/esm/validation/database/exists-except-current-user.d.mts +1 -1
- package/esm/validation/database/exists-except-current-user.d.mts.map +1 -1
- package/esm/validation/database/exists-except-current-user.mjs +1 -1
- package/esm/validation/database/exists-except-current-user.mjs.map +1 -1
- package/esm/validation/database/types.d.mts +1 -1
- package/esm/validation/database/types.d.mts.map +1 -1
- package/esm/validation/database/unique-except-current-id.d.mts +1 -1
- package/esm/validation/database/unique-except-current-id.d.mts.map +1 -1
- package/esm/validation/database/unique-except-current-id.mjs +1 -1
- package/esm/validation/database/unique-except-current-id.mjs.map +1 -1
- package/esm/validation/database/unique-except-current-user.d.mts +1 -1
- package/esm/validation/database/unique-except-current-user.d.mts.map +1 -1
- package/esm/validation/database/unique-except-current-user.mjs +1 -1
- package/esm/validation/database/unique-except-current-user.mjs.map +1 -1
- package/esm/validation/file/file.d.mts +1 -1
- package/esm/validation/file/file.d.mts.map +1 -1
- package/esm/validation/file/file.mjs +1 -1
- package/esm/validation/file/file.mjs.map +1 -1
- package/esm/validation/init.mjs +1 -1
- package/esm/validation/init.mjs.map +1 -1
- package/esm/validation/plugins/database-plugin.mjs +1 -1
- package/esm/validation/plugins/database-plugin.mjs.map +1 -1
- package/esm/validation/plugins/file-plugin.mjs +1 -1
- package/esm/validation/plugins/file-plugin.mjs.map +1 -1
- package/esm/validation/plugins/localized-plugin.mjs +1 -1
- package/esm/validation/plugins/localized-plugin.mjs.map +1 -1
- package/esm/validation/types.d.mts +1 -1
- package/esm/validation/types.d.mts.map +1 -1
- package/esm/validation/validateAll.mjs +1 -1
- package/esm/validation/validateAll.mjs.map +1 -1
- package/esm/validation/validators/file-validator.d.mts +44 -41
- package/esm/validation/validators/file-validator.d.mts.map +1 -1
- package/esm/validation/validators/file-validator.mjs +4 -1
- package/esm/validation/validators/file-validator.mjs.map +1 -1
- package/esm/vite/lower-stage3-decorators.d.mts +1 -1
- package/esm/vite/lower-stage3-decorators.d.mts.map +1 -1
- package/esm/vite/lower-stage3-decorators.mjs +1 -1
- package/esm/vite/lower-stage3-decorators.mjs.map +1 -1
- package/esm/warlock-config/bundle-config.mjs +148 -0
- package/esm/warlock-config/bundle-config.mjs.map +1 -0
- package/esm/warlock-config/default-configurations.mjs +1 -1
- package/esm/warlock-config/default-configurations.mjs.map +1 -1
- package/esm/warlock-config/define-config.d.mts +1 -1
- package/esm/warlock-config/define-config.d.mts.map +1 -1
- package/esm/warlock-config/define-config.mjs +1 -1
- package/esm/warlock-config/define-config.mjs.map +1 -1
- package/esm/warlock-config/index.d.mts +1 -1
- package/esm/warlock-config/index.mjs +1 -1
- package/esm/warlock-config/normalize-build-config.mjs +1 -1
- package/esm/warlock-config/normalize-build-config.mjs.map +1 -1
- package/esm/warlock-config/types.d.mts +1 -1
- package/esm/warlock-config/types.d.mts.map +1 -1
- package/esm/warlock-config/warlock-config.manager.d.mts +32 -7
- package/esm/warlock-config/warlock-config.manager.d.mts.map +1 -1
- package/esm/warlock-config/warlock-config.manager.mjs +94 -18
- package/esm/warlock-config/warlock-config.manager.mjs.map +1 -1
- package/esm/warlock-config/warn-deprecated-config.mjs +1 -1
- package/esm/warlock-config/warn-deprecated-config.mjs.map +1 -1
- package/llms-full.txt +66 -9
- package/package.json +20 -13
- package/skills/configure-app/SKILL.md +23 -1
- package/skills/create-controller/SKILL.md +4 -0
- package/skills/health-checks/SKILL.md +2 -0
- package/skills/register-route/SKILL.md +10 -0
- package/skills/run-app/SKILL.md +9 -2
- package/skills/send-response/SKILL.md +10 -2
- package/skills/store-file/SKILL.md +5 -1
- package/skills/use-middleware/SKILL.md +2 -2
- package/skills/validate-input/SKILL.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-json-manager.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"package-json-manager.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/package-json-manager.ts"],"sourcesContent":["import { getJsonFileAsync } from \"@warlock.js/fs\";\nimport { Path } from \"../utils/normalized-path\";\n\nexport class PackageJsonManager {\n /**\n * Package.json data\n */\n public packageJson: any = {};\n\n /**\n * Initialize the package.json manager\n */\n public async init() {\n this.packageJson = await getJsonFileAsync(Path.toAbsolute(\"package.json\"));\n }\n\n /**\n * Check if the given path is a package path\n */\n public isPathPackage(path: string) {\n const allPackages = Object.keys(this.packageJson.dependencies || {}).concat(\n Object.keys(this.packageJson.devDependencies || {}),\n );\n\n return allPackages.some((packageName) => path.startsWith(packageName));\n }\n}\n\nexport const packageJsonManager = new PackageJsonManager();\n"],"mappings":";;;;AAGA,IAAa,qBAAb,MAAgC;;qBAIJ,CAAC;;;;;CAK3B,MAAa,OAAO;EAClB,KAAK,cAAc,MAAM,iBAAiB,KAAK,WAAW,cAAc,CAAC;CAC3E;;;;CAKA,AAAO,cAAc,MAAc;EAKjC,OAJoB,OAAO,KAAK,KAAK,YAAY,gBAAgB,CAAC,CAAC,CAAC,CAAC,OACnE,OAAO,KAAK,KAAK,YAAY,mBAAmB,CAAC,CAAC,CAGnC,CAAC,CAAC,MAAM,gBAAgB,KAAK,WAAW,WAAW,CAAC;CACvE;AACF;AAEA,MAAa,qBAAqB,IAAI,mBAAmB"}
|
|
@@ -3,8 +3,9 @@ import { tsconfigManager } from "./tsconfig-manager.mjs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { directoryExistsAsync, fileExistsAsync } from "@warlock.js/fs";
|
|
5
5
|
import { parse } from "es-module-lexer";
|
|
6
|
+
import ts from "typescript";
|
|
6
7
|
|
|
7
|
-
//#region
|
|
8
|
+
//#region ../../packages/core/src/dev-server/parse-imports.ts
|
|
8
9
|
/**
|
|
9
10
|
* Detect if a file contains only type definitions (no runtime code)
|
|
10
11
|
*
|
|
@@ -150,11 +151,12 @@ function extractImportPathsWithRegex(source) {
|
|
|
150
151
|
if (dynamicPath === void 0) continue;
|
|
151
152
|
record(dynamicPath, match[0], false);
|
|
152
153
|
}
|
|
153
|
-
const exportFromPattern = /export\s+(?:\{[^}]*\}
|
|
154
|
+
const exportFromPattern = /export\s+(?:type\s+)?(?:\{[^}]*\}|\*(?:\s+as\s+\w+)?|\w+)\s+from\s+['"]([^'"]+)['"]/g;
|
|
154
155
|
while ((match = exportFromPattern.exec(source)) !== null) {
|
|
155
156
|
const fullMatch = match[0];
|
|
156
157
|
const exportPath = match[1];
|
|
157
158
|
if (exportPath === void 0) continue;
|
|
159
|
+
if (/^export\s+type\s/.test(fullMatch)) continue;
|
|
158
160
|
record(exportPath, fullMatch, isExportTypeOnlyStatement(fullMatch));
|
|
159
161
|
}
|
|
160
162
|
return imports;
|
|
@@ -177,8 +179,8 @@ async function parseImports(source, filePath) {
|
|
|
177
179
|
try {
|
|
178
180
|
const [imports] = await parse(source);
|
|
179
181
|
if (imports && imports.length > 0) return await resolveImports(imports, source, filePath);
|
|
180
|
-
} catch
|
|
181
|
-
const regexImports = extractImportPathsWithRegex(source);
|
|
182
|
+
} catch {}
|
|
183
|
+
const regexImports = extractImportPathsWithRegex(stripComments(source, filePath));
|
|
182
184
|
const resolvedImports = /* @__PURE__ */ new Map();
|
|
183
185
|
for (const { path: importPath, isTypeOnly } of regexImports) {
|
|
184
186
|
if (isNodeBuiltin(importPath)) continue;
|
|
@@ -186,7 +188,7 @@ async function parseImports(source, filePath) {
|
|
|
186
188
|
let resolvedPath = null;
|
|
187
189
|
if (tsconfigManager.isAlias(importPath)) resolvedPath = await resolveAliasImport(importPath);
|
|
188
190
|
else if (importPath.startsWith(".")) resolvedPath = await resolveRelativeImport(importPath, filePath);
|
|
189
|
-
if (resolvedPath) mergeResolvedImport(resolvedImports, importPath, resolvedPath, isTypeOnly);
|
|
191
|
+
if (resolvedPath && !isSameFile(resolvedPath, filePath)) mergeResolvedImport(resolvedImports, importPath, resolvedPath, isTypeOnly);
|
|
190
192
|
}
|
|
191
193
|
return resolvedImports;
|
|
192
194
|
} catch (error) {
|
|
@@ -194,6 +196,71 @@ async function parseImports(source, filePath) {
|
|
|
194
196
|
return /* @__PURE__ */ new Map();
|
|
195
197
|
}
|
|
196
198
|
}
|
|
199
|
+
/** True when both paths name the same file (case-insensitively on Windows). */
|
|
200
|
+
function isSameFile(first, second) {
|
|
201
|
+
const normalize = (filePath) => {
|
|
202
|
+
const resolved = Path.normalize(path.resolve(filePath));
|
|
203
|
+
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
204
|
+
};
|
|
205
|
+
return normalize(first) === normalize(second);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Remove `//` and `/* *\/` comments, keeping every newline in place (so
|
|
209
|
+
* line-based matches keep their lines). Only the regex fallback needs it; the
|
|
210
|
+
* lexer already skips comments.
|
|
211
|
+
*
|
|
212
|
+
* Comment ranges come from a real TypeScript parse, never from scanning
|
|
213
|
+
* characters: only the parser can tell a regex literal (`/\/*$/`), a template
|
|
214
|
+
* literal or JSX text (`<p>// not a comment</p>`) from a comment. A character
|
|
215
|
+
* scanner read the `/*` in `p.replace(/\/*$/, "")` as a block comment and
|
|
216
|
+
* erased every import after it.
|
|
217
|
+
*
|
|
218
|
+
* `filePath` picks the dialect (`.tsx`/`.jsx` parse JSX); without it the
|
|
219
|
+
* source is parsed as TSX.
|
|
220
|
+
*/
|
|
221
|
+
function stripComments(source, filePath = "source.tsx") {
|
|
222
|
+
const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, false, scriptKindFor(filePath));
|
|
223
|
+
const ranges = [];
|
|
224
|
+
const seen = /* @__PURE__ */ new Set();
|
|
225
|
+
const collect = (node) => {
|
|
226
|
+
if (node.kind >= ts.SyntaxKind.FirstJSDocNode && node.kind <= ts.SyntaxKind.LastJSDocNode) return;
|
|
227
|
+
const children = node.getChildren(sourceFile);
|
|
228
|
+
if (children.length > 0) {
|
|
229
|
+
for (const child of children) collect(child);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (node.kind === ts.SyntaxKind.JsxText || node.kind === ts.SyntaxKind.JsxTextAllWhiteSpaces) return;
|
|
233
|
+
const tokenStart = node.getStart(sourceFile);
|
|
234
|
+
const trivia = [...ts.getTrailingCommentRanges(source, node.pos) ?? [], ...ts.getLeadingCommentRanges(source, node.pos) ?? []];
|
|
235
|
+
for (const range of trivia) if (range.end <= tokenStart && !seen.has(range.pos)) {
|
|
236
|
+
seen.add(range.pos);
|
|
237
|
+
ranges.push(range);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
collect(sourceFile);
|
|
241
|
+
ranges.sort((first, second) => first.pos - second.pos);
|
|
242
|
+
let output = "";
|
|
243
|
+
let cursor = 0;
|
|
244
|
+
for (const range of ranges) {
|
|
245
|
+
output += source.slice(cursor, range.pos);
|
|
246
|
+
output += source.slice(range.pos, range.end).replace(/[^\n]/g, "");
|
|
247
|
+
cursor = range.end;
|
|
248
|
+
}
|
|
249
|
+
return output + source.slice(cursor);
|
|
250
|
+
}
|
|
251
|
+
/** The parse dialect for a file: JSX only where the extension allows it. */
|
|
252
|
+
function scriptKindFor(filePath) {
|
|
253
|
+
switch (path.extname(filePath).toLowerCase()) {
|
|
254
|
+
case ".ts":
|
|
255
|
+
case ".mts":
|
|
256
|
+
case ".cts": return ts.ScriptKind.TS;
|
|
257
|
+
case ".js":
|
|
258
|
+
case ".mjs":
|
|
259
|
+
case ".cjs": return ts.ScriptKind.JS;
|
|
260
|
+
case ".jsx": return ts.ScriptKind.JSX;
|
|
261
|
+
default: return ts.ScriptKind.TSX;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
197
264
|
/**
|
|
198
265
|
* Merge a resolved import into the output map, preserving the type-only rule:
|
|
199
266
|
* a path is type-only iff every statement that references it is type-only.
|
|
@@ -224,7 +291,7 @@ async function resolveImports(imports, source, filePath) {
|
|
|
224
291
|
let resolvedPath = null;
|
|
225
292
|
if (tsconfigManager.isAlias(importPath)) resolvedPath = await resolveAliasImport(importPath);
|
|
226
293
|
else if (importPath.startsWith(".")) resolvedPath = await resolveRelativeImport(importPath, filePath);
|
|
227
|
-
if (!resolvedPath) continue;
|
|
294
|
+
if (!resolvedPath || isSameFile(resolvedPath, filePath)) continue;
|
|
228
295
|
const isTypeOnly = isLexerStatementTypeOnly(imp, source);
|
|
229
296
|
mergeResolvedImport(resolvedImports, importPath, resolvedPath, isTypeOnly);
|
|
230
297
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-imports.mjs","names":[],"sources":["../../../../../../../core/src/dev-server/parse-imports.ts"],"sourcesContent":["import { fileExistsAsync, directoryExistsAsync } from \"@warlock.js/fs\";\nimport { type ImportSpecifier, parse } from \"es-module-lexer\";\nimport path from \"node:path\";\nimport { Path } from \"../utils/normalized-path\";\nimport { tsconfigManager } from \"./tsconfig-manager\";\n\n/**\n * Detect if a file contains only type definitions (no runtime code)\n *\n * A file is considered type-only if ALL its exports are:\n * - interface declarations\n * - type alias declarations\n * - export type { ... } statements\n * - export type { ... } from \"...\" statements\n *\n * Files with any of these are NOT type-only:\n * - export const/let/var\n * - export function\n * - export class\n * - export default (non-type)\n * - export { ... } (without type keyword)\n * - export * from (without type keyword)\n *\n * @param source - The source code to analyze\n * @returns true if the file exports only types\n */\nexport function isTypeOnlyFile(source: string): boolean {\n // Remove comments to avoid false positives\n const withoutComments = source\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\") // block comments\n .replace(/\\/\\/.*$/gm, \"\"); // line comments\n\n // Remove string literals to avoid false positives\n const withoutStrings = withoutComments\n .replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"''\")\n .replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"\"')\n .replace(/`(?:[^`\\\\]|\\\\.)*`/g, \"``\");\n\n // Patterns for type-only exports (these are safe)\n const typeOnlyPatterns = [\n /export\\s+type\\s+\\{[^}]*\\}/g, // export type { Foo, Bar }\n /export\\s+type\\s+\\{[^}]*\\}\\s+from\\s+['\"]/g, // export type { Foo } from \"...\"\n /export\\s+interface\\s+\\w+/g, // export interface Foo\n /export\\s+type\\s+\\w+\\s*=/g, // export type Foo =\n ];\n\n // Remove all type-only exports from consideration\n let remaining = withoutStrings;\n for (const pattern of typeOnlyPatterns) {\n remaining = remaining.replace(pattern, \"\");\n }\n\n // Patterns for runtime exports (these make the file NOT type-only)\n const runtimeExportPatterns = [\n /export\\s+(?:const|let|var)\\s+\\w+/g, // export const/let/var foo\n /export\\s+function\\s+\\w+/g, // export function foo\n /export\\s+async\\s+function\\s+\\w+/g, // export async function foo\n /export\\s+class\\s+\\w+/g, // export class Foo\n /export\\s+enum\\s+\\w+/g, // export enum Foo (enums have runtime value)\n /export\\s+default\\s+(?!type\\s)/g, // export default (not type)\n /export\\s+\\{[^}]*\\}(?!\\s+from)/g, // export { foo } (local re-export without type)\n /export\\s+\\{[^}]*\\}\\s+from\\s+['\"][^'\"]+['\"]/g, // export { foo } from (without type)\n /export\\s+\\*\\s+from\\s+['\"][^'\"]+['\"]/g, // export * from (re-exports everything)\n /export\\s+\\*\\s+as\\s+\\w+/g, // export * as namespace\n ];\n\n for (const pattern of runtimeExportPatterns) {\n if (pattern.test(remaining)) {\n // Reset regex lastIndex for subsequent tests\n pattern.lastIndex = 0;\n\n // Special case: check if export { } contains only type exports\n if (pattern.source.includes(\"export\\\\s+\\\\{\")) {\n const matches = remaining.match(/export\\s+\\{([^}]*)\\}(?:\\s+from\\s+['\"][^'\"]+['\"])?/g);\n if (matches) {\n for (const match of matches) {\n // Skip if it's already a type export\n if (/^export\\s+type\\s+/.test(match)) continue;\n\n // Extract the specifiers\n const specifiersMatch = match.match(/export\\s+\\{([^}]*)\\}/);\n if (specifiersMatch) {\n // Capture group 1 exists whenever the pattern matched. `?? \"\"`\n // yields an empty specifier list, which `some()` below reads as\n // \"no runtime specifier\" — the same answer an empty `{}` gives.\n const specifiers = specifiersMatch[1] ?? \"\";\n const items = specifiers\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n // If any specifier is NOT prefixed with \"type \", this is a runtime export\n const hasRuntimeSpecifier = items.some((item) => !item.startsWith(\"type \"));\n if (hasRuntimeSpecifier) {\n return false;\n }\n }\n }\n }\n continue;\n }\n\n return false;\n }\n }\n\n // If we get here, no runtime exports were found\n // But we should also verify the file has at least some type exports\n // (an empty file or file with only imports is not really \"type-only\")\n const hasTypeExports = typeOnlyPatterns.some((pattern) => {\n pattern.lastIndex = 0;\n return pattern.test(withoutStrings);\n });\n\n return hasTypeExports;\n}\n\n/**\n * Check if an import statement is a pure `import type` (the keyword sits\n * immediately after `import`, covering `import type { X }`, `import type Foo`,\n * and `import type * as Ns`).\n */\nfunction isTypeOnlyImport(line: string): boolean {\n const trimmed = line.trim();\n\n return trimmed.startsWith(\"import type \") || !!trimmed.match(/^import\\s+type\\s+[\\{\\*]/);\n}\n\n/**\n * Decide whether an `import ... from \"m\"` statement contributes any runtime\n * binding. Returns false for pure `import type` and for destructured imports\n * where every specifier is prefixed with the `type` keyword.\n */\nfunction hasRuntimeImports(line: string): boolean {\n const trimmed = line.trim();\n\n if (isTypeOnlyImport(trimmed)) {\n return false;\n }\n\n const specifiersMatch = trimmed.match(/import\\s+(?:type\\s+)?\\{([^}]+)\\}/);\n\n if (!specifiersMatch) {\n return true;\n }\n\n const items = (specifiersMatch[1] ?? \"\")\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n return !items.every((item) => /^type\\s+\\w+/.test(item));\n}\n\n/**\n * Decide whether an `export ... from \"m\"` statement re-exports only types.\n * Covers `export type { X } from`, `export type * from`, and\n * `export { type X, type Y } from`.\n */\nfunction isExportTypeOnlyStatement(line: string): boolean {\n const trimmed = line.trim();\n\n if (/^export\\s+type\\s+/.test(trimmed)) {\n return true;\n }\n\n const specifiersMatch = trimmed.match(/export\\s+\\{([^}]+)\\}/);\n\n if (!specifiersMatch) {\n return false;\n }\n\n const items = (specifiersMatch[1] ?? \"\")\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n return items.every((item) => /^type\\s+\\w+/.test(item));\n}\n\n/**\n * Extract import paths using regex (more reliable for TypeScript).\n * Each entry carries an `isTypeOnly` flag: true when every occurrence of the\n * path in the source is a type-only statement (no runtime binding).\n * A single runtime occurrence makes the path runtime.\n */\nfunction extractImportPathsWithRegex(\n source: string,\n): Array<{ path: string; originalLine: string; isTypeOnly: boolean }> {\n const imports: Array<{ path: string; originalLine: string; isTypeOnly: boolean }> = [];\n const seenPaths = new Map<string, number>();\n\n /**\n * Record an import path with its type-only flag.\n * If the same path appears in multiple statements, the edge is type-only\n * iff every occurrence is type-only — a single runtime statement makes it runtime.\n */\n const record = (importPath: string, originalLine: string, isTypeOnly: boolean): void => {\n if (!importPath) {\n return;\n }\n\n const existingIndex = seenPaths.get(importPath);\n\n if (existingIndex === undefined) {\n seenPaths.set(importPath, imports.length);\n imports.push({ path: importPath, originalLine, isTypeOnly });\n\n return;\n }\n\n if (!isTypeOnly) {\n const existing = imports[existingIndex];\n\n // `existingIndex` came from findIndex on this same array, so it is in\n // range; the compiler does not carry that here.\n if (existing) existing.isTypeOnly = false;\n }\n };\n\n // Pattern 1: Standard ES module imports (handles multiline)\n // Matches: import { ... } from \"path\", import Foo from \"path\", import Foo, { ... } from \"path\"\n const importRegex =\n /import\\s+(?:type\\s+)?(\\{[\\s\\S]*?\\}|\\*\\s+as\\s+\\w+|\\w+(?:\\s*,\\s*\\{[\\s\\S]*?\\})?)\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n\n let match;\n\n while ((match = importRegex.exec(source)) !== null) {\n const fullMatch = match[0];\n const importPath = match[2];\n\n // Each pattern here captures its path in a group, so a match always carries\n // one. Skipping rather than recording keeps a malformed match out of the\n // dependency graph entirely — recording `undefined` would add an import\n // edge to a module named \"undefined\", which the dev server would then\n // watch, fail to resolve, and report against the wrong file.\n if (importPath === undefined) continue;\n\n const isTypeOnly = !hasRuntimeImports(fullMatch);\n\n record(importPath, fullMatch, isTypeOnly);\n }\n\n // Pattern 1b: Side-effect imports - import \"path\" — always runtime\n const sideEffectRegex = /import\\s+['\"]([^'\"]+)['\"]/g;\n\n while ((match = sideEffectRegex.exec(source)) !== null) {\n const sideEffectPath = match[1];\n\n if (sideEffectPath === undefined) continue;\n\n record(sideEffectPath, match[0], false);\n }\n\n // Pattern 2: Dynamic imports - import(\"path\") — always runtime\n const dynamicImportPattern = /import\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n while ((match = dynamicImportPattern.exec(source)) !== null) {\n const dynamicPath = match[1];\n\n if (dynamicPath === undefined) continue;\n\n record(dynamicPath, match[0], false);\n }\n\n // Pattern 3: Export from - export ... from \"path\"\n const exportFromPattern = /export\\s+(?:\\{[^}]*\\}|\\*|\\w+)\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n\n while ((match = exportFromPattern.exec(source)) !== null) {\n const fullMatch = match[0];\n const exportPath = match[1];\n\n if (exportPath === undefined) continue;\n\n record(exportPath, fullMatch, isExportTypeOnlyStatement(fullMatch));\n }\n\n return imports;\n}\n\n/**\n * Metadata for a single resolved import edge.\n * `isTypeOnly` is true iff every import/export statement that references this\n * path is type-only (pure `import type`, `export type`, or destructured lists\n * where every specifier carries the `type` keyword). A single runtime\n * occurrence flips the flag to false — that's what matters for cycle detection.\n */\nexport type ResolvedImport = {\n absolutePath: string;\n isTypeOnly: boolean;\n};\n\n/**\n * Parse import/export statements in a TS/JS source file and return the\n * resolved dependency edges keyed by the original import path. Includes\n * type-only edges (flagged) so downstream consumers can distinguish runtime\n * cycles from type-only ones.\n *\n * @example\n * const importMap = await parseImports(source, \"/abs/path/to/file.ts\");\n * for (const [importPath, { absolutePath, isTypeOnly }] of importMap) {\n * // ...\n * }\n */\nexport async function parseImports(\n source: string,\n filePath: string,\n): Promise<Map<string, ResolvedImport>> {\n try {\n // Skip .d.ts files - they're type declarations, not runtime code\n if (filePath.endsWith(\".d.ts\")) {\n return new Map();\n }\n\n // Try es-module-lexer first (faster and more accurate for simple cases)\n try {\n const [imports] = await parse(source);\n\n if (imports && imports.length > 0) {\n return await resolveImports(imports as ImportSpecifier[], source, filePath);\n }\n } catch (lexerError) {\n // es-module-lexer failed, fall back to regex-based extraction\n // This is common with TypeScript files that have complex syntax\n }\n\n // Fallback: Use regex-based extraction (more forgiving with TypeScript)\n const regexImports = extractImportPathsWithRegex(source);\n const resolvedImports = new Map<string, ResolvedImport>();\n\n for (const { path: importPath, isTypeOnly } of regexImports) {\n if (isNodeBuiltin(importPath)) {\n continue;\n }\n\n if (!importPath.startsWith(\".\") && !tsconfigManager.isAlias(importPath)) {\n continue;\n }\n\n let resolvedPath: string | null = null;\n\n if (tsconfigManager.isAlias(importPath)) {\n resolvedPath = await resolveAliasImport(importPath);\n } else if (importPath.startsWith(\".\")) {\n resolvedPath = await resolveRelativeImport(importPath, filePath);\n }\n\n if (resolvedPath) {\n mergeResolvedImport(resolvedImports, importPath, resolvedPath, isTypeOnly);\n }\n }\n\n return resolvedImports;\n } catch (error) {\n console.error(`Error parsing imports for ${filePath}:`, error);\n\n return new Map();\n }\n}\n\n/**\n * Merge a resolved import into the output map, preserving the type-only rule:\n * a path is type-only iff every statement that references it is type-only.\n */\nfunction mergeResolvedImport(\n target: Map<string, ResolvedImport>,\n importPath: string,\n absolutePath: string,\n isTypeOnly: boolean,\n): void {\n const existing = target.get(importPath);\n\n if (!existing) {\n target.set(importPath, { absolutePath, isTypeOnly });\n\n return;\n }\n\n if (!isTypeOnly) {\n existing.isTypeOnly = false;\n }\n}\n\n/**\n * Resolve imports from `es-module-lexer` output. For each specifier, slice the\n * raw statement (`ss..se`) and re-run the type-only heuristic so we can flag\n * the edge correctly — the lexer itself does not distinguish `import type`.\n */\nasync function resolveImports(\n imports: ImportSpecifier[],\n source: string,\n filePath: string,\n): Promise<Map<string, ResolvedImport>> {\n const resolvedImports = new Map<string, ResolvedImport>();\n\n for (const imp of imports) {\n const importPath = imp.n;\n\n if (!importPath) {\n continue;\n }\n\n if (isNodeBuiltin(importPath)) {\n continue;\n }\n\n if (!importPath.startsWith(\".\") && !tsconfigManager.isAlias(importPath)) {\n continue;\n }\n\n let resolvedPath: string | null = null;\n\n if (tsconfigManager.isAlias(importPath)) {\n resolvedPath = await resolveAliasImport(importPath);\n } else if (importPath.startsWith(\".\")) {\n resolvedPath = await resolveRelativeImport(importPath, filePath);\n }\n\n if (!resolvedPath) {\n continue;\n }\n\n const isTypeOnly = isLexerStatementTypeOnly(imp, source);\n\n mergeResolvedImport(resolvedImports, importPath, resolvedPath, isTypeOnly);\n }\n\n return resolvedImports;\n}\n\n/**\n * Classify a single lexer-reported statement as type-only or runtime.\n * Dynamic imports (`import(...)`) are always runtime. For static\n * imports/export-from we slice the raw source and apply the same heuristic\n * the regex fallback uses.\n */\nfunction isLexerStatementTypeOnly(imp: ImportSpecifier, source: string): boolean {\n // Dynamic imports always execute — they cannot be type-only.\n // es-module-lexer reports dynamic with a.n === undefined typically, but\n // we guard by checking the statement prefix too.\n const statementStart = imp.ss;\n const statementEnd = imp.se;\n\n if (\n typeof statementStart !== \"number\" ||\n typeof statementEnd !== \"number\" ||\n statementEnd <= statementStart\n ) {\n return false;\n }\n\n const statement = source.slice(statementStart, statementEnd);\n const trimmed = statement.trim();\n\n if (trimmed.startsWith(\"import(\") || /^\\bimport\\s*\\(/.test(trimmed)) {\n return false;\n }\n\n if (trimmed.startsWith(\"export\")) {\n return isExportTypeOnlyStatement(statement);\n }\n\n return !hasRuntimeImports(statement);\n}\n\n/**\n * Resolve alias imports to actual file paths with extensions\n * Example: app/users/services/get-users.service -> /absolute/path/to/src/app/users/services/get-users.service.ts\n */\nasync function resolveAliasImport(importPath: string): Promise<string | null> {\n // Use tsconfig manager to resolve the alias to an absolute path\n const resolvedBase = tsconfigManager.resolveAliasToAbsolute(importPath);\n\n if (!resolvedBase) return null;\n\n // Try to resolve with extensions\n const resolvedPath = await tryResolveWithExtensions(resolvedBase);\n\n return resolvedPath;\n}\n\n/**\n * Resolve relative imports to actual file paths\n * Example: ./../services/get-user.service -> /absolute/path/to/services/get-user.service.ts\n */\nasync function resolveRelativeImport(\n importPath: string,\n currentFilePath: string,\n): Promise<string | null> {\n const dir = path.dirname(currentFilePath);\n // Use path.resolve to handle .. and . properly, then normalize to forward slashes\n const resolvedBase = Path.normalize(path.resolve(dir, importPath));\n\n // Try to resolve with extensions\n const resolvedPath = await tryResolveWithExtensions(resolvedBase);\n\n return resolvedPath;\n}\n\n/**\n * Try to resolve a file path by checking different extensions\n * TypeScript/JavaScript files can be imported without extensions\n *\n * @TODO: For better performance, we need to check the files in files orchestrator\n * instead of using the file system as we will be fetching all project files anyway.\n */\n// Cache for file existence checks to avoid redundant filesystem calls\nconst fileExistsCache = new Map<string, boolean>();\n\n/**\n * Clear the file exists cache\n * Should be called when new files are created to ensure fresh lookups\n */\nexport function clearFileExistsCache(): void {\n fileExistsCache.clear();\n}\n\nasync function cachedFileExists(filePath: string): Promise<boolean> {\n if (fileExistsCache.has(filePath)) {\n return fileExistsCache.get(filePath)!;\n }\n const exists = (await fileExistsAsync(filePath)) as boolean;\n\n // Cache ONLY positive results. A negative (\"does not exist\") answer is the\n // exact case that flips moments later: the \"add a new controller/route\" flow\n // references a file, then creates it. Caching that negative for the whole\n // process lifetime (it was cleared only on a multi-file watcher batch) left\n // a routes.ts import unresolvable after its target was created — the dep\n // edge never formed and the route module import failed, so the new API route\n // 404'd until an unrelated multi-file batch cleared the cache. That is\n // finding 60721e35 (\"backend route HMR needs a second edit\"). A file that\n // exists does not stop existing mid-resolve, so caching the hit is safe;\n // re-probing a still-missing path costs only a handful of stat calls.\n if (exists) {\n fileExistsCache.set(filePath, exists);\n }\n\n return exists;\n}\n\nasync function tryResolveWithExtensions(basePath: string): Promise<string | null> {\n // Normalize the base path first (handle Windows paths)\n const normalizedBase = Path.normalize(basePath);\n\n // List of extensions to try, in order of preference\n const extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"];\n const validExtensions = new Set(extensions);\n\n // If the path already has a VALID code file extension, check if it exists\n const ext = path.extname(normalizedBase);\n if (ext && validExtensions.has(ext)) {\n // NodeNext style: `./x.js` is written, `x.ts`/`x.tsx` is on disk. The\n // loader rewrites it the same way (own-resolver `probeFile`), and a\n // co-located source wins over the literal .js.\n if ([\".js\", \".jsx\", \".mjs\", \".cjs\"].includes(ext)) {\n const stem = normalizedBase.slice(0, -ext.length);\n for (const sourceExt of [\".ts\", \".tsx\"]) {\n if (await cachedFileExists(stem + sourceExt)) {\n return stem + sourceExt;\n }\n }\n }\n if (await cachedFileExists(normalizedBase)) {\n return normalizedBase;\n }\n // If explicit extension doesn't exist, return null\n return null;\n }\n\n // Try all extensions in parallel for better performance\n const pathsToCheck = extensions.map((extension) => normalizedBase + extension);\n const results = await Promise.all(\n pathsToCheck.map(async (p) => ({ path: p, exists: await cachedFileExists(p) })),\n );\n\n // Return the first one that exists (in order of preference)\n for (const result of results) {\n if (result.exists) {\n return result.path;\n }\n }\n\n // Try index files in directory\n if (await directoryExistsAsync(normalizedBase)) {\n const indexPaths = extensions.map((extension) =>\n Path.join(normalizedBase, `index${extension}`),\n );\n const indexResults = await Promise.all(\n indexPaths.map(async (p) => ({ path: p, exists: await cachedFileExists(p) })),\n );\n\n for (const result of indexResults) {\n if (result.exists) {\n return result.path;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Check if import is a Node.js built-in module\n */\nfunction isNodeBuiltin(importPath: string): boolean {\n const builtins = [\n \"fs\",\n \"path\",\n \"http\",\n \"https\",\n \"crypto\",\n \"stream\",\n \"util\",\n \"events\",\n \"buffer\",\n \"child_process\",\n \"os\",\n \"url\",\n \"querystring\",\n \"zlib\",\n \"net\",\n \"tls\",\n \"dns\",\n \"dgram\",\n \"cluster\",\n \"worker_threads\",\n \"perf_hooks\",\n \"async_hooks\",\n \"timers\",\n \"readline\",\n \"repl\",\n \"vm\",\n \"assert\",\n \"console\",\n \"process\",\n \"v8\",\n ];\n\n // Check for node: prefix or direct builtin name\n if (importPath.startsWith(\"node:\")) return true;\n\n // `split` always yields a first element. Falling back to the whole path\n // keeps the builtin check answering about a real name rather than undefined.\n const moduleName = importPath.split(\"/\")[0] ?? importPath;\n\n return builtins.includes(moduleName);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parse-imports.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/parse-imports.ts"],"sourcesContent":["import { fileExistsAsync, directoryExistsAsync } from \"@warlock.js/fs\";\nimport { type ImportSpecifier, parse } from \"es-module-lexer\";\nimport path from \"node:path\";\nimport ts from \"typescript\";\nimport { Path } from \"../utils/normalized-path\";\nimport { tsconfigManager } from \"./tsconfig-manager\";\n\n/**\n * Detect if a file contains only type definitions (no runtime code)\n *\n * A file is considered type-only if ALL its exports are:\n * - interface declarations\n * - type alias declarations\n * - export type { ... } statements\n * - export type { ... } from \"...\" statements\n *\n * Files with any of these are NOT type-only:\n * - export const/let/var\n * - export function\n * - export class\n * - export default (non-type)\n * - export { ... } (without type keyword)\n * - export * from (without type keyword)\n *\n * @param source - The source code to analyze\n * @returns true if the file exports only types\n */\nexport function isTypeOnlyFile(source: string): boolean {\n // Remove comments to avoid false positives\n const withoutComments = source\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\") // block comments\n .replace(/\\/\\/.*$/gm, \"\"); // line comments\n\n // Remove string literals to avoid false positives\n const withoutStrings = withoutComments\n .replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"''\")\n .replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"\"')\n .replace(/`(?:[^`\\\\]|\\\\.)*`/g, \"``\");\n\n // Patterns for type-only exports (these are safe)\n const typeOnlyPatterns = [\n /export\\s+type\\s+\\{[^}]*\\}/g, // export type { Foo, Bar }\n /export\\s+type\\s+\\{[^}]*\\}\\s+from\\s+['\"]/g, // export type { Foo } from \"...\"\n /export\\s+interface\\s+\\w+/g, // export interface Foo\n /export\\s+type\\s+\\w+\\s*=/g, // export type Foo =\n ];\n\n // Remove all type-only exports from consideration\n let remaining = withoutStrings;\n for (const pattern of typeOnlyPatterns) {\n remaining = remaining.replace(pattern, \"\");\n }\n\n // Patterns for runtime exports (these make the file NOT type-only)\n const runtimeExportPatterns = [\n /export\\s+(?:const|let|var)\\s+\\w+/g, // export const/let/var foo\n /export\\s+function\\s+\\w+/g, // export function foo\n /export\\s+async\\s+function\\s+\\w+/g, // export async function foo\n /export\\s+class\\s+\\w+/g, // export class Foo\n /export\\s+enum\\s+\\w+/g, // export enum Foo (enums have runtime value)\n /export\\s+default\\s+(?!type\\s)/g, // export default (not type)\n /export\\s+\\{[^}]*\\}(?!\\s+from)/g, // export { foo } (local re-export without type)\n /export\\s+\\{[^}]*\\}\\s+from\\s+['\"][^'\"]+['\"]/g, // export { foo } from (without type)\n /export\\s+\\*\\s+from\\s+['\"][^'\"]+['\"]/g, // export * from (re-exports everything)\n /export\\s+\\*\\s+as\\s+\\w+/g, // export * as namespace\n ];\n\n for (const pattern of runtimeExportPatterns) {\n if (pattern.test(remaining)) {\n // Reset regex lastIndex for subsequent tests\n pattern.lastIndex = 0;\n\n // Special case: check if export { } contains only type exports\n if (pattern.source.includes(\"export\\\\s+\\\\{\")) {\n const matches = remaining.match(/export\\s+\\{([^}]*)\\}(?:\\s+from\\s+['\"][^'\"]+['\"])?/g);\n if (matches) {\n for (const match of matches) {\n // Skip if it's already a type export\n if (/^export\\s+type\\s+/.test(match)) continue;\n\n // Extract the specifiers\n const specifiersMatch = match.match(/export\\s+\\{([^}]*)\\}/);\n if (specifiersMatch) {\n // Capture group 1 exists whenever the pattern matched. `?? \"\"`\n // yields an empty specifier list, which `some()` below reads as\n // \"no runtime specifier\" — the same answer an empty `{}` gives.\n const specifiers = specifiersMatch[1] ?? \"\";\n const items = specifiers\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n // If any specifier is NOT prefixed with \"type \", this is a runtime export\n const hasRuntimeSpecifier = items.some((item) => !item.startsWith(\"type \"));\n if (hasRuntimeSpecifier) {\n return false;\n }\n }\n }\n }\n continue;\n }\n\n return false;\n }\n }\n\n // If we get here, no runtime exports were found\n // But we should also verify the file has at least some type exports\n // (an empty file or file with only imports is not really \"type-only\")\n const hasTypeExports = typeOnlyPatterns.some((pattern) => {\n pattern.lastIndex = 0;\n return pattern.test(withoutStrings);\n });\n\n return hasTypeExports;\n}\n\n/**\n * Check if an import statement is a pure `import type` (the keyword sits\n * immediately after `import`, covering `import type { X }`, `import type Foo`,\n * and `import type * as Ns`).\n */\nfunction isTypeOnlyImport(line: string): boolean {\n const trimmed = line.trim();\n\n return trimmed.startsWith(\"import type \") || !!trimmed.match(/^import\\s+type\\s+[\\{\\*]/);\n}\n\n/**\n * Decide whether an `import ... from \"m\"` statement contributes any runtime\n * binding. Returns false for pure `import type` and for destructured imports\n * where every specifier is prefixed with the `type` keyword.\n */\nfunction hasRuntimeImports(line: string): boolean {\n const trimmed = line.trim();\n\n if (isTypeOnlyImport(trimmed)) {\n return false;\n }\n\n const specifiersMatch = trimmed.match(/import\\s+(?:type\\s+)?\\{([^}]+)\\}/);\n\n if (!specifiersMatch) {\n return true;\n }\n\n const items = (specifiersMatch[1] ?? \"\")\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n return !items.every((item) => /^type\\s+\\w+/.test(item));\n}\n\n/**\n * Decide whether an `export ... from \"m\"` statement re-exports only types.\n * Covers `export type { X } from`, `export type * from`, and\n * `export { type X, type Y } from`.\n */\nfunction isExportTypeOnlyStatement(line: string): boolean {\n const trimmed = line.trim();\n\n if (/^export\\s+type\\s+/.test(trimmed)) {\n return true;\n }\n\n const specifiersMatch = trimmed.match(/export\\s+\\{([^}]+)\\}/);\n\n if (!specifiersMatch) {\n return false;\n }\n\n const items = (specifiersMatch[1] ?? \"\")\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n return items.every((item) => /^type\\s+\\w+/.test(item));\n}\n\n/**\n * Extract import paths using regex (more reliable for TypeScript).\n * Each entry carries an `isTypeOnly` flag: true when every occurrence of the\n * path in the source is a type-only statement (no runtime binding).\n * A single runtime occurrence makes the path runtime.\n */\nfunction extractImportPathsWithRegex(\n source: string,\n): Array<{ path: string; originalLine: string; isTypeOnly: boolean }> {\n const imports: Array<{ path: string; originalLine: string; isTypeOnly: boolean }> = [];\n const seenPaths = new Map<string, number>();\n\n /**\n * Record an import path with its type-only flag.\n * If the same path appears in multiple statements, the edge is type-only\n * iff every occurrence is type-only — a single runtime statement makes it runtime.\n */\n const record = (importPath: string, originalLine: string, isTypeOnly: boolean): void => {\n if (!importPath) {\n return;\n }\n\n const existingIndex = seenPaths.get(importPath);\n\n if (existingIndex === undefined) {\n seenPaths.set(importPath, imports.length);\n imports.push({ path: importPath, originalLine, isTypeOnly });\n\n return;\n }\n\n if (!isTypeOnly) {\n const existing = imports[existingIndex];\n\n // `existingIndex` came from findIndex on this same array, so it is in\n // range; the compiler does not carry that here.\n if (existing) existing.isTypeOnly = false;\n }\n };\n\n // Pattern 1: Standard ES module imports (handles multiline)\n // Matches: import { ... } from \"path\", import Foo from \"path\", import Foo, { ... } from \"path\"\n const importRegex =\n /import\\s+(?:type\\s+)?(\\{[\\s\\S]*?\\}|\\*\\s+as\\s+\\w+|\\w+(?:\\s*,\\s*\\{[\\s\\S]*?\\})?)\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n\n let match;\n\n while ((match = importRegex.exec(source)) !== null) {\n const fullMatch = match[0];\n const importPath = match[2];\n\n // Each pattern here captures its path in a group, so a match always carries\n // one. Skipping rather than recording keeps a malformed match out of the\n // dependency graph entirely — recording `undefined` would add an import\n // edge to a module named \"undefined\", which the dev server would then\n // watch, fail to resolve, and report against the wrong file.\n if (importPath === undefined) continue;\n\n const isTypeOnly = !hasRuntimeImports(fullMatch);\n\n record(importPath, fullMatch, isTypeOnly);\n }\n\n // Pattern 1b: Side-effect imports - import \"path\" — always runtime\n const sideEffectRegex = /import\\s+['\"]([^'\"]+)['\"]/g;\n\n while ((match = sideEffectRegex.exec(source)) !== null) {\n const sideEffectPath = match[1];\n\n if (sideEffectPath === undefined) continue;\n\n record(sideEffectPath, match[0], false);\n }\n\n // Pattern 2: Dynamic imports - import(\"path\") — always runtime\n const dynamicImportPattern = /import\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n while ((match = dynamicImportPattern.exec(source)) !== null) {\n const dynamicPath = match[1];\n\n if (dynamicPath === undefined) continue;\n\n record(dynamicPath, match[0], false);\n }\n\n // Pattern 3: Export from - export ... from \"path\"\n // A pure `export type { A } from` / `export type * from` re-export is matched\n // and then skipped: it is erased at compile time, so it is no dependency\n // edge. That keeps this fallback in line with the lexer path, which never\n // reports the form, so the graph no longer depends on which path ran.\n // `export { type A } from` (reported by the lexer) stays a type-only edge.\n const exportFromPattern =\n /export\\s+(?:type\\s+)?(?:\\{[^}]*\\}|\\*(?:\\s+as\\s+\\w+)?|\\w+)\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n\n while ((match = exportFromPattern.exec(source)) !== null) {\n const fullMatch = match[0];\n const exportPath = match[1];\n\n if (exportPath === undefined) continue;\n\n if (/^export\\s+type\\s/.test(fullMatch)) continue;\n\n record(exportPath, fullMatch, isExportTypeOnlyStatement(fullMatch));\n }\n\n return imports;\n}\n\n/**\n * Metadata for a single resolved import edge.\n * `isTypeOnly` is true iff every import/export statement that references this\n * path is type-only (pure `import type`, `export type`, or destructured lists\n * where every specifier carries the `type` keyword). A single runtime\n * occurrence flips the flag to false — that's what matters for cycle detection.\n */\nexport type ResolvedImport = {\n absolutePath: string;\n isTypeOnly: boolean;\n};\n\n/**\n * Parse import/export statements in a TS/JS source file and return the\n * resolved dependency edges keyed by the original import path. Includes\n * type-only edges (flagged) so downstream consumers can distinguish runtime\n * cycles from type-only ones.\n *\n * @example\n * const importMap = await parseImports(source, \"/abs/path/to/file.ts\");\n * for (const [importPath, { absolutePath, isTypeOnly }] of importMap) {\n * // ...\n * }\n */\nexport async function parseImports(\n source: string,\n filePath: string,\n): Promise<Map<string, ResolvedImport>> {\n try {\n // Skip .d.ts files - they're type declarations, not runtime code\n if (filePath.endsWith(\".d.ts\")) {\n return new Map();\n }\n\n // es-module-lexer first: it reads the real statements and skips comments.\n try {\n const [imports] = await parse(source);\n\n if (imports && imports.length > 0) {\n return await resolveImports(imports as ImportSpecifier[], source, filePath);\n }\n } catch {\n // The lexer rejects some TypeScript syntax; the regex below covers it.\n }\n\n // Fallback: regex extraction, for files the lexer rejects and for files\n // where it finds nothing (it does not report `export type { A } from`).\n // It runs over the source without comments: scanning them turned a doc\n // comment such as `(await import(\"./query-testing\"))` in a file with no\n // imports into a self edge and a false \"circular dependency\" (FW-13).\n const regexImports = extractImportPathsWithRegex(stripComments(source, filePath));\n const resolvedImports = new Map<string, ResolvedImport>();\n\n for (const { path: importPath, isTypeOnly } of regexImports) {\n if (isNodeBuiltin(importPath)) {\n continue;\n }\n\n if (!importPath.startsWith(\".\") && !tsconfigManager.isAlias(importPath)) {\n continue;\n }\n\n let resolvedPath: string | null = null;\n\n if (tsconfigManager.isAlias(importPath)) {\n resolvedPath = await resolveAliasImport(importPath);\n } else if (importPath.startsWith(\".\")) {\n resolvedPath = await resolveRelativeImport(importPath, filePath);\n }\n\n if (resolvedPath && !isSameFile(resolvedPath, filePath)) {\n mergeResolvedImport(resolvedImports, importPath, resolvedPath, isTypeOnly);\n }\n }\n\n return resolvedImports;\n } catch (error) {\n console.error(`Error parsing imports for ${filePath}:`, error);\n\n return new Map();\n }\n}\n\n/** True when both paths name the same file (case-insensitively on Windows). */\nfunction isSameFile(first: string, second: string): boolean {\n const normalize = (filePath: string) => {\n const resolved = Path.normalize(path.resolve(filePath));\n return process.platform === \"win32\" ? resolved.toLowerCase() : resolved;\n };\n\n return normalize(first) === normalize(second);\n}\n\n/**\n * Remove `//` and `/* *\\/` comments, keeping every newline in place (so\n * line-based matches keep their lines). Only the regex fallback needs it; the\n * lexer already skips comments.\n *\n * Comment ranges come from a real TypeScript parse, never from scanning\n * characters: only the parser can tell a regex literal (`/\\/*$/`), a template\n * literal or JSX text (`<p>// not a comment</p>`) from a comment. A character\n * scanner read the `/*` in `p.replace(/\\/*$/, \"\")` as a block comment and\n * erased every import after it.\n *\n * `filePath` picks the dialect (`.tsx`/`.jsx` parse JSX); without it the\n * source is parsed as TSX.\n */\nexport function stripComments(source: string, filePath = \"source.tsx\"): string {\n const sourceFile = ts.createSourceFile(\n filePath,\n source,\n ts.ScriptTarget.Latest,\n false,\n scriptKindFor(filePath),\n );\n const ranges: ts.CommentRange[] = [];\n const seen = new Set<number>();\n\n const collect = (node: ts.Node): void => {\n // A JSDoc node is itself a comment, already reported as trivia of the\n // token that follows it; its inner tokens are not code.\n if (node.kind >= ts.SyntaxKind.FirstJSDocNode && node.kind <= ts.SyntaxKind.LastJSDocNode) {\n return;\n }\n\n const children = node.getChildren(sourceFile);\n\n if (children.length > 0) {\n for (const child of children) collect(child);\n\n return;\n }\n\n // JSX text has no trivia: its content starts at `pos` and may contain `//`.\n if (node.kind === ts.SyntaxKind.JsxText || node.kind === ts.SyntaxKind.JsxTextAllWhiteSpaces) {\n return;\n }\n\n const tokenStart = node.getStart(sourceFile);\n\n // Trivia before a token holds trailing comments of the previous line\n // (`a; // x`) and leading comments of this one; collect both.\n const trivia = [\n ...(ts.getTrailingCommentRanges(source, node.pos) ?? []),\n ...(ts.getLeadingCommentRanges(source, node.pos) ?? []),\n ];\n\n for (const range of trivia) {\n if (range.end <= tokenStart && !seen.has(range.pos)) {\n seen.add(range.pos);\n ranges.push(range);\n }\n }\n };\n\n collect(sourceFile);\n ranges.sort((first, second) => first.pos - second.pos);\n\n let output = \"\";\n let cursor = 0;\n\n for (const range of ranges) {\n output += source.slice(cursor, range.pos);\n output += source.slice(range.pos, range.end).replace(/[^\\n]/g, \"\");\n cursor = range.end;\n }\n\n return output + source.slice(cursor);\n}\n\n/** The parse dialect for a file: JSX only where the extension allows it. */\nfunction scriptKindFor(filePath: string): ts.ScriptKind {\n const extension = path.extname(filePath).toLowerCase();\n\n switch (extension) {\n case \".ts\":\n case \".mts\":\n case \".cts\":\n return ts.ScriptKind.TS;\n case \".js\":\n case \".mjs\":\n case \".cjs\":\n return ts.ScriptKind.JS;\n case \".jsx\":\n return ts.ScriptKind.JSX;\n default:\n return ts.ScriptKind.TSX;\n }\n}\n\n/**\n * Merge a resolved import into the output map, preserving the type-only rule:\n * a path is type-only iff every statement that references it is type-only.\n */\nfunction mergeResolvedImport(\n target: Map<string, ResolvedImport>,\n importPath: string,\n absolutePath: string,\n isTypeOnly: boolean,\n): void {\n const existing = target.get(importPath);\n\n if (!existing) {\n target.set(importPath, { absolutePath, isTypeOnly });\n\n return;\n }\n\n if (!isTypeOnly) {\n existing.isTypeOnly = false;\n }\n}\n\n/**\n * Resolve imports from `es-module-lexer` output. For each specifier, slice the\n * raw statement (`ss..se`) and re-run the type-only heuristic so we can flag\n * the edge correctly — the lexer itself does not distinguish `import type`.\n */\nasync function resolveImports(\n imports: ImportSpecifier[],\n source: string,\n filePath: string,\n): Promise<Map<string, ResolvedImport>> {\n const resolvedImports = new Map<string, ResolvedImport>();\n\n for (const imp of imports) {\n const importPath = imp.n;\n\n if (!importPath) {\n continue;\n }\n\n if (isNodeBuiltin(importPath)) {\n continue;\n }\n\n if (!importPath.startsWith(\".\") && !tsconfigManager.isAlias(importPath)) {\n continue;\n }\n\n let resolvedPath: string | null = null;\n\n if (tsconfigManager.isAlias(importPath)) {\n resolvedPath = await resolveAliasImport(importPath);\n } else if (importPath.startsWith(\".\")) {\n resolvedPath = await resolveRelativeImport(importPath, filePath);\n }\n\n // A file importing itself is no dependency edge, and as one it reads as\n // a one-file \"cycle\".\n if (!resolvedPath || isSameFile(resolvedPath, filePath)) {\n continue;\n }\n\n const isTypeOnly = isLexerStatementTypeOnly(imp, source);\n\n mergeResolvedImport(resolvedImports, importPath, resolvedPath, isTypeOnly);\n }\n\n return resolvedImports;\n}\n\n/**\n * Classify a single lexer-reported statement as type-only or runtime.\n * Dynamic imports (`import(...)`) are always runtime. For static\n * imports/export-from we slice the raw source and apply the same heuristic\n * the regex fallback uses.\n */\nfunction isLexerStatementTypeOnly(imp: ImportSpecifier, source: string): boolean {\n // Dynamic imports always execute — they cannot be type-only.\n // es-module-lexer reports dynamic with a.n === undefined typically, but\n // we guard by checking the statement prefix too.\n const statementStart = imp.ss;\n const statementEnd = imp.se;\n\n if (\n typeof statementStart !== \"number\" ||\n typeof statementEnd !== \"number\" ||\n statementEnd <= statementStart\n ) {\n return false;\n }\n\n const statement = source.slice(statementStart, statementEnd);\n const trimmed = statement.trim();\n\n if (trimmed.startsWith(\"import(\") || /^\\bimport\\s*\\(/.test(trimmed)) {\n return false;\n }\n\n if (trimmed.startsWith(\"export\")) {\n return isExportTypeOnlyStatement(statement);\n }\n\n return !hasRuntimeImports(statement);\n}\n\n/**\n * Resolve alias imports to actual file paths with extensions\n * Example: app/users/services/get-users.service -> /absolute/path/to/src/app/users/services/get-users.service.ts\n */\nasync function resolveAliasImport(importPath: string): Promise<string | null> {\n // Use tsconfig manager to resolve the alias to an absolute path\n const resolvedBase = tsconfigManager.resolveAliasToAbsolute(importPath);\n\n if (!resolvedBase) return null;\n\n // Try to resolve with extensions\n const resolvedPath = await tryResolveWithExtensions(resolvedBase);\n\n return resolvedPath;\n}\n\n/**\n * Resolve relative imports to actual file paths\n * Example: ./../services/get-user.service -> /absolute/path/to/services/get-user.service.ts\n */\nasync function resolveRelativeImport(\n importPath: string,\n currentFilePath: string,\n): Promise<string | null> {\n const dir = path.dirname(currentFilePath);\n // Use path.resolve to handle .. and . properly, then normalize to forward slashes\n const resolvedBase = Path.normalize(path.resolve(dir, importPath));\n\n // Try to resolve with extensions\n const resolvedPath = await tryResolveWithExtensions(resolvedBase);\n\n return resolvedPath;\n}\n\n/**\n * Try to resolve a file path by checking different extensions\n * TypeScript/JavaScript files can be imported without extensions\n *\n * @TODO: For better performance, we need to check the files in files orchestrator\n * instead of using the file system as we will be fetching all project files anyway.\n */\n// Cache for file existence checks to avoid redundant filesystem calls\nconst fileExistsCache = new Map<string, boolean>();\n\n/**\n * Clear the file exists cache\n * Should be called when new files are created to ensure fresh lookups\n */\nexport function clearFileExistsCache(): void {\n fileExistsCache.clear();\n}\n\nasync function cachedFileExists(filePath: string): Promise<boolean> {\n if (fileExistsCache.has(filePath)) {\n return fileExistsCache.get(filePath)!;\n }\n const exists = (await fileExistsAsync(filePath)) as boolean;\n\n // Cache ONLY positive results. A negative (\"does not exist\") answer is the\n // exact case that flips moments later: the \"add a new controller/route\" flow\n // references a file, then creates it. Caching that negative for the whole\n // process lifetime (it was cleared only on a multi-file watcher batch) left\n // a routes.ts import unresolvable after its target was created — the dep\n // edge never formed and the route module import failed, so the new API route\n // 404'd until an unrelated multi-file batch cleared the cache. That is\n // finding 60721e35 (\"backend route HMR needs a second edit\"). A file that\n // exists does not stop existing mid-resolve, so caching the hit is safe;\n // re-probing a still-missing path costs only a handful of stat calls.\n if (exists) {\n fileExistsCache.set(filePath, exists);\n }\n\n return exists;\n}\n\nasync function tryResolveWithExtensions(basePath: string): Promise<string | null> {\n // Normalize the base path first (handle Windows paths)\n const normalizedBase = Path.normalize(basePath);\n\n // List of extensions to try, in order of preference\n const extensions = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"];\n const validExtensions = new Set(extensions);\n\n // If the path already has a VALID code file extension, check if it exists\n const ext = path.extname(normalizedBase);\n if (ext && validExtensions.has(ext)) {\n // NodeNext style: `./x.js` is written, `x.ts`/`x.tsx` is on disk. The\n // loader rewrites it the same way (own-resolver `probeFile`), and a\n // co-located source wins over the literal .js.\n if ([\".js\", \".jsx\", \".mjs\", \".cjs\"].includes(ext)) {\n const stem = normalizedBase.slice(0, -ext.length);\n for (const sourceExt of [\".ts\", \".tsx\"]) {\n if (await cachedFileExists(stem + sourceExt)) {\n return stem + sourceExt;\n }\n }\n }\n if (await cachedFileExists(normalizedBase)) {\n return normalizedBase;\n }\n // If explicit extension doesn't exist, return null\n return null;\n }\n\n // Try all extensions in parallel for better performance\n const pathsToCheck = extensions.map((extension) => normalizedBase + extension);\n const results = await Promise.all(\n pathsToCheck.map(async (p) => ({ path: p, exists: await cachedFileExists(p) })),\n );\n\n // Return the first one that exists (in order of preference)\n for (const result of results) {\n if (result.exists) {\n return result.path;\n }\n }\n\n // Try index files in directory\n if (await directoryExistsAsync(normalizedBase)) {\n const indexPaths = extensions.map((extension) =>\n Path.join(normalizedBase, `index${extension}`),\n );\n const indexResults = await Promise.all(\n indexPaths.map(async (p) => ({ path: p, exists: await cachedFileExists(p) })),\n );\n\n for (const result of indexResults) {\n if (result.exists) {\n return result.path;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Check if import is a Node.js built-in module\n */\nfunction isNodeBuiltin(importPath: string): boolean {\n const builtins = [\n \"fs\",\n \"path\",\n \"http\",\n \"https\",\n \"crypto\",\n \"stream\",\n \"util\",\n \"events\",\n \"buffer\",\n \"child_process\",\n \"os\",\n \"url\",\n \"querystring\",\n \"zlib\",\n \"net\",\n \"tls\",\n \"dns\",\n \"dgram\",\n \"cluster\",\n \"worker_threads\",\n \"perf_hooks\",\n \"async_hooks\",\n \"timers\",\n \"readline\",\n \"repl\",\n \"vm\",\n \"assert\",\n \"console\",\n \"process\",\n \"v8\",\n ];\n\n // Check for node: prefix or direct builtin name\n if (importPath.startsWith(\"node:\")) return true;\n\n // `split` always yields a first element. Falling back to the whole path\n // keeps the builtin check answering about a real name rather than undefined.\n const moduleName = importPath.split(\"/\")[0] ?? importPath;\n\n return builtins.includes(moduleName);\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-config-ast.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"read-config-ast.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/read-config-ast.ts"],"sourcesContent":["/**\n * Parse one config file into an AST.\n *\n * ## Why this is not `ts.createProgram`\n *\n * It was. The typings generator built a whole TypeScript **Program** for each\n * config file just to call `program.getSourceFile(path)` on it. A Warlock\n * config imports `@warlock.js/core`, which in this monorepo resolves to\n * TypeScript **source**, so every one of those Programs resolved and parsed the\n * entire dependency graph behind it.\n *\n * Measured on the reference app's six configs, 2026-08-24:\n *\n * ```\n * ts.createProgram 82,996.00 ms 2,908 source files per program\n * ts.createSourceFile 5.12 ms\n * ratio 16,212x\n * ```\n *\n * And all of it was discarded. `getTypeChecker()` is never called anywhere in\n * the generator — every question it asks of the AST is syntactic\n * (`isImportDeclaration`, `isTypeAliasDeclaration`, `isVariableDeclaration`,\n * `isObjectLiteralExpression`). Resolving 2,908 files to answer a syntactic\n * question is 2,908 files of work thrown away.\n *\n * A previous pass had already noticed the cost and halved it, from two Programs\n * per file to one — an optimisation inside a premise that did not need to hold.\n *\n * **If a future change here needs a type checker, it needs a Program too, and\n * the cost comes back.** That is the one reason to reconsider this file.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport ts from \"typescript\";\n\nexport async function readConfigAst(filePath: string): Promise<ts.SourceFile | undefined> {\n let contents: string;\n\n try {\n contents = await readFile(filePath, \"utf-8\");\n } catch {\n // Callers already treat a missing config as \"nothing to generate\"; a throw\n // here would turn an absent optional file into a failed generation.\n return undefined;\n }\n\n return ts.createSourceFile(\n filePath,\n contents,\n ts.ScriptTarget.ESNext,\n // The generator's visitors read `node.parent`, which the Program-backed\n // source files provided for free.\n /* setParentNodes */ true,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,eAAsB,cAAc,UAAsD;CACxF,IAAI;CAEJ,IAAI;EACF,WAAW,MAAM,SAAS,UAAU,OAAO;CAC7C,QAAQ;EAGN;CACF;CAEA,OAAO,GAAG,iBACR,UACA,UACA,GAAG,aAAa,QAGK,IACvB;AACF"}
|
|
@@ -4,7 +4,7 @@ import { getHttpReadyReport } from "../http/ready-report.mjs";
|
|
|
4
4
|
import { connectorsManager } from "../connectors/connectors-manager.mjs";
|
|
5
5
|
import { colors } from "@mongez/copper";
|
|
6
6
|
|
|
7
|
-
//#region
|
|
7
|
+
//#region ../../packages/core/src/dev-server/ready-block.ts
|
|
8
8
|
/** Collect the facts from the places that own them. Pure read, no printing. */
|
|
9
9
|
function collectReadyBlockFacts(bootDurationMs) {
|
|
10
10
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ready-block.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"ready-block.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/ready-block.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { Application } from \"../application\";\nimport { connectorsManager } from \"../connectors/connectors-manager\";\nimport { getHttpReadyReport, type HttpReadyReport } from \"../http/ready-report\";\n\n/**\n * The one screen `warlock dev` exists to print.\n *\n * ## What was wrong with the lines this replaces\n *\n * Every fact was announced by whichever component discovered it, the moment it\n * discovered it, in that component's own format:\n *\n * ℹ info (21:28:36.095) [http] [routes] 14 route(s) registered\n * ✓ success (21:28:36.118) [http] [connection] Server ready at http://[::1]:2030\n * 21:28:36 ➜ Development Server is ready in 660.72ms\n *\n * The ORDER of that output is the order the work finished in, which is not a\n * fact about the application and changes between runs. There was no single\n * place stating where to point a browser, and the one URL on screen was an IPv6\n * literal most terminals will not linkify. This is a screen a developer reads a\n * hundred times a day.\n *\n * So the facts are collected (`http/ready-report.ts`) and rendered once, here,\n * after boot has actually completed.\n *\n * ## The rule this file must not break\n *\n * **Warnings never move into the block.** They are logged by whoever found them\n * at the moment they were found, which puts them ABOVE this block — visible,\n * out of the summary, and impossible to mistake for decoration. A block that\n * absorbs warnings is a block that hides them, and this file is deliberately\n * incapable of receiving one: nothing in {@link ReadyBlockFacts} can carry a\n * warning.\n *\n * ## Why the URL is not the address that was bound\n *\n * `listen()` returns what it bound (`http://[::1]:2030` for a dual-stack\n * `localhost`). The block shows `http://localhost:2030`, which resolves back to\n * that exact socket. The transform is display-only and lives in\n * `connectors/describe-server-address.ts`; nothing here touches `host`, and the\n * set of interfaces the server accepts on is unchanged.\n */\n\nexport type ReadyBlockFacts = {\n /** The bound HTTP surface, or `undefined` for a process with no HTTP server. */\n http?: HttpReadyReport;\n /** Whether a web/SSR surface (the `web` connector) serves on the same origin. */\n hasWebSurface: boolean;\n /** `development` / `production` / `test`. */\n mode: string;\n /** How long the boot took, when the caller measured it. */\n bootDurationMs?: number;\n};\n\n/** Collect the facts from the places that own them. Pure read, no printing. */\nexport function collectReadyBlockFacts(bootDurationMs?: number): ReadyBlockFacts {\n return {\n http: getHttpReadyReport(),\n // The web connector serves pages on the SAME origin as the API — one port\n // serves everything in v5 — so its presence is what makes the \"Web\" row\n // true, not a second address. Showing the row unconditionally would tell an\n // API-only app it has a page surface it does not have.\n hasWebSurface: connectorsManager.list().some((connector) => connector.name === \"web\"),\n mode: Application.environment,\n bootDurationMs,\n };\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n if (ms > 60_000) return `${(ms / 60_000).toFixed(2)}m`;\n\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\n/** ` ➜ App http://localhost:2042` */\nfunction urlRow(label: string, url: string, note?: string): string {\n const suffix = note ? ` ${colors.dim(note)}` : \"\";\n\n return ` ${colors.green(\"➜\")} ${colors.bold(label.padEnd(8))}${colors.cyan(url)}${suffix}`;\n}\n\n/** `Port` `2042`, joined into one dim summary line. */\nfunction factRow(pairs: [string, string][]): string {\n const rendered = pairs.map(([key, value]) => `${colors.dim(key)} ${colors.white(value)}`);\n\n return ` ${rendered.join(colors.dim(\" · \"))}`;\n}\n\n/**\n * Render the block as lines. Separated from printing so a test can assert the\n * exact content without capturing stdout, and so the renderer stays pure.\n */\nexport function renderReadyBlock(facts: ReadyBlockFacts): string[] {\n const lines: string[] = [\"\"];\n\n if (facts.http) {\n // A wildcard bind reaches more than loopback. `localhost` is still correct\n // and still reaches it, but the reader is told the bind is wider rather\n // than left to infer it from a URL that no longer says so.\n const note = facts.http.wildcardBind ? \"(all interfaces)\" : undefined;\n\n lines.push(urlRow(\"App\", facts.http.url, note));\n\n if (facts.hasWebSurface) {\n // Same origin, deliberately: pages and API share one port. Repeating the\n // URL is not redundancy here — it answers \"where do I open the site?\"\n // without the reader having to know that.\n lines.push(urlRow(\"Web\", facts.http.url));\n }\n\n if (facts.http.publicUrl) {\n // `publicUrl` arrives pre-labelled from `describeServerAddress`; the block\n // supplies its own label, so strip the prose and keep the address.\n const address = facts.http.publicUrl.replace(/^[^:]*:\\s*/, \"\");\n lines.push(urlRow(\"Public\", address));\n }\n }\n\n const pairs: [string, string][] = [];\n\n if (facts.http) {\n pairs.push([\"port\", String(facts.http.port)]);\n }\n\n pairs.push([\"mode\", facts.mode]);\n\n if (facts.http) {\n pairs.push([\"routes\", String(facts.http.routeCount)]);\n }\n\n if (facts.bootDurationMs !== undefined) {\n pairs.push([\"ready in\", formatDuration(facts.bootDurationMs)]);\n }\n\n lines.push(factRow(pairs));\n lines.push(\"\");\n\n return lines;\n}\n\n/** Collect, render, print. The only function the dev server needs. */\nexport function printReadyBlock(bootDurationMs?: number): void {\n for (const line of renderReadyBlock(collectReadyBlockFacts(bootDurationMs))) {\n console.log(line);\n }\n}\n"],"mappings":";;;;;;;;AAwDA,SAAgB,uBAAuB,gBAA0C;CAC/E,OAAO;EACL,MAAM,mBAAmB;EAKzB,eAAe,kBAAkB,KAAK,CAAC,CAAC,MAAM,cAAc,UAAU,SAAS,KAAK;EACpF,MAAM,YAAY;EAClB;CACF;AACF;AAEA,SAAS,eAAe,IAAoB;CAC1C,IAAI,KAAK,KAAM,OAAO,GAAG,GAAG,QAAQ,CAAC,EAAE;CACvC,IAAI,KAAK,KAAQ,OAAO,IAAI,KAAK,IAAM,CAAE,QAAQ,CAAC,EAAE;CAEpD,OAAO,IAAI,KAAK,IAAI,CAAE,QAAQ,CAAC,EAAE;AACnC;;AAGA,SAAS,OAAO,OAAe,KAAa,MAAuB;CACjE,MAAM,SAAS,OAAO,IAAI,OAAO,IAAI,IAAI,MAAM;CAE/C,OAAO,KAAK,OAAO,MAAM,GAAG,EAAE,IAAI,OAAO,KAAK,MAAM,OAAO,CAAC,CAAC,IAAI,OAAO,KAAK,GAAG,IAAI;AACtF;;AAGA,SAAS,QAAQ,OAAmC;CAGlD,OAAO,QAFU,MAAM,KAAK,CAAC,KAAK,WAAW,GAAG,OAAO,IAAI,GAAG,EAAE,GAAG,OAAO,MAAM,KAAK,GAE/D,CAAC,CAAC,KAAK,OAAO,IAAI,OAAO,CAAC;AAClD;;;;;AAMA,SAAgB,iBAAiB,OAAkC;CACjE,MAAM,QAAkB,CAAC,EAAE;CAE3B,IAAI,MAAM,MAAM;EAId,MAAM,OAAO,MAAM,KAAK,eAAe,qBAAqB;EAE5D,MAAM,KAAK,OAAO,OAAO,MAAM,KAAK,KAAK,IAAI,CAAC;EAE9C,IAAI,MAAM,eAIR,MAAM,KAAK,OAAO,OAAO,MAAM,KAAK,GAAG,CAAC;EAG1C,IAAI,MAAM,KAAK,WAAW;GAGxB,MAAM,UAAU,MAAM,KAAK,UAAU,QAAQ,cAAc,EAAE;GAC7D,MAAM,KAAK,OAAO,UAAU,OAAO,CAAC;EACtC;CACF;CAEA,MAAM,QAA4B,CAAC;CAEnC,IAAI,MAAM,MACR,MAAM,KAAK,CAAC,QAAQ,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC;CAG9C,MAAM,KAAK,CAAC,QAAQ,MAAM,IAAI,CAAC;CAE/B,IAAI,MAAM,MACR,MAAM,KAAK,CAAC,UAAU,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC;CAGtD,IAAI,MAAM,mBAAmB,QAC3B,MAAM,KAAK,CAAC,YAAY,eAAe,MAAM,cAAc,CAAC,CAAC;CAG/D,MAAM,KAAK,QAAQ,KAAK,CAAC;CACzB,MAAM,KAAK,EAAE;CAEb,OAAO;AACT;;AAGA,SAAgB,gBAAgB,gBAA+B;CAC7D,KAAK,MAAM,QAAQ,iBAAiB,uBAAuB,cAAc,CAAC,GACxE,QAAQ,IAAI,IAAI;AAEpB"}
|
|
@@ -4,7 +4,7 @@ import { restartDevServer } from "./restart-dev-server.mjs";
|
|
|
4
4
|
import { devServerShortcuts } from "./shortcuts.mjs";
|
|
5
5
|
import { colors } from "@mongez/copper";
|
|
6
6
|
|
|
7
|
-
//#region
|
|
7
|
+
//#region ../../packages/core/src/dev-server/register-dev-shortcuts.ts
|
|
8
8
|
/**
|
|
9
9
|
* Arm the dev server's standing keyboard shortcuts and print the one-line
|
|
10
10
|
* hint that tells the developer they exist.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-dev-shortcuts.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"register-dev-shortcuts.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/register-dev-shortcuts.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { devLogError } from \"./dev-logger\";\nimport type { DevelopmentServer } from \"./development-server\";\nimport { restartDevServer } from \"./restart-dev-server\";\nimport { devServerShortcuts } from \"./shortcuts\";\nimport { QUIT_EXIT_CODE } from \"./supervisor\";\n\n/**\n * Arm the dev server's standing keyboard shortcuts and print the one-line\n * hint that tells the developer they exist.\n *\n * These stay available for the whole session. The update shortcut (`u`) is\n * deliberately not here — it is armed by the update notice only when there is\n * something to update, and dropped again once it has been used.\n *\n * Entirely TTY-gated: with piped stdin (CI, a supervisor, `warlock dev | tee`)\n * nothing is registered, no hint is printed, and stdin is never touched.\n */\nexport function registerDevShortcuts(devServer: DevelopmentServer): void {\n if (!devServerShortcuts.isSupported()) {\n return;\n }\n\n devServerShortcuts.register({\n key: \"r\",\n description: \"restart the server\",\n handler: () => restart(devServer),\n });\n\n devServerShortcuts.register({\n key: \"c\",\n description: \"clear the console\",\n handler: () => console.clear(),\n });\n\n devServerShortcuts.register({\n key: \"q\",\n description: \"quit\",\n handler: () => quit(devServer),\n });\n\n devServerShortcuts.register({\n key: \"h\",\n description: \"show this help\",\n handler: printShortcuts,\n });\n\n console.log(\n ` ${colors.dim(\"press\")} ${colors.bold(colors.cyan(\"h\"))} ` +\n `${colors.dim(\"for shortcuts\")}`,\n );\n}\n\n/** `r` — bring the server back up on a clean process. */\nasync function restart(devServer: DevelopmentServer): Promise<void> {\n const restarted = await restartDevServer(devServer);\n\n if (!restarted) {\n devServerShortcuts.resume();\n devLogError(\"Restart failed — start the dev server again manually.\");\n }\n}\n\n/** `q` — the same graceful shutdown Ctrl+C performs. */\nasync function quit(devServer: DevelopmentServer): Promise<void> {\n try {\n await devServer.shutdown();\n process.exit(0);\n } catch (error) {\n devLogError(`Shutdown failed: ${(error as Error).message}`);\n process.exit(QUIT_EXIT_CODE);\n }\n}\n\n/** `h` — list whatever is armed right now, `u` included when it is. */\nfunction printShortcuts(): void {\n console.log();\n console.log(` ${colors.bold(\"Shortcuts\")}`);\n\n for (const shortcut of devServerShortcuts.list()) {\n console.log(\n ` ${colors.bold(colors.cyan(shortcut.key))} ${colors.dim(shortcut.description)}`,\n );\n }\n\n console.log(` ${colors.bold(colors.cyan(\"Ctrl+C\"))} ${colors.dim(\"quit\")}`);\n console.log();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,SAAgB,qBAAqB,WAAoC;CACvE,IAAI,CAAC,mBAAmB,YAAY,GAClC;CAGF,mBAAmB,SAAS;EAC1B,KAAK;EACL,aAAa;EACb,eAAe,QAAQ,SAAS;CAClC,CAAC;CAED,mBAAmB,SAAS;EAC1B,KAAK;EACL,aAAa;EACb,eAAe,QAAQ,MAAM;CAC/B,CAAC;CAED,mBAAmB,SAAS;EAC1B,KAAK;EACL,aAAa;EACb,eAAe,KAAK,SAAS;CAC/B,CAAC;CAED,mBAAmB,SAAS;EAC1B,KAAK;EACL,aAAa;EACb,SAAS;CACX,CAAC;CAED,QAAQ,IACN,MAAM,OAAO,IAAI,OAAO,EAAE,GAAG,OAAO,KAAK,OAAO,KAAK,GAAG,CAAC,EAAE,GACtD,OAAO,IAAI,eAAe,GACjC;AACF;;AAGA,eAAe,QAAQ,WAA6C;CAGlE,IAAI,CAAC,MAFmB,iBAAiB,SAAS,GAElC;EACd,mBAAmB,OAAO;EAC1B,YAAY,uDAAuD;CACrE;AACF;;AAGA,eAAe,KAAK,WAA6C;CAC/D,IAAI;EACF,MAAM,UAAU,SAAS;EACzB,QAAQ,KAAK,CAAC;CAChB,SAAS,OAAO;EACd,YAAY,oBAAqB,MAAgB,SAAS;EAC1D,QAAQ,OAAmB;CAC7B;AACF;;AAGA,SAAS,iBAAuB;CAC9B,QAAQ,IAAI;CACZ,QAAQ,IAAI,KAAK,OAAO,KAAK,WAAW,GAAG;CAE3C,KAAK,MAAM,YAAY,mBAAmB,KAAK,GAC7C,QAAQ,IACN,QAAQ,OAAO,KAAK,OAAO,KAAK,SAAS,GAAG,CAAC,EAAE,IAAI,OAAO,IAAI,SAAS,WAAW,GACpF;CAGF,QAAQ,IAAI,QAAQ,OAAO,KAAK,OAAO,KAAK,QAAQ,CAAC,EAAE,IAAI,OAAO,IAAI,MAAM,GAAG;CAC/E,QAAQ,IAAI;AACd"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { connectorsManager } from "../connectors/connectors-manager.mjs";
|
|
2
2
|
import { devLogWarn } from "./dev-logger.mjs";
|
|
3
3
|
|
|
4
|
-
//#region
|
|
4
|
+
//#region ../../packages/core/src/dev-server/register-installed-devtools.ts
|
|
5
5
|
const DEVTOOLS_PACKAGE = "@warlock.js/devtools";
|
|
6
6
|
/**
|
|
7
7
|
* Register `@warlock.js/devtools` when the app has it installed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-installed-devtools.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"register-installed-devtools.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/register-installed-devtools.ts"],"sourcesContent":["import { connectorsManager } from \"../connectors/connectors-manager\";\nimport type { Connector } from \"../connectors/types\";\nimport { devLogWarn } from \"./dev-logger\";\n\nconst DEVTOOLS_PACKAGE = \"@warlock.js/devtools\";\n\ntype DevtoolsModule = {\n devtoolsConnector?: () => Connector;\n};\n\n/**\n * Register `@warlock.js/devtools` when the app has it installed.\n *\n * Called by `warlock dev` only, before the late connector phase, so the app\n * never names devtools in `warlock.config.ts`. That matters because devtools\n * is a DEV dependency: a production install omits it, and a config import of\n * it would fail to resolve there. The production entry never calls this.\n *\n * Skipped when a connector named `devtools` is already registered (an app\n * that wires it by hand keeps control). A missing package is the normal case\n * and stays silent; any other load failure is reported and ignored, because\n * a dev tool must never stop the app from booting.\n */\nexport async function registerInstalledDevtools(\n load: () => Promise<DevtoolsModule> = () => import(DEVTOOLS_PACKAGE),\n): Promise<boolean> {\n if (connectorsManager.has(\"devtools\")) {\n return false;\n }\n\n let devtools: DevtoolsModule;\n\n try {\n devtools = await load();\n } catch (error) {\n if (!isMissingPackage(error)) {\n devLogWarn(`${DEVTOOLS_PACKAGE} is installed but failed to load: ${describe(error)}`);\n }\n\n return false;\n }\n\n if (typeof devtools.devtoolsConnector !== \"function\") {\n devLogWarn(`${DEVTOOLS_PACKAGE} does not export devtoolsConnector(); it was not started`);\n\n return false;\n }\n\n connectorsManager.register(devtools.devtoolsConnector());\n\n return true;\n}\n\n/** True when the error says the devtools package itself is not installed. */\nfunction isMissingPackage(error: unknown): boolean {\n const code = (error as { code?: unknown } | undefined)?.code;\n\n if (code !== \"ERR_MODULE_NOT_FOUND\" && code !== \"MODULE_NOT_FOUND\") {\n return false;\n }\n\n // A missing module INSIDE an installed devtools is a broken install, not an\n // absent package — only the package's own name counts as \"not installed\".\n return (\n describe(error).includes(`'${DEVTOOLS_PACKAGE}'`) ||\n describe(error).includes(`\"${DEVTOOLS_PACKAGE}\"`)\n );\n}\n\nfunction describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":";;;;AAIA,MAAM,mBAAmB;;;;;;;;;;;;;;AAmBzB,eAAsB,0BACpB,aAA4C,OAAO,mBACjC;CAClB,IAAI,kBAAkB,IAAI,UAAU,GAClC,OAAO;CAGT,IAAI;CAEJ,IAAI;EACF,WAAW,MAAM,KAAK;CACxB,SAAS,OAAO;EACd,IAAI,CAAC,iBAAiB,KAAK,GACzB,WAAW,GAAG,iBAAiB,oCAAoC,SAAS,KAAK,GAAG;EAGtF,OAAO;CACT;CAEA,IAAI,OAAO,SAAS,sBAAsB,YAAY;EACpD,WAAW,GAAG,iBAAiB,yDAAyD;EAExF,OAAO;CACT;CAEA,kBAAkB,SAAS,SAAS,kBAAkB,CAAC;CAEvD,OAAO;AACT;;AAGA,SAAS,iBAAiB,OAAyB;CACjD,MAAM,OAAQ,OAA0C;CAExD,IAAI,SAAS,0BAA0B,SAAS,oBAC9C,OAAO;CAKT,OACE,SAAS,KAAK,CAAC,CAAC,SAAS,IAAI,iBAAiB,EAAE,KAChD,SAAS,KAAK,CAAC,CAAC,SAAS,IAAI,iBAAiB,EAAE;AAEpD;AAEA,SAAS,SAAS,OAAwB;CACxC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D"}
|
|
@@ -2,7 +2,7 @@ import { devLogError, devServeLog } from "./dev-logger.mjs";
|
|
|
2
2
|
import { isDevWorker } from "./supervisor.mjs";
|
|
3
3
|
import { colors } from "@mongez/copper";
|
|
4
4
|
|
|
5
|
-
//#region
|
|
5
|
+
//#region ../../packages/core/src/dev-server/restart-dev-server.ts
|
|
6
6
|
/**
|
|
7
7
|
* Restart `warlock dev`.
|
|
8
8
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restart-dev-server.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"restart-dev-server.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/restart-dev-server.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { devLogError, devServeLog } from \"./dev-logger\";\nimport type { DevelopmentServer } from \"./development-server\";\nimport { isDevWorker, RESTART_EXIT_CODE } from \"./supervisor\";\n\n/**\n * Restart `warlock dev`.\n *\n * There is no way to un-load an ES module graph, so a restart is a fresh\n * process. This one doesn't create it: the supervisor that launched us does.\n * We shut down cleanly — which frees the http port before the replacement\n * binds it — and exit with {@link RESTART_EXIT_CODE}, which the supervisor\n * reads as \"spawn me again\".\n *\n * Never returns on the happy path. Returns `false` when a restart isn't\n * possible — no supervisor (a programmatic `startDevelopmentServer` call), or\n * a shutdown that failed — so the caller can carry on with the server it has.\n */\nexport async function restartDevServer(devServer: DevelopmentServer): Promise<boolean> {\n if (!isDevWorker()) {\n devLogError(\"Restart is unavailable — this server was not started by `warlock dev`.\");\n return false;\n }\n\n devServeLog(colors.cyanBright(\"Restarting the development server…\"));\n\n try {\n await devServer.shutdown();\n } catch (error) {\n devLogError(`Shutdown before restart failed: ${(error as Error).message}`);\n return false;\n }\n\n process.exit(RESTART_EXIT_CODE);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,eAAsB,iBAAiB,WAAgD;CACrF,IAAI,CAAC,YAAY,GAAG;EAClB,YAAY,wEAAwE;EACpF,OAAO;CACT;CAEA,YAAY,OAAO,WAAW,oCAAoC,CAAC;CAEnE,IAAI;EACF,MAAM,UAAU,SAAS;CAC3B,SAAS,OAAO;EACd,YAAY,mCAAoC,MAAgB,SAAS;EACzE,OAAO;CACT;CAEA,QAAQ,OAAsB;AAChC"}
|
|
@@ -3,7 +3,7 @@ import { readFile, unlink } from "node:fs/promises";
|
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { moduleResolve } from "import-meta-resolve";
|
|
5
5
|
|
|
6
|
-
//#region
|
|
6
|
+
//#region ../../packages/core/src/dev-server/route-types-publisher.ts
|
|
7
7
|
const WEB_PACKAGE = "@warlock.js/web";
|
|
8
8
|
const WEB_BUILD_PACKAGE = "@warlock.js/web/build";
|
|
9
9
|
const GENERATED_ROUTE_TYPES = ".warlock/typings/web-routes.d.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-types-publisher.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"route-types-publisher.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/route-types-publisher.ts"],"sourcesContent":["import { moduleResolve } from \"import-meta-resolve\";\nimport { readFile, unlink } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { NamedApiRoute } from \"../router/types\";\n\nconst WEB_PACKAGE = \"@warlock.js/web\";\nconst WEB_BUILD_PACKAGE = \"@warlock.js/web/build\";\nconst GENERATED_ROUTE_TYPES = \".warlock/typings/web-routes.d.ts\";\nconst GENERATED_ROUTE_TYPES_HEADER = \"// AUTO-GENERATED by @warlock.js/web -- do not edit.\";\n\ntype WebBuildModule = {\n writeCurrentRouteTypes?: (input: {\n appRoot: string;\n apis: readonly NamedApiRoute[];\n }) => Promise<unknown>;\n};\n\nexport type RouteTypesPublisherPorts = Readonly<{\n resolveModule: (specifier: string, parent: URL) => URL;\n importModule: (url: URL) => Promise<WebBuildModule>;\n}>;\n\nconst defaultPorts: RouteTypesPublisherPorts = {\n resolveModule: moduleResolve,\n importModule: async (url) => (await import(url.href)) as WebBuildModule,\n};\n\nfunction isAbsentOptionalWebPackage(thrown: unknown): boolean {\n return (\n typeof thrown === \"object\" &&\n thrown !== null &&\n \"code\" in thrown &&\n (thrown as { code?: unknown }).code === \"ERR_MODULE_NOT_FOUND\" &&\n thrown instanceof Error &&\n thrown.message.includes(`Cannot find package '${WEB_PACKAGE}'`)\n );\n}\n\n/**\n * Publish dev route declarations through the consuming app's optional Web\n * build entry. A Core-only app performs no work; an installed but incompatible\n * Web package fails loudly instead of leaving stale generated declarations.\n */\nexport async function publishCurrentRouteTypes(\n appRoot: string,\n apis: readonly NamedApiRoute[],\n ports: RouteTypesPublisherPorts = defaultPorts,\n): Promise<boolean> {\n const projectUrl = pathToFileURL(resolve(appRoot, \"package.json\"));\n\n try {\n ports.resolveModule(WEB_PACKAGE, projectUrl);\n } catch (error) {\n if (isAbsentOptionalWebPackage(error)) {\n await clearOwnedRouteTypes(appRoot);\n return false;\n }\n throw error;\n }\n\n const buildModuleUrl = ports.resolveModule(WEB_BUILD_PACKAGE, projectUrl);\n const buildModule = await ports.importModule(buildModuleUrl);\n\n if (typeof buildModule.writeCurrentRouteTypes !== \"function\") {\n throw new Error(\n `${WEB_BUILD_PACKAGE} does not export writeCurrentRouteTypes. Upgrade @warlock.js/web to a compatible version.`,\n );\n }\n\n await buildModule.writeCurrentRouteTypes({ appRoot, apis });\n return true;\n}\n\n/** Remove only this integration's header-proven generated declaration file. */\nexport async function clearOwnedRouteTypes(appRoot: string): Promise<boolean> {\n const target = resolve(appRoot, GENERATED_ROUTE_TYPES);\n\n let content: string;\n try {\n content = await readFile(target, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n }\n\n if (!content.startsWith(GENERATED_ROUTE_TYPES_HEADER)) return false;\n await unlink(target);\n return true;\n}\n"],"mappings":";;;;;;AAMA,MAAM,cAAc;AACpB,MAAM,oBAAoB;AAC1B,MAAM,wBAAwB;AAC9B,MAAM,+BAA+B;AAcrC,MAAM,eAAyC;CAC7C,eAAe;CACf,cAAc,OAAO,QAAS,MAAM,OAAO,IAAI;AACjD;AAEA,SAAS,2BAA2B,QAA0B;CAC5D,OACE,OAAO,WAAW,YAClB,WAAW,QACX,UAAU,UACT,OAA8B,SAAS,0BACxC,kBAAkB,SAClB,OAAO,QAAQ,SAAS,wBAAwB,YAAY,EAAE;AAElE;;;;;;AAOA,eAAsB,yBACpB,SACA,MACA,QAAkC,cAChB;CAClB,MAAM,aAAa,cAAc,QAAQ,SAAS,cAAc,CAAC;CAEjE,IAAI;EACF,MAAM,cAAc,aAAa,UAAU;CAC7C,SAAS,OAAO;EACd,IAAI,2BAA2B,KAAK,GAAG;GACrC,MAAM,qBAAqB,OAAO;GAClC,OAAO;EACT;EACA,MAAM;CACR;CAEA,MAAM,iBAAiB,MAAM,cAAc,mBAAmB,UAAU;CACxE,MAAM,cAAc,MAAM,MAAM,aAAa,cAAc;CAE3D,IAAI,OAAO,YAAY,2BAA2B,YAChD,MAAM,IAAI,MACR,GAAG,kBAAkB,0FACvB;CAGF,MAAM,YAAY,uBAAuB;EAAE;EAAS;CAAK,CAAC;CAC1D,OAAO;AACT;;AAGA,eAAsB,qBAAqB,SAAmC;CAC5E,MAAM,SAAS,QAAQ,SAAS,qBAAqB;CAErD,IAAI;CACJ,IAAI;EACF,UAAU,MAAM,SAAS,QAAQ,MAAM;CACzC,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAAU,OAAO;EAC/D,MAAM;CACR;CAEA,IAAI,CAAC,QAAQ,WAAW,4BAA4B,GAAG,OAAO;CAC9D,MAAM,OAAO,MAAM;CACnB,OAAO;AACT"}
|
|
@@ -2,7 +2,7 @@ import { warlockPath } from "../utils/paths.mjs";
|
|
|
2
2
|
import "../utils/index.mjs";
|
|
3
3
|
import { runTypingsContributions } from "../production/build-contributions.mjs";
|
|
4
4
|
|
|
5
|
-
//#region
|
|
5
|
+
//#region ../../packages/core/src/dev-server/run-connector-typings.ts
|
|
6
6
|
/**
|
|
7
7
|
* Let connectors write their own typings during `warlock generate.typings`.
|
|
8
8
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-connector-typings.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"run-connector-typings.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/run-connector-typings.ts"],"sourcesContent":["import type { Connector } from \"../connectors/types\";\nimport { runTypingsContributions } from \"../production/build-contributions\";\nimport type { NamedApiRoute } from \"../router/types\";\nimport { warlockPath } from \"../utils\";\nimport type { ResolvedBuildConfig } from \"../production/resolve-build-config\";\n\nexport type ConnectorTypingsInput = {\n connectors: readonly Connector[];\n appRoot: string;\n /** Resolved lazily: an app with no typings hook never needs a loaded build config. */\n options(): ResolvedBuildConfig;\n /** Fresh registration-only named API route snapshot (a child process in production). */\n collectRoutes(): Promise<readonly NamedApiRoute[]>;\n};\n\n/**\n * Let connectors write their own typings during `warlock generate.typings`.\n *\n * Core cannot import web, so this drains the `typings` hook of each connector's\n * `build` contribution — the seam `warlock build` reads. The named API snapshot\n * (a child process) is collected only when a hook exists AND the web connector\n * is configured, exactly as the builder does; an API-only app pays nothing and\n * cannot fail here.\n */\nexport async function runConnectorTypings({\n connectors,\n appRoot,\n options,\n collectRoutes,\n}: ConnectorTypingsInput): Promise<void> {\n if (!connectors.some((connector) => Boolean(connector.build?.typings))) return;\n\n const namedApiRoutes = connectors.some((connector) => connector.name === \"web\")\n ? await collectRoutes()\n : undefined;\n\n await runTypingsContributions(connectors, {\n productionDir: warlockPath(\"production\"),\n appRoot,\n options: options(),\n namedApiRoutes,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;AAwBA,eAAsB,oBAAoB,EACxC,YACA,SACA,SACA,iBACuC;CACvC,IAAI,CAAC,WAAW,MAAM,cAAc,QAAQ,UAAU,OAAO,OAAO,CAAC,GAAG;CAExE,MAAM,iBAAiB,WAAW,MAAM,cAAc,UAAU,SAAS,KAAK,IAC1E,MAAM,cAAc,IACpB;CAEJ,MAAM,wBAAwB,YAAY;EACxC,eAAe,YAAY,YAAY;EACvC;EACA,SAAS,QAAQ;EACjB;CACF,CAAC;AACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-typings-generation.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"run-typings-generation.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/run-typings-generation.ts"],"sourcesContent":["/**\n * Run type generation, in this process.\n *\n * ## Why this is not a spawn\n *\n * It used to be. `type-generator.ts` ran `npx warlock generate.typings`, which\n * resolves to `core/bin/warlock.js` → `import \"../esm/cli/start.mjs\"`. This\n * monorepo consumes packages as TypeScript **source**, so there is no `esm/`\n * directory: every dev boot printed `✗ Failed to generate types`, and an\n * `ERR_MODULE_NOT_FOUND` stack rode along inside an otherwise green core suite.\n *\n * Spawning was the mistake underneath the broken path. The CLI command it\n * launched does two things — add the config files to the orchestrator, then\n * call `typeGenerator.generateAll()` — and the dev server has **already**\n * initialised that orchestrator with those files at boot. So it paid for a\n * second Node process to rediscover state it was holding, in order to call a\n * method that lives in the same module it was calling from.\n *\n * Launching a binary through `npx` is separately prohibited in this workspace:\n * resolve and invoke directly.\n *\n * ## Why a failure here is not fatal\n *\n * Generated typings are editor autocomplete. A dev server that refused to boot\n * because it could not write them would be a worse defect than the one this\n * replaces, so this never throws — but it does say **why**, which the old\n * `Failed to generate types` did not. A failure message that names no cause\n * sends the reader hunting, which is most of what the old line achieved.\n */\n\nexport type TypingsGenerationPorts = {\n /** `typeGenerator.generateAll()` in production; a fake in tests. */\n generate(): Promise<void>;\n info(message: string): void;\n success(message: string): void;\n error(message: string): void;\n};\n\nfunction describeCause(thrown: unknown): string {\n if (thrown instanceof Error) return thrown.message;\n\n return String(thrown);\n}\n\nexport async function runTypingsGeneration(ports: TypingsGenerationPorts): Promise<void> {\n ports.info(\"Checking for types generation\");\n\n try {\n await ports.generate();\n\n ports.success(\"Types generated successfully\");\n } catch (thrown) {\n ports.error(`Failed to generate types: ${describeCause(thrown)}`);\n }\n}\n"],"mappings":";AAsCA,SAAS,cAAc,QAAyB;CAC9C,IAAI,kBAAkB,OAAO,OAAO,OAAO;CAE3C,OAAO,OAAO,MAAM;AACtB;AAEA,eAAsB,qBAAqB,OAA8C;CACvF,MAAM,KAAK,+BAA+B;CAE1C,IAAI;EACF,MAAM,MAAM,SAAS;EAErB,MAAM,QAAQ,8BAA8B;CAC9C,SAAS,QAAQ;EACf,MAAM,MAAM,6BAA6B,cAAc,MAAM,GAAG;CAClE;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortcuts.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"shortcuts.mjs","names":[],"sources":["../../../../../../../../packages/core/src/dev-server/shortcuts.ts"],"sourcesContent":["import readline from \"node:readline\";\n\n/**\n * A single-keypress shortcut offered by the dev server while it runs.\n */\nexport type DevServerShortcut = {\n /** The key that triggers it, e.g. `\"u\"`. Matched case-insensitively. */\n key: string;\n /** Short human label, used when we print the available shortcuts. */\n description: string;\n /** What to run when the key is pressed. Rejections are swallowed. */\n handler: () => void | Promise<void>;\n};\n\n/**\n * Single-keypress shortcuts for the dev server (`press u to update`, …).\n *\n * Reading one key at a time requires putting stdin into raw mode, which\n * means this process — not the terminal driver — becomes responsible for\n * `Ctrl+C`. The manager therefore re-raises `SIGINT` itself so the existing\n * graceful-shutdown handlers keep working exactly as before.\n *\n * Everything is opt-in and self-guarding: with no TTY (piped output, CI,\n * a supervisor) `register()` reports `false` and stdin is never touched, so\n * callers can fall back to printing a plain \"run `npx warlock update`\" hint.\n */\nexport class DevServerShortcuts {\n private readonly shortcuts = new Map<string, DevServerShortcut>();\n\n /** Whether we currently hold stdin in raw mode. */\n private listening = false;\n\n /** Set while a handler runs, so a second keypress can't re-enter it. */\n private busy = false;\n\n private keypressListener?: (character: string, key: KeypressEvent) => void;\n\n /**\n * @param explicitInput The stream to read keys from. Tests pass a fake TTY;\n * production code omits it and gets `process.stdin`,\n * resolved lazily — see {@link input}.\n * @param onInterrupt What `Ctrl+C` does once raw mode has taken it away\n * from the terminal driver. Defaults to re-raising\n * `SIGINT`.\n */\n public constructor(\n private readonly explicitInput?: NodeJS.ReadStream,\n private readonly onInterrupt: () => void = raiseInterrupt,\n ) {}\n\n /**\n * The stream to read keys from, resolved on first USE rather than at\n * construction.\n *\n * `devServerShortcuts` below is a process-wide singleton, and every CLI\n * command loads it merely by importing `dev-server.command.ts` —\n * `framework-cli-commands.ts` statically imports every command module up\n * front, for `warlock add`/`migrate`/`routes`/etc. just as much as for\n * `warlock dev`. A constructor-default of `process.stdin` used to run at\n * THAT import, not at `register()`, so simply running any command touched\n * `process.stdin` and made Node construct a real stdin handle nobody asked\n * for — including one-shot commands that never call `register()` and have\n * no terminal to manage. A getter defers the touch to the methods that\n * actually need a stream (`isSupported`/`register`/`listen`/`release`),\n * none of which run for a command that never offers a shortcut.\n */\n private get input(): NodeJS.ReadStream {\n return this.explicitInput ?? process.stdin;\n }\n\n /**\n * Whether the current terminal can deliver individual keypresses. False in\n * CI, when stdin is a pipe, and in any non-interactive shell.\n */\n public isSupported(): boolean {\n return Boolean(this.input.isTTY && typeof this.input.setRawMode === \"function\");\n }\n\n /**\n * Offer a shortcut. Returns whether it was actually registered — `false`\n * means the terminal can't support keypresses and the caller should print\n * a copy-and-paste command instead.\n */\n public register(shortcut: DevServerShortcut): boolean {\n if (!this.isSupported()) {\n return false;\n }\n\n this.shortcuts.set(shortcut.key.toLowerCase(), shortcut);\n this.listen();\n\n return true;\n }\n\n /** Every armed shortcut, in the order it was registered. */\n public list(): DevServerShortcut[] {\n return [...this.shortcuts.values()];\n }\n\n /** Drop a shortcut, releasing the terminal once none are left. */\n public unregister(key: string): void {\n this.shortcuts.delete(key.toLowerCase());\n\n if (this.shortcuts.size === 0) {\n this.release();\n }\n }\n\n /**\n * Hand the terminal back: leave raw mode and stop listening. Call this\n * before spawning a child process that needs stdin (the package manager\n * install), and on shutdown. Registered shortcuts are kept, so `register()`\n * (or `resume()`) can take the terminal again afterwards.\n */\n public release(): void {\n if (!this.listening) {\n return;\n }\n\n this.listening = false;\n\n if (this.keypressListener) {\n this.input.off(\"keypress\", this.keypressListener);\n this.keypressListener = undefined;\n }\n\n if (this.input.isTTY) {\n this.input.setRawMode(false);\n }\n\n this.input.pause();\n }\n\n /** Re-take the terminal after a {@link release}, if shortcuts remain. */\n public resume(): void {\n if (this.shortcuts.size > 0) {\n this.listen();\n }\n }\n\n /** Start (or keep) listening for keypresses. */\n private listen(): void {\n if (this.listening || !this.isSupported()) {\n return;\n }\n\n this.listening = true;\n\n readline.emitKeypressEvents(this.input);\n this.input.setRawMode(true);\n this.input.resume();\n\n this.keypressListener = (_character, key) => {\n void this.handleKeypress(key);\n };\n\n this.input.on(\"keypress\", this.keypressListener);\n }\n\n /**\n * Route a keypress to its shortcut. In raw mode the terminal no longer\n * turns `Ctrl+C` into a signal for us, so we translate it back into a\n * `SIGINT` and let the dev server's shutdown handlers take it from there.\n */\n private async handleKeypress(key: KeypressEvent | undefined): Promise<void> {\n if (!key) {\n return;\n }\n\n if ((key.ctrl && (key.name === \"c\" || key.name === \"d\")) || key.sequence === \"\\u0003\") {\n this.release();\n this.onInterrupt();\n return;\n }\n\n if (this.busy) {\n return;\n }\n\n const shortcut = key.name ? this.shortcuts.get(key.name.toLowerCase()) : undefined;\n\n if (!shortcut) {\n return;\n }\n\n this.busy = true;\n\n try {\n await shortcut.handler();\n } catch {\n // A shortcut is a convenience — never let it take the dev server down.\n } finally {\n this.busy = false;\n }\n }\n}\n\n/** Re-raise the interrupt the terminal would have sent outside raw mode. */\nfunction raiseInterrupt(): void {\n // `process.kill(pid, \"SIGINT\")` is TerminateProcess on Windows, skipping the\n // graceful shutdown; emitting runs the registered handlers on every OS.\n process.emit(\"SIGINT\");\n}\n\n/** The keypress shape emitted by `readline.emitKeypressEvents`. */\ntype KeypressEvent = {\n name?: string;\n sequence?: string;\n ctrl?: boolean;\n meta?: boolean;\n shift?: boolean;\n};\n\n/** Process-wide shortcuts for the running dev server. */\nexport const devServerShortcuts = new DevServerShortcuts();\n"],"mappings":";;;;;;;;;;;;;;;AA0BA,IAAa,qBAAb,MAAgC;;;;;;;;;CAmB9B,AAAO,YACL,AAAiB,eACjB,AAAiB,cAA0B,gBAC3C;EAFiB;EACA;mCApBU,IAAI,IAA+B;mBAG5C;cAGL;CAeZ;;;;;;;;;;;;;;;;;CAkBH,IAAY,QAA2B;EACrC,OAAO,KAAK,iBAAiB,QAAQ;CACvC;;;;;CAMA,AAAO,cAAuB;EAC5B,OAAO,QAAQ,KAAK,MAAM,SAAS,OAAO,KAAK,MAAM,eAAe,UAAU;CAChF;;;;;;CAOA,AAAO,SAAS,UAAsC;EACpD,IAAI,CAAC,KAAK,YAAY,GACpB,OAAO;EAGT,KAAK,UAAU,IAAI,SAAS,IAAI,YAAY,GAAG,QAAQ;EACvD,KAAK,OAAO;EAEZ,OAAO;CACT;;CAGA,AAAO,OAA4B;EACjC,OAAO,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC;CACpC;;CAGA,AAAO,WAAW,KAAmB;EACnC,KAAK,UAAU,OAAO,IAAI,YAAY,CAAC;EAEvC,IAAI,KAAK,UAAU,SAAS,GAC1B,KAAK,QAAQ;CAEjB;;;;;;;CAQA,AAAO,UAAgB;EACrB,IAAI,CAAC,KAAK,WACR;EAGF,KAAK,YAAY;EAEjB,IAAI,KAAK,kBAAkB;GACzB,KAAK,MAAM,IAAI,YAAY,KAAK,gBAAgB;GAChD,KAAK,mBAAmB;EAC1B;EAEA,IAAI,KAAK,MAAM,OACb,KAAK,MAAM,WAAW,KAAK;EAG7B,KAAK,MAAM,MAAM;CACnB;;CAGA,AAAO,SAAe;EACpB,IAAI,KAAK,UAAU,OAAO,GACxB,KAAK,OAAO;CAEhB;;CAGA,AAAQ,SAAe;EACrB,IAAI,KAAK,aAAa,CAAC,KAAK,YAAY,GACtC;EAGF,KAAK,YAAY;EAEjB,SAAS,mBAAmB,KAAK,KAAK;EACtC,KAAK,MAAM,WAAW,IAAI;EAC1B,KAAK,MAAM,OAAO;EAElB,KAAK,oBAAoB,YAAY,QAAQ;GAC3C,AAAK,KAAK,eAAe,GAAG;EAC9B;EAEA,KAAK,MAAM,GAAG,YAAY,KAAK,gBAAgB;CACjD;;;;;;CAOA,MAAc,eAAe,KAA+C;EAC1E,IAAI,CAAC,KACH;EAGF,IAAK,IAAI,SAAS,IAAI,SAAS,OAAO,IAAI,SAAS,QAAS,IAAI,aAAa,KAAU;GACrF,KAAK,QAAQ;GACb,KAAK,YAAY;GACjB;EACF;EAEA,IAAI,KAAK,MACP;EAGF,MAAM,WAAW,IAAI,OAAO,KAAK,UAAU,IAAI,IAAI,KAAK,YAAY,CAAC,IAAI;EAEzE,IAAI,CAAC,UACH;EAGF,KAAK,OAAO;EAEZ,IAAI;GACF,MAAM,SAAS,QAAQ;EACzB,QAAQ,CAER,UAAU;GACR,KAAK,OAAO;EACd;CACF;AACF;;AAGA,SAAS,iBAAuB;CAG9B,QAAQ,KAAK,QAAQ;AACvB;;AAYA,MAAa,qBAAqB,IAAI,mBAAmB"}
|