@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
package/src/model.ts
ADDED
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2017,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 {AnyObject, DataObject, Options, PrototypeOf} from './common-types';
|
|
7
|
+
import {
|
|
8
|
+
BelongsToDefinition,
|
|
9
|
+
HasManyDefinition,
|
|
10
|
+
HasOneDefinition,
|
|
11
|
+
JsonSchema,
|
|
12
|
+
RelationMetadata,
|
|
13
|
+
RelationType,
|
|
14
|
+
} from './index';
|
|
15
|
+
import {TypeResolver} from './type-resolver';
|
|
16
|
+
import {Type} from './types';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This module defines the key classes representing building blocks for Domain
|
|
20
|
+
* Driven Design.
|
|
21
|
+
* See https://en.wikipedia.org/wiki/Domain-driven_design#Building_blocks
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
25
|
+
|
|
26
|
+
export interface JsonSchemaWithExtensions extends JsonSchema {
|
|
27
|
+
[attributes: string]: any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type PropertyType =
|
|
31
|
+
| string
|
|
32
|
+
| Function
|
|
33
|
+
| object
|
|
34
|
+
| Type<any>
|
|
35
|
+
| TypeResolver<Model>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Property definition for a model
|
|
39
|
+
*/
|
|
40
|
+
export interface PropertyDefinition {
|
|
41
|
+
type: PropertyType; // For example, 'string', String, or {}
|
|
42
|
+
id?: boolean | number;
|
|
43
|
+
/**
|
|
44
|
+
* Used to hide this property from the response body,
|
|
45
|
+
* adding this property to the hiddenProperties array
|
|
46
|
+
*/
|
|
47
|
+
hidden?: boolean;
|
|
48
|
+
json?: PropertyForm;
|
|
49
|
+
jsonSchema?: JsonSchemaWithExtensions;
|
|
50
|
+
store?: PropertyForm;
|
|
51
|
+
itemType?: PropertyType; // type of array
|
|
52
|
+
[attribute: string]: any; // Other attributes
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Defining the settings for a model
|
|
57
|
+
* See https://loopback.io/doc/en/lb4/Model.html#supported-entries-of-model-definition
|
|
58
|
+
*/
|
|
59
|
+
export interface ModelSettings {
|
|
60
|
+
/**
|
|
61
|
+
* Description of the model
|
|
62
|
+
*/
|
|
63
|
+
description?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Prevent clients from setting the auto-generated ID value manually
|
|
66
|
+
*/
|
|
67
|
+
forceId?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Hides properties from response bodies
|
|
70
|
+
*/
|
|
71
|
+
hiddenProperties?: string[];
|
|
72
|
+
/**
|
|
73
|
+
* Scope enables you to set a scope that will apply to every query made by the model's repository
|
|
74
|
+
*/
|
|
75
|
+
scope?: object;
|
|
76
|
+
/**
|
|
77
|
+
* Specifies whether the model accepts only predefined properties or not
|
|
78
|
+
*/
|
|
79
|
+
strict?: boolean | 'filter';
|
|
80
|
+
|
|
81
|
+
// Other variable settings
|
|
82
|
+
[name: string]: any;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* See https://github.com/loopbackio/loopback-datasource-juggler/issues/432
|
|
87
|
+
*/
|
|
88
|
+
export interface PropertyForm {
|
|
89
|
+
in?: boolean; // Can the property be used for input
|
|
90
|
+
out?: boolean; // Can the property be used for output
|
|
91
|
+
name?: string; // Custom name for this form
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A key-value map describing model relations.
|
|
96
|
+
* A relation name is used as the key, a relation definition is the value.
|
|
97
|
+
*/
|
|
98
|
+
export type RelationDefinitionMap = {
|
|
99
|
+
[relationName: string]: RelationMetadata;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* DSL for building a model definition.
|
|
104
|
+
*/
|
|
105
|
+
export interface ModelDefinitionSyntax {
|
|
106
|
+
name: string;
|
|
107
|
+
properties?: {[name: string]: PropertyDefinition | PropertyType};
|
|
108
|
+
settings?: ModelSettings;
|
|
109
|
+
relations?: RelationDefinitionMap;
|
|
110
|
+
jsonSchema?: JsonSchemaWithExtensions;
|
|
111
|
+
[attribute: string]: any;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Definition for a model
|
|
116
|
+
*/
|
|
117
|
+
export class ModelDefinition {
|
|
118
|
+
readonly name: string;
|
|
119
|
+
properties: {[name: string]: PropertyDefinition};
|
|
120
|
+
settings: ModelSettings;
|
|
121
|
+
relations: RelationDefinitionMap;
|
|
122
|
+
// indexes: Map<string, any>;
|
|
123
|
+
[attribute: string]: any; // Other attributes
|
|
124
|
+
|
|
125
|
+
constructor(nameOrDef: string | ModelDefinitionSyntax) {
|
|
126
|
+
if (typeof nameOrDef === 'string') {
|
|
127
|
+
nameOrDef = {name: nameOrDef};
|
|
128
|
+
}
|
|
129
|
+
const {name, properties, settings, relations} = nameOrDef;
|
|
130
|
+
|
|
131
|
+
this.name = name;
|
|
132
|
+
|
|
133
|
+
this.properties = {};
|
|
134
|
+
if (properties) {
|
|
135
|
+
for (const p in properties) {
|
|
136
|
+
this.addProperty(p, properties[p]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
this.settings = settings ?? new Map();
|
|
141
|
+
this.relations = relations ?? {};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Add a property
|
|
146
|
+
* @param name - Property definition or name (string)
|
|
147
|
+
* @param definitionOrType - Definition or property type
|
|
148
|
+
*/
|
|
149
|
+
addProperty(
|
|
150
|
+
name: string,
|
|
151
|
+
definitionOrType: PropertyDefinition | PropertyType,
|
|
152
|
+
): this {
|
|
153
|
+
const definition = (definitionOrType as PropertyDefinition).type
|
|
154
|
+
? (definitionOrType as PropertyDefinition)
|
|
155
|
+
: {type: definitionOrType};
|
|
156
|
+
|
|
157
|
+
if (
|
|
158
|
+
definition.id === true &&
|
|
159
|
+
definition.generated === true &&
|
|
160
|
+
definition.type !== undefined &&
|
|
161
|
+
definition.useDefaultIdType === undefined
|
|
162
|
+
) {
|
|
163
|
+
definition.useDefaultIdType = false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
this.properties[name] = definition;
|
|
167
|
+
return this;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Add a setting
|
|
172
|
+
* @param name - Setting name
|
|
173
|
+
* @param value - Setting value
|
|
174
|
+
*/
|
|
175
|
+
addSetting(name: string, value: any): this {
|
|
176
|
+
this.settings[name] = value;
|
|
177
|
+
return this;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Define a new relation.
|
|
182
|
+
* @param definition - The definition of the new relation.
|
|
183
|
+
*/
|
|
184
|
+
addRelation(definition: RelationMetadata): this {
|
|
185
|
+
this.relations[definition.name] = definition;
|
|
186
|
+
return this;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Define a new belongsTo relation.
|
|
191
|
+
* @param name - The name of the belongsTo relation.
|
|
192
|
+
* @param definition - The definition of the belongsTo relation.
|
|
193
|
+
*/
|
|
194
|
+
belongsTo(
|
|
195
|
+
name: string,
|
|
196
|
+
definition: Omit<BelongsToDefinition, 'name' | 'type' | 'targetsMany'>,
|
|
197
|
+
): this {
|
|
198
|
+
const meta: BelongsToDefinition = {
|
|
199
|
+
...definition,
|
|
200
|
+
name,
|
|
201
|
+
type: RelationType.belongsTo,
|
|
202
|
+
targetsMany: false,
|
|
203
|
+
};
|
|
204
|
+
return this.addRelation(meta);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Define a new hasOne relation.
|
|
209
|
+
* @param name - The name of the hasOne relation.
|
|
210
|
+
* @param definition - The definition of the hasOne relation.
|
|
211
|
+
*/
|
|
212
|
+
hasOne(
|
|
213
|
+
name: string,
|
|
214
|
+
definition: Omit<HasOneDefinition, 'name' | 'type' | 'targetsMany'>,
|
|
215
|
+
): this {
|
|
216
|
+
const meta: HasOneDefinition = {
|
|
217
|
+
...definition,
|
|
218
|
+
name,
|
|
219
|
+
type: RelationType.hasOne,
|
|
220
|
+
targetsMany: false,
|
|
221
|
+
};
|
|
222
|
+
return this.addRelation(meta);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Define a new hasMany relation.
|
|
227
|
+
* @param name - The name of the hasMany relation.
|
|
228
|
+
* @param definition - The definition of the hasMany relation.
|
|
229
|
+
*/
|
|
230
|
+
hasMany(
|
|
231
|
+
name: string,
|
|
232
|
+
definition: Omit<HasManyDefinition, 'name' | 'type' | 'targetsMany'>,
|
|
233
|
+
): this {
|
|
234
|
+
const meta: HasManyDefinition = {
|
|
235
|
+
...definition,
|
|
236
|
+
name,
|
|
237
|
+
type: RelationType.hasMany,
|
|
238
|
+
targetsMany: true,
|
|
239
|
+
};
|
|
240
|
+
return this.addRelation(meta);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Get an array of names of ID properties, which are specified in
|
|
245
|
+
* the model settings or properties with `id` attribute.
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```ts
|
|
249
|
+
* {
|
|
250
|
+
* settings: {
|
|
251
|
+
* id: ['id']
|
|
252
|
+
* }
|
|
253
|
+
* properties: {
|
|
254
|
+
* id: {
|
|
255
|
+
* type: 'string',
|
|
256
|
+
* id: true
|
|
257
|
+
* }
|
|
258
|
+
* }
|
|
259
|
+
* }
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
idProperties(): string[] {
|
|
263
|
+
if (typeof this.settings.id === 'string') {
|
|
264
|
+
return [this.settings.id];
|
|
265
|
+
} else if (Array.isArray(this.settings.id)) {
|
|
266
|
+
return this.settings.id;
|
|
267
|
+
}
|
|
268
|
+
const idProps = Object.keys(this.properties).filter(
|
|
269
|
+
prop => this.properties[prop].id,
|
|
270
|
+
);
|
|
271
|
+
return idProps;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function asJSON(value: any): any {
|
|
276
|
+
if (value == null) return value;
|
|
277
|
+
if (typeof value.toJSON === 'function') {
|
|
278
|
+
return value.toJSON();
|
|
279
|
+
}
|
|
280
|
+
// Handle arrays
|
|
281
|
+
if (Array.isArray(value)) {
|
|
282
|
+
return value.map(item => asJSON(item));
|
|
283
|
+
}
|
|
284
|
+
return value;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Convert a value to a plain object as DTO.
|
|
289
|
+
*
|
|
290
|
+
* - The prototype of the value in primitive types are preserved,
|
|
291
|
+
* like `Date`, `ObjectId`.
|
|
292
|
+
* - If the value is an instance of custom model, call `toObject` to convert.
|
|
293
|
+
* - If the value is an array, convert each element recursively.
|
|
294
|
+
*
|
|
295
|
+
* @param value the value to convert
|
|
296
|
+
* @param options the options
|
|
297
|
+
*/
|
|
298
|
+
function asObject(value: any, options?: Options): any {
|
|
299
|
+
if (value == null) return value;
|
|
300
|
+
if (typeof value.toObject === 'function') {
|
|
301
|
+
return value.toObject(options);
|
|
302
|
+
}
|
|
303
|
+
if (Array.isArray(value)) {
|
|
304
|
+
return value.map(item => asObject(item, options));
|
|
305
|
+
}
|
|
306
|
+
return value;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Base class for models
|
|
311
|
+
*/
|
|
312
|
+
export class Model {
|
|
313
|
+
static get modelName(): string {
|
|
314
|
+
return this.definition?.name || this.name;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
static definition: ModelDefinition;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Serialize into a plain JSON object
|
|
321
|
+
*/
|
|
322
|
+
toJSON(): Object {
|
|
323
|
+
const def = (this.constructor as typeof Model).definition;
|
|
324
|
+
if (def == null || def.settings.strict === false) {
|
|
325
|
+
return this.toObject({ignoreUnknownProperties: false});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const copyPropertyAsJson = (key: string) => {
|
|
329
|
+
const val = asJSON((this as AnyObject)[key]);
|
|
330
|
+
if (val !== undefined) {
|
|
331
|
+
json[key] = val;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const json: AnyObject = {};
|
|
336
|
+
const hiddenProperties: string[] = def.settings.hiddenProperties || [];
|
|
337
|
+
for (const p in def.properties) {
|
|
338
|
+
if (p in this && !hiddenProperties.includes(p)) {
|
|
339
|
+
copyPropertyAsJson(p);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
for (const r in def.relations) {
|
|
344
|
+
const relName = def.relations[r].name;
|
|
345
|
+
if (relName in this) {
|
|
346
|
+
copyPropertyAsJson(relName);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return json;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Convert to a plain object as DTO
|
|
355
|
+
*
|
|
356
|
+
* If `ignoreUnknownProperty` is set to false, convert all properties in the
|
|
357
|
+
* model instance, otherwise only convert the ones defined in the model
|
|
358
|
+
* definitions.
|
|
359
|
+
*
|
|
360
|
+
* See function `asObject` for each property's conversion rules.
|
|
361
|
+
*/
|
|
362
|
+
toObject(options?: Options): Object {
|
|
363
|
+
const def = (this.constructor as typeof Model).definition;
|
|
364
|
+
const obj: AnyObject = {};
|
|
365
|
+
|
|
366
|
+
if (options?.ignoreUnknownProperties === false) {
|
|
367
|
+
const hiddenProperties: string[] = def?.settings.hiddenProperties || [];
|
|
368
|
+
for (const p in this) {
|
|
369
|
+
if (!hiddenProperties.includes(p)) {
|
|
370
|
+
const val = (this as AnyObject)[p];
|
|
371
|
+
obj[p] = asObject(val, options);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return obj;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (def?.relations) {
|
|
378
|
+
for (const r in def.relations) {
|
|
379
|
+
const relName = def.relations[r].name;
|
|
380
|
+
if (relName in this) {
|
|
381
|
+
obj[relName] = asObject((this as AnyObject)[relName], {
|
|
382
|
+
...options,
|
|
383
|
+
ignoreUnknownProperties: false,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const props = def.properties;
|
|
390
|
+
const keys = Object.keys(props);
|
|
391
|
+
|
|
392
|
+
for (const i in keys) {
|
|
393
|
+
const propertyName = keys[i];
|
|
394
|
+
const val = (this as AnyObject)[propertyName];
|
|
395
|
+
|
|
396
|
+
if (val === undefined) continue;
|
|
397
|
+
obj[propertyName] = asObject(val, options);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return obj;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
constructor(data?: DataObject<Model>) {
|
|
404
|
+
Object.assign(this, data);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export interface Persistable {
|
|
409
|
+
// isNew: boolean;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Base class for value objects - An object that contains attributes but has no
|
|
414
|
+
* conceptual identity. They should be treated as immutable.
|
|
415
|
+
*/
|
|
416
|
+
export abstract class ValueObject extends Model implements Persistable {}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Base class for entities which have unique ids
|
|
420
|
+
*/
|
|
421
|
+
export class Entity extends Model implements Persistable {
|
|
422
|
+
/**
|
|
423
|
+
* Get the names of identity properties (primary keys).
|
|
424
|
+
*/
|
|
425
|
+
static getIdProperties(): string[] {
|
|
426
|
+
return this.definition.idProperties();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Get the identity value for a given entity instance or entity data object.
|
|
431
|
+
*
|
|
432
|
+
* @param entityOrData - The data object for which to determine the identity
|
|
433
|
+
* value.
|
|
434
|
+
*/
|
|
435
|
+
static getIdOf(entityOrData: AnyObject): any {
|
|
436
|
+
if (typeof entityOrData.getId === 'function') {
|
|
437
|
+
return entityOrData.getId();
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const idName = this.getIdProperties()[0];
|
|
441
|
+
return entityOrData[idName];
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Get the identity value. If the identity is a composite key, returns
|
|
446
|
+
* an object.
|
|
447
|
+
*/
|
|
448
|
+
getId(): any {
|
|
449
|
+
const definition = (this.constructor as typeof Entity).definition;
|
|
450
|
+
const idProps = definition.idProperties();
|
|
451
|
+
if (idProps.length === 1) {
|
|
452
|
+
return (this as AnyObject)[idProps[0]];
|
|
453
|
+
}
|
|
454
|
+
if (!idProps.length) {
|
|
455
|
+
throw new Error(
|
|
456
|
+
`Invalid Entity ${this.constructor.name}:` +
|
|
457
|
+
'missing primary key (id) property',
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
return this.getIdObject();
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Get the identity as an object, such as `{id: 1}` or
|
|
465
|
+
* `{schoolId: 1, studentId: 2}`
|
|
466
|
+
*/
|
|
467
|
+
getIdObject(): Object {
|
|
468
|
+
const definition = (this.constructor as typeof Entity).definition;
|
|
469
|
+
const idProps = definition.idProperties();
|
|
470
|
+
const idObj = {} as any;
|
|
471
|
+
for (const idProp of idProps) {
|
|
472
|
+
idObj[idProp] = (this as AnyObject)[idProp];
|
|
473
|
+
}
|
|
474
|
+
return idObj;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Build the where object for the given id
|
|
479
|
+
* @param id - The id value
|
|
480
|
+
*/
|
|
481
|
+
static buildWhereForId(id: any) {
|
|
482
|
+
const where = {} as any;
|
|
483
|
+
const idProps = this.definition.idProperties();
|
|
484
|
+
if (idProps.length === 1) {
|
|
485
|
+
where[idProps[0]] = id;
|
|
486
|
+
} else {
|
|
487
|
+
for (const idProp of idProps) {
|
|
488
|
+
where[idProp] = id[idProp];
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return where;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Domain events
|
|
497
|
+
*/
|
|
498
|
+
export class Event {
|
|
499
|
+
source: any;
|
|
500
|
+
type: string;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
export type EntityData = DataObject<Entity>;
|
|
504
|
+
|
|
505
|
+
export type EntityResolver<T extends Entity> = TypeResolver<T, typeof Entity>;
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Check model data for navigational properties linking to related models.
|
|
509
|
+
* Throw a descriptive error if any such property is found.
|
|
510
|
+
*
|
|
511
|
+
* @param modelClass Model constructor, e.g. `Product`.
|
|
512
|
+
* @param entityData Model instance or a plain-data object,
|
|
513
|
+
* e.g. `{name: 'pen'}`.
|
|
514
|
+
*/
|
|
515
|
+
export function rejectNavigationalPropertiesInData<M extends typeof Entity>(
|
|
516
|
+
modelClass: M,
|
|
517
|
+
data: DataObject<PrototypeOf<M>>,
|
|
518
|
+
) {
|
|
519
|
+
const def = modelClass.definition;
|
|
520
|
+
const props = def.properties;
|
|
521
|
+
|
|
522
|
+
for (const r in def.relations) {
|
|
523
|
+
const relName = def.relations[r].name;
|
|
524
|
+
if (!(relName in data)) continue;
|
|
525
|
+
|
|
526
|
+
let msg =
|
|
527
|
+
'Navigational properties are not allowed in model data ' +
|
|
528
|
+
`(model "${modelClass.modelName}" property "${relName}"), ` +
|
|
529
|
+
'please remove it.';
|
|
530
|
+
|
|
531
|
+
if (relName in props) {
|
|
532
|
+
msg +=
|
|
533
|
+
' The error might be invoked by belongsTo relations, please make' +
|
|
534
|
+
' sure the relation name is not the same as the property name.';
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
throw new Error(msg);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2018,2019. 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 debugFactory from 'debug';
|
|
7
|
+
import {DataObject} from '../../common-types';
|
|
8
|
+
import {Entity} from '../../model';
|
|
9
|
+
import {EntityCrudRepository} from '../../repositories/repository';
|
|
10
|
+
import {
|
|
11
|
+
BelongsToDefinition,
|
|
12
|
+
Getter,
|
|
13
|
+
InclusionResolver,
|
|
14
|
+
} from '../relation.types';
|
|
15
|
+
import {resolveBelongsToMetadata} from './belongs-to.helpers';
|
|
16
|
+
import {createBelongsToInclusionResolver} from './belongs-to.inclusion-resolver';
|
|
17
|
+
import {DefaultBelongsToRepository} from './belongs-to.repository';
|
|
18
|
+
|
|
19
|
+
const debug = debugFactory('loopback:repository:relations:belongs-to:accessor');
|
|
20
|
+
|
|
21
|
+
export interface BelongsToAccessor<Target extends Entity, SourceId> {
|
|
22
|
+
/**
|
|
23
|
+
* Invoke the function to obtain HasManyRepository.
|
|
24
|
+
*/
|
|
25
|
+
(sourceId: SourceId): Promise<Target>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Use `resolver` property to obtain an InclusionResolver for this relation.
|
|
29
|
+
*/
|
|
30
|
+
inclusionResolver: InclusionResolver<Entity, Target>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Enforces a BelongsTo constraint on a repository
|
|
35
|
+
*/
|
|
36
|
+
export function createBelongsToAccessor<
|
|
37
|
+
Target extends Entity,
|
|
38
|
+
TargetId,
|
|
39
|
+
Source extends Entity,
|
|
40
|
+
SourceId,
|
|
41
|
+
>(
|
|
42
|
+
belongsToMetadata: BelongsToDefinition,
|
|
43
|
+
targetRepoGetter: Getter<EntityCrudRepository<Target, TargetId>>,
|
|
44
|
+
sourceRepository: EntityCrudRepository<Source, SourceId>,
|
|
45
|
+
): BelongsToAccessor<Target, SourceId> {
|
|
46
|
+
const meta = resolveBelongsToMetadata(belongsToMetadata);
|
|
47
|
+
debug('Resolved BelongsTo relation metadata: %o', meta);
|
|
48
|
+
const result: BelongsToAccessor<Target, SourceId> =
|
|
49
|
+
async function getTargetInstanceOfBelongsTo(sourceId: SourceId) {
|
|
50
|
+
const foreignKey = meta.keyFrom;
|
|
51
|
+
const primaryKey = meta.keyTo;
|
|
52
|
+
const sourceModel = await sourceRepository.findById(sourceId);
|
|
53
|
+
const foreignKeyValue = sourceModel[foreignKey as keyof Source];
|
|
54
|
+
// workaround to check referential integrity.
|
|
55
|
+
// should be removed once the memory connector ref integrity is done
|
|
56
|
+
// GH issue: https://github.com/loopbackio/loopback-next/issues/2333
|
|
57
|
+
if (!foreignKeyValue) {
|
|
58
|
+
return undefined as unknown as Target;
|
|
59
|
+
}
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
+
const constraint: any = {[primaryKey]: foreignKeyValue};
|
|
62
|
+
const constrainedRepo = new DefaultBelongsToRepository(
|
|
63
|
+
targetRepoGetter,
|
|
64
|
+
constraint as DataObject<Target>,
|
|
65
|
+
);
|
|
66
|
+
return constrainedRepo.get();
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
result.inclusionResolver = createBelongsToInclusionResolver(
|
|
70
|
+
meta,
|
|
71
|
+
targetRepoGetter,
|
|
72
|
+
);
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
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 {DecoratorFactory, MetadataInspector} from '@loopback/core';
|
|
7
|
+
import {property} from '../../decorators';
|
|
8
|
+
import {relation} from '../relation.decorator';
|
|
9
|
+
import {Entity, EntityResolver, PropertyDefinition} from '../../model';
|
|
10
|
+
import {BelongsToDefinition, RelationType} from '../relation.types';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Decorator for belongsTo
|
|
14
|
+
* @param targetResolver - A resolver function that returns the target model for
|
|
15
|
+
* a belongsTo relation
|
|
16
|
+
* @param definition - Optional metadata for setting up a belongsTo relation
|
|
17
|
+
* @param propertyDefinition - Optional metadata for setting up the property
|
|
18
|
+
* @returns A property decorator
|
|
19
|
+
*/
|
|
20
|
+
export function belongsTo<T extends Entity>(
|
|
21
|
+
targetResolver: EntityResolver<T>,
|
|
22
|
+
definition?: Partial<BelongsToDefinition>,
|
|
23
|
+
propertyDefinition?: Partial<PropertyDefinition>,
|
|
24
|
+
) {
|
|
25
|
+
return function (decoratedTarget: Entity, decoratedKey: string) {
|
|
26
|
+
const propType =
|
|
27
|
+
MetadataInspector.getDesignTypeForProperty(
|
|
28
|
+
decoratedTarget,
|
|
29
|
+
decoratedKey,
|
|
30
|
+
) ?? propertyDefinition?.type;
|
|
31
|
+
|
|
32
|
+
if (!propType) {
|
|
33
|
+
const fullPropName = DecoratorFactory.getTargetName(
|
|
34
|
+
decoratedTarget,
|
|
35
|
+
decoratedKey,
|
|
36
|
+
);
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Cannot infer type of model property ${fullPropName} because ` +
|
|
39
|
+
'TypeScript compiler option `emitDecoratorMetadata` is not set. ' +
|
|
40
|
+
'Please enable `emitDecoratorMetadata` or use the third argument of ' +
|
|
41
|
+
'`@belongsTo` decorator to specify the property type explicitly.',
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const propMeta: PropertyDefinition = Object.assign(
|
|
46
|
+
{},
|
|
47
|
+
// properties provided by the caller
|
|
48
|
+
propertyDefinition,
|
|
49
|
+
// properties enforced by the decorator
|
|
50
|
+
{
|
|
51
|
+
type: propType,
|
|
52
|
+
// TODO(bajtos) Make the foreign key required once our REST API layer
|
|
53
|
+
// allows controller methods to exclude required properties
|
|
54
|
+
// required: true,
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
property(propMeta)(decoratedTarget, decoratedKey);
|
|
58
|
+
|
|
59
|
+
// @belongsTo() is typically decorating the foreign key property,
|
|
60
|
+
// e.g. customerId. We need to strip the trailing "Id" suffix from the name.
|
|
61
|
+
const relationName = decoratedKey.replace(/Id$/, '');
|
|
62
|
+
|
|
63
|
+
const meta: BelongsToDefinition = Object.assign(
|
|
64
|
+
// default values, can be customized by the caller
|
|
65
|
+
{
|
|
66
|
+
keyFrom: decoratedKey,
|
|
67
|
+
name: relationName,
|
|
68
|
+
},
|
|
69
|
+
// properties provided by the caller
|
|
70
|
+
definition,
|
|
71
|
+
// properties enforced by the decorator
|
|
72
|
+
{
|
|
73
|
+
type: RelationType.belongsTo,
|
|
74
|
+
targetsMany: false,
|
|
75
|
+
source: decoratedTarget.constructor,
|
|
76
|
+
target: targetResolver,
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
relation(meta)(decoratedTarget, decoratedKey);
|
|
80
|
+
};
|
|
81
|
+
}
|