@webda/core 4.0.0-beta.2 → 4.0.0-beta.4
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 +468 -0
- package/lib/application/application.d.ts.map +1 -0
- package/lib/application/application.js +845 -0
- package/lib/application/application.js.map +1 -0
- package/lib/application/deployment.d.ts +93 -0
- package/lib/application/deployment.d.ts.map +1 -0
- package/lib/application/deployment.js +99 -0
- package/lib/application/deployment.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/{unpackedapplication.d.ts → application/unpackedapplication.d.ts} +43 -23
- package/lib/application/unpackedapplication.d.ts.map +1 -0
- package/lib/application/unpackedapplication.js +500 -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 +196 -0
- package/lib/bin/cli.d.ts.map +1 -0
- package/lib/bin/cli.js +934 -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 -58
- 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 +44 -19
- package/lib/contexts/httpcontext.d.ts.map +1 -0
- package/lib/{utils → contexts}/httpcontext.js +95 -27
- 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 +182 -0
- package/lib/contexts/operationcontext.d.ts.map +1 -0
- package/lib/contexts/operationcontext.js +361 -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 +94 -0
- package/lib/core/hooks.d.ts.map +1 -0
- package/lib/core/hooks.js +97 -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/deployers/deployer.d.ts +157 -0
- package/lib/deployers/deployer.d.ts.map +1 -0
- package/lib/deployers/deployer.js +81 -0
- package/lib/deployers/deployer.js.map +1 -0
- package/lib/deployers/git.d.ts +27 -0
- package/lib/deployers/git.d.ts.map +1 -0
- package/lib/deployers/git.js +66 -0
- package/lib/deployers/git.js.map +1 -0
- package/lib/deployers/packager.d.ts +85 -0
- package/lib/deployers/packager.d.ts.map +1 -0
- package/lib/deployers/packager.js +259 -0
- package/lib/deployers/packager.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 +88 -54
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +88 -64
- 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 +20 -76
- package/lib/models/aclmodel.d.ts.map +1 -1
- package/lib/models/aclmodel.js +27 -203
- 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 +67 -0
- package/lib/models/decorator.d.ts.map +1 -0
- package/lib/models/decorator.js +67 -0
- package/lib/models/decorator.js.map +1 -0
- package/lib/models/deployment.d.ts +2 -21
- package/lib/models/deployment.d.ts.map +1 -1
- package/lib/models/encrypted.model.d.ts +46 -0
- package/lib/models/encrypted.model.d.ts.map +1 -0
- package/lib/models/encrypted.model.js +87 -0
- package/lib/models/encrypted.model.js.map +1 -0
- package/lib/models/ident.model.d.ts +128 -0
- package/lib/models/ident.model.d.ts.map +1 -0
- package/lib/models/ident.model.js +207 -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 +113 -0
- package/lib/models/ownermodel.model.js.map +1 -0
- package/lib/models/password.model.d.ts +78 -0
- package/lib/models/password.model.d.ts.map +1 -0
- package/lib/models/password.model.js +171 -0
- package/lib/models/password.model.js.map +1 -0
- package/lib/models/refreshtoken.model.d.ts +30 -0
- package/lib/models/refreshtoken.model.d.ts.map +1 -0
- package/lib/models/refreshtoken.model.js +29 -0
- package/lib/models/refreshtoken.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.js → rolemodel.model.js} +23 -5
- 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 +124 -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 +164 -0
- package/lib/models/user.model.js.map +1 -0
- package/lib/queues/{memoryqueue.d.ts → memoryqueue.service.d.ts} +26 -13
- package/lib/queues/memoryqueue.service.d.ts.map +1 -0
- package/lib/queues/{memoryqueue.js → memoryqueue.service.js} +55 -31
- package/lib/queues/memoryqueue.service.js.map +1 -0
- package/lib/queues/pubsubservice.d.ts +8 -6
- package/lib/queues/pubsubservice.d.ts.map +1 -1
- package/lib/queues/pubsubservice.js +5 -4
- package/lib/queues/pubsubservice.js.map +1 -1
- package/lib/queues/queueservice.d.ts +9 -11
- package/lib/queues/queueservice.d.ts.map +1 -1
- package/lib/queues/queueservice.js +41 -13
- 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 +432 -0
- package/lib/services/audit.model.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 +17 -12
- package/lib/services/cloudbinary.d.ts.map +1 -1
- package/lib/services/cloudbinary.js +23 -17
- 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} +75 -141
- 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.js → debugmailer.service.js} +25 -10
- package/lib/services/debugmailer.service.js.map +1 -0
- package/lib/services/domainservice.service.d.ts +242 -0
- package/lib/services/domainservice.service.d.ts.map +1 -0
- package/lib/services/domainservice.service.js +676 -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 +202 -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 -11
- 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/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 -12
- 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.d.ts → resource.service.d.ts} +34 -15
- 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 +87 -188
- package/lib/services/service.d.ts.map +1 -1
- package/lib/services/service.js +407 -422
- 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 +171 -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/services/token.service.d.ts +95 -0
- package/lib/services/token.service.d.ts.map +1 -0
- package/lib/services/token.service.js +182 -0
- package/lib/services/token.service.js.map +1 -0
- package/lib/{utils → session}/cookie.d.ts +32 -19
- 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 +87 -0
- package/lib/session/manager.model.d.ts.map +1 -0
- package/lib/session/manager.model.js +212 -0
- package/lib/session/manager.model.js.map +1 -0
- package/lib/session/session.d.ts +100 -0
- package/lib/session/session.d.ts.map +1 -0
- package/lib/session/session.js +175 -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 +344 -0
- package/lib/stores/memory.service.js.map +1 -0
- package/lib/stores/store.d.ts +126 -626
- package/lib/stores/store.d.ts.map +1 -1
- package/lib/stores/store.js +257 -1117
- package/lib/stores/store.js.map +1 -1
- package/lib/templates/templates.d.ts +47 -0
- package/lib/templates/templates.d.ts.map +1 -0
- package/lib/templates/templates.js +101 -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/behavior-fixture.model.d.ts +30 -0
- package/lib/test/behavior-fixture.model.d.ts.map +1 -0
- package/lib/test/behavior-fixture.model.js +63 -0
- package/lib/test/behavior-fixture.model.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/legacyident.fixture.model.d.ts +98 -0
- package/lib/test/legacyident.fixture.model.d.ts.map +1 -0
- package/lib/test/legacyident.fixture.model.js +125 -0
- package/lib/test/legacyident.fixture.model.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 +4 -2
- package/lib/utils/abstractdeployer.d.ts.map +1 -1
- package/lib/utils/abstractdeployer.js +3 -0
- package/lib/utils/abstractdeployer.js.map +1 -1
- package/package.json +102 -60
- package/test/cachedapp/webda.config.json +1 -5
- package/test/config-cached.json +3 -6
- package/test/config.json +3 -10
- package/test/my-cnf.json +9 -0
- package/webda.module.json +3755 -2496
- package/lib/application.d.ts +0 -888
- package/lib/application.d.ts.map +0 -1
- package/lib/application.js +0 -768
- package/lib/application.js.map +0 -1
- package/lib/application.spec.d.ts +0 -2
- package/lib/application.spec.d.ts.map +0 -1
- package/lib/application.spec.js +0 -248
- package/lib/application.spec.js.map +0 -1
- package/lib/core.d.ts +0 -743
- package/lib/core.d.ts.map +0 -1
- package/lib/core.js +0 -1334
- package/lib/core.js.map +0 -1
- package/lib/core.spec.d.ts +0 -2
- package/lib/core.spec.d.ts.map +0 -1
- package/lib/core.spec.js +0 -790
- package/lib/core.spec.js.map +0 -1
- package/lib/errors.d.ts +0 -64
- package/lib/errors.d.ts.map +0 -1
- package/lib/errors.js +0 -97
- package/lib/errors.js.map +0 -1
- package/lib/errors.spec.d.ts +0 -2
- package/lib/errors.spec.d.ts.map +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 -2
- package/lib/models/aclmodel.spec.d.ts.map +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 -896
- package/lib/models/coremodel.d.ts.map +0 -1
- package/lib/models/coremodel.js +0 -1214
- package/lib/models/coremodel.js.map +0 -1
- package/lib/models/coremodel.spec.d.ts +0 -2
- package/lib/models/coremodel.spec.d.ts.map +0 -1
- package/lib/models/coremodel.spec.js +0 -464
- package/lib/models/coremodel.spec.js.map +0 -1
- package/lib/models/ident.d.ts +0 -68
- package/lib/models/ident.d.ts.map +0 -1
- package/lib/models/ident.js +0 -26
- package/lib/models/ident.js.map +0 -1
- package/lib/models/ident.spec.d.ts +0 -2
- package/lib/models/ident.spec.d.ts.map +0 -1
- package/lib/models/ident.spec.js +0 -24
- package/lib/models/ident.spec.js.map +0 -1
- package/lib/models/ownermodel.d.ts +0 -51
- package/lib/models/ownermodel.d.ts.map +0 -1
- package/lib/models/ownermodel.js +0 -65
- package/lib/models/ownermodel.js.map +0 -1
- package/lib/models/ownermodel.spec.d.ts +0 -2
- package/lib/models/ownermodel.spec.d.ts.map +0 -1
- package/lib/models/ownermodel.spec.js +0 -215
- package/lib/models/ownermodel.spec.js.map +0 -1
- package/lib/models/relations.d.ts +0 -182
- package/lib/models/relations.d.ts.map +0 -1
- package/lib/models/relations.js +0 -157
- package/lib/models/relations.js.map +0 -1
- package/lib/models/relations.spec.d.ts +0 -14
- package/lib/models/relations.spec.d.ts.map +0 -1
- package/lib/models/relations.spec.js +0 -217
- package/lib/models/relations.spec.js.map +0 -1
- package/lib/models/rolemodel.d.ts +0 -11
- package/lib/models/rolemodel.d.ts.map +0 -1
- package/lib/models/rolemodel.js.map +0 -1
- package/lib/models/rolemodel.spec.d.ts +0 -2
- package/lib/models/rolemodel.spec.d.ts.map +0 -1
- package/lib/models/rolemodel.spec.js +0 -90
- package/lib/models/rolemodel.spec.js.map +0 -1
- package/lib/models/simpleuser.d.ts +0 -47
- package/lib/models/simpleuser.d.ts.map +0 -1
- package/lib/models/simpleuser.js +0 -84
- package/lib/models/simpleuser.js.map +0 -1
- package/lib/models/test.d.ts +0 -11
- package/lib/models/test.d.ts.map +0 -1
- package/lib/models/test.js +0 -7
- package/lib/models/test.js.map +0 -1
- package/lib/models/user.d.ts +0 -67
- package/lib/models/user.d.ts.map +0 -1
- package/lib/models/user.js +0 -86
- package/lib/models/user.js.map +0 -1
- package/lib/models/user.spec.d.ts +0 -2
- package/lib/models/user.spec.d.ts.map +0 -1
- package/lib/models/user.spec.js +0 -89
- package/lib/models/user.spec.js.map +0 -1
- package/lib/queues/filequeue.d.ts +0 -59
- package/lib/queues/filequeue.d.ts.map +0 -1
- package/lib/queues/filequeue.js +0 -131
- package/lib/queues/filequeue.js.map +0 -1
- package/lib/queues/filequeue.spec.d.ts +0 -2
- package/lib/queues/filequeue.spec.d.ts.map +0 -1
- package/lib/queues/filequeue.spec.js +0 -84
- package/lib/queues/filequeue.spec.js.map +0 -1
- package/lib/queues/memoryqueue.d.ts.map +0 -1
- package/lib/queues/memoryqueue.js.map +0 -1
- package/lib/queues/memoryqueue.spec.d.ts +0 -2
- package/lib/queues/memoryqueue.spec.d.ts.map +0 -1
- package/lib/queues/memoryqueue.spec.js +0 -203
- package/lib/queues/memoryqueue.spec.js.map +0 -1
- package/lib/queues/queue.spec.d.ts +0 -6
- package/lib/queues/queue.spec.d.ts.map +0 -1
- package/lib/queues/queue.spec.js +0 -55
- package/lib/queues/queue.spec.js.map +0 -1
- package/lib/rest/restdomainservice.d.ts +0 -63
- package/lib/rest/restdomainservice.d.ts.map +0 -1
- package/lib/rest/restdomainservice.js +0 -687
- package/lib/rest/restdomainservice.js.map +0 -1
- package/lib/rest/restdomainservice.spec.d.ts +0 -2
- package/lib/rest/restdomainservice.spec.d.ts.map +0 -1
- package/lib/rest/restdomainservice.spec.js +0 -124
- package/lib/rest/restdomainservice.spec.js.map +0 -1
- package/lib/rest/router.d.ts +0 -174
- package/lib/rest/router.d.ts.map +0 -1
- package/lib/rest/router.js +0 -429
- package/lib/rest/router.js.map +0 -1
- package/lib/rest/router.spec.d.ts +0 -2
- package/lib/rest/router.spec.d.ts.map +0 -1
- package/lib/rest/router.spec.js +0 -255
- package/lib/rest/router.spec.js.map +0 -1
- package/lib/services/asyncevents.d.ts +0 -152
- package/lib/services/asyncevents.d.ts.map +0 -1
- package/lib/services/asyncevents.js +0 -217
- package/lib/services/asyncevents.js.map +0 -1
- package/lib/services/asyncevents.spec.d.ts +0 -2
- package/lib/services/asyncevents.spec.d.ts.map +0 -1
- package/lib/services/asyncevents.spec.js +0 -118
- package/lib/services/asyncevents.spec.js.map +0 -1
- package/lib/services/authentication.d.ts +0 -361
- package/lib/services/authentication.d.ts.map +0 -1
- package/lib/services/authentication.js +0 -773
- package/lib/services/authentication.js.map +0 -1
- package/lib/services/authentication.spec.d.ts +0 -2
- package/lib/services/authentication.spec.d.ts.map +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 -477
- package/lib/services/binary.d.ts.map +0 -1
- package/lib/services/binary.js +0 -617
- package/lib/services/binary.js.map +0 -1
- package/lib/services/binary.spec.d.ts +0 -41
- package/lib/services/binary.spec.d.ts.map +0 -1
- package/lib/services/binary.spec.js +0 -151
- package/lib/services/binary.spec.js.map +0 -1
- package/lib/services/cloudbinary.spec.d.ts +0 -6
- package/lib/services/cloudbinary.spec.d.ts.map +0 -1
- package/lib/services/cloudbinary.spec.js +0 -66
- package/lib/services/cloudbinary.spec.js.map +0 -1
- package/lib/services/configuration.d.ts.map +0 -1
- package/lib/services/configuration.js +0 -193
- package/lib/services/configuration.js.map +0 -1
- package/lib/services/configuration.spec.d.ts +0 -2
- package/lib/services/configuration.spec.d.ts.map +0 -1
- package/lib/services/configuration.spec.js +0 -130
- package/lib/services/configuration.spec.js.map +0 -1
- package/lib/services/cron.d.ts +0 -74
- package/lib/services/cron.d.ts.map +0 -1
- package/lib/services/cron.js +0 -141
- package/lib/services/cron.js.map +0 -1
- package/lib/services/cron.spec.d.ts +0 -2
- package/lib/services/cron.spec.d.ts.map +0 -1
- package/lib/services/cron.spec.js +0 -76
- package/lib/services/cron.spec.js.map +0 -1
- package/lib/services/cryptoservice.d.ts.map +0 -1
- package/lib/services/cryptoservice.js +0 -433
- package/lib/services/cryptoservice.js.map +0 -1
- package/lib/services/cryptoservice.spec.d.ts +0 -2
- package/lib/services/cryptoservice.spec.d.ts.map +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.d.ts.map +0 -1
- package/lib/services/debugmailer.js.map +0 -1
- package/lib/services/debugmailer.spec.d.ts +0 -2
- package/lib/services/debugmailer.spec.d.ts.map +0 -1
- package/lib/services/debugmailer.spec.js +0 -32
- package/lib/services/debugmailer.spec.js.map +0 -1
- package/lib/services/domainservice.d.ts +0 -272
- package/lib/services/domainservice.d.ts.map +0 -1
- package/lib/services/domainservice.js +0 -651
- package/lib/services/domainservice.js.map +0 -1
- package/lib/services/domainservice.spec.d.ts +0 -2
- package/lib/services/domainservice.spec.d.ts.map +0 -1
- package/lib/services/domainservice.spec.js +0 -592
- package/lib/services/domainservice.spec.js.map +0 -1
- package/lib/services/filebinary.d.ts +0 -136
- package/lib/services/filebinary.d.ts.map +0 -1
- package/lib/services/filebinary.js +0 -373
- package/lib/services/filebinary.js.map +0 -1
- package/lib/services/filebinary.spec.d.ts +0 -25
- package/lib/services/filebinary.spec.d.ts.map +0 -1
- package/lib/services/filebinary.spec.js +0 -428
- package/lib/services/filebinary.spec.js.map +0 -1
- package/lib/services/fileconfiguration.d.ts +0 -23
- package/lib/services/fileconfiguration.d.ts.map +0 -1
- package/lib/services/fileconfiguration.js +0 -48
- package/lib/services/fileconfiguration.js.map +0 -1
- package/lib/services/fileconfiguration.spec.d.ts +0 -2
- package/lib/services/fileconfiguration.spec.d.ts.map +0 -1
- package/lib/services/fileconfiguration.spec.js +0 -215
- package/lib/services/fileconfiguration.spec.js.map +0 -1
- package/lib/services/invitationservice.d.ts +0 -223
- package/lib/services/invitationservice.d.ts.map +0 -1
- package/lib/services/invitationservice.js +0 -529
- package/lib/services/invitationservice.js.map +0 -1
- package/lib/services/invitationservice.spec.d.ts +0 -2
- package/lib/services/invitationservice.spec.d.ts.map +0 -1
- package/lib/services/invitationservice.spec.js +0 -567
- package/lib/services/invitationservice.spec.js.map +0 -1
- package/lib/services/kubernetesconfiguration.d.ts +0 -27
- package/lib/services/kubernetesconfiguration.d.ts.map +0 -1
- package/lib/services/kubernetesconfiguration.js +0 -52
- package/lib/services/kubernetesconfiguration.js.map +0 -1
- package/lib/services/kubernetesconfiguration.spec.d.ts +0 -2
- package/lib/services/kubernetesconfiguration.spec.d.ts.map +0 -1
- package/lib/services/kubernetesconfiguration.spec.js +0 -206
- package/lib/services/kubernetesconfiguration.spec.js.map +0 -1
- package/lib/services/mailer.d.ts +0 -166
- package/lib/services/mailer.d.ts.map +0 -1
- package/lib/services/mailer.js +0 -176
- package/lib/services/mailer.js.map +0 -1
- package/lib/services/mailer.spec.d.ts +0 -2
- package/lib/services/mailer.spec.d.ts.map +0 -1
- package/lib/services/mailer.spec.js +0 -158
- package/lib/services/mailer.spec.js.map +0 -1
- package/lib/services/notificationservice.d.ts.map +0 -1
- package/lib/services/notificationservice.js.map +0 -1
- package/lib/services/notificationservice.spec.d.ts +0 -2
- package/lib/services/notificationservice.spec.d.ts.map +0 -1
- package/lib/services/notificationservice.spec.js +0 -83
- package/lib/services/notificationservice.spec.js.map +0 -1
- package/lib/services/oauth.d.ts +0 -226
- package/lib/services/oauth.d.ts.map +0 -1
- package/lib/services/oauth.js +0 -294
- package/lib/services/oauth.js.map +0 -1
- package/lib/services/oauth.spec.d.ts +0 -2
- package/lib/services/oauth.spec.d.ts.map +0 -1
- package/lib/services/oauth.spec.js +0 -208
- package/lib/services/oauth.spec.js.map +0 -1
- package/lib/services/prometheus.d.ts.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 -2
- package/lib/services/prometheus.spec.d.ts.map +0 -1
- package/lib/services/prometheus.spec.js +0 -76
- package/lib/services/prometheus.spec.js.map +0 -1
- package/lib/services/resource.d.ts.map +0 -1
- package/lib/services/resource.js +0 -170
- package/lib/services/resource.js.map +0 -1
- package/lib/services/resource.spec.d.ts +0 -2
- package/lib/services/resource.spec.d.ts.map +0 -1
- package/lib/services/resource.spec.js +0 -140
- package/lib/services/resource.spec.js.map +0 -1
- package/lib/services/service.spec.d.ts +0 -2
- package/lib/services/service.spec.d.ts.map +0 -1
- package/lib/services/service.spec.js +0 -286
- package/lib/services/service.spec.js.map +0 -1
- package/lib/stores/aggregator.d.ts +0 -48
- package/lib/stores/aggregator.d.ts.map +0 -1
- package/lib/stores/aggregator.js +0 -80
- package/lib/stores/aggregator.js.map +0 -1
- package/lib/stores/file.d.ts +0 -108
- package/lib/stores/file.d.ts.map +0 -1
- package/lib/stores/file.js +0 -188
- package/lib/stores/file.js.map +0 -1
- package/lib/stores/file.spec.d.ts +0 -13
- package/lib/stores/file.spec.d.ts.map +0 -1
- package/lib/stores/file.spec.js +0 -138
- package/lib/stores/file.spec.js.map +0 -1
- package/lib/stores/mapper.d.ts +0 -150
- package/lib/stores/mapper.d.ts.map +0 -1
- package/lib/stores/mapper.js +0 -293
- package/lib/stores/mapper.js.map +0 -1
- package/lib/stores/mapper.spec.d.ts +0 -2
- package/lib/stores/mapper.spec.d.ts.map +0 -1
- package/lib/stores/mapper.spec.js +0 -167
- package/lib/stores/mapper.spec.js.map +0 -1
- package/lib/stores/memory.d.ts +0 -152
- package/lib/stores/memory.d.ts.map +0 -1
- package/lib/stores/memory.js +0 -371
- package/lib/stores/memory.js.map +0 -1
- package/lib/stores/memory.spec.d.ts +0 -14
- package/lib/stores/memory.spec.d.ts.map +0 -1
- package/lib/stores/memory.spec.js +0 -263
- package/lib/stores/memory.spec.js.map +0 -1
- package/lib/stores/modelmapper.d.ts +0 -62
- package/lib/stores/modelmapper.d.ts.map +0 -1
- package/lib/stores/modelmapper.js +0 -197
- package/lib/stores/modelmapper.js.map +0 -1
- package/lib/stores/store.spec.d.ts +0 -57
- package/lib/stores/store.spec.d.ts.map +0 -1
- package/lib/stores/store.spec.js +0 -737
- package/lib/stores/store.spec.js.map +0 -1
- package/lib/test.d.ts +0 -265
- package/lib/test.d.ts.map +0 -1
- package/lib/test.js +0 -622
- package/lib/test.js.map +0 -1
- package/lib/unpackedapplication.d.ts.map +0 -1
- package/lib/unpackedapplication.js +0 -350
- package/lib/unpackedapplication.js.map +0 -1
- package/lib/utils/abstractdeployer.spec.d.ts +0 -2
- package/lib/utils/abstractdeployer.spec.d.ts.map +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 -8
- package/lib/utils/case.d.ts.map +0 -1
- package/lib/utils/case.js +0 -43
- package/lib/utils/case.js.map +0 -1
- package/lib/utils/case.spec.d.ts +0 -2
- package/lib/utils/case.spec.d.ts.map +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 -482
- package/lib/utils/context.d.ts.map +0 -1
- package/lib/utils/context.js +0 -739
- package/lib/utils/context.js.map +0 -1
- package/lib/utils/context.spec.d.ts +0 -10
- package/lib/utils/context.spec.d.ts.map +0 -1
- package/lib/utils/context.spec.js +0 -383
- package/lib/utils/context.spec.js.map +0 -1
- package/lib/utils/cookie.d.ts.map +0 -1
- package/lib/utils/cookie.js.map +0 -1
- package/lib/utils/cookie.spec.d.ts +0 -2
- package/lib/utils/cookie.spec.d.ts.map +0 -1
- package/lib/utils/cookie.spec.js +0 -88
- package/lib/utils/cookie.spec.js.map +0 -1
- package/lib/utils/esm.d.ts +0 -14
- package/lib/utils/esm.d.ts.map +0 -1
- package/lib/utils/esm.js +0 -19
- package/lib/utils/esm.js.map +0 -1
- package/lib/utils/httpcontext.d.ts.map +0 -1
- package/lib/utils/httpcontext.js.map +0 -1
- package/lib/utils/httpcontext.spec.d.ts +0 -5
- package/lib/utils/httpcontext.spec.d.ts.map +0 -1
- package/lib/utils/httpcontext.spec.js +0 -77
- package/lib/utils/httpcontext.spec.js.map +0 -1
- package/lib/utils/logger.d.ts +0 -92
- package/lib/utils/logger.d.ts.map +0 -1
- package/lib/utils/logger.js +0 -121
- package/lib/utils/logger.js.map +0 -1
- package/lib/utils/logger.spec.d.ts +0 -2
- package/lib/utils/logger.spec.d.ts.map +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 -162
- package/lib/utils/serializers.d.ts.map +0 -1
- package/lib/utils/serializers.js +0 -420
- package/lib/utils/serializers.js.map +0 -1
- package/lib/utils/serializers.spec.d.ts +0 -2
- package/lib/utils/serializers.spec.d.ts.map +0 -1
- package/lib/utils/serializers.spec.js +0 -311
- package/lib/utils/serializers.spec.js.map +0 -1
- package/lib/utils/session.d.ts +0 -123
- package/lib/utils/session.d.ts.map +0 -1
- package/lib/utils/session.js +0 -156
- package/lib/utils/session.js.map +0 -1
- package/lib/utils/session.spec.d.ts +0 -2
- package/lib/utils/session.spec.d.ts.map +0 -1
- package/lib/utils/session.spec.js +0 -81
- package/lib/utils/session.spec.js.map +0 -1
- package/lib/utils/throttler.d.ts +0 -99
- package/lib/utils/throttler.d.ts.map +0 -1
- package/lib/utils/throttler.js +0 -160
- package/lib/utils/throttler.js.map +0 -1
- package/lib/utils/throttler.spec.d.ts +0 -2
- package/lib/utils/throttler.spec.d.ts.map +0 -1
- package/lib/utils/throttler.spec.js +0 -53
- package/lib/utils/throttler.spec.js.map +0 -1
- package/lib/utils/waiter.d.ts +0 -94
- package/lib/utils/waiter.d.ts.map +0 -1
- package/lib/utils/waiter.js +0 -148
- package/lib/utils/waiter.js.map +0 -1
- package/lib/utils/waiter.spec.d.ts +0 -2
- package/lib/utils/waiter.spec.d.ts.map +0 -1
- package/lib/utils/waiter.spec.js +0 -98
- package/lib/utils/waiter.spec.js.map +0 -1
- package/test/jsonutils/mdocs.yaml +0 -56
- package/test/jsonutils/test.json +0 -3
- package/test/jsonutils/test.yml +0 -5
|
@@ -0,0 +1,1365 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import * as crypto from "crypto";
|
|
36
|
+
import * as fs from "fs";
|
|
37
|
+
import * as mime from "mime-types";
|
|
38
|
+
import * as path from "path";
|
|
39
|
+
import { Readable } from "stream";
|
|
40
|
+
import * as WebdaError from "../errors/errors.js";
|
|
41
|
+
import { Service } from "./service.js";
|
|
42
|
+
import { NotEnumerable } from "@webda/tsc-esm";
|
|
43
|
+
import { useCore, useModelMetadata } from "../core/hooks.js";
|
|
44
|
+
import { ServiceParameters } from "./serviceparameters.js";
|
|
45
|
+
import { Counter } from "../metrics/metrics.js";
|
|
46
|
+
import { WEBDA_STORAGE } from "@webda/models";
|
|
47
|
+
import { streamToBuffer, FileSize } from "@webda/utils";
|
|
48
|
+
import { Action } from "../models/decorator.js";
|
|
49
|
+
import { useContext } from "../contexts/execution.js";
|
|
50
|
+
import { WebContext } from "../contexts/webcontext.js";
|
|
51
|
+
/**
|
|
52
|
+
* Emitted if binary does not exist
|
|
53
|
+
*/
|
|
54
|
+
export class BinaryNotFoundError extends WebdaError.CodeError {
|
|
55
|
+
/** Create a new BinaryNotFoundError
|
|
56
|
+
* @param hash - the binary hash
|
|
57
|
+
* @param storeName - the binary service name
|
|
58
|
+
*/
|
|
59
|
+
constructor(hash, storeName) {
|
|
60
|
+
super("BINARY_NOTFOUND", `Binary not found ${hash} BinaryService(${storeName})`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Represent a file to store
|
|
65
|
+
* @WebdaSchema
|
|
66
|
+
*/
|
|
67
|
+
export class BinaryFile {
|
|
68
|
+
/**
|
|
69
|
+
* Current name
|
|
70
|
+
*/
|
|
71
|
+
name;
|
|
72
|
+
/**
|
|
73
|
+
* Original name
|
|
74
|
+
*/
|
|
75
|
+
originalname;
|
|
76
|
+
/**
|
|
77
|
+
* Size of the binary
|
|
78
|
+
*/
|
|
79
|
+
size;
|
|
80
|
+
/**
|
|
81
|
+
* Mimetype of the binary
|
|
82
|
+
*/
|
|
83
|
+
mimetype;
|
|
84
|
+
/**
|
|
85
|
+
* Will be computed by the service
|
|
86
|
+
*
|
|
87
|
+
* hash of the content prefixed by 'WEBDA'
|
|
88
|
+
*/
|
|
89
|
+
challenge;
|
|
90
|
+
/**
|
|
91
|
+
* Will be computed by the service
|
|
92
|
+
*
|
|
93
|
+
* hash of the content
|
|
94
|
+
*/
|
|
95
|
+
hash;
|
|
96
|
+
/**
|
|
97
|
+
* Metadatas stored along with the binary
|
|
98
|
+
*/
|
|
99
|
+
metadata;
|
|
100
|
+
/** Create a new BinaryFile
|
|
101
|
+
* @param info - the binary file information
|
|
102
|
+
*/
|
|
103
|
+
constructor(info) {
|
|
104
|
+
this.set(info);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Set the information
|
|
108
|
+
* @param info - the information object
|
|
109
|
+
*/
|
|
110
|
+
set(info) {
|
|
111
|
+
this.name = info.name;
|
|
112
|
+
this.challenge = info.challenge;
|
|
113
|
+
this.hash = info.hash;
|
|
114
|
+
this.mimetype = info.mimetype || "application/octet-stream";
|
|
115
|
+
this.metadata = info.metadata || {};
|
|
116
|
+
this.size = info.size;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Retrieve a plain BinaryFileInfo object
|
|
120
|
+
* @returns the result
|
|
121
|
+
*/
|
|
122
|
+
toBinaryFileInfo() {
|
|
123
|
+
return {
|
|
124
|
+
hash: this.hash,
|
|
125
|
+
size: this.size,
|
|
126
|
+
mimetype: this.mimetype,
|
|
127
|
+
metadata: this.metadata,
|
|
128
|
+
challenge: this.challenge,
|
|
129
|
+
// Fallback on original name
|
|
130
|
+
name: this.name || this.originalname
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Create hashes
|
|
135
|
+
* @param buffer - the buffer
|
|
136
|
+
* @returns the result
|
|
137
|
+
*/
|
|
138
|
+
async getHashes() {
|
|
139
|
+
if (!this.hash) {
|
|
140
|
+
// Using MD5 as S3 content verification use md5
|
|
141
|
+
const hash = crypto.createHash("md5");
|
|
142
|
+
const challenge = crypto.createHash("md5");
|
|
143
|
+
const stream = await this.get();
|
|
144
|
+
challenge.update("WEBDA");
|
|
145
|
+
await new Promise((resolve, reject) => {
|
|
146
|
+
stream.on("error", err => reject(err));
|
|
147
|
+
stream.on("end", () => {
|
|
148
|
+
this.hash = hash.digest("hex");
|
|
149
|
+
this.challenge = challenge.digest("hex");
|
|
150
|
+
resolve();
|
|
151
|
+
});
|
|
152
|
+
stream.on("data", chunk => {
|
|
153
|
+
const buffer = Buffer.from(chunk);
|
|
154
|
+
hash.update(buffer);
|
|
155
|
+
challenge.update(buffer);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
hash: this.hash,
|
|
161
|
+
challenge: this.challenge
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** BinaryFile backed by a local filesystem path */
|
|
166
|
+
export class LocalBinaryFile extends BinaryFile {
|
|
167
|
+
/**
|
|
168
|
+
* Path on the hard drive
|
|
169
|
+
*/
|
|
170
|
+
path;
|
|
171
|
+
/** Create a new LocalBinaryFile
|
|
172
|
+
* @param filePath - path to the local file
|
|
173
|
+
*/
|
|
174
|
+
constructor(filePath) {
|
|
175
|
+
super({
|
|
176
|
+
name: path.basename(filePath),
|
|
177
|
+
size: fs.statSync(filePath).size,
|
|
178
|
+
mimetype: mime.lookup(filePath) || "application/octet-stream"
|
|
179
|
+
});
|
|
180
|
+
this.path = filePath;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* @override
|
|
184
|
+
*/
|
|
185
|
+
async get() {
|
|
186
|
+
return fs.createReadStream(this.path);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** BinaryFile backed by an in-memory Buffer */
|
|
190
|
+
let MemoryBinaryFile = (() => {
|
|
191
|
+
let _classSuper = BinaryFile;
|
|
192
|
+
let _buffer_decorators;
|
|
193
|
+
let _buffer_initializers = [];
|
|
194
|
+
let _buffer_extraInitializers = [];
|
|
195
|
+
return class MemoryBinaryFile extends _classSuper {
|
|
196
|
+
static {
|
|
197
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
198
|
+
_buffer_decorators = [NotEnumerable];
|
|
199
|
+
__esDecorate(null, null, _buffer_decorators, { kind: "field", name: "buffer", static: false, private: false, access: { has: obj => "buffer" in obj, get: obj => obj.buffer, set: (obj, value) => { obj.buffer = value; } }, metadata: _metadata }, _buffer_initializers, _buffer_extraInitializers);
|
|
200
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Content
|
|
204
|
+
*/
|
|
205
|
+
buffer = __runInitializers(this, _buffer_initializers, void 0);
|
|
206
|
+
/** Create a new MemoryBinaryFile
|
|
207
|
+
* @param buffer - the binary content
|
|
208
|
+
* @param info - optional file information
|
|
209
|
+
*/
|
|
210
|
+
constructor(buffer, info = {}) {
|
|
211
|
+
super({
|
|
212
|
+
...info,
|
|
213
|
+
size: info.size || buffer.length,
|
|
214
|
+
name: info.name || "data.bin",
|
|
215
|
+
mimetype: info.mimetype || "application/octet-stream"
|
|
216
|
+
});
|
|
217
|
+
__runInitializers(this, _buffer_extraInitializers);
|
|
218
|
+
this.buffer = typeof buffer === "string" ? Buffer.from(buffer) : buffer;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* @override
|
|
222
|
+
*/
|
|
223
|
+
async get() {
|
|
224
|
+
return Readable.from(this.buffer);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
})();
|
|
228
|
+
export { MemoryBinaryFile };
|
|
229
|
+
/**
|
|
230
|
+
* This is a map used to retrieve binary
|
|
231
|
+
*
|
|
232
|
+
* @class BinaryMap
|
|
233
|
+
*/
|
|
234
|
+
export class BinaryMap extends BinaryFile {
|
|
235
|
+
/**
|
|
236
|
+
* Link to the binary store
|
|
237
|
+
*/
|
|
238
|
+
[WEBDA_STORAGE] = {};
|
|
239
|
+
/** Create a new BinaryMap
|
|
240
|
+
* @param service - the binary service
|
|
241
|
+
* @param obj - the binary file information
|
|
242
|
+
*/
|
|
243
|
+
constructor(service, obj) {
|
|
244
|
+
super(obj);
|
|
245
|
+
this.set(obj);
|
|
246
|
+
this[WEBDA_STORAGE].service = service;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get the binary data
|
|
250
|
+
*
|
|
251
|
+
* @returns the result
|
|
252
|
+
*/
|
|
253
|
+
get() {
|
|
254
|
+
return this[WEBDA_STORAGE].service.get(this);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get into a buffer
|
|
258
|
+
* @returns the result
|
|
259
|
+
*/
|
|
260
|
+
async getAsBuffer() {
|
|
261
|
+
return BinaryService.streamToBuffer(await this.get());
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Download the binary to a path
|
|
265
|
+
*
|
|
266
|
+
* Shortcut to call {@link Binary.downloadTo} with current object
|
|
267
|
+
*
|
|
268
|
+
* @param filename - the filename
|
|
269
|
+
* @returns the result
|
|
270
|
+
*/
|
|
271
|
+
async downloadTo(filename) {
|
|
272
|
+
return this[WEBDA_STORAGE].service.downloadTo(this, filename);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* One Binary instance — single-cardinality binary attribute on a CoreModel.
|
|
277
|
+
*
|
|
278
|
+
* Tagged as a Behavior so the compiler picks it up via the same path as every
|
|
279
|
+
* other `@WebdaBehavior` class. Its `@Action`-decorated methods are exposed
|
|
280
|
+
* as model-scoped operations (`<Model>.<Attribute>.<Action>`) and routed by
|
|
281
|
+
* `RESTOperationsTransport.exposeBehaviorRoutes`.
|
|
282
|
+
*
|
|
283
|
+
* Constructor takes no required arguments because the transformer-emitted
|
|
284
|
+
* `__hydrateBehaviors` calls `new Binary()` with zero args before stamping
|
|
285
|
+
* the parent reference into `WEBDA_STORAGE["__parent__"]`. Legacy 2-arg
|
|
286
|
+
* usage (`new Binary(attribute, model)`) is still supported for direct
|
|
287
|
+
* callers and tests; when present, the constructor eagerly resolves the
|
|
288
|
+
* service and copies the existing model attribute value so callers can call
|
|
289
|
+
* `isEmpty()` and `hash`/`size` immediately.
|
|
290
|
+
*
|
|
291
|
+
* @readOnly
|
|
292
|
+
* @WebdaBehavior Webda/Binary
|
|
293
|
+
*/
|
|
294
|
+
let Binary = (() => {
|
|
295
|
+
let _classSuper = BinaryMap;
|
|
296
|
+
let _instanceExtraInitializers = [];
|
|
297
|
+
let _delete_decorators;
|
|
298
|
+
let _attach_decorators;
|
|
299
|
+
let _attachChallenge_decorators;
|
|
300
|
+
let _download_decorators;
|
|
301
|
+
let _downloadUrl_decorators;
|
|
302
|
+
let _setMetadata_decorators;
|
|
303
|
+
return class Binary extends _classSuper {
|
|
304
|
+
static {
|
|
305
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
306
|
+
_delete_decorators = [Action({ rest: { route: "{hash}", method: "DELETE" } })];
|
|
307
|
+
_attach_decorators = [Action({ rest: { route: ".", method: "POST" } })];
|
|
308
|
+
_attachChallenge_decorators = [Action({ rest: { route: ".", method: "PUT" } })];
|
|
309
|
+
_download_decorators = [Action({ rest: { route: ".", method: "GET" } })];
|
|
310
|
+
_downloadUrl_decorators = [Action({ rest: { route: "url", method: "GET" } })];
|
|
311
|
+
_setMetadata_decorators = [Action({ rest: { route: "{hash}", method: "PUT" } })];
|
|
312
|
+
__esDecorate(this, null, _delete_decorators, { kind: "method", name: "delete", static: false, private: false, access: { has: obj => "delete" in obj, get: obj => obj.delete }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
313
|
+
__esDecorate(this, null, _attach_decorators, { kind: "method", name: "attach", static: false, private: false, access: { has: obj => "attach" in obj, get: obj => obj.attach }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
314
|
+
__esDecorate(this, null, _attachChallenge_decorators, { kind: "method", name: "attachChallenge", static: false, private: false, access: { has: obj => "attachChallenge" in obj, get: obj => obj.attachChallenge }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
315
|
+
__esDecorate(this, null, _download_decorators, { kind: "method", name: "download", static: false, private: false, access: { has: obj => "download" in obj, get: obj => obj.download }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
316
|
+
__esDecorate(this, null, _downloadUrl_decorators, { kind: "method", name: "downloadUrl", static: false, private: false, access: { has: obj => "downloadUrl" in obj, get: obj => obj.downloadUrl }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
317
|
+
__esDecorate(this, null, _setMetadata_decorators, { kind: "method", name: "setMetadata", static: false, private: false, access: { has: obj => "setMetadata" in obj, get: obj => obj.setMetadata }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
318
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
319
|
+
}
|
|
320
|
+
// NOTE: do NOT redeclare `[WEBDA_STORAGE]` as a field here — class field
|
|
321
|
+
// initializers in the subclass run AFTER `super()` returns and OVERWRITE
|
|
322
|
+
// whatever BinaryMap (and BinaryFile before it) stored. We rely on the
|
|
323
|
+
// inherited `[WEBDA_STORAGE]: { service: BinaryService } = {}` from
|
|
324
|
+
// BinaryMap and stash the Behavior-specific keys (`empty`, `__parent__`)
|
|
325
|
+
// through a typed cast at the assignment site.
|
|
326
|
+
/** Create a new Binary.
|
|
327
|
+
*
|
|
328
|
+
* Callable with no arguments (the Behavior-hydration path the transformer
|
|
329
|
+
* emits) or with the legacy `(attribute, model)` pair for direct
|
|
330
|
+
* instantiation in tests / non-hydrated code.
|
|
331
|
+
* @param attribute - the model attribute name (legacy form)
|
|
332
|
+
* @param model - the parent model (legacy form)
|
|
333
|
+
*/
|
|
334
|
+
constructor(attribute, model) {
|
|
335
|
+
// `super()` must be the constructor's first statement, unconditionally.
|
|
336
|
+
// The decorator runtime injects instance initialisers right after it, and
|
|
337
|
+
// with `super()` inside `if`/`else` there is nowhere correct to put them:
|
|
338
|
+
// TypeScript 6 silently dropped them — so `@Action` `addInitializer` hooks
|
|
339
|
+
// never ran for Binary — and tsgo runs them before `super()`, which throws
|
|
340
|
+
// ReferenceError on `new Binary()`. TypeScript 6 also drops them when
|
|
341
|
+
// any statement precedes `super()`, hence the repeated condition.
|
|
342
|
+
//
|
|
343
|
+
// Legacy eager wiring resolves the service and loads the existing data, so
|
|
344
|
+
// callers can use `isEmpty()` / `.hash` / `.size` right away. The hydration
|
|
345
|
+
// path (no arguments) leaves both unresolved: the generated
|
|
346
|
+
// `__hydrateBehaviors` stamps `__parent__` afterwards and the public API
|
|
347
|
+
// resolves the service lazily through `getService()`.
|
|
348
|
+
super(attribute !== undefined && model !== undefined
|
|
349
|
+
? useCore().getBinaryStore(model, attribute)
|
|
350
|
+
: undefined, attribute !== undefined && model !== undefined ? model[attribute] || {} : {});
|
|
351
|
+
__runInitializers(this, _instanceExtraInitializers);
|
|
352
|
+
const eager = attribute !== undefined && model !== undefined;
|
|
353
|
+
this[WEBDA_STORAGE].empty = eager ? model[attribute] === undefined : true;
|
|
354
|
+
if (eager)
|
|
355
|
+
this[WEBDA_STORAGE]["__parent__"] = { instance: model, attribute };
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Resolve the BinaryService lazily via the Behavior parent reference.
|
|
359
|
+
*
|
|
360
|
+
* The transformer-emitted `__hydrateBehaviors` writes
|
|
361
|
+
* `WEBDA_STORAGE["__parent__"]` after construction, and the per-Behavior
|
|
362
|
+
* `parent` getter (also emitted by the transformer) surfaces it as
|
|
363
|
+
* `this.parent`. We resolve the service on first call and cache it on the
|
|
364
|
+
* storage slot so subsequent calls don't re-walk the binary registry.
|
|
365
|
+
*
|
|
366
|
+
* @returns the BinaryService that owns this Binary's parent attribute
|
|
367
|
+
*/
|
|
368
|
+
getService() {
|
|
369
|
+
if (!this[WEBDA_STORAGE].service) {
|
|
370
|
+
const parent = this.getParent();
|
|
371
|
+
if (!parent) {
|
|
372
|
+
throw new Error("Binary parent not yet wired — cannot resolve BinaryService");
|
|
373
|
+
}
|
|
374
|
+
this[WEBDA_STORAGE].service = useCore().getBinaryStore(parent.instance, parent.attribute);
|
|
375
|
+
}
|
|
376
|
+
return this[WEBDA_STORAGE].service;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Read the Behavior parent reference. The transformer-emitted `parent`
|
|
380
|
+
* getter on `@WebdaBehavior` classes returns the same slot, but Binary
|
|
381
|
+
* may also be used in code paths where the transformer hasn't run (e.g.
|
|
382
|
+
* unit tests that hand-roll instances), so we read the slot directly.
|
|
383
|
+
*
|
|
384
|
+
* @returns the parent reference or undefined
|
|
385
|
+
*/
|
|
386
|
+
getParent() {
|
|
387
|
+
return this[WEBDA_STORAGE]["__parent__"];
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* isEmpty
|
|
391
|
+
* @returns the result
|
|
392
|
+
*/
|
|
393
|
+
isEmpty() {
|
|
394
|
+
return this[WEBDA_STORAGE].empty;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Ensure empty is set correctly.
|
|
398
|
+
*
|
|
399
|
+
* `BinaryFile`'s constructor calls `this.set(info)` before subclass class-field
|
|
400
|
+
* initializers run, so `this[WEBDA_STORAGE]` is still `undefined` the first
|
|
401
|
+
* time we get here when constructing a fresh `new Binary()` (the no-args
|
|
402
|
+
* path used by the transformer's `__hydrateBehaviors`). Initialize the
|
|
403
|
+
* slot lazily on the first set call to keep that boot path crash-free —
|
|
404
|
+
* the class-field initializer on `BinaryMap` will then OVERWRITE this on
|
|
405
|
+
* its way back from super, but that's fine because it preserves the
|
|
406
|
+
* shape `{ service?, empty?, ... }` and we've passed through `set` only
|
|
407
|
+
* once at this point.
|
|
408
|
+
*
|
|
409
|
+
* @param info - the information object
|
|
410
|
+
*/
|
|
411
|
+
set(info) {
|
|
412
|
+
super.set(info);
|
|
413
|
+
const slot = (this[WEBDA_STORAGE] ??= {});
|
|
414
|
+
slot.empty = false;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Replace the binary by uploading a new file. Direct programmatic use
|
|
418
|
+
* (non-HTTP). Equivalent to the `attach(...)` HTTP action minus the
|
|
419
|
+
* context handling.
|
|
420
|
+
* @param file - the binary file to upload
|
|
421
|
+
* @returns the result
|
|
422
|
+
*/
|
|
423
|
+
async upload(file) {
|
|
424
|
+
const parent = this.getParent();
|
|
425
|
+
if (!parent) {
|
|
426
|
+
throw new Error("Binary parent not yet wired — cannot upload");
|
|
427
|
+
}
|
|
428
|
+
await this.getService().store(parent.instance, parent.attribute, file);
|
|
429
|
+
this.set(file);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Delete this binary from storage and clear local state.
|
|
433
|
+
*
|
|
434
|
+
* Exposed as a Behavior `@Action` (DELETE on `{uuid}/<attribute>/{hash}`).
|
|
435
|
+
* The URL `{hash}` must match the current binary's hash; this guards
|
|
436
|
+
* against accidental deletes when the client raced a metadata update.
|
|
437
|
+
*
|
|
438
|
+
* Migrated from `DomainService.binaryAction` (action="delete",
|
|
439
|
+
* single-cardinality branch).
|
|
440
|
+
* @param hash - the URL-supplied hash; must match `this.hash`
|
|
441
|
+
*/
|
|
442
|
+
async delete(hash) {
|
|
443
|
+
const parent = this.getParent();
|
|
444
|
+
if (!parent) {
|
|
445
|
+
throw new Error("Binary parent not yet wired — cannot delete");
|
|
446
|
+
}
|
|
447
|
+
if (!this.hash || this.hash !== hash) {
|
|
448
|
+
throw new WebdaError.BadRequest("Hash does not match");
|
|
449
|
+
}
|
|
450
|
+
await this.getService().delete(parent.instance, parent.attribute);
|
|
451
|
+
this.set({});
|
|
452
|
+
this[WEBDA_STORAGE].empty = true;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Direct (multipart / raw) upload from an HTTP request.
|
|
456
|
+
*
|
|
457
|
+
* `POST /<plural>/{uuid}/<attribute>` — accepts the binary content as the
|
|
458
|
+
* request body, hashes it, stores it on the BinaryService, and updates
|
|
459
|
+
* this Binary's metadata. Returns early if the new content's hash matches
|
|
460
|
+
* what we already hold (idempotent on duplicate uploads).
|
|
461
|
+
*
|
|
462
|
+
* Migrated from `DomainService.binaryPut`; the parent-loading step is
|
|
463
|
+
* unnecessary here because the Behavior is already attached to its parent
|
|
464
|
+
* by `__hydrateBehaviors`.
|
|
465
|
+
*/
|
|
466
|
+
async attach() {
|
|
467
|
+
const context = useContext();
|
|
468
|
+
const parent = this.getParent();
|
|
469
|
+
if (!parent) {
|
|
470
|
+
throw new Error("Binary parent not yet wired — cannot attach");
|
|
471
|
+
}
|
|
472
|
+
const service = this.getService();
|
|
473
|
+
const file = await service.getFile(context);
|
|
474
|
+
const { hash } = await file.getHashes();
|
|
475
|
+
if (this.hash === hash) {
|
|
476
|
+
return; // already linked — idempotent
|
|
477
|
+
}
|
|
478
|
+
await service.store(parent.instance, parent.attribute, file);
|
|
479
|
+
this.set(file);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Challenge-based upload handshake.
|
|
483
|
+
*
|
|
484
|
+
* `PUT /<plural>/{uuid}/<attribute>` — the client sends `{ hash, challenge,
|
|
485
|
+
* size?, name?, mimetype?, metadata? }`; we ask the BinaryService for a
|
|
486
|
+
* pre-signed upload URL (or a "done" flag if dedup matched) and return it.
|
|
487
|
+
*
|
|
488
|
+
* Migrated from `DomainService.binaryChallenge`.
|
|
489
|
+
* @param body - the challenge body forwarded by `resolveArguments`; falls
|
|
490
|
+
* back to `context.getInput()` when undefined.
|
|
491
|
+
* @returns `{ url?, method?, headers?, done, md5 }`
|
|
492
|
+
*/
|
|
493
|
+
async attachChallenge(body) {
|
|
494
|
+
const context = useContext();
|
|
495
|
+
const parent = this.getParent();
|
|
496
|
+
if (!parent) {
|
|
497
|
+
throw new Error("Binary parent not yet wired — cannot attachChallenge");
|
|
498
|
+
}
|
|
499
|
+
const service = this.getService();
|
|
500
|
+
if (body === undefined) {
|
|
501
|
+
body = await context.getInput();
|
|
502
|
+
}
|
|
503
|
+
if (this.hash === body.hash) {
|
|
504
|
+
return; // already linked
|
|
505
|
+
}
|
|
506
|
+
const url = await service.putRedirectUrl(parent.instance, parent.attribute, body, context);
|
|
507
|
+
const md5 = Buffer.from(body.hash, "hex").toString("base64");
|
|
508
|
+
return {
|
|
509
|
+
...url,
|
|
510
|
+
done: url === undefined,
|
|
511
|
+
md5
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Stream the binary to the response, or 302-redirect to a signed URL.
|
|
516
|
+
*
|
|
517
|
+
* `GET /<plural>/{uuid}/<attribute>` — if the underlying BinaryService
|
|
518
|
+
* supports redirect URLs (e.g. S3) we 302 to the signed URL; otherwise we
|
|
519
|
+
* pipe the bytes directly through the response.
|
|
520
|
+
*
|
|
521
|
+
* Named `download` (not `get`) so the parent `BinaryMap.get(): Readable`
|
|
522
|
+
* accessor isn't shadowed — Behavior @Action methods can't change the
|
|
523
|
+
* parent type's contract, and a plain `get()` overload that returns
|
|
524
|
+
* `void` would break callers that consume the Readable.
|
|
525
|
+
*
|
|
526
|
+
* Migrated from `DomainService.binaryGet` (single-cardinality branch).
|
|
527
|
+
*/
|
|
528
|
+
async download() {
|
|
529
|
+
const context = useContext();
|
|
530
|
+
const service = this.getService();
|
|
531
|
+
if (!this.hash) {
|
|
532
|
+
throw new WebdaError.NotFound("Object does not exist or attachment does not exist");
|
|
533
|
+
}
|
|
534
|
+
const url = await service.getRedirectUrlFromObject(this, context);
|
|
535
|
+
if (url === null) {
|
|
536
|
+
// No redirect — stream directly through the response.
|
|
537
|
+
context.writeHead(200, {
|
|
538
|
+
"Content-Type": this.mimetype === undefined ? "application/octet-stream" : this.mimetype,
|
|
539
|
+
"Content-Length": this.size
|
|
540
|
+
});
|
|
541
|
+
const readStream = await service.get(this);
|
|
542
|
+
await new Promise((resolve, reject) => {
|
|
543
|
+
context._stream.on("finish", resolve);
|
|
544
|
+
context._stream.on("error", reject);
|
|
545
|
+
readStream.pipe(context._stream);
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
context.writeHead(302, { Location: url });
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Return a JSON `{ Location, Map }` describing where to fetch the binary.
|
|
554
|
+
*
|
|
555
|
+
* `GET /<plural>/{uuid}/<attribute>/url` — variant of `download()` that
|
|
556
|
+
* returns the URL as JSON instead of redirecting. Used by clients that
|
|
557
|
+
* want to discover the URL without following the redirect.
|
|
558
|
+
*
|
|
559
|
+
* Migrated from `DomainService.binaryGet`'s `returnUrl` branch.
|
|
560
|
+
* @returns `{ Location, Map }`
|
|
561
|
+
*/
|
|
562
|
+
async downloadUrl() {
|
|
563
|
+
const context = useContext();
|
|
564
|
+
const service = this.getService();
|
|
565
|
+
if (!this.hash) {
|
|
566
|
+
throw new WebdaError.NotFound("Object does not exist or attachment does not exist");
|
|
567
|
+
}
|
|
568
|
+
const url = await service.getRedirectUrlFromObject(this, context);
|
|
569
|
+
if (url === null) {
|
|
570
|
+
// No service-level signed URL: fall back to the same URL minus `/url`.
|
|
571
|
+
if (context instanceof WebContext) {
|
|
572
|
+
return {
|
|
573
|
+
Location: context
|
|
574
|
+
.getHttpContext()
|
|
575
|
+
.getAbsoluteUrl()
|
|
576
|
+
.replace(/\/url$/, ""),
|
|
577
|
+
Map: this
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
return { Location: undefined, Map: this };
|
|
581
|
+
}
|
|
582
|
+
return { Location: url, Map: this };
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Update the metadata sidecar attached to this binary.
|
|
586
|
+
*
|
|
587
|
+
* `PUT /<plural>/{uuid}/<attribute>/{hash}` — verifies the URL `{hash}`
|
|
588
|
+
* matches the current binary, applies the new metadata, and persists via
|
|
589
|
+
* `parent.instance.patch(...)`. Metadata payload is capped at 4 KB to
|
|
590
|
+
* mirror the existing `DomainService.binaryAction` rule.
|
|
591
|
+
*
|
|
592
|
+
* Migrated from `DomainService.binaryAction` (action="metadata" branch).
|
|
593
|
+
* @param hash - the URL-supplied hash; must match `this.hash`
|
|
594
|
+
* @param metadata - the new metadata blob (≤ 4 KB JSON)
|
|
595
|
+
*/
|
|
596
|
+
async setMetadata(hash, metadata) {
|
|
597
|
+
const context = useContext();
|
|
598
|
+
const parent = this.getParent();
|
|
599
|
+
if (!parent) {
|
|
600
|
+
throw new Error("Binary parent not yet wired — cannot setMetadata");
|
|
601
|
+
}
|
|
602
|
+
if (this.hash !== hash) {
|
|
603
|
+
throw new WebdaError.BadRequest("Hash does not match");
|
|
604
|
+
}
|
|
605
|
+
if (metadata === undefined) {
|
|
606
|
+
metadata = await context.getInput();
|
|
607
|
+
}
|
|
608
|
+
if (JSON.stringify(metadata).length >= 4096) {
|
|
609
|
+
throw new WebdaError.BadRequest("Metadata is too big: 4kb max");
|
|
610
|
+
}
|
|
611
|
+
this.metadata = metadata;
|
|
612
|
+
await parent.instance.patch({
|
|
613
|
+
[parent.attribute]: this
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Return undefined at runtime if no hash; the type annotation deliberately
|
|
618
|
+
* narrows to the populated shape so the schema generator follows
|
|
619
|
+
* `BinaryFileInfo<T>` for the Output/Stored schemas.
|
|
620
|
+
* @returns the result
|
|
621
|
+
*/
|
|
622
|
+
toJSON() {
|
|
623
|
+
if (!this.hash) {
|
|
624
|
+
return undefined;
|
|
625
|
+
}
|
|
626
|
+
return this;
|
|
627
|
+
}
|
|
628
|
+
get parent() { return this[WEBDA_STORAGE]["__parent__"]; }
|
|
629
|
+
};
|
|
630
|
+
})();
|
|
631
|
+
export { Binary };
|
|
632
|
+
/**
|
|
633
|
+
* Define a Binary map stored in a Binaries collection
|
|
634
|
+
*/
|
|
635
|
+
export class BinariesItem extends BinaryMap {
|
|
636
|
+
[WEBDA_STORAGE] = {};
|
|
637
|
+
/** Create a new BinariesItem
|
|
638
|
+
* @param parent - the parent binaries collection
|
|
639
|
+
* @param info - the binary file information
|
|
640
|
+
*/
|
|
641
|
+
constructor(parent, info) {
|
|
642
|
+
super(parent[WEBDA_STORAGE].service, info);
|
|
643
|
+
this[WEBDA_STORAGE].parent = parent;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Replace the binary
|
|
647
|
+
* @param id - the identifier
|
|
648
|
+
* @param ctx - the operation context
|
|
649
|
+
* @param file - the file path
|
|
650
|
+
* @returns the result
|
|
651
|
+
*/
|
|
652
|
+
async upload(file) {
|
|
653
|
+
await this[WEBDA_STORAGE].parent.upload(file, this);
|
|
654
|
+
this.set(file);
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Delete the binary, if you need to replace just use upload
|
|
658
|
+
* @returns the result
|
|
659
|
+
*/
|
|
660
|
+
async delete() {
|
|
661
|
+
return this[WEBDA_STORAGE].parent.delete(this);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Define a collection of Binary — many-cardinality binary attribute.
|
|
666
|
+
*
|
|
667
|
+
* Tagged as a Behavior so its `@Action` methods register as
|
|
668
|
+
* `<Model>.<Attribute>.<Action>` operations alongside Single-Binary ones.
|
|
669
|
+
* Inherits from `Array<BinariesItem<T>>` so it preserves array semantics
|
|
670
|
+
* (iteration, indexed access, JSON.stringify-as-array). The transformer
|
|
671
|
+
* detects this Array-subclass shape and emits a push-based hydration
|
|
672
|
+
* coercion — see `behaviors.ts:createHydrationBlock`.
|
|
673
|
+
*
|
|
674
|
+
* @readOnly
|
|
675
|
+
* @WebdaBehavior Webda/BinariesImpl
|
|
676
|
+
*/
|
|
677
|
+
let BinariesImpl = (() => {
|
|
678
|
+
let _classSuper = Array;
|
|
679
|
+
let _instanceExtraInitializers = [];
|
|
680
|
+
let _attach_decorators;
|
|
681
|
+
let _attachChallenge_decorators;
|
|
682
|
+
let _get_decorators;
|
|
683
|
+
let _getUrl_decorators;
|
|
684
|
+
let _deleteAt_decorators;
|
|
685
|
+
let _setMetadata_decorators;
|
|
686
|
+
return class BinariesImpl extends _classSuper {
|
|
687
|
+
static {
|
|
688
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
689
|
+
_attach_decorators = [Action({ rest: { route: ".", method: "POST" } })];
|
|
690
|
+
_attachChallenge_decorators = [Action({ rest: { route: ".", method: "PUT" } })];
|
|
691
|
+
_get_decorators = [Action({ rest: { route: "{index}", method: "GET" } })];
|
|
692
|
+
_getUrl_decorators = [Action({ rest: { route: "{index}/url", method: "GET" } })];
|
|
693
|
+
_deleteAt_decorators = [Action({ rest: { route: "{index}/{hash}", method: "DELETE" } })];
|
|
694
|
+
_setMetadata_decorators = [Action({ rest: { route: "{index}/{hash}", method: "PUT" } })];
|
|
695
|
+
__esDecorate(this, null, _attach_decorators, { kind: "method", name: "attach", static: false, private: false, access: { has: obj => "attach" in obj, get: obj => obj.attach }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
696
|
+
__esDecorate(this, null, _attachChallenge_decorators, { kind: "method", name: "attachChallenge", static: false, private: false, access: { has: obj => "attachChallenge" in obj, get: obj => obj.attachChallenge }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
697
|
+
__esDecorate(this, null, _get_decorators, { kind: "method", name: "get", static: false, private: false, access: { has: obj => "get" in obj, get: obj => obj.get }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
698
|
+
__esDecorate(this, null, _getUrl_decorators, { kind: "method", name: "getUrl", static: false, private: false, access: { has: obj => "getUrl" in obj, get: obj => obj.getUrl }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
699
|
+
__esDecorate(this, null, _deleteAt_decorators, { kind: "method", name: "deleteAt", static: false, private: false, access: { has: obj => "deleteAt" in obj, get: obj => obj.deleteAt }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
700
|
+
__esDecorate(this, null, _setMetadata_decorators, { kind: "method", name: "setMetadata", static: false, private: false, access: { has: obj => "setMetadata" in obj, get: obj => obj.setMetadata }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
701
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
702
|
+
}
|
|
703
|
+
[WEBDA_STORAGE] = (__runInitializers(this, _instanceExtraInitializers), {});
|
|
704
|
+
/**
|
|
705
|
+
* Bind this collection to a model and attribute, populating from existing binary data.
|
|
706
|
+
*
|
|
707
|
+
* Legacy entry-point used by code that constructs a `BinariesImpl()`
|
|
708
|
+
* directly (tests, manual instantiation). The Behavior-hydration path the
|
|
709
|
+
* transformer emits writes `WEBDA_STORAGE["__parent__"]` instead and
|
|
710
|
+
* never calls `assign`.
|
|
711
|
+
*
|
|
712
|
+
* @param model - the model to use
|
|
713
|
+
* @param attribute - the attribute name
|
|
714
|
+
* @returns this for chaining
|
|
715
|
+
*/
|
|
716
|
+
assign(model, attribute) {
|
|
717
|
+
this[WEBDA_STORAGE]["__parent__"] = { instance: model, attribute };
|
|
718
|
+
for (const binary of model[attribute] || []) {
|
|
719
|
+
this.push(binary);
|
|
720
|
+
}
|
|
721
|
+
this[WEBDA_STORAGE].service = useCore().getBinaryStore(model, attribute);
|
|
722
|
+
return this;
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Resolve the BinaryService lazily via the Behavior parent reference.
|
|
726
|
+
*
|
|
727
|
+
* Mirrors `Binary.getService()`. The transformer-emitted parent slot
|
|
728
|
+
* (`WEBDA_STORAGE["__parent__"]`) is the source of truth.
|
|
729
|
+
*
|
|
730
|
+
* @returns the BinaryService for this collection's parent attribute
|
|
731
|
+
*/
|
|
732
|
+
getService() {
|
|
733
|
+
if (!this[WEBDA_STORAGE].service) {
|
|
734
|
+
const parent = this.getParent();
|
|
735
|
+
if (!parent) {
|
|
736
|
+
throw new Error("Binaries parent not yet wired — cannot resolve BinaryService");
|
|
737
|
+
}
|
|
738
|
+
this[WEBDA_STORAGE].service = useCore().getBinaryStore(parent.instance, parent.attribute);
|
|
739
|
+
}
|
|
740
|
+
return this[WEBDA_STORAGE].service;
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Read the Behavior parent reference. Mirrors `Binary.getParent()`.
|
|
744
|
+
* @returns the parent reference or undefined
|
|
745
|
+
*/
|
|
746
|
+
getParent() {
|
|
747
|
+
return this[WEBDA_STORAGE]["__parent__"];
|
|
748
|
+
}
|
|
749
|
+
/** @throws Readonly collection */
|
|
750
|
+
pop() {
|
|
751
|
+
throw new Error("Readonly");
|
|
752
|
+
}
|
|
753
|
+
/** @throws Readonly collection */
|
|
754
|
+
slice() {
|
|
755
|
+
throw new Error("Readonly");
|
|
756
|
+
}
|
|
757
|
+
/** @throws Readonly collection */
|
|
758
|
+
unshift() {
|
|
759
|
+
throw new Error("Readonly");
|
|
760
|
+
}
|
|
761
|
+
/** @throws Readonly collection */
|
|
762
|
+
shift() {
|
|
763
|
+
throw new Error("Readonly");
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Add binary items, wrapping plain objects in BinariesItem
|
|
767
|
+
* @param args - additional arguments
|
|
768
|
+
* @returns the result number
|
|
769
|
+
*/
|
|
770
|
+
push(...args) {
|
|
771
|
+
return super.push(...args.map(arg => (arg instanceof BinariesItem ? arg : new BinariesItem(this, arg))));
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Upload a file to this model. Direct programmatic API (non-HTTP).
|
|
775
|
+
* @param file - the file path
|
|
776
|
+
* @param replace - whether to replace existing
|
|
777
|
+
*/
|
|
778
|
+
async upload(file, replace) {
|
|
779
|
+
const parent = this.getParent();
|
|
780
|
+
if (!parent) {
|
|
781
|
+
throw new Error("Binaries parent not yet wired — cannot upload");
|
|
782
|
+
}
|
|
783
|
+
await this.getService().store(parent.instance, parent.attribute, file);
|
|
784
|
+
// Should call the store first
|
|
785
|
+
super.push(new BinariesItem(this, file));
|
|
786
|
+
if (replace) {
|
|
787
|
+
await this.delete(replace);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Delete an item by reference or index. Direct programmatic API (non-HTTP).
|
|
792
|
+
* @param item - the item to delete
|
|
793
|
+
*/
|
|
794
|
+
async delete(item) {
|
|
795
|
+
const parent = this.getParent();
|
|
796
|
+
if (!parent) {
|
|
797
|
+
throw new Error("Binaries parent not yet wired — cannot delete");
|
|
798
|
+
}
|
|
799
|
+
let itemIndex = this.indexOf(item);
|
|
800
|
+
if (itemIndex === -1) {
|
|
801
|
+
throw new Error("Item not found");
|
|
802
|
+
}
|
|
803
|
+
await this.getService().delete(parent.instance, parent.attribute, itemIndex);
|
|
804
|
+
itemIndex = this.indexOf(item);
|
|
805
|
+
if (itemIndex >= 0) {
|
|
806
|
+
// Call store delete here
|
|
807
|
+
this.splice(itemIndex, 1);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Direct (multipart / raw) upload from an HTTP request. Pushes a new item
|
|
812
|
+
* onto the collection.
|
|
813
|
+
*
|
|
814
|
+
* `POST /<plural>/{uuid}/<attribute>` — same shape as `Binary.attach` but
|
|
815
|
+
* pushes the new file rather than replacing the existing one.
|
|
816
|
+
* Migrated from `DomainService.binaryPut` (MANY-cardinality branch).
|
|
817
|
+
*/
|
|
818
|
+
async attach() {
|
|
819
|
+
const context = useContext();
|
|
820
|
+
const parent = this.getParent();
|
|
821
|
+
if (!parent) {
|
|
822
|
+
throw new Error("Binaries parent not yet wired — cannot attach");
|
|
823
|
+
}
|
|
824
|
+
const service = this.getService();
|
|
825
|
+
const file = await service.getFile(context);
|
|
826
|
+
const { hash } = await file.getHashes();
|
|
827
|
+
if (this.find(item => item.hash === hash)) {
|
|
828
|
+
return; // dedup
|
|
829
|
+
}
|
|
830
|
+
await service.store(parent.instance, parent.attribute, file);
|
|
831
|
+
super.push(new BinariesItem(this, file));
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Challenge-based upload handshake for the next item.
|
|
835
|
+
*
|
|
836
|
+
* `PUT /<plural>/{uuid}/<attribute>` — request a pre-signed upload URL
|
|
837
|
+
* for a new item identified by `{ hash, challenge, ... }`. Returns the
|
|
838
|
+
* URL or a `done` flag if dedup matched.
|
|
839
|
+
*
|
|
840
|
+
* Migrated from `DomainService.binaryChallenge` (MANY-cardinality branch).
|
|
841
|
+
* @param body - the challenge body; falls back to `context.getInput()`
|
|
842
|
+
* @returns `{ url?, method?, headers?, done, md5 }`
|
|
843
|
+
*/
|
|
844
|
+
async attachChallenge(body) {
|
|
845
|
+
const context = useContext();
|
|
846
|
+
const parent = this.getParent();
|
|
847
|
+
if (!parent) {
|
|
848
|
+
throw new Error("Binaries parent not yet wired — cannot attachChallenge");
|
|
849
|
+
}
|
|
850
|
+
const service = this.getService();
|
|
851
|
+
if (body === undefined) {
|
|
852
|
+
body = await context.getInput();
|
|
853
|
+
}
|
|
854
|
+
if (this.find(item => item.hash === body.hash)) {
|
|
855
|
+
return; // dedup
|
|
856
|
+
}
|
|
857
|
+
const url = await service.putRedirectUrl(parent.instance, parent.attribute, body, context);
|
|
858
|
+
const md5 = Buffer.from(body.hash, "hex").toString("base64");
|
|
859
|
+
return {
|
|
860
|
+
...url,
|
|
861
|
+
done: url === undefined,
|
|
862
|
+
md5
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Stream a single item to the response, or 302-redirect to a signed URL.
|
|
867
|
+
*
|
|
868
|
+
* `GET /<plural>/{uuid}/<attribute>/{index}` — locates the item by `index`
|
|
869
|
+
* and behaves like `Binary.get` for that single entry.
|
|
870
|
+
*
|
|
871
|
+
* Migrated from `DomainService.binaryGet` (MANY-cardinality branch).
|
|
872
|
+
* @param index - the item position in the collection
|
|
873
|
+
*/
|
|
874
|
+
async get(index) {
|
|
875
|
+
const context = useContext();
|
|
876
|
+
const service = this.getService();
|
|
877
|
+
const idx = typeof index === "number" ? index : parseInt(index);
|
|
878
|
+
if (this.length <= idx || idx < 0) {
|
|
879
|
+
throw new WebdaError.NotFound("Object does not exist or attachment does not exist");
|
|
880
|
+
}
|
|
881
|
+
const file = this[idx];
|
|
882
|
+
const url = await service.getRedirectUrlFromObject(file, context);
|
|
883
|
+
if (url === null) {
|
|
884
|
+
context.writeHead(200, {
|
|
885
|
+
"Content-Type": file.mimetype === undefined ? "application/octet-stream" : file.mimetype,
|
|
886
|
+
"Content-Length": file.size
|
|
887
|
+
});
|
|
888
|
+
const readStream = await service.get(file);
|
|
889
|
+
await new Promise((resolve, reject) => {
|
|
890
|
+
context._stream.on("finish", resolve);
|
|
891
|
+
context._stream.on("error", reject);
|
|
892
|
+
readStream.pipe(context._stream);
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
else {
|
|
896
|
+
context.writeHead(302, { Location: url });
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Return a `{ Location, Map }` JSON for a single item.
|
|
901
|
+
*
|
|
902
|
+
* `GET /<plural>/{uuid}/<attribute>/{index}/url` — variant of `get` that
|
|
903
|
+
* returns the URL as JSON instead of redirecting / streaming.
|
|
904
|
+
*
|
|
905
|
+
* Migrated from `DomainService.binaryGet`'s `returnUrl` branch
|
|
906
|
+
* (MANY-cardinality).
|
|
907
|
+
* @param index - the item position in the collection
|
|
908
|
+
* @returns `{ Location, Map }`
|
|
909
|
+
*/
|
|
910
|
+
async getUrl(index) {
|
|
911
|
+
const context = useContext();
|
|
912
|
+
const service = this.getService();
|
|
913
|
+
const idx = typeof index === "number" ? index : parseInt(index);
|
|
914
|
+
if (this.length <= idx || idx < 0) {
|
|
915
|
+
throw new WebdaError.NotFound("Object does not exist or attachment does not exist");
|
|
916
|
+
}
|
|
917
|
+
const file = this[idx];
|
|
918
|
+
const url = await service.getRedirectUrlFromObject(file, context);
|
|
919
|
+
if (url === null) {
|
|
920
|
+
if (context instanceof WebContext) {
|
|
921
|
+
return {
|
|
922
|
+
Location: context
|
|
923
|
+
.getHttpContext()
|
|
924
|
+
.getAbsoluteUrl()
|
|
925
|
+
.replace(/\/url$/, ""),
|
|
926
|
+
Map: file
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
return { Location: undefined, Map: file };
|
|
930
|
+
}
|
|
931
|
+
return { Location: url, Map: file };
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Delete a single item by `(index, hash)`.
|
|
935
|
+
*
|
|
936
|
+
* `DELETE /<plural>/{uuid}/<attribute>/{index}/{hash}` — the URL `{hash}`
|
|
937
|
+
* must match the item at `{index}`. Removes from storage and from the
|
|
938
|
+
* in-memory collection.
|
|
939
|
+
*
|
|
940
|
+
* Migrated from `DomainService.binaryAction` (action="delete",
|
|
941
|
+
* MANY-cardinality branch).
|
|
942
|
+
* @param index - the item position
|
|
943
|
+
* @param hash - the URL-supplied hash; must match `this[index].hash`
|
|
944
|
+
*/
|
|
945
|
+
async deleteAt(index, hash) {
|
|
946
|
+
const parent = this.getParent();
|
|
947
|
+
if (!parent) {
|
|
948
|
+
throw new Error("Binaries parent not yet wired — cannot delete");
|
|
949
|
+
}
|
|
950
|
+
const idx = typeof index === "number" ? index : parseInt(index);
|
|
951
|
+
const file = this[idx];
|
|
952
|
+
if (!file || file.hash !== hash) {
|
|
953
|
+
throw new WebdaError.BadRequest("Hash does not match");
|
|
954
|
+
}
|
|
955
|
+
await this.getService().delete(parent.instance, parent.attribute, idx);
|
|
956
|
+
if (this[idx] && this[idx].hash === hash) {
|
|
957
|
+
this.splice(idx, 1);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* Update the metadata sidecar of a single item.
|
|
962
|
+
*
|
|
963
|
+
* `PUT /<plural>/{uuid}/<attribute>/{index}/{hash}` — verifies the hash,
|
|
964
|
+
* applies the new metadata, and persists via `parent.instance.patch(...)`.
|
|
965
|
+
* Metadata payload capped at 4 KB.
|
|
966
|
+
*
|
|
967
|
+
* Migrated from `DomainService.binaryAction` (action="metadata",
|
|
968
|
+
* MANY-cardinality branch).
|
|
969
|
+
* @param index - the item position
|
|
970
|
+
* @param hash - the URL-supplied hash; must match `this[index].hash`
|
|
971
|
+
* @param metadata - the new metadata blob (≤ 4 KB JSON)
|
|
972
|
+
*/
|
|
973
|
+
async setMetadata(index, hash, metadata) {
|
|
974
|
+
const context = useContext();
|
|
975
|
+
const parent = this.getParent();
|
|
976
|
+
if (!parent) {
|
|
977
|
+
throw new Error("Binaries parent not yet wired — cannot setMetadata");
|
|
978
|
+
}
|
|
979
|
+
const idx = typeof index === "number" ? index : parseInt(index);
|
|
980
|
+
const file = this[idx];
|
|
981
|
+
if (!file || file.hash !== hash) {
|
|
982
|
+
throw new WebdaError.BadRequest("Hash does not match");
|
|
983
|
+
}
|
|
984
|
+
if (metadata === undefined) {
|
|
985
|
+
metadata = await context.getInput();
|
|
986
|
+
}
|
|
987
|
+
if (JSON.stringify(metadata).length >= 4096) {
|
|
988
|
+
throw new WebdaError.BadRequest("Metadata is too big: 4kb max");
|
|
989
|
+
}
|
|
990
|
+
file.metadata = metadata;
|
|
991
|
+
await parent.instance.patch({
|
|
992
|
+
[parent.attribute]: this
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Native array serialization. The transformer adds a Behavior-style
|
|
997
|
+
* `toJSON` to every Behavior class unless the author defines one;
|
|
998
|
+
* we override it explicitly so JSON.stringify produces a plain array of
|
|
999
|
+
* items rather than an object keyed by indices.
|
|
1000
|
+
* @returns the result array
|
|
1001
|
+
*/
|
|
1002
|
+
toJSON() {
|
|
1003
|
+
return Array.from(this);
|
|
1004
|
+
}
|
|
1005
|
+
get parent() { return this[WEBDA_STORAGE]["__parent__"]; }
|
|
1006
|
+
};
|
|
1007
|
+
})();
|
|
1008
|
+
export { BinariesImpl };
|
|
1009
|
+
/** Parameters for BinaryService, defining model mappings and max upload size */
|
|
1010
|
+
export class BinaryParameters extends ServiceParameters {
|
|
1011
|
+
/**
|
|
1012
|
+
* max file size
|
|
1013
|
+
*/
|
|
1014
|
+
_maxFileSize;
|
|
1015
|
+
/**
|
|
1016
|
+
* Define the map of models
|
|
1017
|
+
* * indicates all models
|
|
1018
|
+
*
|
|
1019
|
+
* key is a Store name
|
|
1020
|
+
* the string[] represent all valids attributes to store files in * indicates all attributes
|
|
1021
|
+
*/
|
|
1022
|
+
models;
|
|
1023
|
+
/**
|
|
1024
|
+
* Define the maximum filesize to accept as direct upload
|
|
1025
|
+
*
|
|
1026
|
+
* @default 10 MB
|
|
1027
|
+
*/
|
|
1028
|
+
set maxFileSize(value) {
|
|
1029
|
+
this._maxFileSize = new FileSize(value).valueOf();
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Get the max file size in bytes
|
|
1033
|
+
* @returns the result number
|
|
1034
|
+
*/
|
|
1035
|
+
get maxFileSize() {
|
|
1036
|
+
return this._maxFileSize;
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Load parameters with defaults for model mappings and max file size
|
|
1040
|
+
* @param params - the service parameters
|
|
1041
|
+
* @returns this for chaining
|
|
1042
|
+
*/
|
|
1043
|
+
load(params = {}) {
|
|
1044
|
+
super.load(params);
|
|
1045
|
+
// Store all models in it by default
|
|
1046
|
+
this.models ??= {
|
|
1047
|
+
"*": ["*"]
|
|
1048
|
+
};
|
|
1049
|
+
this.maxFileSize = new FileSize(params.maxFileSize ?? "10 MB").valueOf();
|
|
1050
|
+
return this;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* This is an abstract service to represent a storage of files
|
|
1055
|
+
* The binary allow you to expose this service as HTTP
|
|
1056
|
+
*
|
|
1057
|
+
* It supports two modes:
|
|
1058
|
+
* - attached to a CoreModel (attach, detach, reattach)
|
|
1059
|
+
* - pure storage with no managed id (read, write, delete)
|
|
1060
|
+
*
|
|
1061
|
+
* As we have deduplication builtin you can get some stats
|
|
1062
|
+
* - getUsageCount(hash)
|
|
1063
|
+
* - getUsageCountForRaw()
|
|
1064
|
+
* - getUsageCountForMap()
|
|
1065
|
+
*
|
|
1066
|
+
* The Binary storage should store only once a binary and reference every object that are used by this binary, so it can be cleaned.
|
|
1067
|
+
*
|
|
1068
|
+
*
|
|
1069
|
+
* @see FileBinary
|
|
1070
|
+
* @see S3Binary
|
|
1071
|
+
*
|
|
1072
|
+
* @exports
|
|
1073
|
+
* @abstract
|
|
1074
|
+
* @WebdaModda Binary
|
|
1075
|
+
*/
|
|
1076
|
+
export class BinaryService extends Service {
|
|
1077
|
+
_lowercaseMaps;
|
|
1078
|
+
/**
|
|
1079
|
+
* @override
|
|
1080
|
+
*/
|
|
1081
|
+
initMetrics() {
|
|
1082
|
+
super.initMetrics();
|
|
1083
|
+
this.metrics.upload = this.getMetric(Counter, {
|
|
1084
|
+
name: "binary_upload",
|
|
1085
|
+
help: "Number of binary upload"
|
|
1086
|
+
});
|
|
1087
|
+
this.metrics.delete = this.getMetric(Counter, {
|
|
1088
|
+
name: "binary_delete",
|
|
1089
|
+
help: "Number of binary deleted"
|
|
1090
|
+
});
|
|
1091
|
+
this.metrics.download = this.getMetric(Counter, {
|
|
1092
|
+
name: "binary_download",
|
|
1093
|
+
help: "Number of binary upload"
|
|
1094
|
+
});
|
|
1095
|
+
this.metrics.metadataUpdate = this.getMetric(Counter, {
|
|
1096
|
+
name: "binary_metadata_update",
|
|
1097
|
+
help: "Number of binary metadata updated"
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Get a UrlFromObject
|
|
1102
|
+
*
|
|
1103
|
+
* @param binaryMap - the binary map definition
|
|
1104
|
+
* @param _context - the execution context
|
|
1105
|
+
* @param _expires - the expiration time
|
|
1106
|
+
* @returns the result
|
|
1107
|
+
*/
|
|
1108
|
+
async getRedirectUrlFromObject(binaryMap, _context, _expires = 30) {
|
|
1109
|
+
return null;
|
|
1110
|
+
}
|
|
1111
|
+
/**
|
|
1112
|
+
* Define if binary is managed by the store
|
|
1113
|
+
* @param modelName - the model name
|
|
1114
|
+
* @param attribute - the attribute name
|
|
1115
|
+
* @returns -1 if not managed, 0 if managed but by default, 1 if managed and in the map, 2 if explicit with attribute and model
|
|
1116
|
+
*/
|
|
1117
|
+
handleBinary(modelName, attribute) {
|
|
1118
|
+
let key = Object.keys(this.parameters.models).find(k => k === modelName);
|
|
1119
|
+
if (key) {
|
|
1120
|
+
// Explicit model
|
|
1121
|
+
const attributes = this.parameters.models[key];
|
|
1122
|
+
if (attributes.includes(attribute)) {
|
|
1123
|
+
return 2;
|
|
1124
|
+
}
|
|
1125
|
+
else if (attributes.includes("*")) {
|
|
1126
|
+
return 1;
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
// Default to all model - 593-594,598-599
|
|
1130
|
+
key = Object.keys(this.parameters.models).find(k => k === "*");
|
|
1131
|
+
if (!key) {
|
|
1132
|
+
return -1;
|
|
1133
|
+
}
|
|
1134
|
+
const attributes = this.parameters.models[key];
|
|
1135
|
+
if (attributes.includes(attribute)) {
|
|
1136
|
+
return 1;
|
|
1137
|
+
}
|
|
1138
|
+
if (attributes.includes("*")) {
|
|
1139
|
+
return 0;
|
|
1140
|
+
}
|
|
1141
|
+
return -1;
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Get a binary
|
|
1145
|
+
*
|
|
1146
|
+
* @param {Object} info The reference stored in your target object
|
|
1147
|
+
* @emits 'binaryGet'
|
|
1148
|
+
* @returns the result
|
|
1149
|
+
*/
|
|
1150
|
+
async get(info) {
|
|
1151
|
+
await this.emit("Binary.Get", {
|
|
1152
|
+
object: info,
|
|
1153
|
+
service: this
|
|
1154
|
+
});
|
|
1155
|
+
this.metrics.download.inc();
|
|
1156
|
+
return this._get(info);
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Download a binary to a file
|
|
1160
|
+
*
|
|
1161
|
+
* @param {Object} info The reference stored in your target object
|
|
1162
|
+
* @param {String} filepath to save the binary to
|
|
1163
|
+
* @param filename - the filename
|
|
1164
|
+
*/
|
|
1165
|
+
async downloadTo(info, filename) {
|
|
1166
|
+
await this.emit("Binary.Get", {
|
|
1167
|
+
object: info,
|
|
1168
|
+
service: this
|
|
1169
|
+
});
|
|
1170
|
+
this.metrics.download.inc();
|
|
1171
|
+
const readStream = await this._get(info);
|
|
1172
|
+
const writeStream = fs.createWriteStream(filename);
|
|
1173
|
+
return new Promise((resolve, reject) => {
|
|
1174
|
+
writeStream.on("finish", () => {
|
|
1175
|
+
return resolve();
|
|
1176
|
+
});
|
|
1177
|
+
writeStream.on("error", src => {
|
|
1178
|
+
try {
|
|
1179
|
+
fs.unlinkSync(filename);
|
|
1180
|
+
// Stubing the fs module in ESM seems complicated for now
|
|
1181
|
+
/* c8 ignore next 3 */
|
|
1182
|
+
}
|
|
1183
|
+
catch (err) {
|
|
1184
|
+
this.log("ERROR", err);
|
|
1185
|
+
}
|
|
1186
|
+
return reject(src);
|
|
1187
|
+
});
|
|
1188
|
+
readStream.pipe(writeStream);
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Based on the raw Map init a BinaryMap
|
|
1193
|
+
* @param obj - the target object
|
|
1194
|
+
* @returns the result map
|
|
1195
|
+
*/
|
|
1196
|
+
newModel(obj) {
|
|
1197
|
+
return new BinaryMap(this, obj);
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Read a stream to a buffer
|
|
1201
|
+
*
|
|
1202
|
+
* @param stream - the stream
|
|
1203
|
+
* @returns the result
|
|
1204
|
+
*/
|
|
1205
|
+
static streamToBuffer(stream) {
|
|
1206
|
+
// codesnippet from https://stackoverflow.com/questions/14269233/node-js-how-to-read-a-stream-into-a-buffer
|
|
1207
|
+
return streamToBuffer(stream);
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Check if a map is defined
|
|
1211
|
+
*
|
|
1212
|
+
* @param name - the name to use
|
|
1213
|
+
* @param property - the property name
|
|
1214
|
+
* @param object - the target object
|
|
1215
|
+
*/
|
|
1216
|
+
checkMap(object, property) {
|
|
1217
|
+
const { Identifier } = useModelMetadata(object);
|
|
1218
|
+
if (this.handleBinary(Identifier, property) !== -1) {
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
throw new Error("Unknown mapping");
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* Ensure events are sent correctly after an upload and update the BinaryFileInfo in targetted object
|
|
1225
|
+
* @param object - the target object
|
|
1226
|
+
* @param property - the property name
|
|
1227
|
+
* @param fileInfo - the file information
|
|
1228
|
+
*/
|
|
1229
|
+
async uploadSuccess(object, property, fileInfo) {
|
|
1230
|
+
let file;
|
|
1231
|
+
// Ensure we do not have a full object
|
|
1232
|
+
if (fileInfo["toBinaryFileInfo"] && typeof fileInfo["toBinaryFileInfo"] === "function") {
|
|
1233
|
+
file = fileInfo["toBinaryFileInfo"]();
|
|
1234
|
+
}
|
|
1235
|
+
else {
|
|
1236
|
+
file = fileInfo;
|
|
1237
|
+
}
|
|
1238
|
+
// `.filter()` always returns an array, and an empty array is truthy —
|
|
1239
|
+
// the previous `if ((additionalAttr = filter(...)))` form fired on every
|
|
1240
|
+
// upload (legitimate or not), throwing with an empty `properties: `
|
|
1241
|
+
// suffix because `[].join(",")` is `""`. Compare length instead.
|
|
1242
|
+
const additionalAttr = Object.keys(file).filter(k => !["name", "size", "mimetype", "hash", "challenge", "metadata"].includes(k));
|
|
1243
|
+
if (additionalAttr.length > 0) {
|
|
1244
|
+
throw new Error("Invalid file object it should be a plain BinaryFileInfo found additional properties: " +
|
|
1245
|
+
additionalAttr.join(","));
|
|
1246
|
+
}
|
|
1247
|
+
// Persist the BinaryFileInfo on the parent model. After the
|
|
1248
|
+
// Binary→Behavior migration the cardinality lives on
|
|
1249
|
+
// `Metadata.Relations.behaviors[]` (no more `Relations.binaries[]`).
|
|
1250
|
+
// `Webda/BinariesImpl` ⇒ MANY (append), anything else (`Webda/Binary`)
|
|
1251
|
+
// ⇒ ONE (replace).
|
|
1252
|
+
const behaviorRels = object?.constructor?.Metadata?.Relations?.behaviors;
|
|
1253
|
+
const beh = Array.isArray(behaviorRels)
|
|
1254
|
+
? behaviorRels.find(b => b.attribute === property)
|
|
1255
|
+
: undefined;
|
|
1256
|
+
const isCollection = beh?.behavior === "Webda/BinariesImpl";
|
|
1257
|
+
if (isCollection) {
|
|
1258
|
+
const current = Array.isArray(object[property])
|
|
1259
|
+
? [...object[property]]
|
|
1260
|
+
: [];
|
|
1261
|
+
// Idempotent push — already-linked check (preserves the previous
|
|
1262
|
+
// behaviour of the now-deleted early-return guard above).
|
|
1263
|
+
if (!current.some(i => i.hash === file.hash)) {
|
|
1264
|
+
current.push(file);
|
|
1265
|
+
}
|
|
1266
|
+
await object.patch({ [property]: current });
|
|
1267
|
+
}
|
|
1268
|
+
else {
|
|
1269
|
+
await object.patch({ [property]: file });
|
|
1270
|
+
}
|
|
1271
|
+
this.metrics.upload.inc();
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
*
|
|
1275
|
+
* @param targetStore - the target store
|
|
1276
|
+
* @param object - the target object
|
|
1277
|
+
* @param property - the property name
|
|
1278
|
+
* @param index - the index
|
|
1279
|
+
* @returns the result
|
|
1280
|
+
*/
|
|
1281
|
+
async deleteSuccess(object, property, index) {
|
|
1282
|
+
// Cardinality lives on `Metadata.Relations.behaviors[]` after the
|
|
1283
|
+
// Binary→Behavior migration. `Webda/BinariesImpl` ⇒ MANY (splice),
|
|
1284
|
+
// anything else (`Webda/Binary`) ⇒ ONE (clear). Mirrors the lookup in
|
|
1285
|
+
// `uploadSuccess`.
|
|
1286
|
+
const behaviorRels = object?.constructor?.Metadata?.Relations?.behaviors;
|
|
1287
|
+
const beh = Array.isArray(behaviorRels)
|
|
1288
|
+
? behaviorRels.find(b => b.attribute === property)
|
|
1289
|
+
: undefined;
|
|
1290
|
+
const isCollection = beh?.behavior === "Webda/BinariesImpl";
|
|
1291
|
+
const info = (isCollection && index !== undefined ? object[property][index] : object[property]);
|
|
1292
|
+
if (isCollection) {
|
|
1293
|
+
const current = Array.isArray(object[property])
|
|
1294
|
+
? [...object[property]]
|
|
1295
|
+
: [];
|
|
1296
|
+
if (index !== undefined && index >= 0 && index < current.length) {
|
|
1297
|
+
current.splice(index, 1);
|
|
1298
|
+
}
|
|
1299
|
+
await object.patch({ [property]: current });
|
|
1300
|
+
}
|
|
1301
|
+
else {
|
|
1302
|
+
await object.patch({ [property]: undefined });
|
|
1303
|
+
}
|
|
1304
|
+
await this.emit("Binary.Delete", {
|
|
1305
|
+
object: info,
|
|
1306
|
+
service: this
|
|
1307
|
+
});
|
|
1308
|
+
this.metrics.delete.inc();
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Get file either from multipart post or raw
|
|
1312
|
+
* @param req - the request
|
|
1313
|
+
* @returns the result
|
|
1314
|
+
*/
|
|
1315
|
+
async getFile(req) {
|
|
1316
|
+
const { size } = req.getParameters();
|
|
1317
|
+
let { mimetype, name } = req.getParameters();
|
|
1318
|
+
if (size > this.parameters.maxFileSize) {
|
|
1319
|
+
throw new WebdaError.BadRequest("File too big");
|
|
1320
|
+
}
|
|
1321
|
+
const file = await req.getRawInput(size ?? this.parameters.maxFileSize);
|
|
1322
|
+
mimetype ??= "application/octet-stream";
|
|
1323
|
+
name ??= "data.bin";
|
|
1324
|
+
return new MemoryBinaryFile(Buffer.from(file), {
|
|
1325
|
+
mimetype,
|
|
1326
|
+
size,
|
|
1327
|
+
name: name,
|
|
1328
|
+
hash: crypto.createHash("md5").update(file).digest("hex"),
|
|
1329
|
+
challenge: crypto
|
|
1330
|
+
.createHash("md5")
|
|
1331
|
+
.update("WEBDA" + file)
|
|
1332
|
+
.digest("hex")
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Return the name of the service for OpenAPI
|
|
1337
|
+
* @returns the result string
|
|
1338
|
+
*/
|
|
1339
|
+
getOperationName() {
|
|
1340
|
+
return this.name.toLowerCase() === "binary" ? "" : this.name;
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Based on the request parameter verify it match a known mapping
|
|
1344
|
+
* @param ctx - the operation context
|
|
1345
|
+
* @returns the result
|
|
1346
|
+
*/
|
|
1347
|
+
verifyMapAndStore(ctx) {
|
|
1348
|
+
// Check for model
|
|
1349
|
+
if (this.handleBinary(ctx.parameter("model"), ctx.parameter("property")) === -1) {
|
|
1350
|
+
throw new WebdaError.NotFound("Model not managed by this store");
|
|
1351
|
+
}
|
|
1352
|
+
// TODO: Refactor
|
|
1353
|
+
return null; //<IStore>useCore().getModelStore(useModel(ctx.parameter("model")));
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* By default no challenge is managed so throws 404
|
|
1357
|
+
*
|
|
1358
|
+
* @param args - additional arguments
|
|
1359
|
+
*/
|
|
1360
|
+
async putRedirectUrl(...args) {
|
|
1361
|
+
// Dont handle the redirect url
|
|
1362
|
+
throw new WebdaError.NotFound("No redirect url");
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
//# sourceMappingURL=binary.service.js.map
|