@webda/core 4.0.0-beta.1 → 4.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +252 -0
- package/lib/application/application.d.ts +437 -0
- package/lib/application/application.d.ts.map +1 -0
- package/lib/application/application.js +792 -0
- package/lib/application/application.js.map +1 -0
- package/lib/application/hooks.d.ts +34 -0
- package/lib/application/hooks.d.ts.map +1 -0
- package/lib/application/hooks.js +57 -0
- package/lib/application/hooks.js.map +1 -0
- package/lib/application/iapplication.d.ts +43 -0
- package/lib/application/iapplication.d.ts.map +1 -0
- package/lib/application/iapplication.js +2 -0
- package/lib/application/iapplication.js.map +1 -0
- package/lib/application/iconfiguration.d.ts +176 -0
- package/lib/application/iconfiguration.d.ts.map +1 -0
- package/lib/application/iconfiguration.js +8 -0
- package/lib/application/iconfiguration.js.map +1 -0
- package/lib/application/runner.d.ts +8 -0
- package/lib/application/runner.d.ts.map +1 -0
- package/lib/application/runner.js +26 -0
- package/lib/application/runner.js.map +1 -0
- package/lib/application/unpackedapplication.d.ts +104 -0
- package/lib/application/unpackedapplication.d.ts.map +1 -0
- package/lib/application/unpackedapplication.js +492 -0
- package/lib/application/unpackedapplication.js.map +1 -0
- package/lib/bin/cli-phase.d.ts +28 -0
- package/lib/bin/cli-phase.d.ts.map +1 -0
- package/lib/bin/cli-phase.js +44 -0
- package/lib/bin/cli-phase.js.map +1 -0
- package/lib/bin/cli.d.ts +161 -0
- package/lib/bin/cli.d.ts.map +1 -0
- package/lib/bin/cli.js +828 -0
- package/lib/bin/cli.js.map +1 -0
- package/lib/bin/launcher.d.ts +3 -0
- package/lib/bin/launcher.d.ts.map +1 -0
- package/lib/bin/launcher.js +50 -0
- package/lib/bin/launcher.js.map +1 -0
- package/lib/cache/cache.d.ts +33 -0
- package/lib/cache/cache.d.ts.map +1 -0
- package/lib/cache/cache.js +8 -0
- package/lib/cache/cache.js.map +1 -0
- package/lib/{services/configuration.d.ts → configurations/configuration.service.d.ts} +58 -49
- package/lib/configurations/configuration.service.d.ts.map +1 -0
- package/lib/configurations/configuration.service.js +248 -0
- package/lib/configurations/configuration.service.js.map +1 -0
- package/lib/configurations/fileconfiguration.service.d.ts +30 -0
- package/lib/configurations/fileconfiguration.service.d.ts.map +1 -0
- package/lib/configurations/fileconfiguration.service.js +65 -0
- package/lib/configurations/fileconfiguration.service.js.map +1 -0
- package/lib/configurations/kubernetesconfiguration.service.d.ts +43 -0
- package/lib/configurations/kubernetesconfiguration.service.d.ts.map +1 -0
- package/lib/configurations/kubernetesconfiguration.service.js +83 -0
- package/lib/configurations/kubernetesconfiguration.service.js.map +1 -0
- package/lib/contexts/execution.d.ts +33 -0
- package/lib/contexts/execution.d.ts.map +1 -0
- package/lib/contexts/execution.js +73 -0
- package/lib/contexts/execution.js.map +1 -0
- package/lib/contexts/globalcontext.d.ts +29 -0
- package/lib/contexts/globalcontext.d.ts.map +1 -0
- package/lib/contexts/globalcontext.js +38 -0
- package/lib/contexts/globalcontext.js.map +1 -0
- package/lib/{utils → contexts}/httpcontext.d.ts +45 -19
- package/lib/contexts/httpcontext.d.ts.map +1 -0
- package/lib/{utils → contexts}/httpcontext.js +102 -34
- package/lib/contexts/httpcontext.js.map +1 -0
- package/lib/contexts/icontext.d.ts +236 -0
- package/lib/contexts/icontext.d.ts.map +1 -0
- package/lib/contexts/icontext.js +230 -0
- package/lib/contexts/icontext.js.map +1 -0
- package/lib/contexts/operationcontext.d.ts +179 -0
- package/lib/contexts/operationcontext.d.ts.map +1 -0
- package/lib/contexts/operationcontext.js +358 -0
- package/lib/contexts/operationcontext.js.map +1 -0
- package/lib/contexts/simplecontext.d.ts +31 -0
- package/lib/contexts/simplecontext.d.ts.map +1 -0
- package/lib/contexts/simplecontext.js +45 -0
- package/lib/contexts/simplecontext.js.map +1 -0
- package/lib/contexts/webcontext.d.ts +218 -0
- package/lib/contexts/webcontext.d.ts.map +1 -0
- package/lib/contexts/webcontext.js +389 -0
- package/lib/contexts/webcontext.js.map +1 -0
- package/lib/core/authorizer.d.ts +23 -0
- package/lib/core/authorizer.d.ts.map +1 -0
- package/lib/core/authorizer.js +17 -0
- package/lib/core/authorizer.js.map +1 -0
- package/lib/core/core.d.ts +225 -0
- package/lib/core/core.d.ts.map +1 -0
- package/lib/core/core.js +576 -0
- package/lib/core/core.js.map +1 -0
- package/lib/core/hooks.d.ts +72 -0
- package/lib/core/hooks.d.ts.map +1 -0
- package/lib/core/hooks.js +73 -0
- package/lib/core/hooks.js.map +1 -0
- package/lib/core/icore.d.ts +249 -0
- package/lib/core/icore.d.ts.map +1 -0
- package/lib/core/icore.js +15 -0
- package/lib/core/icore.js.map +1 -0
- package/lib/core/instancestorage.d.ts +61 -0
- package/lib/core/instancestorage.d.ts.map +1 -0
- package/lib/core/instancestorage.js +75 -0
- package/lib/core/instancestorage.js.map +1 -0
- package/lib/core/operations.d.ts +181 -0
- package/lib/core/operations.d.ts.map +1 -0
- package/lib/core/operations.js +559 -0
- package/lib/core/operations.js.map +1 -0
- package/lib/errors/errors.d.ts +126 -0
- package/lib/errors/errors.d.ts.map +1 -0
- package/lib/errors/errors.js +165 -0
- package/lib/errors/errors.js.map +1 -0
- package/lib/events/asynceventemitter.d.ts +159 -0
- package/lib/events/asynceventemitter.d.ts.map +1 -0
- package/lib/events/asynceventemitter.js +152 -0
- package/lib/events/asynceventemitter.js.map +1 -0
- package/lib/events/events.d.ts +112 -0
- package/lib/events/events.d.ts.map +1 -0
- package/lib/events/events.js +45 -0
- package/lib/events/events.js.map +1 -0
- package/lib/index.d.ts +84 -51
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +82 -59
- package/lib/index.js.map +1 -1
- package/lib/loggers/console.service.d.ts +24 -0
- package/lib/loggers/console.service.d.ts.map +1 -0
- package/lib/loggers/console.service.js +30 -0
- package/lib/loggers/console.service.js.map +1 -0
- package/lib/loggers/file.service.d.ts +25 -0
- package/lib/loggers/file.service.d.ts.map +1 -0
- package/lib/loggers/file.service.js +33 -0
- package/lib/loggers/file.service.js.map +1 -0
- package/lib/loggers/hooks.d.ts +20 -0
- package/lib/loggers/hooks.d.ts.map +1 -0
- package/lib/loggers/hooks.js +40 -0
- package/lib/loggers/hooks.js.map +1 -0
- package/lib/loggers/ilogger.d.ts +76 -0
- package/lib/loggers/ilogger.d.ts.map +1 -0
- package/lib/loggers/ilogger.js +108 -0
- package/lib/loggers/ilogger.js.map +1 -0
- package/lib/loggers/logger.d.ts +13 -0
- package/lib/loggers/logger.d.ts.map +1 -0
- package/lib/loggers/logger.js +18 -0
- package/lib/loggers/logger.js.map +1 -0
- package/lib/loggers/memory.service.d.ts +18 -0
- package/lib/loggers/memory.service.d.ts.map +1 -0
- package/lib/loggers/memory.service.js +21 -0
- package/lib/loggers/memory.service.js.map +1 -0
- package/lib/loggers/params.d.ts +47 -0
- package/lib/loggers/params.d.ts.map +1 -0
- package/lib/loggers/params.js +56 -0
- package/lib/loggers/params.js.map +1 -0
- package/lib/metrics/metrics.d.ts +25 -0
- package/lib/metrics/metrics.d.ts.map +1 -0
- package/lib/metrics/metrics.js +51 -0
- package/lib/metrics/metrics.js.map +1 -0
- package/lib/models/aclmodel.d.ts +21 -77
- package/lib/models/aclmodel.d.ts.map +1 -0
- package/lib/models/aclmodel.js +27 -204
- package/lib/models/aclmodel.js.map +1 -1
- package/lib/models/coremodel.model.d.ts +5 -0
- package/lib/models/coremodel.model.d.ts.map +1 -0
- package/lib/models/coremodel.model.js +5 -0
- package/lib/models/coremodel.model.js.map +1 -0
- package/lib/models/decorator.d.ts +63 -0
- package/lib/models/decorator.d.ts.map +1 -0
- package/lib/models/decorator.js +63 -0
- package/lib/models/decorator.js.map +1 -0
- package/lib/models/deployment.d.ts +2 -1
- package/lib/models/deployment.d.ts.map +1 -0
- package/lib/models/ident.model.d.ts +89 -0
- package/lib/models/ident.model.d.ts.map +1 -0
- package/lib/models/ident.model.js +115 -0
- package/lib/models/ident.model.js.map +1 -0
- package/lib/models/ownermodel.model.d.ts +68 -0
- package/lib/models/ownermodel.model.d.ts.map +1 -0
- package/lib/models/ownermodel.model.js +112 -0
- package/lib/models/ownermodel.model.js.map +1 -0
- package/lib/models/registry.model.d.ts +76 -0
- package/lib/models/registry.model.d.ts.map +1 -0
- package/lib/models/registry.model.js +104 -0
- package/lib/models/registry.model.js.map +1 -0
- package/lib/models/rolemodel.model.d.ts +28 -0
- package/lib/models/rolemodel.model.d.ts.map +1 -0
- package/lib/models/rolemodel.model.js +53 -0
- package/lib/models/rolemodel.model.js.map +1 -0
- package/lib/models/simpleuser.model.d.ts +78 -0
- package/lib/models/simpleuser.model.d.ts.map +1 -0
- package/lib/models/simpleuser.model.js +123 -0
- package/lib/models/simpleuser.model.js.map +1 -0
- package/lib/models/types.d.ts +113 -0
- package/lib/models/types.d.ts.map +1 -0
- package/lib/models/types.js +2 -0
- package/lib/models/types.js.map +1 -0
- package/lib/models/user.model.d.ts +103 -0
- package/lib/models/user.model.d.ts.map +1 -0
- package/lib/models/user.model.js +125 -0
- package/lib/models/user.model.js.map +1 -0
- package/lib/queues/memoryqueue.service.d.ts +72 -0
- package/lib/queues/memoryqueue.service.d.ts.map +1 -0
- package/lib/queues/memoryqueue.service.js +136 -0
- package/lib/queues/memoryqueue.service.js.map +1 -0
- package/lib/queues/pubsubservice.d.ts +9 -6
- package/lib/queues/pubsubservice.d.ts.map +1 -0
- package/lib/queues/pubsubservice.js +5 -4
- package/lib/queues/pubsubservice.js.map +1 -1
- package/lib/queues/queueservice.d.ts +10 -11
- package/lib/queues/queueservice.d.ts.map +1 -0
- package/lib/queues/queueservice.js +48 -20
- package/lib/queues/queueservice.js.map +1 -1
- package/lib/rest/hooks.d.ts +8 -0
- package/lib/rest/hooks.d.ts.map +1 -0
- package/lib/rest/hooks.js +10 -0
- package/lib/rest/hooks.js.map +1 -0
- package/lib/rest/irest.d.ts +212 -0
- package/lib/rest/irest.d.ts.map +1 -0
- package/lib/rest/irest.js +39 -0
- package/lib/rest/irest.js.map +1 -0
- package/lib/rest/originfilter.d.ts +38 -0
- package/lib/rest/originfilter.d.ts.map +1 -0
- package/lib/rest/originfilter.js +61 -0
- package/lib/rest/originfilter.js.map +1 -0
- package/lib/rest/restoperationstransport.service.d.ts +193 -0
- package/lib/rest/restoperationstransport.service.d.ts.map +1 -0
- package/lib/rest/restoperationstransport.service.js +780 -0
- package/lib/rest/restoperationstransport.service.js.map +1 -0
- package/lib/rest/router.service.d.ts +244 -0
- package/lib/rest/router.service.d.ts.map +1 -0
- package/lib/rest/router.service.js +843 -0
- package/lib/rest/router.service.js.map +1 -0
- package/lib/schemas/hooks.d.ts +48 -0
- package/lib/schemas/hooks.d.ts.map +1 -0
- package/lib/schemas/hooks.js +152 -0
- package/lib/schemas/hooks.js.map +1 -0
- package/lib/services/audit.model.d.ts +208 -0
- package/lib/services/audit.model.d.ts.map +1 -0
- package/lib/services/audit.model.js +431 -0
- package/lib/services/audit.model.js.map +1 -0
- package/lib/services/{authentication.d.ts → authentication.service.d.ts} +140 -58
- package/lib/services/authentication.service.d.ts.map +1 -0
- package/lib/services/authentication.service.js +932 -0
- package/lib/services/authentication.service.js.map +1 -0
- package/lib/services/binary.service.d.ts +808 -0
- package/lib/services/binary.service.d.ts.map +1 -0
- package/lib/services/binary.service.js +1365 -0
- package/lib/services/binary.service.js.map +1 -0
- package/lib/services/cloudbinary.d.ts +19 -13
- package/lib/services/cloudbinary.d.ts.map +1 -0
- package/lib/services/cloudbinary.js +24 -18
- package/lib/services/cloudbinary.js.map +1 -1
- package/lib/services/command.d.ts +118 -0
- package/lib/services/command.d.ts.map +1 -0
- package/lib/services/command.js +97 -0
- package/lib/services/command.js.map +1 -0
- package/lib/services/cron.service.d.ts +142 -0
- package/lib/services/cron.service.d.ts.map +1 -0
- package/lib/services/cron.service.js +291 -0
- package/lib/services/cron.service.js.map +1 -0
- package/lib/services/{cryptoservice.d.ts → cryptoservice.service.d.ts} +77 -142
- package/lib/services/cryptoservice.service.d.ts.map +1 -0
- package/lib/services/cryptoservice.service.js +527 -0
- package/lib/services/cryptoservice.service.js.map +1 -0
- package/lib/services/debugmailer.service.d.ts +49 -0
- package/lib/services/debugmailer.service.d.ts.map +1 -0
- package/lib/services/debugmailer.service.js +66 -0
- package/lib/services/debugmailer.service.js.map +1 -0
- package/lib/services/domainservice.service.d.ts +203 -0
- package/lib/services/domainservice.service.d.ts.map +1 -0
- package/lib/services/domainservice.service.js +600 -0
- package/lib/services/domainservice.service.js.map +1 -0
- package/lib/services/httpserver.service.d.ts +248 -0
- package/lib/services/httpserver.service.d.ts.map +1 -0
- package/lib/services/httpserver.service.js +673 -0
- package/lib/services/httpserver.service.js.map +1 -0
- package/lib/services/iauthentication.d.ts +9 -0
- package/lib/services/iauthentication.d.ts.map +1 -0
- package/lib/services/iauthentication.js +2 -0
- package/lib/services/iauthentication.js.map +1 -0
- package/lib/services/icryptoservice.d.ts +127 -0
- package/lib/services/icryptoservice.d.ts.map +1 -0
- package/lib/services/icryptoservice.js +68 -0
- package/lib/services/icryptoservice.js.map +1 -0
- package/lib/services/imailer.d.ts +17 -0
- package/lib/services/imailer.d.ts.map +1 -0
- package/lib/services/imailer.js +2 -0
- package/lib/services/imailer.js.map +1 -0
- package/lib/services/iservice.d.ts +104 -0
- package/lib/services/iservice.d.ts.map +1 -0
- package/lib/services/iservice.js +63 -0
- package/lib/services/iservice.js.map +1 -0
- package/lib/services/mailer.service.d.ts +220 -0
- package/lib/services/mailer.service.d.ts.map +1 -0
- package/lib/services/mailer.service.js +251 -0
- package/lib/services/mailer.service.js.map +1 -0
- package/lib/services/{notificationservice.d.ts → notificationservice.service.d.ts} +10 -10
- package/lib/services/notificationservice.service.d.ts.map +1 -0
- package/lib/services/{notificationservice.js → notificationservice.service.js} +24 -12
- package/lib/services/notificationservice.service.js.map +1 -0
- package/lib/services/oauth.d.ts +58 -31
- package/lib/services/oauth.d.ts.map +1 -0
- package/lib/services/oauth.js +365 -251
- package/lib/services/oauth.js.map +1 -1
- package/lib/services/operationstransport.d.ts +65 -0
- package/lib/services/operationstransport.d.ts.map +1 -0
- package/lib/services/operationstransport.js +103 -0
- package/lib/services/operationstransport.js.map +1 -0
- package/lib/services/{prometheus.d.ts → prometheus.service.d.ts} +13 -11
- package/lib/services/prometheus.service.d.ts.map +1 -0
- package/lib/services/prometheus.service.js +203 -0
- package/lib/services/prometheus.service.js.map +1 -0
- package/lib/services/resource.service.d.ts +121 -0
- package/lib/services/resource.service.d.ts.map +1 -0
- package/lib/services/resource.service.js +301 -0
- package/lib/services/resource.service.js.map +1 -0
- package/lib/services/service.d.ts +88 -189
- package/lib/services/service.d.ts.map +1 -0
- package/lib/services/service.js +407 -432
- package/lib/services/service.js.map +1 -1
- package/lib/services/servicecommands.d.ts +99 -0
- package/lib/services/servicecommands.d.ts.map +1 -0
- package/lib/services/servicecommands.js +165 -0
- package/lib/services/servicecommands.js.map +1 -0
- package/lib/services/serviceparameters.d.ts +33 -0
- package/lib/services/serviceparameters.d.ts.map +1 -0
- package/lib/services/serviceparameters.js +79 -0
- package/lib/services/serviceparameters.js.map +1 -0
- package/lib/{utils → session}/cookie.d.ts +32 -18
- package/lib/session/cookie.d.ts.map +1 -0
- package/lib/{utils → session}/cookie.js +76 -23
- package/lib/session/cookie.js.map +1 -0
- package/lib/session/manager.model.d.ts +71 -0
- package/lib/session/manager.model.d.ts.map +1 -0
- package/lib/session/manager.model.js +155 -0
- package/lib/session/manager.model.js.map +1 -0
- package/lib/session/session.d.ts +57 -0
- package/lib/session/session.d.ts.map +1 -0
- package/lib/session/session.js +126 -0
- package/lib/session/session.js.map +1 -0
- package/lib/stores/istore.d.ts +99 -0
- package/lib/stores/istore.d.ts.map +1 -0
- package/lib/stores/istore.js +26 -0
- package/lib/stores/istore.js.map +1 -0
- package/lib/stores/memory.service.d.ts +114 -0
- package/lib/stores/memory.service.d.ts.map +1 -0
- package/lib/stores/memory.service.js +343 -0
- package/lib/stores/memory.service.js.map +1 -0
- package/lib/stores/store.d.ts +127 -768
- package/lib/stores/store.d.ts.map +1 -0
- package/lib/stores/store.js +258 -1718
- package/lib/stores/store.js.map +1 -1
- package/lib/templates/templates.d.ts +39 -0
- package/lib/templates/templates.d.ts.map +1 -0
- package/lib/templates/templates.js +92 -0
- package/lib/templates/templates.js.map +1 -0
- package/lib/test/application.d.ts +174 -0
- package/lib/test/application.d.ts.map +1 -0
- package/lib/test/application.js +288 -0
- package/lib/test/application.js.map +1 -0
- package/lib/test/asyncstorage.d.ts +16 -0
- package/lib/test/asyncstorage.d.ts.map +1 -0
- package/lib/test/asyncstorage.js +32 -0
- package/lib/test/asyncstorage.js.map +1 -0
- package/lib/test/core.d.ts +63 -0
- package/lib/test/core.d.ts.map +1 -0
- package/lib/test/core.js +190 -0
- package/lib/test/core.js.map +1 -0
- package/lib/test/index.d.ts +7 -0
- package/lib/test/index.d.ts.map +1 -0
- package/lib/test/index.js +8 -0
- package/lib/test/index.js.map +1 -0
- package/lib/test/internal.d.ts +34 -0
- package/lib/test/internal.d.ts.map +1 -0
- package/lib/test/internal.js +156 -0
- package/lib/test/internal.js.map +1 -0
- package/lib/test/objects.d.ts +318 -0
- package/lib/test/objects.d.ts.map +1 -0
- package/lib/test/objects.js +443 -0
- package/lib/test/objects.js.map +1 -0
- package/lib/utils/abstractdeployer.d.ts +5 -2
- package/lib/utils/abstractdeployer.d.ts.map +1 -0
- package/lib/utils/abstractdeployer.js +3 -0
- package/lib/utils/abstractdeployer.js.map +1 -1
- package/package.json +85 -56
- package/test/cachedapp/webda.config.json +1 -5
- package/test/config-cached.json +1 -5
- package/test/config.json +6 -99
- package/test/data/.env +1 -0
- package/test/my-cnf.json +9 -0
- package/webda.module.json +3462 -2231
- package/lib/application.d.ts +0 -876
- package/lib/application.js +0 -741
- package/lib/application.js.map +0 -1
- package/lib/application.spec.d.ts +0 -1
- package/lib/application.spec.js +0 -234
- package/lib/application.spec.js.map +0 -1
- package/lib/core.d.ts +0 -740
- package/lib/core.js +0 -1310
- package/lib/core.js.map +0 -1
- package/lib/core.spec.d.ts +0 -1
- package/lib/core.spec.js +0 -761
- package/lib/core.spec.js.map +0 -1
- package/lib/errors.d.ts +0 -65
- package/lib/errors.js +0 -113
- package/lib/errors.js.map +0 -1
- package/lib/errors.spec.d.ts +0 -1
- package/lib/errors.spec.js +0 -33
- package/lib/errors.spec.js.map +0 -1
- package/lib/models/aclmodel.spec.d.ts +0 -1
- package/lib/models/aclmodel.spec.js +0 -187
- package/lib/models/aclmodel.spec.js.map +0 -1
- package/lib/models/coremodel.d.ts +0 -887
- package/lib/models/coremodel.js +0 -1208
- package/lib/models/coremodel.js.map +0 -1
- package/lib/models/coremodel.spec.d.ts +0 -1
- package/lib/models/coremodel.spec.js +0 -462
- package/lib/models/coremodel.spec.js.map +0 -1
- package/lib/models/ident.d.ts +0 -53
- package/lib/models/ident.js +0 -40
- package/lib/models/ident.js.map +0 -1
- package/lib/models/ident.spec.d.ts +0 -1
- package/lib/models/ident.spec.js +0 -43
- package/lib/models/ident.spec.js.map +0 -1
- package/lib/models/ownermodel.d.ts +0 -50
- package/lib/models/ownermodel.js +0 -65
- package/lib/models/ownermodel.js.map +0 -1
- package/lib/models/ownermodel.spec.d.ts +0 -1
- package/lib/models/ownermodel.spec.js +0 -191
- package/lib/models/ownermodel.spec.js.map +0 -1
- package/lib/models/relations.d.ts +0 -181
- package/lib/models/relations.js +0 -157
- package/lib/models/relations.js.map +0 -1
- package/lib/models/relations.spec.d.ts +0 -12
- package/lib/models/relations.spec.js +0 -224
- package/lib/models/relations.spec.js.map +0 -1
- package/lib/models/rolemodel.d.ts +0 -10
- package/lib/models/rolemodel.js +0 -35
- package/lib/models/rolemodel.js.map +0 -1
- package/lib/models/rolemodel.spec.d.ts +0 -1
- package/lib/models/rolemodel.spec.js +0 -86
- package/lib/models/rolemodel.spec.js.map +0 -1
- package/lib/models/user.d.ts +0 -100
- package/lib/models/user.js +0 -157
- package/lib/models/user.js.map +0 -1
- package/lib/models/user.spec.d.ts +0 -1
- package/lib/models/user.spec.js +0 -88
- package/lib/models/user.spec.js.map +0 -1
- package/lib/queues/filequeue.d.ts +0 -58
- package/lib/queues/filequeue.js +0 -131
- package/lib/queues/filequeue.js.map +0 -1
- package/lib/queues/filequeue.spec.d.ts +0 -1
- package/lib/queues/filequeue.spec.js +0 -78
- package/lib/queues/filequeue.spec.js.map +0 -1
- package/lib/queues/memoryqueue.d.ts +0 -45
- package/lib/queues/memoryqueue.js +0 -81
- package/lib/queues/memoryqueue.js.map +0 -1
- package/lib/queues/memoryqueue.spec.d.ts +0 -1
- package/lib/queues/memoryqueue.spec.js +0 -192
- package/lib/queues/memoryqueue.spec.js.map +0 -1
- package/lib/queues/queue.spec.d.ts +0 -5
- package/lib/queues/queue.spec.js +0 -55
- package/lib/queues/queue.spec.js.map +0 -1
- package/lib/router.d.ts +0 -172
- package/lib/router.js +0 -419
- package/lib/router.js.map +0 -1
- package/lib/router.spec.d.ts +0 -1
- package/lib/router.spec.js +0 -229
- package/lib/router.spec.js.map +0 -1
- package/lib/services/asyncevents.d.ts +0 -151
- package/lib/services/asyncevents.js +0 -217
- package/lib/services/asyncevents.js.map +0 -1
- package/lib/services/asyncevents.spec.d.ts +0 -1
- package/lib/services/asyncevents.spec.js +0 -118
- package/lib/services/asyncevents.spec.js.map +0 -1
- package/lib/services/authentication.js +0 -772
- package/lib/services/authentication.js.map +0 -1
- package/lib/services/authentication.spec.d.ts +0 -1
- package/lib/services/authentication.spec.js +0 -458
- package/lib/services/authentication.spec.js.map +0 -1
- package/lib/services/binary.d.ts +0 -549
- package/lib/services/binary.js +0 -986
- package/lib/services/binary.js.map +0 -1
- package/lib/services/binary.spec.d.ts +0 -44
- package/lib/services/binary.spec.js +0 -438
- package/lib/services/binary.spec.js.map +0 -1
- package/lib/services/cloudbinary.spec.d.ts +0 -13
- package/lib/services/cloudbinary.spec.js +0 -192
- package/lib/services/cloudbinary.spec.js.map +0 -1
- package/lib/services/configuration.js +0 -178
- package/lib/services/configuration.js.map +0 -1
- package/lib/services/configuration.spec.d.ts +0 -1
- package/lib/services/configuration.spec.js +0 -87
- package/lib/services/configuration.spec.js.map +0 -1
- package/lib/services/cron.d.ts +0 -73
- package/lib/services/cron.js +0 -141
- package/lib/services/cron.js.map +0 -1
- package/lib/services/cron.spec.d.ts +0 -1
- package/lib/services/cron.spec.js +0 -76
- package/lib/services/cron.spec.js.map +0 -1
- package/lib/services/cryptoservice.js +0 -434
- package/lib/services/cryptoservice.js.map +0 -1
- package/lib/services/cryptoservice.spec.d.ts +0 -1
- package/lib/services/cryptoservice.spec.js +0 -177
- package/lib/services/cryptoservice.spec.js.map +0 -1
- package/lib/services/debugmailer.d.ts +0 -36
- package/lib/services/debugmailer.js +0 -52
- package/lib/services/debugmailer.js.map +0 -1
- package/lib/services/debugmailer.spec.d.ts +0 -1
- package/lib/services/debugmailer.spec.js +0 -29
- package/lib/services/debugmailer.spec.js.map +0 -1
- package/lib/services/domainservice.d.ts +0 -152
- package/lib/services/domainservice.js +0 -881
- package/lib/services/domainservice.js.map +0 -1
- package/lib/services/domainservice.spec.d.ts +0 -1
- package/lib/services/domainservice.spec.js +0 -401
- package/lib/services/domainservice.spec.js.map +0 -1
- package/lib/services/filebinary.d.ts +0 -133
- package/lib/services/filebinary.js +0 -371
- package/lib/services/filebinary.js.map +0 -1
- package/lib/services/filebinary.spec.d.ts +0 -21
- package/lib/services/filebinary.spec.js +0 -415
- package/lib/services/filebinary.spec.js.map +0 -1
- package/lib/services/fileconfiguration.d.ts +0 -22
- package/lib/services/fileconfiguration.js +0 -48
- package/lib/services/fileconfiguration.js.map +0 -1
- package/lib/services/fileconfiguration.spec.d.ts +0 -1
- package/lib/services/fileconfiguration.spec.js +0 -177
- package/lib/services/fileconfiguration.spec.js.map +0 -1
- package/lib/services/invitationservice.d.ts +0 -222
- package/lib/services/invitationservice.js +0 -526
- package/lib/services/invitationservice.js.map +0 -1
- package/lib/services/invitationservice.spec.d.ts +0 -1
- package/lib/services/invitationservice.spec.js +0 -516
- package/lib/services/invitationservice.spec.js.map +0 -1
- package/lib/services/kubernetesconfiguration.d.ts +0 -26
- package/lib/services/kubernetesconfiguration.js +0 -54
- package/lib/services/kubernetesconfiguration.js.map +0 -1
- package/lib/services/kubernetesconfiguration.spec.d.ts +0 -1
- package/lib/services/kubernetesconfiguration.spec.js +0 -147
- package/lib/services/kubernetesconfiguration.spec.js.map +0 -1
- package/lib/services/mailer.d.ts +0 -165
- package/lib/services/mailer.js +0 -176
- package/lib/services/mailer.js.map +0 -1
- package/lib/services/mailer.spec.d.ts +0 -1
- package/lib/services/mailer.spec.js +0 -144
- package/lib/services/mailer.spec.js.map +0 -1
- package/lib/services/notificationservice.js.map +0 -1
- package/lib/services/notificationservice.spec.d.ts +0 -1
- package/lib/services/notificationservice.spec.js +0 -78
- package/lib/services/notificationservice.spec.js.map +0 -1
- package/lib/services/oauth.spec.d.ts +0 -1
- package/lib/services/oauth.spec.js +0 -184
- package/lib/services/oauth.spec.js.map +0 -1
- package/lib/services/prometheus.js +0 -160
- package/lib/services/prometheus.js.map +0 -1
- package/lib/services/prometheus.spec.d.ts +0 -1
- package/lib/services/prometheus.spec.js +0 -57
- package/lib/services/prometheus.spec.js.map +0 -1
- package/lib/services/resource.d.ts +0 -87
- package/lib/services/resource.js +0 -156
- package/lib/services/resource.js.map +0 -1
- package/lib/services/resource.spec.d.ts +0 -1
- package/lib/services/resource.spec.js +0 -122
- package/lib/services/resource.spec.js.map +0 -1
- package/lib/services/service.spec.d.ts +0 -1
- package/lib/services/service.spec.js +0 -268
- package/lib/services/service.spec.js.map +0 -1
- package/lib/stores/aggregator.d.ts +0 -41
- package/lib/stores/aggregator.js +0 -80
- package/lib/stores/aggregator.js.map +0 -1
- package/lib/stores/aliasstore.d.ts +0 -108
- package/lib/stores/aliasstore.js +0 -168
- package/lib/stores/aliasstore.js.map +0 -1
- package/lib/stores/aliasstore.spec.d.ts +0 -11
- package/lib/stores/aliasstore.spec.js +0 -89
- package/lib/stores/aliasstore.spec.js.map +0 -1
- package/lib/stores/file.d.ts +0 -107
- package/lib/stores/file.js +0 -188
- package/lib/stores/file.js.map +0 -1
- package/lib/stores/file.spec.d.ts +0 -19
- package/lib/stores/file.spec.js +0 -232
- package/lib/stores/file.spec.js.map +0 -1
- package/lib/stores/mapper.d.ts +0 -149
- package/lib/stores/mapper.js +0 -293
- package/lib/stores/mapper.js.map +0 -1
- package/lib/stores/mapper.spec.d.ts +0 -1
- package/lib/stores/mapper.spec.js +0 -160
- package/lib/stores/mapper.spec.js.map +0 -1
- package/lib/stores/memory.d.ts +0 -151
- package/lib/stores/memory.js +0 -371
- package/lib/stores/memory.js.map +0 -1
- package/lib/stores/memory.spec.d.ts +0 -20
- package/lib/stores/memory.spec.js +0 -328
- package/lib/stores/memory.spec.js.map +0 -1
- package/lib/stores/modelmapper.d.ts +0 -61
- package/lib/stores/modelmapper.js +0 -199
- package/lib/stores/modelmapper.js.map +0 -1
- package/lib/stores/store.spec.d.ts +0 -65
- package/lib/stores/store.spec.js +0 -906
- package/lib/stores/store.spec.js.map +0 -1
- package/lib/test.d.ts +0 -162
- package/lib/test.js +0 -399
- package/lib/test.js.map +0 -1
- package/lib/unpackedapplication.d.ts +0 -76
- package/lib/unpackedapplication.js +0 -299
- package/lib/unpackedapplication.js.map +0 -1
- package/lib/utils/abstractdeployer.spec.d.ts +0 -1
- package/lib/utils/abstractdeployer.spec.js +0 -21
- package/lib/utils/abstractdeployer.spec.js.map +0 -1
- package/lib/utils/case.d.ts +0 -7
- package/lib/utils/case.js +0 -43
- package/lib/utils/case.js.map +0 -1
- package/lib/utils/case.spec.d.ts +0 -1
- package/lib/utils/case.spec.js +0 -50
- package/lib/utils/case.spec.js.map +0 -1
- package/lib/utils/context.d.ts +0 -462
- package/lib/utils/context.js +0 -732
- package/lib/utils/context.js.map +0 -1
- package/lib/utils/context.spec.d.ts +0 -9
- package/lib/utils/context.spec.js +0 -372
- package/lib/utils/context.spec.js.map +0 -1
- package/lib/utils/cookie.js.map +0 -1
- package/lib/utils/cookie.spec.d.ts +0 -1
- package/lib/utils/cookie.spec.js +0 -78
- package/lib/utils/cookie.spec.js.map +0 -1
- package/lib/utils/esm.d.ts +0 -13
- package/lib/utils/esm.js +0 -19
- package/lib/utils/esm.js.map +0 -1
- package/lib/utils/httpcontext.js.map +0 -1
- package/lib/utils/httpcontext.spec.d.ts +0 -4
- package/lib/utils/httpcontext.spec.js +0 -77
- package/lib/utils/httpcontext.spec.js.map +0 -1
- package/lib/utils/logger.d.ts +0 -91
- package/lib/utils/logger.js +0 -121
- package/lib/utils/logger.js.map +0 -1
- package/lib/utils/logger.spec.d.ts +0 -1
- package/lib/utils/logger.spec.js +0 -48
- package/lib/utils/logger.spec.js.map +0 -1
- package/lib/utils/serializers.d.ts +0 -161
- package/lib/utils/serializers.js +0 -420
- package/lib/utils/serializers.js.map +0 -1
- package/lib/utils/serializers.spec.d.ts +0 -1
- package/lib/utils/serializers.spec.js +0 -313
- package/lib/utils/serializers.spec.js.map +0 -1
- package/lib/utils/session.d.ts +0 -126
- package/lib/utils/session.js +0 -166
- package/lib/utils/session.js.map +0 -1
- package/lib/utils/session.spec.d.ts +0 -1
- package/lib/utils/session.spec.js +0 -71
- package/lib/utils/session.spec.js.map +0 -1
- package/lib/utils/throttler.d.ts +0 -102
- package/lib/utils/throttler.js +0 -168
- package/lib/utils/throttler.js.map +0 -1
- package/lib/utils/throttler.spec.d.ts +0 -1
- package/lib/utils/throttler.spec.js +0 -55
- package/lib/utils/throttler.spec.js.map +0 -1
- package/lib/utils/waiter.d.ts +0 -93
- package/lib/utils/waiter.js +0 -148
- package/lib/utils/waiter.js.map +0 -1
- package/lib/utils/waiter.spec.d.ts +0 -1
- package/lib/utils/waiter.spec.js +0 -98
- package/lib/utils/waiter.spec.js.map +0 -1
- package/test/config-file-missing-file-no-default.json +0 -44
- package/test/config-file-missing-file.json +0 -55
- package/test/config-file-no-reload.json +0 -69
- package/test/config-file-reload.json +0 -68
- package/test/config-invitation.json +0 -63
- package/test/config-kube-reload.json +0 -68
- package/test/config-reload.json +0 -66
- package/test/config.old.json +0 -152
- package/test/jsonutils/mdocs.yaml +0 -56
- package/test/jsonutils/test.json +0 -3
- package/test/jsonutils/test.yml +0 -5
- package/test/moddas/annotatedservice.js +0 -23
- package/test/moddas/debugmailer.js +0 -13
- package/test/moddas/fakeservice.js +0 -4
- package/test/moddas/voidstore.js +0 -66
- package/test/models/ident.js +0 -36
- package/test/models/task.js +0 -42
package/lib/bin/cli.js
ADDED
|
@@ -0,0 +1,828 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import yargs from "yargs";
|
|
3
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
4
|
+
import { resolve, join } from "node:path";
|
|
5
|
+
import { isMainModule } from "@webda/tsc-esm";
|
|
6
|
+
import { Application, installConfigurationFactories } from "../application/application.js";
|
|
7
|
+
import { UnpackedApplication } from "../application/unpackedapplication.js";
|
|
8
|
+
import { collectServiceCommands, executeServiceCommand } from "../services/servicecommands.js";
|
|
9
|
+
import { Core } from "../core/core.js";
|
|
10
|
+
import { bootCoreForCommand } from "./cli-phase.js";
|
|
11
|
+
import { runWithInstanceStorage, useInstanceStorage } from "../core/instancestorage.js";
|
|
12
|
+
import { CancelablePromise } from "@webda/utils";
|
|
13
|
+
import { ConsoleLogger, patchConsole, useLog, useLogLevel, useOutput, useWorkerOutput } from "@webda/workout";
|
|
14
|
+
import { createInterface } from "node:readline";
|
|
15
|
+
import { createRequire } from "node:module";
|
|
16
|
+
/**
|
|
17
|
+
* Well-known parameter schemas mapped to yargs positionals/options
|
|
18
|
+
*/
|
|
19
|
+
const KNOWN_PARAMS = {
|
|
20
|
+
uuidRequest: {
|
|
21
|
+
positional: "uuid"
|
|
22
|
+
},
|
|
23
|
+
searchRequest: {
|
|
24
|
+
options: {
|
|
25
|
+
query: { type: "string", alias: "q", describe: "Search query (WebdaQL)" }
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Convert a JSON Schema's properties into yargs option definitions.
|
|
31
|
+
*
|
|
32
|
+
* @param schema - JSON Schema describing an object with properties
|
|
33
|
+
* @param skipRequired - When true, all options are marked optional (useful when input can also come from --json/--file)
|
|
34
|
+
* @returns Map of property names to yargs {@link Options} definitions
|
|
35
|
+
*/
|
|
36
|
+
function schemaToOptions(schema, skipRequired) {
|
|
37
|
+
if (schema.type !== "object" || !schema.properties)
|
|
38
|
+
return {};
|
|
39
|
+
const opts = {};
|
|
40
|
+
const required = new Set(schema.required || []);
|
|
41
|
+
for (const [name, prop] of Object.entries(schema.properties)) {
|
|
42
|
+
if (typeof prop === "boolean")
|
|
43
|
+
continue;
|
|
44
|
+
const o = { describe: prop.description || name, demandOption: skipRequired ? false : required.has(name) };
|
|
45
|
+
if (prop.type === "number" || prop.type === "integer")
|
|
46
|
+
o.type = "number";
|
|
47
|
+
else if (prop.type === "boolean")
|
|
48
|
+
o.type = "boolean";
|
|
49
|
+
else if (prop.type === "array")
|
|
50
|
+
o.type = "array";
|
|
51
|
+
else
|
|
52
|
+
o.type = "string";
|
|
53
|
+
if (prop.enum)
|
|
54
|
+
o.choices = prop.enum;
|
|
55
|
+
if (prop.default !== undefined)
|
|
56
|
+
o.default = prop.default;
|
|
57
|
+
opts[name] = o;
|
|
58
|
+
}
|
|
59
|
+
return opts;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Load .webda/operations.json from an application directory
|
|
63
|
+
* @param appPath - the application path
|
|
64
|
+
* @returns the result
|
|
65
|
+
*/
|
|
66
|
+
export function loadOperations(appPath = ".") {
|
|
67
|
+
const filePath = join(resolve(appPath), ".webda", "operations.json");
|
|
68
|
+
if (!existsSync(filePath)) {
|
|
69
|
+
throw new Error(`Operations not found: ${filePath}\nRun 'webdac build' to generate it.`);
|
|
70
|
+
}
|
|
71
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Group operations by their prefix before the first dot (e.g., "Task.Create" belongs to group "Task").
|
|
75
|
+
*
|
|
76
|
+
* @param operations - Map of operation IDs to their entries
|
|
77
|
+
* @returns Map of group names to their operation entries
|
|
78
|
+
*/
|
|
79
|
+
function groupOperations(operations) {
|
|
80
|
+
const groups = new Map();
|
|
81
|
+
for (const op of Object.values(operations)) {
|
|
82
|
+
const dot = op.id.indexOf(".");
|
|
83
|
+
const group = dot >= 0 ? op.id.substring(0, dot) : op.id;
|
|
84
|
+
if (!groups.has(group))
|
|
85
|
+
groups.set(group, []);
|
|
86
|
+
groups.get(group).push(op);
|
|
87
|
+
}
|
|
88
|
+
return groups;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Add parameter and input options to a yargs command
|
|
92
|
+
* @param y - the yargs instance
|
|
93
|
+
* @param op - the operation
|
|
94
|
+
* @param ops - the operations list
|
|
95
|
+
* @returns the result
|
|
96
|
+
*/
|
|
97
|
+
function addOperationOptions(y, op, ops) {
|
|
98
|
+
const hasInput = op.input && op.input !== "void";
|
|
99
|
+
const paramDef = hasInput ? KNOWN_PARAMS[op.input] : undefined;
|
|
100
|
+
// Add well-known parameter options (e.g., uuidRequest -> positional uuid)
|
|
101
|
+
if (paramDef?.options) {
|
|
102
|
+
for (const [name, opt] of Object.entries(paramDef.options)) {
|
|
103
|
+
y.option(name, opt);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Add custom input options from schema
|
|
107
|
+
if (hasInput && !paramDef && ops.schemas[op.input]) {
|
|
108
|
+
// Offer both raw JSON/file and per-property CLI options
|
|
109
|
+
y.option("json", { type: "string", describe: "JSON input (inline)" });
|
|
110
|
+
y.option("file", { type: "string", alias: "f", describe: "JSON input from file" });
|
|
111
|
+
for (const [name, opt] of Object.entries(schemaToOptions(ops.schemas[op.input], true))) {
|
|
112
|
+
y.option(name, opt);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return y;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Extract operation parameters from parsed CLI args using well-known param defs or custom schemas.
|
|
119
|
+
*
|
|
120
|
+
* @param args - Parsed yargs arguments
|
|
121
|
+
* @param op - The operation entry defining which parameters to extract
|
|
122
|
+
* @param ops - The full operations file (for resolving custom parameter schemas)
|
|
123
|
+
* @returns Object containing only the recognized parameter values
|
|
124
|
+
*/
|
|
125
|
+
function extractParameters(args, op, ops) {
|
|
126
|
+
const params = {};
|
|
127
|
+
const hasInput = op.input && op.input !== "void";
|
|
128
|
+
const paramDef = hasInput ? KNOWN_PARAMS[op.input] : undefined;
|
|
129
|
+
if (paramDef?.positional && args[paramDef.positional] !== undefined) {
|
|
130
|
+
params[paramDef.positional] = args[paramDef.positional];
|
|
131
|
+
}
|
|
132
|
+
if (paramDef?.options) {
|
|
133
|
+
for (const name of Object.keys(paramDef.options)) {
|
|
134
|
+
if (args[name] !== undefined)
|
|
135
|
+
params[name] = args[name];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return params;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Extract operation input body from parsed CLI args (via --json, --file, or individual schema properties).
|
|
142
|
+
*
|
|
143
|
+
* @param args - Parsed yargs arguments
|
|
144
|
+
* @param op - The operation entry defining the input schema
|
|
145
|
+
* @param ops - The full operations file (for resolving input schemas)
|
|
146
|
+
* @returns Parsed input object, or undefined if no input was provided
|
|
147
|
+
*/
|
|
148
|
+
function extractInput(args, op, ops) {
|
|
149
|
+
const hasInput = op.input && op.input !== "void";
|
|
150
|
+
// When input is a well-known param schema (e.g., uuidRequest), it is handled
|
|
151
|
+
// via extractParameters and positional args, not as body input.
|
|
152
|
+
if (hasInput && KNOWN_PARAMS[op.input]) {
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
if (args.json) {
|
|
156
|
+
return JSON.parse(args.json);
|
|
157
|
+
}
|
|
158
|
+
if (args.file) {
|
|
159
|
+
return JSON.parse(readFileSync(args.file, "utf-8"));
|
|
160
|
+
}
|
|
161
|
+
// Build input from individual CLI options matching the input schema properties
|
|
162
|
+
if (hasInput && ops.schemas[op.input]?.properties) {
|
|
163
|
+
const input = {};
|
|
164
|
+
for (const name of Object.keys(ops.schemas[op.input].properties)) {
|
|
165
|
+
if (args[name] !== undefined)
|
|
166
|
+
input[name] = args[name];
|
|
167
|
+
}
|
|
168
|
+
if (Object.keys(input).length > 0)
|
|
169
|
+
return input;
|
|
170
|
+
}
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Build a yargs CLI from an operations.json file
|
|
175
|
+
*
|
|
176
|
+
* Groups operations by their prefix (e.g., "Task") and creates nested
|
|
177
|
+
* subcommands for each action (e.g., "create", "get", "delete").
|
|
178
|
+
*
|
|
179
|
+
* Usage examples (given Task CRUD operations):
|
|
180
|
+
* webda task create --json '{"title":"My Task"}'
|
|
181
|
+
* webda task get <uuid>
|
|
182
|
+
* webda task delete <uuid>
|
|
183
|
+
* webda tasks query --query "status = 'active'"
|
|
184
|
+
*
|
|
185
|
+
* @param ops Loaded operations file
|
|
186
|
+
* @param handler Called when an operation command is invoked
|
|
187
|
+
* @param argv Command-line arguments (defaults to process.argv.slice(2))
|
|
188
|
+
* @returns the result
|
|
189
|
+
*/
|
|
190
|
+
export function buildCli(ops, handler, argv) {
|
|
191
|
+
const groups = groupOperations(ops.operations);
|
|
192
|
+
// Lowercase command/subcommand args for case-insensitive matching
|
|
193
|
+
// Stop lowercasing at the first flag (--option) or positional value after commands
|
|
194
|
+
const rawArgv = argv ?? process.argv.slice(2);
|
|
195
|
+
const normalizedArgv = rawArgv.map((arg, i) => {
|
|
196
|
+
// Once we hit a flag, stop lowercasing
|
|
197
|
+
if (arg.startsWith("-"))
|
|
198
|
+
return arg;
|
|
199
|
+
// Stop lowercasing after the first two positional words (command + action)
|
|
200
|
+
const positionalIndex = rawArgv.slice(0, i).filter(a => !a.startsWith("-")).length;
|
|
201
|
+
return positionalIndex < 2 ? arg.toLowerCase() : arg;
|
|
202
|
+
});
|
|
203
|
+
const cli = yargs(normalizedArgv).scriptName("webda").usage("$0 <command> <action> [options]");
|
|
204
|
+
for (const [group, operations] of groups) {
|
|
205
|
+
cli.command(group.toLowerCase(), `${group} operations`, groupY => {
|
|
206
|
+
for (const op of operations) {
|
|
207
|
+
const action = op.id.substring(op.id.indexOf(".") + 1).toLowerCase();
|
|
208
|
+
const hasInput = op.input && op.input !== "void";
|
|
209
|
+
const paramDef = hasInput ? KNOWN_PARAMS[op.input] : undefined;
|
|
210
|
+
// Build command string with positional if needed
|
|
211
|
+
const cmd = paramDef?.positional ? `${action} <${paramDef.positional}>` : action;
|
|
212
|
+
groupY.command(cmd, op.id, y => addOperationOptions(y, op, ops), async (args) => {
|
|
213
|
+
await handler({
|
|
214
|
+
id: op.id,
|
|
215
|
+
parameters: extractParameters(args, op, ops),
|
|
216
|
+
input: hasInput ? extractInput(args, op, ops) : undefined
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return groupY.demandCommand(1, `Specify an action for ${group.toLowerCase()}`);
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return cli.completion("completion", false).demandCommand(1, "Specify a command").help();
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Add service commands (from `@Command` decorators) to a yargs CLI instance.
|
|
227
|
+
*
|
|
228
|
+
* Reads commands from `webda.module.json` via the Application and registers
|
|
229
|
+
* them as yargs commands. Subcommands (space-separated names like `"aws s3"`)
|
|
230
|
+
* are nested as yargs subcommand groups.
|
|
231
|
+
*
|
|
232
|
+
* A global `--service` option is added to filter which services handle a command
|
|
233
|
+
* when multiple services declare the same command name.
|
|
234
|
+
*
|
|
235
|
+
* @param cli - The yargs CLI instance to add commands to
|
|
236
|
+
* @param serviceCommands - Command map from {@link collectServiceCommands}
|
|
237
|
+
* @param handler - Called when a service command is invoked, receives command name and parsed args
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* import { collectServiceCommands, addServiceCommandsToCli } from "@webda/core";
|
|
242
|
+
*
|
|
243
|
+
* const cmds = collectServiceCommands(app);
|
|
244
|
+
* const cli = yargs().scriptName("webda");
|
|
245
|
+
* addServiceCommandsToCli(cli, cmds, async (cmdName, args) => {
|
|
246
|
+
* await executeServiceCommand(cmdName, cmds[cmdName], args, core.getServices(), args.service?.split(","));
|
|
247
|
+
* });
|
|
248
|
+
* ```
|
|
249
|
+
* @returns the result
|
|
250
|
+
*/
|
|
251
|
+
export function addServiceCommandsToCli(cli, serviceCommands, handler) {
|
|
252
|
+
// Add global --service filter
|
|
253
|
+
cli.option("service", {
|
|
254
|
+
type: "string",
|
|
255
|
+
description: "Filter command to specific service(s), comma-separated",
|
|
256
|
+
global: true
|
|
257
|
+
});
|
|
258
|
+
// Group commands by top-level name for subcommand support
|
|
259
|
+
const topLevel = new Map();
|
|
260
|
+
for (const [cmdName, cmdInfo] of Object.entries(serviceCommands)) {
|
|
261
|
+
const parts = cmdName.split(" ");
|
|
262
|
+
const top = parts[0];
|
|
263
|
+
if (!topLevel.has(top))
|
|
264
|
+
topLevel.set(top, []);
|
|
265
|
+
topLevel.get(top).push({ name: cmdName, info: cmdInfo });
|
|
266
|
+
}
|
|
267
|
+
for (const [top, commands] of topLevel) {
|
|
268
|
+
if (commands.length === 1 && commands[0].name === top) {
|
|
269
|
+
// Simple command (no subcommands)
|
|
270
|
+
const { name, info } = commands[0];
|
|
271
|
+
cli.command(top, info.description, y => addCommandArgs(y, info.args), async (args) => handler(name, args));
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
// Command group with subcommands
|
|
275
|
+
cli.command(top, `${top} commands`, groupY => {
|
|
276
|
+
for (const { name, info } of commands) {
|
|
277
|
+
const sub = name.substring(top.length + 1) || top;
|
|
278
|
+
groupY.command(sub, info.description, y => addCommandArgs(y, info.args), async (args) => handler(name, args));
|
|
279
|
+
}
|
|
280
|
+
return groupY.demandCommand(1, `Specify a subcommand for ${top}`);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return cli;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Add command argument definitions to a yargs builder.
|
|
288
|
+
* @param y - the yargs instance
|
|
289
|
+
* @returns the result
|
|
290
|
+
*/
|
|
291
|
+
function addCommandArgs(y, args) {
|
|
292
|
+
for (const [argName, argDef] of Object.entries(args)) {
|
|
293
|
+
y.option(argName, {
|
|
294
|
+
type: argDef.type,
|
|
295
|
+
default: argDef.default,
|
|
296
|
+
alias: argDef.alias,
|
|
297
|
+
description: argDef.description,
|
|
298
|
+
demandOption: argDef.required
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
return y;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Prompt the user interactively for missing input properties.
|
|
305
|
+
* If stdin is not a TTY, returns the input as-is (validation will fail later).
|
|
306
|
+
*
|
|
307
|
+
* @param input - Partially filled input object
|
|
308
|
+
* @param schema - JSON Schema describing expected input properties (used to determine what is missing)
|
|
309
|
+
* @returns The input object augmented with user-provided values, coerced to the expected types
|
|
310
|
+
*/
|
|
311
|
+
async function promptForMissingInput(input, schema) {
|
|
312
|
+
if (schema.type !== "object" || !schema.properties)
|
|
313
|
+
return input;
|
|
314
|
+
// Collect missing properties
|
|
315
|
+
const missing = [];
|
|
316
|
+
for (const [name, prop] of Object.entries(schema.properties)) {
|
|
317
|
+
if (typeof prop === "boolean" || input[name] !== undefined)
|
|
318
|
+
continue;
|
|
319
|
+
missing.push([name, prop]);
|
|
320
|
+
}
|
|
321
|
+
if (missing.length === 0)
|
|
322
|
+
return input;
|
|
323
|
+
// Non-interactive: return as-is, let validation report the error
|
|
324
|
+
if (!process.stdin.isTTY)
|
|
325
|
+
return input;
|
|
326
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
327
|
+
const ask = (question) => new Promise(resolve => rl.question(question, resolve));
|
|
328
|
+
try {
|
|
329
|
+
for (const [name, prop] of missing) {
|
|
330
|
+
const typeHint = prop.type ? ` (${prop.type})` : "";
|
|
331
|
+
const description = prop.description || name;
|
|
332
|
+
const answer = await ask(`${description}${typeHint}: `);
|
|
333
|
+
if (answer === "")
|
|
334
|
+
continue;
|
|
335
|
+
// Coerce to the expected type
|
|
336
|
+
if (prop.type === "number" || prop.type === "integer") {
|
|
337
|
+
input[name] = Number(answer);
|
|
338
|
+
}
|
|
339
|
+
else if (prop.type === "boolean") {
|
|
340
|
+
input[name] = answer.toLowerCase() === "true" || answer === "1";
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
input[name] = answer;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
finally {
|
|
348
|
+
rl.close();
|
|
349
|
+
}
|
|
350
|
+
return input;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Ensure a service is available in the app configuration, injecting it if necessary.
|
|
354
|
+
* For beans that aren't registered as moddas, this dynamically imports and registers them.
|
|
355
|
+
*
|
|
356
|
+
* @param app - The application instance whose configuration may be modified
|
|
357
|
+
* @param serviceName - Name (or namespace-qualified name) of the service to ensure
|
|
358
|
+
*/
|
|
359
|
+
async function ensureServiceInConfig(app, serviceName) {
|
|
360
|
+
const appConfig = app.getConfiguration();
|
|
361
|
+
appConfig.services ??= {};
|
|
362
|
+
if (appConfig.services[serviceName])
|
|
363
|
+
return;
|
|
364
|
+
const modules = app.getModules();
|
|
365
|
+
for (const section of ["beans", "moddas"]) {
|
|
366
|
+
for (const fullName of Object.keys(modules[section] || {})) {
|
|
367
|
+
if (fullName === serviceName || fullName.endsWith(`/${serviceName}`)) {
|
|
368
|
+
appConfig.services[serviceName] = { type: fullName };
|
|
369
|
+
// Beans aren't loaded as moddas by default — register them so Core can find the type
|
|
370
|
+
if (!app.getModdas()[fullName]) {
|
|
371
|
+
const meta = modules[section][fullName];
|
|
372
|
+
const importPath = join(resolve(app.getPath()), meta.Import);
|
|
373
|
+
const [importFilename, importName = "default"] = importPath.split(":");
|
|
374
|
+
const mod = await import(importFilename.endsWith(".js") ? importFilename : importFilename + ".js");
|
|
375
|
+
const constructor = mod[importName];
|
|
376
|
+
if (constructor) {
|
|
377
|
+
app.getModdas()[fullName] = constructor;
|
|
378
|
+
// Set up filterParameters and createConfiguration like sectionLoader does
|
|
379
|
+
const { ServiceParameters: DefaultParams } = await import("../services/serviceparameters.js");
|
|
380
|
+
let configClass = DefaultParams;
|
|
381
|
+
if (meta.Configuration) {
|
|
382
|
+
const configPath = join(resolve(app.getPath()), meta.Configuration);
|
|
383
|
+
const [cfgFile, cfgName = "default"] = configPath.split(":");
|
|
384
|
+
const cfgMod = await import(cfgFile.endsWith(".js") ? cfgFile : cfgFile + ".js");
|
|
385
|
+
configClass = cfgMod[cfgName] || DefaultParams;
|
|
386
|
+
}
|
|
387
|
+
installConfigurationFactories(constructor, configClass, meta.Schema);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Default handler: prints the operation call as JSON
|
|
397
|
+
* @param call - the function to call
|
|
398
|
+
*/
|
|
399
|
+
async function defaultHandler(call) {
|
|
400
|
+
useOutput(JSON.stringify(call, undefined, 2));
|
|
401
|
+
}
|
|
402
|
+
/** Values accepted by the `--log-stream` option */
|
|
403
|
+
const LOG_STREAM_CHOICES = ["auto", "stdout", "stderr"];
|
|
404
|
+
/**
|
|
405
|
+
* Resolve where log lines go, from the raw CLI arguments
|
|
406
|
+
*
|
|
407
|
+
* `--log-stream=auto` (the default) sends logs to stderr when stdout is not a
|
|
408
|
+
* TTY, so a piped command result stays clean; `stdout` or `stderr` force it.
|
|
409
|
+
* Read from raw argv because the logger is created before yargs parses.
|
|
410
|
+
* @param argv - the raw CLI arguments
|
|
411
|
+
* @param stdoutIsTTY - whether stdout is a terminal
|
|
412
|
+
* @returns the stream for log lines
|
|
413
|
+
*/
|
|
414
|
+
export function resolveLogStream(argv, stdoutIsTTY) {
|
|
415
|
+
let value;
|
|
416
|
+
for (let i = 0; i < argv.length; i++) {
|
|
417
|
+
if (argv[i].startsWith("--log-stream=")) {
|
|
418
|
+
value = argv[i].substring("--log-stream=".length);
|
|
419
|
+
}
|
|
420
|
+
else if (argv[i] === "--log-stream") {
|
|
421
|
+
value = argv[i + 1];
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (value === "stdout" || value === "stderr") {
|
|
425
|
+
return value;
|
|
426
|
+
}
|
|
427
|
+
return stdoutIsTTY ? "stdout" : "stderr";
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Whether to route `console.*` calls to the logger, from the raw CLI arguments
|
|
431
|
+
* @param argv - the raw CLI arguments
|
|
432
|
+
* @returns false when `--no-console-patch` is given
|
|
433
|
+
*/
|
|
434
|
+
export function shouldPatchConsole(argv) {
|
|
435
|
+
return !argv.includes("--no-console-patch") && !argv.includes("--console-patch=false");
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Load the Application from a path, choosing packaged or unpacked mode based on the presence of `.webda/packaged.json`.
|
|
439
|
+
*
|
|
440
|
+
* @param appPath - Absolute or relative path to the application root directory
|
|
441
|
+
* @returns An {@link Application} (packaged) or {@link UnpackedApplication} instance
|
|
442
|
+
*/
|
|
443
|
+
function loadApplication(appPath) {
|
|
444
|
+
if (!existsSync(join(appPath, ".webda", "packaged.json"))) {
|
|
445
|
+
return new UnpackedApplication(appPath);
|
|
446
|
+
}
|
|
447
|
+
return new Application(appPath);
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Ensure services that declare a command exist in the app configuration.
|
|
451
|
+
* If a service type is not already configured, it is injected with a generated name.
|
|
452
|
+
*
|
|
453
|
+
* @param app - The loaded Application
|
|
454
|
+
* @param services - Service targets from the command metadata
|
|
455
|
+
*/
|
|
456
|
+
export function ensureCommandServices(app, services) {
|
|
457
|
+
const appConfig = app.getConfiguration();
|
|
458
|
+
appConfig.services ??= {};
|
|
459
|
+
for (const svc of services) {
|
|
460
|
+
const hasProvider = Object.values(appConfig.services).some((cfg) => cfg.type === svc.type || cfg.type === svc.type.split("/").pop()) || appConfig.services[svc.name];
|
|
461
|
+
if (!hasProvider) {
|
|
462
|
+
appConfig.services[svc.name] = { type: svc.type };
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Resolve required capabilities for a command, auto-injecting default providers
|
|
468
|
+
* into the app config if not already configured.
|
|
469
|
+
*
|
|
470
|
+
* @param app - The loaded Application
|
|
471
|
+
* @param requires - Capability names required by the command
|
|
472
|
+
*/
|
|
473
|
+
export function resolveCapabilities(app, requires) {
|
|
474
|
+
if (!requires || requires.length === 0)
|
|
475
|
+
return;
|
|
476
|
+
const modules = app.getModules();
|
|
477
|
+
const capabilities = modules.capabilities || {};
|
|
478
|
+
const appConfig = app.getConfiguration();
|
|
479
|
+
appConfig.services ??= {};
|
|
480
|
+
for (const cap of requires) {
|
|
481
|
+
const serviceType = capabilities[cap];
|
|
482
|
+
if (!serviceType) {
|
|
483
|
+
useLog("WARN", `No provider found for capability '${cap}'`);
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
// Check if a service with this type is already configured
|
|
487
|
+
const shortName = serviceType.split("/").pop();
|
|
488
|
+
const hasProvider = Object.values(appConfig.services).some((cfg) => cfg.type === serviceType || cfg.type === shortName) || appConfig.services[shortName];
|
|
489
|
+
if (!hasProvider) {
|
|
490
|
+
appConfig.services[shortName] = { type: serviceType };
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Shutdown sequence of a CLI command: stop Core once, then exit
|
|
496
|
+
*
|
|
497
|
+
* The command finishing and a signal can both trigger it: only the first call counts.
|
|
498
|
+
*
|
|
499
|
+
* @param core - the Core to stop
|
|
500
|
+
* @param core.stop - stop every service
|
|
501
|
+
* @param exit - process exit, replaceable for tests
|
|
502
|
+
* @returns `shutdown(code)` to stop then exit with the code, and `interrupt()` for SIGINT/SIGTERM
|
|
503
|
+
*/
|
|
504
|
+
export function createCommandShutdown(core, exit = code => process.exit(code)) {
|
|
505
|
+
let stopping;
|
|
506
|
+
const shutdown = (code) => {
|
|
507
|
+
stopping ??= (async () => {
|
|
508
|
+
try {
|
|
509
|
+
await core.stop();
|
|
510
|
+
}
|
|
511
|
+
catch (err) {
|
|
512
|
+
useLog("ERROR", "Cannot stop the application", err);
|
|
513
|
+
code ||= 1;
|
|
514
|
+
}
|
|
515
|
+
exit(code);
|
|
516
|
+
})();
|
|
517
|
+
return stopping;
|
|
518
|
+
};
|
|
519
|
+
const interrupt = async () => {
|
|
520
|
+
// Settle the long-running commands (serve, worker) before stopping Core
|
|
521
|
+
try {
|
|
522
|
+
await CancelablePromise.cancelAll();
|
|
523
|
+
}
|
|
524
|
+
catch (err) {
|
|
525
|
+
useLog("WARN", "Cannot cancel running processes", err);
|
|
526
|
+
}
|
|
527
|
+
await shutdown(0);
|
|
528
|
+
};
|
|
529
|
+
return { shutdown, interrupt };
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Run `interrupt` once on SIGINT or SIGTERM (Kubernetes stops pods with SIGTERM)
|
|
533
|
+
*
|
|
534
|
+
* Later signals are ignored while shutting down: on a terminal, Ctrl+C reaches both
|
|
535
|
+
* the launcher (which forwards it) and the CLI.
|
|
536
|
+
*
|
|
537
|
+
* @param interrupt - the interruption handler
|
|
538
|
+
*/
|
|
539
|
+
export function onInterrupt(interrupt) {
|
|
540
|
+
let interrupted = false;
|
|
541
|
+
const handler = () => {
|
|
542
|
+
if (interrupted)
|
|
543
|
+
return;
|
|
544
|
+
interrupted = true;
|
|
545
|
+
void interrupt();
|
|
546
|
+
};
|
|
547
|
+
process.on("SIGINT", handler);
|
|
548
|
+
process.on("SIGTERM", handler);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Run a service command until it settles, then shut down with its exit code
|
|
552
|
+
*
|
|
553
|
+
* A command that throws exits with code 1.
|
|
554
|
+
*
|
|
555
|
+
* @param cmdName - the command name, for logs
|
|
556
|
+
* @param execute - run the command and resolve with its exit code
|
|
557
|
+
* @param shutdown - stop Core then exit with the code
|
|
558
|
+
*/
|
|
559
|
+
export async function settleServiceCommand(cmdName, execute, shutdown) {
|
|
560
|
+
let exitCode;
|
|
561
|
+
try {
|
|
562
|
+
exitCode = await execute();
|
|
563
|
+
}
|
|
564
|
+
catch (err) {
|
|
565
|
+
useLog("ERROR", `Command '${cmdName}' failed`, err);
|
|
566
|
+
exitCode = 1;
|
|
567
|
+
}
|
|
568
|
+
await shutdown(exitCode);
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Log the outcome of a service command started without waiting for it (watch mode)
|
|
572
|
+
*
|
|
573
|
+
* @param cmdName - the command name, for logs
|
|
574
|
+
* @param execution - the running command, resolving with its exit code
|
|
575
|
+
*/
|
|
576
|
+
export function reportServiceCommand(cmdName, execution) {
|
|
577
|
+
execution.then(exitCode => {
|
|
578
|
+
if (exitCode !== 0) {
|
|
579
|
+
useLog("ERROR", `Command '${cmdName}' exited with code ${exitCode}`);
|
|
580
|
+
}
|
|
581
|
+
}, err => useLog("ERROR", `Command '${cmdName}' failed`, err));
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Run a service command with file watching: compiles first, then restarts on changes.
|
|
585
|
+
*
|
|
586
|
+
* @param appPath - application root path
|
|
587
|
+
* @param app - the loaded Application instance
|
|
588
|
+
* @param cmdName - the service command name
|
|
589
|
+
* @param cmdInfo - the command metadata
|
|
590
|
+
* @param args - parsed CLI arguments
|
|
591
|
+
* @param serviceFilter - optional service name filter
|
|
592
|
+
*/
|
|
593
|
+
async function runWithWatch(appPath, app, cmdName, cmdInfo, args, serviceFilter) {
|
|
594
|
+
const { Compiler, WebdaProject } = await import("@webda/compiler");
|
|
595
|
+
const project = new WebdaProject(resolve(appPath), useWorkerOutput());
|
|
596
|
+
let core;
|
|
597
|
+
let restarting = false;
|
|
598
|
+
const bootCore = async () => {
|
|
599
|
+
// Reload application to pick up regenerated webda.module.json
|
|
600
|
+
await app.load();
|
|
601
|
+
core = new Core(app);
|
|
602
|
+
await bootCoreForCommand(core, cmdName, cmdInfo);
|
|
603
|
+
// Long-running commands (serve, worker) stay pending until a restart stops Core: do not wait for them
|
|
604
|
+
reportServiceCommand(cmdName, executeServiceCommand(cmdName, cmdInfo, args, core.getServices(), serviceFilter));
|
|
605
|
+
};
|
|
606
|
+
const restart = async () => {
|
|
607
|
+
if (restarting)
|
|
608
|
+
return;
|
|
609
|
+
restarting = true;
|
|
610
|
+
await useLogLevel("INFO", async () => {
|
|
611
|
+
try {
|
|
612
|
+
if (core) {
|
|
613
|
+
useLog("INFO", "Restarting...");
|
|
614
|
+
await core.stop();
|
|
615
|
+
core = undefined;
|
|
616
|
+
}
|
|
617
|
+
await bootCore();
|
|
618
|
+
}
|
|
619
|
+
catch (err) {
|
|
620
|
+
useLog("ERROR", "Failed to restart", err.message);
|
|
621
|
+
}
|
|
622
|
+
finally {
|
|
623
|
+
restarting = false;
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
};
|
|
627
|
+
// Subscribe to compiler events
|
|
628
|
+
project.on("compiling", () => {
|
|
629
|
+
useLogLevel("INFO", () => useLog("INFO", "Changes detected, recompiling..."));
|
|
630
|
+
});
|
|
631
|
+
project.on("compilationError", () => {
|
|
632
|
+
useLog("ERROR", "Compilation failed, keeping current server running");
|
|
633
|
+
});
|
|
634
|
+
// On successful compilation + module generation, restart
|
|
635
|
+
let firstBuild = true;
|
|
636
|
+
const firstBuildReady = new Promise(resolveReady => {
|
|
637
|
+
project.on("done", async () => {
|
|
638
|
+
if (firstBuild) {
|
|
639
|
+
firstBuild = false;
|
|
640
|
+
resolveReady();
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
await restart();
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
// Start the compiler in watch mode with reduced log verbosity
|
|
648
|
+
const compiler = new Compiler(project);
|
|
649
|
+
useLogLevel("WARN", () => compiler.watch(() => { }));
|
|
650
|
+
// Wait for initial compilation before booting
|
|
651
|
+
await firstBuildReady;
|
|
652
|
+
await bootCore();
|
|
653
|
+
// Handle SIGINT and SIGTERM
|
|
654
|
+
const { interrupt } = createCommandShutdown({ stop: async () => core?.stop() });
|
|
655
|
+
onInterrupt(async () => {
|
|
656
|
+
compiler.stopWatch();
|
|
657
|
+
await interrupt();
|
|
658
|
+
});
|
|
659
|
+
// Keep process alive
|
|
660
|
+
await new Promise(() => { });
|
|
661
|
+
}
|
|
662
|
+
// Main entry point when run directly
|
|
663
|
+
const isMain = isMainModule(import.meta);
|
|
664
|
+
if (isMain) {
|
|
665
|
+
const appPath = resolve(process.env.WEBDA_APP_PATH || ".");
|
|
666
|
+
await runWithInstanceStorage({}, async () => {
|
|
667
|
+
// Ensure console output is available before anything else
|
|
668
|
+
const rawArgv = process.argv.slice(2);
|
|
669
|
+
new ConsoleLogger(useWorkerOutput(), undefined, undefined, resolveLogStream(rawArgv, !!process.stdout.isTTY));
|
|
670
|
+
if (shouldPatchConsole(rawArgv)) {
|
|
671
|
+
patchConsole();
|
|
672
|
+
}
|
|
673
|
+
try {
|
|
674
|
+
const app = loadApplication(appPath);
|
|
675
|
+
useInstanceStorage().application = app;
|
|
676
|
+
await app.load();
|
|
677
|
+
// Collect service commands from webda.module.json
|
|
678
|
+
const serviceCommands = collectServiceCommands(app);
|
|
679
|
+
// Track which command was matched so we know whether to boot Core
|
|
680
|
+
let matchedCommand;
|
|
681
|
+
// Detect if @webda/compiler is available for --watch support
|
|
682
|
+
let hasCompiler = false;
|
|
683
|
+
try {
|
|
684
|
+
createRequire(join(resolve(appPath), "package.json")).resolve("@webda/compiler");
|
|
685
|
+
hasCompiler = true;
|
|
686
|
+
}
|
|
687
|
+
catch {
|
|
688
|
+
// @webda/compiler not installed
|
|
689
|
+
}
|
|
690
|
+
// Build the CLI with operations (if available) and service commands
|
|
691
|
+
const cli = yargs(rawArgv).scriptName("webda").usage("$0 <command> [options]");
|
|
692
|
+
// Logging options are applied from raw argv before parsing; declared here for --help and validation
|
|
693
|
+
cli.option("log-stream", {
|
|
694
|
+
choices: LOG_STREAM_CHOICES,
|
|
695
|
+
default: "auto",
|
|
696
|
+
description: "Where logs go: auto sends them to stderr when stdout is not a TTY"
|
|
697
|
+
});
|
|
698
|
+
cli.option("console-patch", {
|
|
699
|
+
type: "boolean",
|
|
700
|
+
default: true,
|
|
701
|
+
description: "Route console.log/info/warn/error/debug/trace to the logger"
|
|
702
|
+
});
|
|
703
|
+
// Add --watch flag only if compiler is available
|
|
704
|
+
if (hasCompiler) {
|
|
705
|
+
cli.option("watch", {
|
|
706
|
+
alias: "w",
|
|
707
|
+
type: "boolean",
|
|
708
|
+
description: "Watch for changes, recompile and restart (requires @webda/compiler)",
|
|
709
|
+
default: false
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
// Add service commands (serve, build, etc. from @Command decorators)
|
|
713
|
+
addServiceCommandsToCli(cli, serviceCommands, async (cmdName, args) => {
|
|
714
|
+
matchedCommand = { type: "service", name: cmdName, args };
|
|
715
|
+
});
|
|
716
|
+
// Add operation commands if operations.json exists
|
|
717
|
+
const opsPath = join(resolve(appPath), ".webda", "operations.json");
|
|
718
|
+
let ops;
|
|
719
|
+
if (existsSync(opsPath)) {
|
|
720
|
+
ops = JSON.parse(readFileSync(opsPath, "utf-8"));
|
|
721
|
+
const groups = groupOperations(ops.operations);
|
|
722
|
+
for (const [group, operations] of groups) {
|
|
723
|
+
cli.command(group.toLowerCase(), `${group} operations`, groupY => {
|
|
724
|
+
for (const op of operations) {
|
|
725
|
+
const action = op.id.substring(op.id.indexOf(".") + 1).toLowerCase();
|
|
726
|
+
const hasInput = op.input && op.input !== "void";
|
|
727
|
+
const paramDef = hasInput ? KNOWN_PARAMS[op.input] : undefined;
|
|
728
|
+
const cmd = paramDef?.positional ? `${action} <${paramDef.positional}>` : action;
|
|
729
|
+
groupY.command(cmd, op.id, y => addOperationOptions(y, op, ops), async (args) => {
|
|
730
|
+
matchedCommand = {
|
|
731
|
+
type: "operation",
|
|
732
|
+
call: {
|
|
733
|
+
id: op.id,
|
|
734
|
+
parameters: extractParameters(args, op, ops),
|
|
735
|
+
input: hasInput ? extractInput(args, op, ops) : undefined
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
return groupY.demandCommand(1, `Specify an action for ${group.toLowerCase()}`);
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
cli.completion("completion", false).demandCommand(1, "Specify a command").help();
|
|
745
|
+
await cli.parseAsync();
|
|
746
|
+
if (!matchedCommand) {
|
|
747
|
+
// No command matched, yargs already showed help or error
|
|
748
|
+
process.exit(1);
|
|
749
|
+
}
|
|
750
|
+
if (matchedCommand.type === "operation") {
|
|
751
|
+
// Execute the operation through Core
|
|
752
|
+
const call = matchedCommand.call;
|
|
753
|
+
// Derive service name and method from the operation ID (e.g. "TestBean.TestOperation")
|
|
754
|
+
const dot = call.id.indexOf(".");
|
|
755
|
+
const serviceName = call.id.substring(0, dot);
|
|
756
|
+
const methodName = call.id.substring(dot + 1, dot + 2).toLowerCase() + call.id.substring(dot + 2);
|
|
757
|
+
// Ensure the operation's service exists in the configuration
|
|
758
|
+
await ensureServiceInConfig(app, serviceName);
|
|
759
|
+
const core = new Core(app);
|
|
760
|
+
onInterrupt(createCommandShutdown(core).interrupt);
|
|
761
|
+
await core.init();
|
|
762
|
+
// Find the service
|
|
763
|
+
const services = core.getServices();
|
|
764
|
+
let service = services[serviceName];
|
|
765
|
+
if (!service) {
|
|
766
|
+
for (const [name, svc] of Object.entries(services)) {
|
|
767
|
+
if (svc?.constructor?.name === serviceName || name.endsWith(`/${serviceName}`)) {
|
|
768
|
+
service = svc;
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
if (!service) {
|
|
774
|
+
useLog("ERROR", `Service '${serviceName}' not found for operation '${call.id}'`);
|
|
775
|
+
process.exit(1);
|
|
776
|
+
}
|
|
777
|
+
if (typeof service[methodName] !== "function") {
|
|
778
|
+
useLog("ERROR", `Method '${methodName}' not found on service '${serviceName}'`);
|
|
779
|
+
process.exit(1);
|
|
780
|
+
}
|
|
781
|
+
// Validate input against JSON schema if the operation defines one
|
|
782
|
+
// If interactive and missing properties, prompt the user
|
|
783
|
+
const opEntry = ops?.operations[call.id];
|
|
784
|
+
if (opEntry?.input && ops.schemas[opEntry.input]) {
|
|
785
|
+
const inputSchema = ops.schemas[opEntry.input];
|
|
786
|
+
call.input = await promptForMissingInput(call.input ?? {}, inputSchema);
|
|
787
|
+
const { registerSchema, validateSchema } = await import("../schemas/hooks.js");
|
|
788
|
+
registerSchema(opEntry.input, inputSchema);
|
|
789
|
+
validateSchema(opEntry.input, call.input);
|
|
790
|
+
}
|
|
791
|
+
// Call the method with input properties as positional arguments
|
|
792
|
+
const inputArgs = call.input ? Object.values(call.input) : [];
|
|
793
|
+
const result = await service[methodName](...inputArgs);
|
|
794
|
+
if (result !== undefined) {
|
|
795
|
+
useOutput(typeof result === "string" ? result : JSON.stringify(result, undefined, 2));
|
|
796
|
+
}
|
|
797
|
+
await core.stop();
|
|
798
|
+
process.exit(0);
|
|
799
|
+
}
|
|
800
|
+
else {
|
|
801
|
+
// Service command: boot Core and execute
|
|
802
|
+
const cmdInfo = serviceCommands[matchedCommand.name];
|
|
803
|
+
const serviceFilter = matchedCommand.args.service?.split(",");
|
|
804
|
+
// Ensure services required by this command exist in the configuration
|
|
805
|
+
ensureCommandServices(app, cmdInfo.services);
|
|
806
|
+
// Auto-inject capability providers required by this command
|
|
807
|
+
resolveCapabilities(app, cmdInfo.requires);
|
|
808
|
+
if (matchedCommand.args.watch && hasCompiler) {
|
|
809
|
+
await runWithWatch(appPath, app, matchedCommand.name, cmdInfo, matchedCommand.args, serviceFilter);
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
812
|
+
const core = new Core(app);
|
|
813
|
+
const { shutdown, interrupt } = createCommandShutdown(core);
|
|
814
|
+
onInterrupt(interrupt);
|
|
815
|
+
await bootCoreForCommand(core, matchedCommand.name, cmdInfo);
|
|
816
|
+
// Long-running commands (serve, worker) only settle once stopped or interrupted
|
|
817
|
+
const { name: commandName, args: commandArgs } = matchedCommand;
|
|
818
|
+
await settleServiceCommand(commandName, () => executeServiceCommand(commandName, cmdInfo, commandArgs, core.getServices(), serviceFilter), shutdown);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
catch (err) {
|
|
823
|
+
console.error(err.message);
|
|
824
|
+
process.exit(1);
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
//# sourceMappingURL=cli.js.map
|