@loopback/repository 4.0.0-alpha.8 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +25 -0
- package/README.md +93 -389
- package/dist/common-types.d.ts +96 -0
- package/dist/common-types.js +24 -0
- package/dist/common-types.js.map +1 -0
- package/dist/connectors/connector.d.ts +48 -0
- package/{lib → dist/connectors}/connector.js +1 -1
- package/dist/connectors/connector.js.map +1 -0
- package/{lib/crud-connector.d.ts → dist/connectors/crud.connector.d.ts} +51 -51
- package/{lib/common-types.js → dist/connectors/crud.connector.js} +2 -2
- package/dist/connectors/crud.connector.js.map +1 -0
- package/dist/connectors/index.d.ts +3 -0
- package/dist/connectors/index.js +11 -0
- package/dist/connectors/index.js.map +1 -0
- package/{lib6/kv-connector.d.ts → dist/connectors/kv.connector.d.ts} +28 -28
- package/{lib/datasource.js → dist/connectors/kv.connector.js} +2 -2
- package/dist/connectors/kv.connector.js.map +1 -0
- package/dist/datasource.d.ts +27 -0
- package/{lib6 → dist}/datasource.js +1 -1
- package/dist/datasource.js.map +1 -0
- package/dist/decorators/index.d.ts +3 -0
- package/dist/decorators/index.js +11 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/metadata.d.ts +12 -0
- package/dist/decorators/metadata.js +51 -0
- package/dist/decorators/metadata.js.map +1 -0
- package/dist/decorators/model.decorator.d.ts +40 -0
- package/dist/decorators/model.decorator.js +112 -0
- package/dist/decorators/model.decorator.js.map +1 -0
- package/dist/decorators/repository.decorator.d.ts +106 -0
- package/dist/decorators/repository.decorator.js +114 -0
- package/dist/decorators/repository.decorator.js.map +1 -0
- package/dist/define-model-class.d.ts +55 -0
- package/dist/define-model-class.js +57 -0
- package/dist/define-model-class.js.map +1 -0
- package/dist/define-repository-class.d.ts +119 -0
- package/dist/define-repository-class.js +98 -0
- package/dist/define-repository-class.js.map +1 -0
- package/dist/errors/entity-not-found.error.d.ts +8 -0
- package/dist/errors/entity-not-found.error.js +28 -0
- package/dist/errors/entity-not-found.error.js.map +1 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.js +10 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/invalid-relation.error.d.ts +10 -0
- package/dist/errors/invalid-relation.error.js +28 -0
- package/dist/errors/invalid-relation.error.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/keys.d.ts +34 -0
- package/dist/keys.js +44 -0
- package/dist/keys.js.map +1 -0
- package/dist/mixins/index.d.ts +1 -0
- package/dist/mixins/index.js +9 -0
- package/dist/mixins/index.js.map +1 -0
- package/dist/mixins/repository.mixin.d.ts +377 -0
- package/dist/mixins/repository.mixin.js +405 -0
- package/dist/mixins/repository.mixin.js.map +1 -0
- package/dist/model.d.ts +232 -0
- package/dist/model.js +367 -0
- package/dist/model.js.map +1 -0
- package/dist/relations/belongs-to/belongs-to.accessor.d.ts +17 -0
- package/dist/relations/belongs-to/belongs-to.accessor.js +40 -0
- package/dist/relations/belongs-to/belongs-to.accessor.js.map +1 -0
- package/dist/relations/belongs-to/belongs-to.decorator.d.ts +11 -0
- package/dist/relations/belongs-to/belongs-to.decorator.js +64 -0
- package/dist/relations/belongs-to/belongs-to.decorator.js.map +1 -0
- package/dist/relations/belongs-to/belongs-to.helpers.d.ts +17 -0
- package/dist/relations/belongs-to/belongs-to.helpers.js +63 -0
- package/dist/relations/belongs-to/belongs-to.helpers.js.map +1 -0
- package/dist/relations/belongs-to/belongs-to.inclusion-resolver.d.ts +14 -0
- package/dist/relations/belongs-to/belongs-to.inclusion-resolver.js +36 -0
- package/dist/relations/belongs-to/belongs-to.inclusion-resolver.js.map +1 -0
- package/dist/relations/belongs-to/belongs-to.repository.d.ts +28 -0
- package/dist/relations/belongs-to/belongs-to.repository.js +33 -0
- package/dist/relations/belongs-to/belongs-to.repository.js.map +1 -0
- package/dist/relations/belongs-to/index.d.ts +4 -0
- package/dist/relations/belongs-to/index.js +12 -0
- package/dist/relations/belongs-to/index.js.map +1 -0
- package/dist/relations/has-many/has-many-through.helpers.d.ts +182 -0
- package/dist/relations/has-many/has-many-through.helpers.js +282 -0
- package/dist/relations/has-many/has-many-through.helpers.js.map +1 -0
- package/dist/relations/has-many/has-many-through.inclusion-resolver.d.ts +16 -0
- package/dist/relations/has-many/has-many-through.inclusion-resolver.js +78 -0
- package/dist/relations/has-many/has-many-through.inclusion-resolver.js.map +1 -0
- package/dist/relations/has-many/has-many-through.repository-factory.d.ts +17 -0
- package/dist/relations/has-many/has-many-through.repository-factory.js +37 -0
- package/dist/relations/has-many/has-many-through.repository-factory.js.map +1 -0
- package/dist/relations/has-many/has-many-through.repository.d.ts +114 -0
- package/dist/relations/has-many/has-many-through.repository.js +103 -0
- package/dist/relations/has-many/has-many-through.repository.js.map +1 -0
- package/dist/relations/has-many/has-many.decorator.d.ts +11 -0
- package/dist/relations/has-many/has-many.decorator.js +36 -0
- package/dist/relations/has-many/has-many.decorator.js.map +1 -0
- package/dist/relations/has-many/has-many.helpers.d.ts +26 -0
- package/dist/relations/has-many/has-many.helpers.js +78 -0
- package/dist/relations/has-many/has-many.helpers.js.map +1 -0
- package/dist/relations/has-many/has-many.inclusion-resolver.d.ts +14 -0
- package/dist/relations/has-many/has-many.inclusion-resolver.js +45 -0
- package/dist/relations/has-many/has-many.inclusion-resolver.js.map +1 -0
- package/dist/relations/has-many/has-many.repository-factory.d.ts +28 -0
- package/dist/relations/has-many/has-many.repository-factory.js +39 -0
- package/dist/relations/has-many/has-many.repository-factory.js.map +1 -0
- package/dist/relations/has-many/has-many.repository.d.ts +54 -0
- package/dist/relations/has-many/has-many.repository.js +38 -0
- package/dist/relations/has-many/has-many.repository.js.map +1 -0
- package/dist/relations/has-many/index.d.ts +6 -0
- package/dist/relations/has-many/index.js +14 -0
- package/dist/relations/has-many/index.js.map +1 -0
- package/dist/relations/has-one/has-one.decorator.d.ts +3 -0
- package/dist/relations/has-one/has-one.decorator.js +37 -0
- package/dist/relations/has-one/has-one.decorator.js.map +1 -0
- package/dist/relations/has-one/has-one.helpers.d.ts +17 -0
- package/dist/relations/has-one/has-one.helpers.js +64 -0
- package/dist/relations/has-one/has-one.helpers.js.map +1 -0
- package/dist/relations/has-one/has-one.inclusion-resolver.d.ts +14 -0
- package/dist/relations/has-one/has-one.inclusion-resolver.js +35 -0
- package/dist/relations/has-one/has-one.inclusion-resolver.js.map +1 -0
- package/dist/relations/has-one/has-one.repository-factory.d.ts +28 -0
- package/dist/relations/has-one/has-one.repository-factory.js +39 -0
- package/dist/relations/has-one/has-one.repository-factory.js.map +1 -0
- package/dist/relations/has-one/has-one.repository.d.ts +53 -0
- package/dist/relations/has-one/has-one.repository.js +45 -0
- package/dist/relations/has-one/has-one.repository.js.map +1 -0
- package/dist/relations/has-one/index.d.ts +3 -0
- package/dist/relations/has-one/index.js +11 -0
- package/dist/relations/has-one/index.js.map +1 -0
- package/dist/relations/index.d.ts +6 -0
- package/dist/relations/index.js +14 -0
- package/dist/relations/index.js.map +1 -0
- package/dist/relations/relation.decorator.d.ts +39 -0
- package/dist/relations/relation.decorator.js +88 -0
- package/dist/relations/relation.decorator.js.map +1 -0
- package/dist/relations/relation.helpers.d.ts +105 -0
- package/dist/relations/relation.helpers.js +304 -0
- package/dist/relations/relation.helpers.js.map +1 -0
- package/dist/relations/relation.types.d.ts +142 -0
- package/dist/relations/relation.types.js +21 -0
- package/dist/relations/relation.types.js.map +1 -0
- package/dist/repositories/constraint-utils.d.ts +49 -0
- package/dist/repositories/constraint-utils.js +87 -0
- package/dist/repositories/constraint-utils.js.map +1 -0
- package/dist/repositories/index.d.ts +5 -0
- package/dist/repositories/index.js +13 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/repositories/kv.repository.bridge.d.ts +30 -0
- package/dist/repositories/kv.repository.bridge.js +76 -0
- package/dist/repositories/kv.repository.bridge.js.map +1 -0
- package/dist/repositories/kv.repository.d.ts +74 -0
- package/{lib/crud-connector.js → dist/repositories/kv.repository.js} +2 -2
- package/dist/repositories/kv.repository.js.map +1 -0
- package/dist/repositories/legacy-juggler-bridge.d.ts +305 -0
- package/dist/repositories/legacy-juggler-bridge.js +452 -0
- package/dist/repositories/legacy-juggler-bridge.js.map +1 -0
- package/dist/repositories/repository.d.ts +223 -0
- package/dist/repositories/repository.js +157 -0
- package/dist/repositories/repository.js.map +1 -0
- package/dist/transaction.d.ts +30 -0
- package/dist/transaction.js +18 -0
- package/dist/transaction.js.map +1 -0
- package/dist/type-resolver.d.ts +42 -0
- package/dist/type-resolver.js +61 -0
- package/dist/type-resolver.js.map +1 -0
- package/{lib → dist}/types/any.d.ts +1 -1
- package/{lib6 → dist}/types/any.js +3 -2
- package/dist/types/any.js.map +1 -0
- package/{lib6 → dist}/types/array.d.ts +4 -4
- package/{lib → dist}/types/array.js +6 -4
- package/dist/types/array.js.map +1 -0
- package/{lib → dist}/types/boolean.d.ts +1 -1
- package/{lib6 → dist}/types/boolean.js +3 -2
- package/dist/types/boolean.js.map +1 -0
- package/{lib6 → dist}/types/buffer.d.ts +2 -2
- package/{lib → dist}/types/buffer.js +8 -6
- package/dist/types/buffer.js.map +1 -0
- package/{lib → dist}/types/date.d.ts +1 -1
- package/{lib → dist}/types/date.js +6 -4
- package/dist/types/date.js.map +1 -0
- package/{lib → dist}/types/index.d.ts +11 -9
- package/dist/types/index.js +49 -0
- package/dist/types/index.js.map +1 -0
- package/{lib6 → dist}/types/model.d.ts +2 -1
- package/{lib6 → dist}/types/model.js +2 -2
- package/dist/types/model.js.map +1 -0
- package/dist/types/null.d.ts +12 -0
- package/{lib/types/boolean.js → dist/types/null.js} +12 -11
- package/dist/types/null.js.map +1 -0
- package/{lib6 → dist}/types/number.d.ts +1 -1
- package/{lib → dist}/types/number.js +6 -4
- package/dist/types/number.js.map +1 -0
- package/{lib → dist}/types/object.d.ts +1 -1
- package/{lib → dist}/types/object.js +7 -6
- package/dist/types/object.js.map +1 -0
- package/{lib → dist}/types/string.d.ts +1 -1
- package/{lib → dist}/types/string.js +3 -2
- package/dist/types/string.js.map +1 -0
- package/{lib6 → dist}/types/type.d.ts +7 -7
- package/{lib6 → dist}/types/type.js +1 -1
- package/dist/types/type.js.map +1 -0
- package/{lib → dist}/types/union.d.ts +1 -1
- package/{lib → dist}/types/union.js +6 -4
- package/dist/types/union.js.map +1 -0
- package/package.json +49 -33
- package/src/common-types.ts +123 -0
- package/src/connectors/connector.ts +70 -0
- package/src/connectors/crud.connector.ts +208 -0
- package/src/connectors/index.ts +8 -0
- package/src/connectors/kv.connector.ts +113 -0
- package/src/datasource.ts +37 -0
- package/src/decorators/index.ts +8 -0
- package/src/decorators/metadata.ts +84 -0
- package/src/decorators/model.decorator.ts +166 -0
- package/src/decorators/repository.decorator.ts +223 -0
- package/src/define-model-class.ts +90 -0
- package/src/define-repository-class.ts +170 -0
- package/src/errors/entity-not-found.error.ts +40 -0
- package/src/errors/index.ts +7 -0
- package/src/errors/invalid-relation.error.ts +39 -0
- package/src/index.ts +36 -0
- package/src/keys.ts +40 -0
- package/{index.d.ts → src/mixins/index.ts} +2 -2
- package/src/mixins/repository.mixin.ts +499 -0
- package/src/model.ts +539 -0
- package/src/relations/belongs-to/belongs-to.accessor.ts +74 -0
- package/src/relations/belongs-to/belongs-to.decorator.ts +81 -0
- package/src/relations/belongs-to/belongs-to.helpers.ts +78 -0
- package/src/relations/belongs-to/belongs-to.inclusion-resolver.ts +71 -0
- package/src/relations/belongs-to/belongs-to.repository.ts +55 -0
- package/src/relations/belongs-to/index.ts +9 -0
- package/src/relations/has-many/has-many-through.helpers.ts +361 -0
- package/src/relations/has-many/has-many-through.inclusion-resolver.ts +135 -0
- package/src/relations/has-many/has-many-through.repository-factory.ts +121 -0
- package/src/relations/has-many/has-many-through.repository.ts +318 -0
- package/src/relations/has-many/has-many.decorator.ts +38 -0
- package/src/relations/has-many/has-many.helpers.ts +100 -0
- package/src/relations/has-many/has-many.inclusion-resolver.ts +88 -0
- package/src/relations/has-many/has-many.repository-factory.ts +76 -0
- package/src/relations/has-many/has-many.repository.ts +118 -0
- package/src/relations/has-many/index.ts +11 -0
- package/src/relations/has-one/has-one.decorator.ts +40 -0
- package/src/relations/has-one/has-one.helpers.ts +84 -0
- package/src/relations/has-one/has-one.inclusion-resolver.ts +65 -0
- package/src/relations/has-one/has-one.repository-factory.ts +72 -0
- package/src/relations/has-one/has-one.repository.ts +127 -0
- package/src/relations/has-one/index.ts +8 -0
- package/src/relations/index.ts +11 -0
- package/src/relations/relation.decorator.ts +90 -0
- package/src/relations/relation.helpers.ts +373 -0
- package/src/relations/relation.types.ts +180 -0
- package/src/repositories/constraint-utils.ts +98 -0
- package/src/repositories/index.ts +10 -0
- package/src/repositories/kv.repository.bridge.ts +97 -0
- package/src/repositories/kv.repository.ts +87 -0
- package/src/repositories/legacy-juggler-bridge.ts +788 -0
- package/src/repositories/repository.ts +441 -0
- package/src/transaction.ts +39 -0
- package/src/type-resolver.ts +98 -0
- package/src/types/any.ts +38 -0
- package/src/types/array.ts +53 -0
- package/src/types/boolean.ts +35 -0
- package/src/types/buffer.ts +53 -0
- package/src/types/date.ts +61 -0
- package/src/types/index.ts +52 -0
- package/src/types/model.ts +24 -0
- package/src/types/null.ts +35 -0
- package/src/types/number.ts +42 -0
- package/src/types/object.ts +53 -0
- package/src/types/string.ts +42 -0
- package/src/types/type.ts +51 -0
- package/src/types/union.ts +55 -0
- package/api-docs/apple-touch-icon-114x114-precomposed.png +0 -0
- package/api-docs/apple-touch-icon-144x144-precomposed.png +0 -0
- package/api-docs/apple-touch-icon-57x57-precomposed.png +0 -0
- package/api-docs/apple-touch-icon-72x72-precomposed.png +0 -0
- package/api-docs/apple-touch-icon-precomposed.png +0 -0
- package/api-docs/apple-touch-icon.png +0 -0
- package/api-docs/css/bootstrap.min.css +0 -9
- package/api-docs/css/code-themes/arta.css +0 -158
- package/api-docs/css/code-themes/ascetic.css +0 -50
- package/api-docs/css/code-themes/brown_paper.css +0 -104
- package/api-docs/css/code-themes/brown_papersq.png +0 -0
- package/api-docs/css/code-themes/dark.css +0 -103
- package/api-docs/css/code-themes/default.css +0 -135
- package/api-docs/css/code-themes/far.css +0 -111
- package/api-docs/css/code-themes/github.css +0 -127
- package/api-docs/css/code-themes/googlecode.css +0 -144
- package/api-docs/css/code-themes/idea.css +0 -121
- package/api-docs/css/code-themes/ir_black.css +0 -104
- package/api-docs/css/code-themes/magula.css +0 -121
- package/api-docs/css/code-themes/monokai.css +0 -114
- package/api-docs/css/code-themes/pojoaque.css +0 -104
- package/api-docs/css/code-themes/pojoaque.jpg +0 -0
- package/api-docs/css/code-themes/rainbow.css +0 -114
- package/api-docs/css/code-themes/school_book.css +0 -111
- package/api-docs/css/code-themes/school_book.png +0 -0
- package/api-docs/css/code-themes/sl-theme.css +0 -45
- package/api-docs/css/code-themes/solarized_dark.css +0 -88
- package/api-docs/css/code-themes/solarized_light.css +0 -88
- package/api-docs/css/code-themes/sunburst.css +0 -158
- package/api-docs/css/code-themes/tomorrow-night-blue.css +0 -52
- package/api-docs/css/code-themes/tomorrow-night-bright.css +0 -51
- package/api-docs/css/code-themes/tomorrow-night-eighties.css +0 -51
- package/api-docs/css/code-themes/tomorrow-night.css +0 -52
- package/api-docs/css/code-themes/tomorrow.css +0 -49
- package/api-docs/css/code-themes/vs.css +0 -86
- package/api-docs/css/code-themes/xcode.css +0 -154
- package/api-docs/css/code-themes/zenburn.css +0 -115
- package/api-docs/css/main.css +0 -139
- package/api-docs/favicon.ico +0 -0
- package/api-docs/fonts/0ihfXUL2emPh0ROJezvraLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
- package/api-docs/fonts/OsJ2DjdpjqFRVUSto6IffLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
- package/api-docs/fonts/_aijTyevf54tkVDLy-dlnLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
- package/api-docs/index.html +0 -18017
- package/api-docs/js/main.js +0 -19
- package/api-docs/js/vendor/bootstrap.min.js +0 -6
- package/api-docs/js/vendor/jquery-1.10.1.min.js +0 -6
- package/api-docs/js/vendor/jquery.scrollTo-1.4.3.1.js +0 -218
- package/api-docs/js/vendor/modernizr-2.6.2-respond-1.1.0.min.js +0 -11
- package/index.js +0 -9
- package/lib/common-types.d.ts +0 -44
- package/lib/common-types.js.map +0 -1
- package/lib/connector.d.ts +0 -12
- package/lib/connector.js.map +0 -1
- package/lib/crud-connector.js.map +0 -1
- package/lib/datasource.d.ts +0 -11
- package/lib/datasource.js.map +0 -1
- package/lib/decorators/model.d.ts +0 -17
- package/lib/decorators/model.js +0 -55
- package/lib/decorators/model.js.map +0 -1
- package/lib/decorators/relation.d.ts +0 -65
- package/lib/decorators/relation.js +0 -126
- package/lib/decorators/relation.js.map +0 -1
- package/lib/decorators/repository.d.ts +0 -61
- package/lib/decorators/repository.js +0 -107
- package/lib/decorators/repository.js.map +0 -1
- package/lib/index.d.ts +0 -17
- package/lib/index.js +0 -21
- package/lib/index.js.map +0 -1
- package/lib/kv-connector.d.ts +0 -77
- package/lib/kv-connector.js +0 -7
- package/lib/kv-connector.js.map +0 -1
- package/lib/kv-repository.d.ts +0 -78
- package/lib/kv-repository.js +0 -7
- package/lib/kv-repository.js.map +0 -1
- package/lib/legacy-juggler-bridge.d.ts +0 -53
- package/lib/legacy-juggler-bridge.js +0 -142
- package/lib/legacy-juggler-bridge.js.map +0 -1
- package/lib/loopback-datasource-juggler.d.ts +0 -666
- package/lib/loopback-datasource-juggler.js +0 -8
- package/lib/loopback-datasource-juggler.js.map +0 -1
- package/lib/mixin.d.ts +0 -43
- package/lib/mixin.js +0 -34
- package/lib/mixin.js.map +0 -1
- package/lib/model.d.ts +0 -137
- package/lib/model.js +0 -182
- package/lib/model.js.map +0 -1
- package/lib/query.d.ts +0 -112
- package/lib/query.js +0 -25
- package/lib/query.js.map +0 -1
- package/lib/repository-mixin.d.ts +0 -20
- package/lib/repository-mixin.js +0 -111
- package/lib/repository-mixin.js.map +0 -1
- package/lib/repository.d.ts +0 -172
- package/lib/repository.js +0 -127
- package/lib/repository.js.map +0 -1
- package/lib/types/any.js +0 -35
- package/lib/types/any.js.map +0 -1
- package/lib/types/array.d.ts +0 -14
- package/lib/types/array.js.map +0 -1
- package/lib/types/boolean.js.map +0 -1
- package/lib/types/buffer.d.ts +0 -14
- package/lib/types/buffer.js.map +0 -1
- package/lib/types/date.js.map +0 -1
- package/lib/types/index.js +0 -33
- package/lib/types/index.js.map +0 -1
- package/lib/types/model.d.ts +0 -11
- package/lib/types/model.js +0 -25
- package/lib/types/model.js.map +0 -1
- package/lib/types/number.d.ts +0 -12
- package/lib/types/number.js.map +0 -1
- package/lib/types/object.js.map +0 -1
- package/lib/types/string.js.map +0 -1
- package/lib/types/type.d.ts +0 -38
- package/lib/types/type.js +0 -7
- package/lib/types/type.js.map +0 -1
- package/lib/types/union.js.map +0 -1
- package/lib6/common-types.d.ts +0 -44
- package/lib6/common-types.js +0 -7
- package/lib6/common-types.js.map +0 -1
- package/lib6/connector.d.ts +0 -12
- package/lib6/connector.js +0 -7
- package/lib6/connector.js.map +0 -1
- package/lib6/crud-connector.d.ts +0 -130
- package/lib6/crud-connector.js +0 -7
- package/lib6/crud-connector.js.map +0 -1
- package/lib6/datasource.d.ts +0 -11
- package/lib6/datasource.js.map +0 -1
- package/lib6/decorators/model.d.ts +0 -17
- package/lib6/decorators/model.js +0 -55
- package/lib6/decorators/model.js.map +0 -1
- package/lib6/decorators/relation.d.ts +0 -65
- package/lib6/decorators/relation.js +0 -126
- package/lib6/decorators/relation.js.map +0 -1
- package/lib6/decorators/repository.d.ts +0 -61
- package/lib6/decorators/repository.js +0 -117
- package/lib6/decorators/repository.js.map +0 -1
- package/lib6/index.d.ts +0 -17
- package/lib6/index.js +0 -21
- package/lib6/index.js.map +0 -1
- package/lib6/kv-connector.js +0 -7
- package/lib6/kv-connector.js.map +0 -1
- package/lib6/kv-repository.d.ts +0 -78
- package/lib6/kv-repository.js +0 -7
- package/lib6/kv-repository.js.map +0 -1
- package/lib6/legacy-juggler-bridge.d.ts +0 -53
- package/lib6/legacy-juggler-bridge.js +0 -158
- package/lib6/legacy-juggler-bridge.js.map +0 -1
- package/lib6/loopback-datasource-juggler.d.ts +0 -666
- package/lib6/loopback-datasource-juggler.js +0 -8
- package/lib6/loopback-datasource-juggler.js.map +0 -1
- package/lib6/mixin.d.ts +0 -43
- package/lib6/mixin.js +0 -34
- package/lib6/mixin.js.map +0 -1
- package/lib6/model.d.ts +0 -137
- package/lib6/model.js +0 -182
- package/lib6/model.js.map +0 -1
- package/lib6/query.d.ts +0 -112
- package/lib6/query.js +0 -25
- package/lib6/query.js.map +0 -1
- package/lib6/repository-mixin.d.ts +0 -20
- package/lib6/repository-mixin.js +0 -111
- package/lib6/repository-mixin.js.map +0 -1
- package/lib6/repository.d.ts +0 -172
- package/lib6/repository.js +0 -127
- package/lib6/repository.js.map +0 -1
- package/lib6/types/any.d.ts +0 -12
- package/lib6/types/any.js.map +0 -1
- package/lib6/types/array.js +0 -53
- package/lib6/types/array.js.map +0 -1
- package/lib6/types/boolean.d.ts +0 -12
- package/lib6/types/boolean.js.map +0 -1
- package/lib6/types/buffer.js +0 -57
- package/lib6/types/buffer.js.map +0 -1
- package/lib6/types/date.d.ts +0 -12
- package/lib6/types/date.js +0 -60
- package/lib6/types/date.js.map +0 -1
- package/lib6/types/index.d.ts +0 -30
- package/lib6/types/index.js +0 -33
- package/lib6/types/index.js.map +0 -1
- package/lib6/types/model.js.map +0 -1
- package/lib6/types/number.js +0 -40
- package/lib6/types/number.js.map +0 -1
- package/lib6/types/object.d.ts +0 -15
- package/lib6/types/object.js +0 -49
- package/lib6/types/object.js.map +0 -1
- package/lib6/types/string.d.ts +0 -12
- package/lib6/types/string.js +0 -40
- package/lib6/types/string.js.map +0 -1
- package/lib6/types/type.js.map +0 -1
- package/lib6/types/union.d.ts +0 -14
- package/lib6/types/union.js +0 -51
- package/lib6/types/union.js.map +0 -1
|
@@ -0,0 +1,788 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2018,2020. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/repository
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {Getter} from '@loopback/core';
|
|
7
|
+
import {
|
|
8
|
+
Filter,
|
|
9
|
+
FilterExcludingWhere,
|
|
10
|
+
InclusionFilter,
|
|
11
|
+
Where,
|
|
12
|
+
} from '@loopback/filter';
|
|
13
|
+
import assert from 'assert';
|
|
14
|
+
import legacy from 'loopback-datasource-juggler';
|
|
15
|
+
import {
|
|
16
|
+
AnyObject,
|
|
17
|
+
Command,
|
|
18
|
+
Count,
|
|
19
|
+
DataObject,
|
|
20
|
+
DeepPartial,
|
|
21
|
+
NamedParameters,
|
|
22
|
+
Options,
|
|
23
|
+
PositionalParameters,
|
|
24
|
+
} from '../common-types';
|
|
25
|
+
import {EntityNotFoundError} from '../errors';
|
|
26
|
+
import {
|
|
27
|
+
Entity,
|
|
28
|
+
Model,
|
|
29
|
+
PropertyType,
|
|
30
|
+
rejectNavigationalPropertiesInData,
|
|
31
|
+
} from '../model';
|
|
32
|
+
import {
|
|
33
|
+
BelongsToAccessor,
|
|
34
|
+
BelongsToDefinition,
|
|
35
|
+
createBelongsToAccessor,
|
|
36
|
+
createHasManyRepositoryFactory,
|
|
37
|
+
createHasManyThroughRepositoryFactory,
|
|
38
|
+
createHasOneRepositoryFactory,
|
|
39
|
+
HasManyDefinition,
|
|
40
|
+
HasManyRepositoryFactory,
|
|
41
|
+
HasManyThroughRepositoryFactory,
|
|
42
|
+
HasOneDefinition,
|
|
43
|
+
HasOneRepositoryFactory,
|
|
44
|
+
includeRelatedModels,
|
|
45
|
+
InclusionResolver,
|
|
46
|
+
} from '../relations';
|
|
47
|
+
import {IsolationLevel, Transaction} from '../transaction';
|
|
48
|
+
import {isTypeResolver, resolveType} from '../type-resolver';
|
|
49
|
+
import {
|
|
50
|
+
EntityCrudRepository,
|
|
51
|
+
TransactionalEntityRepository,
|
|
52
|
+
} from './repository';
|
|
53
|
+
|
|
54
|
+
export namespace juggler {
|
|
55
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
56
|
+
export import DataSource = legacy.DataSource;
|
|
57
|
+
export import ModelBase = legacy.ModelBase;
|
|
58
|
+
export import ModelBaseClass = legacy.ModelBaseClass;
|
|
59
|
+
export import PersistedModel = legacy.PersistedModel;
|
|
60
|
+
export import KeyValueModel = legacy.KeyValueModel;
|
|
61
|
+
export import PersistedModelClass = legacy.PersistedModelClass;
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
63
|
+
export import Transaction = legacy.Transaction;
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
65
|
+
export import IsolationLevel = legacy.IsolationLevel;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isModelClass(
|
|
69
|
+
propertyType: PropertyType | undefined,
|
|
70
|
+
): propertyType is typeof Model {
|
|
71
|
+
return (
|
|
72
|
+
!isTypeResolver(propertyType) &&
|
|
73
|
+
typeof propertyType === 'function' &&
|
|
74
|
+
typeof (propertyType as typeof Model).definition === 'object' &&
|
|
75
|
+
propertyType.toString().startsWith('class ')
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* This is a bridge to the legacy DAO class. The function mixes DAO methods
|
|
81
|
+
* into a model class and attach it to a given data source
|
|
82
|
+
* @param modelClass - Model class
|
|
83
|
+
* @param ds - Data source
|
|
84
|
+
* @returns {} The new model class with DAO (CRUD) operations
|
|
85
|
+
*/
|
|
86
|
+
export function bindModel<T extends juggler.ModelBaseClass>(
|
|
87
|
+
modelClass: T,
|
|
88
|
+
ds: juggler.DataSource,
|
|
89
|
+
): T {
|
|
90
|
+
const BoundModelClass = class extends modelClass {};
|
|
91
|
+
BoundModelClass.attachTo(ds);
|
|
92
|
+
return BoundModelClass;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Ensure the value is a promise
|
|
97
|
+
* @param p - Promise or void
|
|
98
|
+
*/
|
|
99
|
+
export function ensurePromise<T>(p: legacy.PromiseOrVoid<T>): Promise<T> {
|
|
100
|
+
if (p && p instanceof Promise) {
|
|
101
|
+
return p;
|
|
102
|
+
} else {
|
|
103
|
+
return Promise.reject(new Error('The value should be a Promise: ' + p));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Default implementation of CRUD repository using legacy juggler model
|
|
109
|
+
* and data source
|
|
110
|
+
*/
|
|
111
|
+
export class DefaultCrudRepository<
|
|
112
|
+
T extends Entity,
|
|
113
|
+
ID,
|
|
114
|
+
Relations extends object = {},
|
|
115
|
+
> implements EntityCrudRepository<T, ID, Relations>
|
|
116
|
+
{
|
|
117
|
+
modelClass: juggler.PersistedModelClass;
|
|
118
|
+
|
|
119
|
+
public readonly inclusionResolvers: Map<
|
|
120
|
+
string,
|
|
121
|
+
InclusionResolver<T, Entity>
|
|
122
|
+
> = new Map();
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Constructor of DefaultCrudRepository
|
|
126
|
+
* @param entityClass - LoopBack 4 entity class
|
|
127
|
+
* @param dataSource - Legacy juggler data source
|
|
128
|
+
*/
|
|
129
|
+
constructor(
|
|
130
|
+
// entityClass should have type "typeof T", but that's not supported by TSC
|
|
131
|
+
public entityClass: typeof Entity & {prototype: T},
|
|
132
|
+
public dataSource: juggler.DataSource,
|
|
133
|
+
) {
|
|
134
|
+
const definition = entityClass.definition;
|
|
135
|
+
assert(
|
|
136
|
+
!!definition,
|
|
137
|
+
`Entity ${entityClass.name} must have valid model definition.`,
|
|
138
|
+
);
|
|
139
|
+
assert(
|
|
140
|
+
definition.idProperties().length > 0,
|
|
141
|
+
`Entity ${entityClass.name} must have at least one id/pk property.`,
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
this.modelClass = this.ensurePersistedModel(entityClass);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Create an internal legacy Model attached to the datasource
|
|
148
|
+
private ensurePersistedModel(
|
|
149
|
+
entityClass: typeof Model,
|
|
150
|
+
): typeof juggler.PersistedModel {
|
|
151
|
+
const definition = entityClass.definition;
|
|
152
|
+
assert(
|
|
153
|
+
!!definition,
|
|
154
|
+
`Entity ${entityClass.name} must have valid model definition.`,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const dataSource = this.dataSource;
|
|
158
|
+
|
|
159
|
+
const model = dataSource.getModel(definition.name);
|
|
160
|
+
if (model) {
|
|
161
|
+
// The backing persisted model has been already defined.
|
|
162
|
+
return model as typeof juggler.PersistedModel;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return this.definePersistedModel(entityClass);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Creates a legacy persisted model class, attaches it to the datasource and
|
|
170
|
+
* returns it. This method can be overriden in sub-classes to acess methods
|
|
171
|
+
* and properties in the generated model class.
|
|
172
|
+
* @param entityClass - LB4 Entity constructor
|
|
173
|
+
*/
|
|
174
|
+
protected definePersistedModel(
|
|
175
|
+
entityClass: typeof Model,
|
|
176
|
+
): typeof juggler.PersistedModel {
|
|
177
|
+
const dataSource = this.dataSource;
|
|
178
|
+
const definition = entityClass.definition;
|
|
179
|
+
|
|
180
|
+
// To handle circular reference back to the same model,
|
|
181
|
+
// we create a placeholder model that will be replaced by real one later
|
|
182
|
+
dataSource.getModel(definition.name, true /* forceCreate */);
|
|
183
|
+
|
|
184
|
+
// We need to convert property definitions from PropertyDefinition
|
|
185
|
+
// to plain data object because of a juggler limitation
|
|
186
|
+
const properties: {[name: string]: object} = {};
|
|
187
|
+
|
|
188
|
+
// We need to convert PropertyDefinition into the definition that
|
|
189
|
+
// the juggler understands
|
|
190
|
+
Object.entries(definition.properties).forEach(([key, value]) => {
|
|
191
|
+
// always clone value so that we do not modify the original model definition
|
|
192
|
+
// ensures that model definitions can be reused with multiple datasources
|
|
193
|
+
if (value.type === 'array' || value.type === Array) {
|
|
194
|
+
value = Object.assign({}, value, {
|
|
195
|
+
type: [value.itemType && this.resolvePropertyType(value.itemType)],
|
|
196
|
+
});
|
|
197
|
+
delete value.itemType;
|
|
198
|
+
} else {
|
|
199
|
+
value = Object.assign({}, value, {
|
|
200
|
+
type: this.resolvePropertyType(value.type),
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
properties[key] = Object.assign({}, value);
|
|
204
|
+
});
|
|
205
|
+
const modelClass = dataSource.createModel<juggler.PersistedModelClass>(
|
|
206
|
+
definition.name,
|
|
207
|
+
properties,
|
|
208
|
+
Object.assign(
|
|
209
|
+
// settings that users can override
|
|
210
|
+
{strict: true},
|
|
211
|
+
// user-defined settings
|
|
212
|
+
definition.settings,
|
|
213
|
+
// settings enforced by the framework
|
|
214
|
+
{strictDelete: false},
|
|
215
|
+
),
|
|
216
|
+
);
|
|
217
|
+
modelClass.attachTo(dataSource);
|
|
218
|
+
return modelClass;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private resolvePropertyType(type: PropertyType): PropertyType {
|
|
222
|
+
const resolved = resolveType(type);
|
|
223
|
+
return isModelClass(resolved)
|
|
224
|
+
? this.ensurePersistedModel(resolved)
|
|
225
|
+
: resolved;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @deprecated
|
|
230
|
+
* Function to create a constrained relation repository factory
|
|
231
|
+
*
|
|
232
|
+
* Use `this.createHasManyRepositoryFactoryFor()` instead
|
|
233
|
+
*
|
|
234
|
+
* @param relationName - Name of the relation defined on the source model
|
|
235
|
+
* @param targetRepo - Target repository instance
|
|
236
|
+
*/
|
|
237
|
+
protected _createHasManyRepositoryFactoryFor<
|
|
238
|
+
Target extends Entity,
|
|
239
|
+
TargetID,
|
|
240
|
+
ForeignKeyType,
|
|
241
|
+
>(
|
|
242
|
+
relationName: string,
|
|
243
|
+
targetRepoGetter: Getter<EntityCrudRepository<Target, TargetID>>,
|
|
244
|
+
): HasManyRepositoryFactory<Target, ForeignKeyType> {
|
|
245
|
+
return this.createHasManyRepositoryFactoryFor(
|
|
246
|
+
relationName,
|
|
247
|
+
targetRepoGetter,
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Function to create a constrained relation repository factory
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```ts
|
|
256
|
+
* class CustomerRepository extends DefaultCrudRepository<
|
|
257
|
+
* Customer,
|
|
258
|
+
* typeof Customer.prototype.id,
|
|
259
|
+
* CustomerRelations
|
|
260
|
+
* > {
|
|
261
|
+
* public readonly orders: HasManyRepositoryFactory<Order, typeof Customer.prototype.id>;
|
|
262
|
+
*
|
|
263
|
+
* constructor(
|
|
264
|
+
* protected db: juggler.DataSource,
|
|
265
|
+
* orderRepository: EntityCrudRepository<Order, typeof Order.prototype.id>,
|
|
266
|
+
* ) {
|
|
267
|
+
* super(Customer, db);
|
|
268
|
+
* this.orders = this._createHasManyRepositoryFactoryFor(
|
|
269
|
+
* 'orders',
|
|
270
|
+
* orderRepository,
|
|
271
|
+
* );
|
|
272
|
+
* }
|
|
273
|
+
* }
|
|
274
|
+
* ```
|
|
275
|
+
*
|
|
276
|
+
* @param relationName - Name of the relation defined on the source model
|
|
277
|
+
* @param targetRepo - Target repository instance
|
|
278
|
+
*/
|
|
279
|
+
protected createHasManyRepositoryFactoryFor<
|
|
280
|
+
Target extends Entity,
|
|
281
|
+
TargetID,
|
|
282
|
+
ForeignKeyType,
|
|
283
|
+
>(
|
|
284
|
+
relationName: string,
|
|
285
|
+
targetRepoGetter: Getter<EntityCrudRepository<Target, TargetID>>,
|
|
286
|
+
): HasManyRepositoryFactory<Target, ForeignKeyType> {
|
|
287
|
+
const meta = this.entityClass.definition.relations[relationName];
|
|
288
|
+
return createHasManyRepositoryFactory<Target, TargetID, ForeignKeyType>(
|
|
289
|
+
meta as HasManyDefinition,
|
|
290
|
+
targetRepoGetter,
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Function to create a constrained hasManyThrough relation repository factory
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```ts
|
|
299
|
+
* class CustomerRepository extends DefaultCrudRepository<
|
|
300
|
+
* Customer,
|
|
301
|
+
* typeof Customer.prototype.id,
|
|
302
|
+
* CustomerRelations
|
|
303
|
+
* > {
|
|
304
|
+
* public readonly cartItems: HasManyRepositoryFactory<CartItem, typeof Customer.prototype.id>;
|
|
305
|
+
*
|
|
306
|
+
* constructor(
|
|
307
|
+
* protected db: juggler.DataSource,
|
|
308
|
+
* cartItemRepository: EntityCrudRepository<CartItem, typeof, CartItem.prototype.id>,
|
|
309
|
+
* throughRepository: EntityCrudRepository<Through, typeof Through.prototype.id>,
|
|
310
|
+
* ) {
|
|
311
|
+
* super(Customer, db);
|
|
312
|
+
* this.cartItems = this.createHasManyThroughRepositoryFactoryFor(
|
|
313
|
+
* 'cartItems',
|
|
314
|
+
* cartItemRepository,
|
|
315
|
+
* );
|
|
316
|
+
* }
|
|
317
|
+
* }
|
|
318
|
+
* ```
|
|
319
|
+
*
|
|
320
|
+
* @param relationName - Name of the relation defined on the source model
|
|
321
|
+
* @param targetRepo - Target repository instance
|
|
322
|
+
* @param throughRepo - Through repository instance
|
|
323
|
+
*/
|
|
324
|
+
protected createHasManyThroughRepositoryFactoryFor<
|
|
325
|
+
Target extends Entity,
|
|
326
|
+
TargetID,
|
|
327
|
+
Through extends Entity,
|
|
328
|
+
ThroughID,
|
|
329
|
+
ForeignKeyType,
|
|
330
|
+
>(
|
|
331
|
+
relationName: string,
|
|
332
|
+
targetRepoGetter: Getter<EntityCrudRepository<Target, TargetID>>,
|
|
333
|
+
throughRepoGetter: Getter<EntityCrudRepository<Through, ThroughID>>,
|
|
334
|
+
): HasManyThroughRepositoryFactory<
|
|
335
|
+
Target,
|
|
336
|
+
TargetID,
|
|
337
|
+
Through,
|
|
338
|
+
ForeignKeyType
|
|
339
|
+
> {
|
|
340
|
+
const meta = this.entityClass.definition.relations[relationName];
|
|
341
|
+
return createHasManyThroughRepositoryFactory<
|
|
342
|
+
Target,
|
|
343
|
+
TargetID,
|
|
344
|
+
Through,
|
|
345
|
+
ThroughID,
|
|
346
|
+
ForeignKeyType
|
|
347
|
+
>(meta as HasManyDefinition, targetRepoGetter, throughRepoGetter);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* @deprecated
|
|
352
|
+
* Function to create a belongs to accessor
|
|
353
|
+
*
|
|
354
|
+
* Use `this.createBelongsToAccessorFor()` instead
|
|
355
|
+
*
|
|
356
|
+
* @param relationName - Name of the relation defined on the source model
|
|
357
|
+
* @param targetRepo - Target repository instance
|
|
358
|
+
*/
|
|
359
|
+
protected _createBelongsToAccessorFor<Target extends Entity, TargetId>(
|
|
360
|
+
relationName: string,
|
|
361
|
+
targetRepoGetter: Getter<EntityCrudRepository<Target, TargetId>>,
|
|
362
|
+
): BelongsToAccessor<Target, ID> {
|
|
363
|
+
return this.createBelongsToAccessorFor(relationName, targetRepoGetter);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Function to create a belongs to accessor
|
|
368
|
+
*
|
|
369
|
+
* @param relationName - Name of the relation defined on the source model
|
|
370
|
+
* @param targetRepo - Target repository instance
|
|
371
|
+
*/
|
|
372
|
+
protected createBelongsToAccessorFor<Target extends Entity, TargetId>(
|
|
373
|
+
relationName: string,
|
|
374
|
+
targetRepoGetter: Getter<EntityCrudRepository<Target, TargetId>>,
|
|
375
|
+
): BelongsToAccessor<Target, ID> {
|
|
376
|
+
const meta = this.entityClass.definition.relations[relationName];
|
|
377
|
+
return createBelongsToAccessor<Target, TargetId, T, ID>(
|
|
378
|
+
meta as BelongsToDefinition,
|
|
379
|
+
targetRepoGetter,
|
|
380
|
+
this,
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* @deprecated
|
|
386
|
+
* Function to create a constrained hasOne relation repository factory
|
|
387
|
+
*
|
|
388
|
+
* @param relationName - Name of the relation defined on the source model
|
|
389
|
+
* @param targetRepo - Target repository instance
|
|
390
|
+
*/
|
|
391
|
+
protected _createHasOneRepositoryFactoryFor<
|
|
392
|
+
Target extends Entity,
|
|
393
|
+
TargetID,
|
|
394
|
+
ForeignKeyType,
|
|
395
|
+
>(
|
|
396
|
+
relationName: string,
|
|
397
|
+
targetRepoGetter: Getter<EntityCrudRepository<Target, TargetID>>,
|
|
398
|
+
): HasOneRepositoryFactory<Target, ForeignKeyType> {
|
|
399
|
+
return this.createHasOneRepositoryFactoryFor(
|
|
400
|
+
relationName,
|
|
401
|
+
targetRepoGetter,
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Function to create a constrained hasOne relation repository factory
|
|
407
|
+
*
|
|
408
|
+
* @param relationName - Name of the relation defined on the source model
|
|
409
|
+
* @param targetRepo - Target repository instance
|
|
410
|
+
*/
|
|
411
|
+
protected createHasOneRepositoryFactoryFor<
|
|
412
|
+
Target extends Entity,
|
|
413
|
+
TargetID,
|
|
414
|
+
ForeignKeyType,
|
|
415
|
+
>(
|
|
416
|
+
relationName: string,
|
|
417
|
+
targetRepoGetter: Getter<EntityCrudRepository<Target, TargetID>>,
|
|
418
|
+
): HasOneRepositoryFactory<Target, ForeignKeyType> {
|
|
419
|
+
const meta = this.entityClass.definition.relations[relationName];
|
|
420
|
+
return createHasOneRepositoryFactory<Target, TargetID, ForeignKeyType>(
|
|
421
|
+
meta as HasOneDefinition,
|
|
422
|
+
targetRepoGetter,
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
async create(entity: DataObject<T>, options?: Options): Promise<T> {
|
|
427
|
+
// perform persist hook
|
|
428
|
+
const data = await this.entityToData(entity, options);
|
|
429
|
+
const model = await ensurePromise(this.modelClass.create(data, options));
|
|
430
|
+
return this.toEntity(model);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
async createAll(entities: DataObject<T>[], options?: Options): Promise<T[]> {
|
|
434
|
+
// perform persist hook
|
|
435
|
+
const data = await Promise.all(
|
|
436
|
+
entities.map(e => this.entityToData(e, options)),
|
|
437
|
+
);
|
|
438
|
+
const models = await ensurePromise(this.modelClass.create(data, options));
|
|
439
|
+
return this.toEntities(models);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
async save(entity: T, options?: Options): Promise<T> {
|
|
443
|
+
const id = this.entityClass.getIdOf(entity);
|
|
444
|
+
if (id == null) {
|
|
445
|
+
return this.create(entity, options);
|
|
446
|
+
} else {
|
|
447
|
+
await this.replaceById(id, entity, options);
|
|
448
|
+
return new this.entityClass(entity.toObject()) as T;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async find(
|
|
453
|
+
filter?: Filter<T>,
|
|
454
|
+
options?: Options,
|
|
455
|
+
): Promise<(T & Relations)[]> {
|
|
456
|
+
const include = filter?.include;
|
|
457
|
+
const models = await ensurePromise(
|
|
458
|
+
this.modelClass.find(this.normalizeFilter(filter), options),
|
|
459
|
+
);
|
|
460
|
+
const entities = this.toEntities(models);
|
|
461
|
+
return this.includeRelatedModels(entities, include, options);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
async findOne(
|
|
465
|
+
filter?: Filter<T>,
|
|
466
|
+
options?: Options,
|
|
467
|
+
): Promise<(T & Relations) | null> {
|
|
468
|
+
const model = await ensurePromise(
|
|
469
|
+
this.modelClass.findOne(this.normalizeFilter(filter), options),
|
|
470
|
+
);
|
|
471
|
+
if (!model) return null;
|
|
472
|
+
const entity = this.toEntity(model);
|
|
473
|
+
const include = filter?.include;
|
|
474
|
+
const resolved = await this.includeRelatedModels(
|
|
475
|
+
[entity],
|
|
476
|
+
include,
|
|
477
|
+
options,
|
|
478
|
+
);
|
|
479
|
+
return resolved[0];
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
async findById(
|
|
483
|
+
id: ID,
|
|
484
|
+
filter?: FilterExcludingWhere<T>,
|
|
485
|
+
options?: Options,
|
|
486
|
+
): Promise<T & Relations> {
|
|
487
|
+
const include = filter?.include;
|
|
488
|
+
const model = await ensurePromise(
|
|
489
|
+
this.modelClass.findById(id, this.normalizeFilter(filter), options),
|
|
490
|
+
);
|
|
491
|
+
if (!model) {
|
|
492
|
+
throw new EntityNotFoundError(this.entityClass, id);
|
|
493
|
+
}
|
|
494
|
+
const entity = this.toEntity(model);
|
|
495
|
+
const resolved = await this.includeRelatedModels(
|
|
496
|
+
[entity],
|
|
497
|
+
include,
|
|
498
|
+
options,
|
|
499
|
+
);
|
|
500
|
+
return resolved[0];
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
update(entity: T, options?: Options): Promise<void> {
|
|
504
|
+
return this.updateById(entity.getId(), entity, options);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
async delete(entity: T, options?: Options): Promise<void> {
|
|
508
|
+
// perform persist hook
|
|
509
|
+
await this.entityToData(entity, options);
|
|
510
|
+
return this.deleteById(entity.getId(), options);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
async updateAll(
|
|
514
|
+
data: DataObject<T>,
|
|
515
|
+
where?: Where<T>,
|
|
516
|
+
options?: Options,
|
|
517
|
+
): Promise<Count> {
|
|
518
|
+
where = where ?? {};
|
|
519
|
+
const persistedData = await this.entityToData(data, options);
|
|
520
|
+
const result = await ensurePromise(
|
|
521
|
+
this.modelClass.updateAll(where, persistedData, options),
|
|
522
|
+
);
|
|
523
|
+
return {count: result.count};
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
async updateById(
|
|
527
|
+
id: ID,
|
|
528
|
+
data: DataObject<T>,
|
|
529
|
+
options?: Options,
|
|
530
|
+
): Promise<void> {
|
|
531
|
+
if (id === undefined) {
|
|
532
|
+
throw new Error('Invalid Argument: id cannot be undefined');
|
|
533
|
+
}
|
|
534
|
+
const idProp = this.modelClass.definition.idName();
|
|
535
|
+
const where = {} as Where<T>;
|
|
536
|
+
(where as AnyObject)[idProp] = id;
|
|
537
|
+
const result = await this.updateAll(data, where, options);
|
|
538
|
+
if (result.count === 0) {
|
|
539
|
+
throw new EntityNotFoundError(this.entityClass, id);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
async replaceById(
|
|
544
|
+
id: ID,
|
|
545
|
+
data: DataObject<T>,
|
|
546
|
+
options?: Options,
|
|
547
|
+
): Promise<void> {
|
|
548
|
+
try {
|
|
549
|
+
const payload = await this.entityToData(data, options);
|
|
550
|
+
await ensurePromise(this.modelClass.replaceById(id, payload, options));
|
|
551
|
+
} catch (err) {
|
|
552
|
+
if (err.statusCode === 404) {
|
|
553
|
+
throw new EntityNotFoundError(this.entityClass, id);
|
|
554
|
+
}
|
|
555
|
+
throw err;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
async deleteAll(where?: Where<T>, options?: Options): Promise<Count> {
|
|
560
|
+
const result = await ensurePromise(
|
|
561
|
+
this.modelClass.deleteAll(where, options),
|
|
562
|
+
);
|
|
563
|
+
return {count: result.count};
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
async deleteById(id: ID, options?: Options): Promise<void> {
|
|
567
|
+
const result = await ensurePromise(this.modelClass.deleteById(id, options));
|
|
568
|
+
if (result.count === 0) {
|
|
569
|
+
throw new EntityNotFoundError(this.entityClass, id);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
async count(where?: Where<T>, options?: Options): Promise<Count> {
|
|
574
|
+
const result = await ensurePromise(this.modelClass.count(where, options));
|
|
575
|
+
return {count: result};
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
exists(id: ID, options?: Options): Promise<boolean> {
|
|
579
|
+
return ensurePromise(this.modelClass.exists(id, options));
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Execute a SQL command.
|
|
584
|
+
*
|
|
585
|
+
* **WARNING:** In general, it is always better to perform database actions
|
|
586
|
+
* through repository methods. Directly executing SQL may lead to unexpected
|
|
587
|
+
* results, corrupted data, security vulnerabilities and other issues.
|
|
588
|
+
*
|
|
589
|
+
* @example
|
|
590
|
+
*
|
|
591
|
+
* ```ts
|
|
592
|
+
* // MySQL
|
|
593
|
+
* const result = await repo.execute(
|
|
594
|
+
* 'SELECT * FROM Products WHERE size > ?',
|
|
595
|
+
* [42]
|
|
596
|
+
* );
|
|
597
|
+
*
|
|
598
|
+
* // PostgreSQL
|
|
599
|
+
* const result = await repo.execute(
|
|
600
|
+
* 'SELECT * FROM Products WHERE size > $1',
|
|
601
|
+
* [42]
|
|
602
|
+
* );
|
|
603
|
+
* ```
|
|
604
|
+
*
|
|
605
|
+
* @param command A parameterized SQL command or query.
|
|
606
|
+
* Check your database documentation for information on which characters to
|
|
607
|
+
* use as parameter placeholders.
|
|
608
|
+
* @param parameters List of parameter values to use.
|
|
609
|
+
* @param options Additional options, for example `transaction`.
|
|
610
|
+
* @returns A promise which resolves to the command output as returned by the
|
|
611
|
+
* database driver. The output type (data structure) is database specific and
|
|
612
|
+
* often depends on the command executed.
|
|
613
|
+
*/
|
|
614
|
+
execute(
|
|
615
|
+
command: Command,
|
|
616
|
+
parameters: NamedParameters | PositionalParameters,
|
|
617
|
+
options?: Options,
|
|
618
|
+
): Promise<AnyObject>;
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Execute a MongoDB command.
|
|
622
|
+
*
|
|
623
|
+
* **WARNING:** In general, it is always better to perform database actions
|
|
624
|
+
* through repository methods. Directly executing MongoDB commands may lead
|
|
625
|
+
* to unexpected results and other issues.
|
|
626
|
+
*
|
|
627
|
+
* @example
|
|
628
|
+
*
|
|
629
|
+
* ```ts
|
|
630
|
+
* const result = await repo.execute('MyCollection', 'aggregate', [
|
|
631
|
+
* {$lookup: {
|
|
632
|
+
* // ...
|
|
633
|
+
* }},
|
|
634
|
+
* {$unwind: '$data'},
|
|
635
|
+
* {$out: 'tempData'}
|
|
636
|
+
* ]);
|
|
637
|
+
* ```
|
|
638
|
+
*
|
|
639
|
+
* @param collectionName The name of the collection to execute the command on.
|
|
640
|
+
* @param command The command name. See
|
|
641
|
+
* [Collection API docs](http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html)
|
|
642
|
+
* for the list of commands supported by the MongoDB client.
|
|
643
|
+
* @param parameters Command parameters (arguments), as described in MongoDB API
|
|
644
|
+
* docs for individual collection methods.
|
|
645
|
+
* @returns A promise which resolves to the command output as returned by the
|
|
646
|
+
* database driver.
|
|
647
|
+
*/
|
|
648
|
+
execute(
|
|
649
|
+
collectionName: string,
|
|
650
|
+
command: string,
|
|
651
|
+
...parameters: PositionalParameters
|
|
652
|
+
): Promise<AnyObject>;
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Execute a raw database command using a connector that's not described
|
|
656
|
+
* by LoopBack's `execute` API yet.
|
|
657
|
+
*
|
|
658
|
+
* **WARNING:** In general, it is always better to perform database actions
|
|
659
|
+
* through repository methods. Directly executing database commands may lead
|
|
660
|
+
* to unexpected results and other issues.
|
|
661
|
+
*
|
|
662
|
+
* @param args Command and parameters, please consult your connector's
|
|
663
|
+
* documentation to learn about supported commands and their parameters.
|
|
664
|
+
* @returns A promise which resolves to the command output as returned by the
|
|
665
|
+
* database driver.
|
|
666
|
+
*/
|
|
667
|
+
execute(...args: PositionalParameters): Promise<AnyObject>;
|
|
668
|
+
|
|
669
|
+
async execute(...args: PositionalParameters): Promise<AnyObject> {
|
|
670
|
+
return ensurePromise(this.dataSource.execute(...args));
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
protected toEntity<R extends T>(model: juggler.PersistedModel): R {
|
|
674
|
+
return new this.entityClass(model.toObject()) as R;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
protected toEntities<R extends T>(models: juggler.PersistedModel[]): R[] {
|
|
678
|
+
return models.map(m => this.toEntity<R>(m));
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Register an inclusion resolver for the related model name.
|
|
683
|
+
*
|
|
684
|
+
* @param relationName - Name of the relation defined on the source model
|
|
685
|
+
* @param resolver - Resolver function for getting related model entities
|
|
686
|
+
*/
|
|
687
|
+
registerInclusionResolver(
|
|
688
|
+
relationName: string,
|
|
689
|
+
resolver: InclusionResolver<T, Entity>,
|
|
690
|
+
) {
|
|
691
|
+
this.inclusionResolvers.set(relationName, resolver);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Returns model instances that include related models of this repository
|
|
696
|
+
* that have a registered resolver.
|
|
697
|
+
*
|
|
698
|
+
* @param entities - An array of entity instances or data
|
|
699
|
+
* @param include -Inclusion filter
|
|
700
|
+
* @param options - Options for the operations
|
|
701
|
+
*/
|
|
702
|
+
protected async includeRelatedModels(
|
|
703
|
+
entities: T[],
|
|
704
|
+
include?: InclusionFilter[],
|
|
705
|
+
options?: Options,
|
|
706
|
+
): Promise<(T & Relations)[]> {
|
|
707
|
+
return includeRelatedModels<T, Relations>(this, entities, include, options);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* This function works as a persist hook.
|
|
712
|
+
* It converts an entity from the CRUD operations' caller
|
|
713
|
+
* to a persistable data that can will be stored in the
|
|
714
|
+
* back-end database.
|
|
715
|
+
*
|
|
716
|
+
* User can extend `DefaultCrudRepository` then override this
|
|
717
|
+
* function to execute custom persist hook.
|
|
718
|
+
* @param entity The entity passed from CRUD operations' caller.
|
|
719
|
+
* @param options
|
|
720
|
+
*/
|
|
721
|
+
protected async entityToData<R extends T>(
|
|
722
|
+
entity: R | DataObject<R>,
|
|
723
|
+
options = {},
|
|
724
|
+
): Promise<legacy.ModelData<legacy.PersistedModel>> {
|
|
725
|
+
return this.ensurePersistable(entity, options);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
/** Converts an entity object to a JSON object to check if it contains navigational property.
|
|
729
|
+
* Throws an error if `entity` contains navigational property.
|
|
730
|
+
*
|
|
731
|
+
* @param entity The entity passed from CRUD operations' caller.
|
|
732
|
+
* @param options
|
|
733
|
+
*/
|
|
734
|
+
protected ensurePersistable<R extends T>(
|
|
735
|
+
entity: R | DataObject<R>,
|
|
736
|
+
options = {},
|
|
737
|
+
): legacy.ModelData<legacy.PersistedModel> {
|
|
738
|
+
// FIXME(bajtos) Ideally, we should call toJSON() to convert R to data object
|
|
739
|
+
// Unfortunately that breaks replaceById for MongoDB connector, where we
|
|
740
|
+
// would call replaceId with id *argument* set to ObjectID value but
|
|
741
|
+
// id *property* set to string value.
|
|
742
|
+
/*
|
|
743
|
+
const data: AnyObject =
|
|
744
|
+
typeof entity.toJSON === 'function' ? entity.toJSON() : {...entity};
|
|
745
|
+
*/
|
|
746
|
+
const data: DeepPartial<R> = new this.entityClass(entity);
|
|
747
|
+
|
|
748
|
+
rejectNavigationalPropertiesInData(this.entityClass, data);
|
|
749
|
+
|
|
750
|
+
return data;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Removes juggler's "include" filter as it does not apply to LoopBack 4
|
|
755
|
+
* relations.
|
|
756
|
+
*
|
|
757
|
+
* @param filter - Query filter
|
|
758
|
+
*/
|
|
759
|
+
protected normalizeFilter(filter?: Filter<T>): legacy.Filter | undefined {
|
|
760
|
+
if (!filter) return undefined;
|
|
761
|
+
return {...filter, include: undefined} as legacy.Filter;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Default implementation of CRUD repository using legacy juggler model
|
|
767
|
+
* and data source with beginTransaction() method for connectors which
|
|
768
|
+
* support Transactions
|
|
769
|
+
*/
|
|
770
|
+
|
|
771
|
+
export class DefaultTransactionalRepository<
|
|
772
|
+
T extends Entity,
|
|
773
|
+
ID,
|
|
774
|
+
Relations extends object = {},
|
|
775
|
+
>
|
|
776
|
+
extends DefaultCrudRepository<T, ID, Relations>
|
|
777
|
+
implements TransactionalEntityRepository<T, ID, Relations>
|
|
778
|
+
{
|
|
779
|
+
async beginTransaction(
|
|
780
|
+
options?: IsolationLevel | Options,
|
|
781
|
+
): Promise<Transaction> {
|
|
782
|
+
const dsOptions: juggler.IsolationLevel | Options = options ?? {};
|
|
783
|
+
// juggler.Transaction still has the Promise/Callback variants of the
|
|
784
|
+
// Transaction methods
|
|
785
|
+
// so we need it cast it back
|
|
786
|
+
return (await this.dataSource.beginTransaction(dsOptions)) as Transaction;
|
|
787
|
+
}
|
|
788
|
+
}
|