@nocobase/database 0.5.0-alpha.38 → 0.7.0-alpha.10
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 +201 -21
- package/esm/collection-importer.d.ts +7 -0
- package/esm/collection-importer.js +49 -0
- package/esm/collection-importer.js.map +1 -0
- package/esm/collection.d.ts +73 -0
- package/esm/collection.js +224 -0
- package/esm/collection.js.map +1 -0
- package/esm/database.d.ts +101 -0
- package/esm/database.js +275 -0
- package/esm/database.js.map +1 -0
- package/esm/fields/array-field.d.ts +11 -0
- package/esm/fields/array-field.js +26 -0
- package/esm/fields/array-field.js.map +1 -0
- package/esm/fields/belongs-to-field.d.ts +12 -0
- package/esm/fields/belongs-to-field.js +57 -0
- package/esm/fields/belongs-to-field.js.map +1 -0
- package/esm/fields/belongs-to-many-field.d.ts +11 -0
- package/esm/fields/belongs-to-many-field.js +55 -0
- package/esm/fields/belongs-to-many-field.js.map +1 -0
- package/esm/fields/boolean-field.d.ts +8 -0
- package/esm/fields/boolean-field.js +8 -0
- package/esm/fields/boolean-field.js.map +1 -0
- package/esm/fields/context-field.d.ts +13 -0
- package/esm/fields/context-field.js +43 -0
- package/esm/fields/context-field.js.map +1 -0
- package/esm/fields/date-field.d.ts +8 -0
- package/esm/fields/date-field.js +8 -0
- package/esm/fields/date-field.js.map +1 -0
- package/esm/fields/field.d.ts +37 -0
- package/esm/fields/field.js +74 -0
- package/esm/fields/field.js.map +1 -0
- package/esm/fields/has-inverse-field.d.ts +4 -0
- package/esm/fields/has-inverse-field.js +2 -0
- package/esm/fields/has-inverse-field.js.map +1 -0
- package/esm/fields/has-many-field.d.ts +64 -0
- package/esm/fields/has-many-field.js +58 -0
- package/esm/fields/has-many-field.js.map +1 -0
- package/esm/fields/has-one-field.d.ts +64 -0
- package/esm/fields/has-one-field.js +57 -0
- package/esm/fields/has-one-field.js.map +1 -0
- package/esm/fields/index.d.ts +40 -0
- package/esm/fields/index.js +21 -0
- package/esm/fields/index.js.map +1 -0
- package/esm/fields/json-field.d.ts +14 -0
- package/esm/fields/json-field.js +17 -0
- package/esm/fields/json-field.js.map +1 -0
- package/esm/fields/number-field.d.ts +32 -0
- package/esm/fields/number-field.js +28 -0
- package/esm/fields/number-field.js.map +1 -0
- package/esm/fields/password-field.d.ts +21 -0
- package/esm/fields/password-field.js +71 -0
- package/esm/fields/password-field.js.map +1 -0
- package/esm/fields/radio-field.d.ts +14 -0
- package/esm/fields/radio-field.js +49 -0
- package/esm/fields/radio-field.js.map +1 -0
- package/esm/fields/relation-field.d.ts +20 -0
- package/esm/fields/relation-field.js +27 -0
- package/esm/fields/relation-field.js.map +1 -0
- package/esm/fields/sort-field.d.ts +16 -0
- package/esm/fields/sort-field.js +90 -0
- package/esm/fields/sort-field.js.map +1 -0
- package/esm/fields/string-field.d.ts +8 -0
- package/esm/fields/string-field.js +8 -0
- package/esm/fields/string-field.js.map +1 -0
- package/esm/fields/text-field.d.ts +8 -0
- package/esm/fields/text-field.js +8 -0
- package/esm/fields/text-field.js.map +1 -0
- package/esm/fields/time-field.d.ts +8 -0
- package/esm/fields/time-field.js +8 -0
- package/esm/fields/time-field.js.map +1 -0
- package/esm/fields/uid-field.d.ts +10 -0
- package/esm/fields/uid-field.js +27 -0
- package/esm/fields/uid-field.js.map +1 -0
- package/esm/fields/virtual-field.d.ts +8 -0
- package/esm/fields/virtual-field.js +8 -0
- package/esm/fields/virtual-field.js.map +1 -0
- package/esm/filter-parser.d.ts +27 -0
- package/esm/filter-parser.js +185 -0
- package/esm/filter-parser.js.map +1 -0
- package/esm/index.d.ts +15 -0
- package/esm/index.js +16 -0
- package/esm/index.js.map +1 -0
- package/esm/magic-attribute-model.d.ts +7 -0
- package/esm/magic-attribute-model.js +70 -0
- package/esm/magic-attribute-model.js.map +1 -0
- package/esm/mock-database.d.ts +22 -0
- package/esm/mock-database.js +34 -0
- package/esm/mock-database.js.map +1 -0
- package/esm/model-hook.d.ts +12 -0
- package/esm/model-hook.js +61 -0
- package/esm/model-hook.js.map +1 -0
- package/esm/model.d.ts +15 -0
- package/esm/model.js +80 -0
- package/esm/model.js.map +1 -0
- package/esm/operators/array.d.ts +26 -0
- package/esm/operators/array.js +105 -0
- package/esm/operators/array.js.map +1 -0
- package/esm/operators/association.d.ts +10 -0
- package/esm/operators/association.js +14 -0
- package/esm/operators/association.js.map +1 -0
- package/esm/operators/date.d.ts +34 -0
- package/esm/operators/date.js +35 -0
- package/esm/operators/date.js.map +1 -0
- package/esm/operators/empty.d.ts +28 -0
- package/esm/operators/empty.js +58 -0
- package/esm/operators/empty.js.map +1 -0
- package/esm/operators/index.d.ts +2 -0
- package/esm/operators/index.js +2 -0
- package/esm/operators/index.js.map +1 -0
- package/esm/operators/ne.d.ts +10 -0
- package/esm/operators/ne.js +12 -0
- package/esm/operators/ne.js.map +1 -0
- package/esm/operators/string.d.ts +21 -0
- package/esm/operators/string.js +35 -0
- package/esm/operators/string.js.map +1 -0
- package/esm/operators/utils.d.ts +4 -0
- package/esm/operators/utils.js +11 -0
- package/esm/operators/utils.js.map +1 -0
- package/esm/options-parser.d.ts +31 -0
- package/esm/options-parser.js +225 -0
- package/esm/options-parser.js.map +1 -0
- package/esm/playground.d.ts +1 -0
- package/esm/playground.js +53 -0
- package/esm/playground.js.map +1 -0
- package/esm/relation-repository/belongs-to-many-repository.d.ts +36 -0
- package/esm/relation-repository/belongs-to-many-repository.js +199 -0
- package/esm/relation-repository/belongs-to-many-repository.js.map +1 -0
- package/esm/relation-repository/belongs-to-repository.d.ts +17 -0
- package/esm/relation-repository/belongs-to-repository.js +4 -0
- package/esm/relation-repository/belongs-to-repository.js.map +1 -0
- package/esm/relation-repository/hasmany-repository.d.ts +23 -0
- package/esm/relation-repository/hasmany-repository.js +125 -0
- package/esm/relation-repository/hasmany-repository.js.map +1 -0
- package/esm/relation-repository/hasone-repository.d.ts +17 -0
- package/esm/relation-repository/hasone-repository.js +4 -0
- package/esm/relation-repository/hasone-repository.js.map +1 -0
- package/esm/relation-repository/multiple-relation-repository.d.ts +23 -0
- package/esm/relation-repository/multiple-relation-repository.js +149 -0
- package/esm/relation-repository/multiple-relation-repository.js.map +1 -0
- package/esm/relation-repository/relation-repository.d.ts +32 -0
- package/esm/relation-repository/relation-repository.js +93 -0
- package/esm/relation-repository/relation-repository.js.map +1 -0
- package/esm/relation-repository/single-relation-repository.d.ts +23 -0
- package/esm/relation-repository/single-relation-repository.js +96 -0
- package/esm/relation-repository/single-relation-repository.js.map +1 -0
- package/esm/relation-repository/types.d.ts +7 -0
- package/esm/relation-repository/types.js +2 -0
- package/esm/relation-repository/types.js.map +1 -0
- package/esm/repository.d.ts +165 -0
- package/esm/repository.js +276 -0
- package/esm/repository.js.map +1 -0
- package/esm/transaction-decorator.d.ts +1 -0
- package/esm/transaction-decorator.js +63 -0
- package/esm/transaction-decorator.js.map +1 -0
- package/esm/update-associations.d.ts +60 -0
- package/esm/update-associations.js +362 -0
- package/esm/update-associations.js.map +1 -0
- package/esm/update-guard.d.ts +26 -0
- package/esm/update-guard.js +122 -0
- package/esm/update-guard.js.map +1 -0
- package/lib/collection-importer.d.ts +7 -0
- package/lib/collection-importer.js +75 -0
- package/lib/collection-importer.js.map +1 -0
- package/lib/collection.d.ts +73 -0
- package/lib/collection.js +231 -0
- package/lib/collection.js.map +1 -0
- package/lib/database.d.ts +93 -43
- package/lib/database.js +277 -471
- package/lib/database.js.map +1 -1
- package/lib/fields/array-field.d.ts +11 -0
- package/lib/fields/array-field.js +30 -0
- package/lib/fields/array-field.js.map +1 -0
- package/lib/fields/belongs-to-field.d.ts +12 -0
- package/lib/fields/belongs-to-field.js +61 -0
- package/lib/fields/belongs-to-field.js.map +1 -0
- package/lib/fields/belongs-to-many-field.d.ts +11 -0
- package/lib/fields/belongs-to-many-field.js +59 -0
- package/lib/fields/belongs-to-many-field.js.map +1 -0
- package/lib/fields/boolean-field.d.ts +8 -0
- package/lib/fields/boolean-field.js +12 -0
- package/lib/fields/boolean-field.js.map +1 -0
- package/lib/fields/context-field.d.ts +13 -0
- package/lib/fields/context-field.js +50 -0
- package/lib/fields/context-field.js.map +1 -0
- package/lib/fields/date-field.d.ts +8 -0
- package/lib/fields/date-field.js +12 -0
- package/lib/fields/date-field.js.map +1 -0
- package/lib/fields/field.d.ts +37 -0
- package/lib/fields/field.js +81 -0
- package/lib/fields/field.js.map +1 -0
- package/lib/fields/has-inverse-field.d.ts +4 -0
- package/lib/fields/has-inverse-field.js +3 -0
- package/lib/fields/has-inverse-field.js.map +1 -0
- package/lib/fields/has-many-field.d.ts +64 -0
- package/lib/fields/has-many-field.js +62 -0
- package/lib/fields/has-many-field.js.map +1 -0
- package/lib/fields/has-one-field.d.ts +64 -0
- package/lib/fields/has-one-field.js +61 -0
- package/lib/fields/has-one-field.js.map +1 -0
- package/lib/fields/index.d.ts +40 -10
- package/lib/fields/index.js +31 -138
- package/lib/fields/index.js.map +1 -1
- package/lib/fields/json-field.d.ts +14 -0
- package/lib/fields/json-field.js +22 -0
- package/lib/fields/json-field.js.map +1 -0
- package/lib/fields/number-field.d.ts +32 -0
- package/lib/fields/number-field.js +36 -0
- package/lib/fields/number-field.js.map +1 -0
- package/lib/fields/password-field.d.ts +21 -0
- package/lib/fields/password-field.js +78 -0
- package/lib/fields/password-field.js.map +1 -0
- package/lib/fields/radio-field.d.ts +14 -0
- package/lib/fields/radio-field.js +53 -0
- package/lib/fields/radio-field.js.map +1 -0
- package/lib/fields/relation-field.d.ts +20 -0
- package/lib/fields/relation-field.js +31 -0
- package/lib/fields/relation-field.js.map +1 -0
- package/lib/fields/sort-field.d.ts +16 -0
- package/lib/fields/sort-field.js +94 -0
- package/lib/fields/sort-field.js.map +1 -0
- package/lib/fields/string-field.d.ts +8 -0
- package/lib/fields/string-field.js +12 -0
- package/lib/fields/string-field.js.map +1 -0
- package/lib/fields/text-field.d.ts +8 -0
- package/lib/fields/text-field.js +12 -0
- package/lib/fields/text-field.js.map +1 -0
- package/lib/fields/time-field.d.ts +8 -0
- package/lib/fields/time-field.js +12 -0
- package/lib/fields/time-field.js.map +1 -0
- package/lib/fields/uid-field.d.ts +10 -0
- package/lib/fields/uid-field.js +31 -0
- package/lib/fields/uid-field.js.map +1 -0
- package/lib/fields/virtual-field.d.ts +8 -0
- package/lib/fields/virtual-field.js +12 -0
- package/lib/fields/virtual-field.js.map +1 -0
- package/lib/filter-parser.d.ts +27 -0
- package/lib/filter-parser.js +191 -0
- package/lib/filter-parser.js.map +1 -0
- package/lib/index.d.ts +13 -6
- package/lib/index.js +27 -60
- package/lib/index.js.map +1 -1
- package/lib/magic-attribute-model.d.ts +7 -0
- package/lib/magic-attribute-model.js +77 -0
- package/lib/magic-attribute-model.js.map +1 -0
- package/lib/mock-database.d.ts +22 -0
- package/lib/mock-database.js +40 -0
- package/lib/mock-database.js.map +1 -0
- package/lib/model-hook.d.ts +12 -0
- package/lib/model-hook.js +68 -0
- package/lib/model-hook.js.map +1 -0
- package/lib/model.d.ts +11 -45
- package/lib/model.js +76 -452
- package/lib/model.js.map +1 -1
- package/lib/operators/array.d.ts +26 -0
- package/lib/operators/array.js +107 -0
- package/lib/operators/array.js.map +1 -0
- package/lib/operators/association.d.ts +10 -0
- package/lib/operators/association.js +16 -0
- package/lib/operators/association.js.map +1 -0
- package/lib/operators/date.d.ts +34 -0
- package/lib/operators/date.js +40 -0
- package/lib/operators/date.js.map +1 -0
- package/lib/operators/empty.d.ts +28 -0
- package/lib/operators/empty.js +82 -0
- package/lib/operators/empty.js.map +1 -0
- package/lib/operators/index.d.ts +2 -0
- package/lib/operators/index.js +4 -0
- package/lib/operators/index.js.map +1 -0
- package/lib/operators/ne.d.ts +10 -0
- package/lib/operators/ne.js +14 -0
- package/lib/operators/ne.js.map +1 -0
- package/lib/operators/string.d.ts +21 -0
- package/lib/operators/string.js +37 -0
- package/lib/operators/string.js.map +1 -0
- package/lib/operators/utils.d.ts +4 -0
- package/lib/operators/utils.js +16 -0
- package/lib/operators/utils.js.map +1 -0
- package/lib/options-parser.d.ts +31 -0
- package/lib/options-parser.js +232 -0
- package/lib/options-parser.js.map +1 -0
- package/lib/playground.d.ts +1 -0
- package/lib/playground.js +55 -0
- package/lib/playground.js.map +1 -0
- package/lib/relation-repository/belongs-to-many-repository.d.ts +36 -0
- package/lib/relation-repository/belongs-to-many-repository.js +206 -0
- package/lib/relation-repository/belongs-to-many-repository.js.map +1 -0
- package/lib/relation-repository/belongs-to-repository.d.ts +17 -0
- package/lib/relation-repository/belongs-to-repository.js +8 -0
- package/lib/relation-repository/belongs-to-repository.js.map +1 -0
- package/lib/relation-repository/hasmany-repository.d.ts +23 -0
- package/lib/relation-repository/hasmany-repository.js +129 -0
- package/lib/relation-repository/hasmany-repository.js.map +1 -0
- package/lib/relation-repository/hasone-repository.d.ts +17 -0
- package/lib/relation-repository/hasone-repository.js +8 -0
- package/lib/relation-repository/hasone-repository.js.map +1 -0
- package/lib/relation-repository/multiple-relation-repository.d.ts +23 -0
- package/lib/relation-repository/multiple-relation-repository.js +153 -0
- package/lib/relation-repository/multiple-relation-repository.js.map +1 -0
- package/lib/relation-repository/relation-repository.d.ts +32 -0
- package/lib/relation-repository/relation-repository.js +100 -0
- package/lib/relation-repository/relation-repository.js.map +1 -0
- package/lib/relation-repository/single-relation-repository.d.ts +23 -0
- package/lib/relation-repository/single-relation-repository.js +103 -0
- package/lib/relation-repository/single-relation-repository.js.map +1 -0
- package/lib/relation-repository/types.d.ts +7 -0
- package/lib/relation-repository/types.js +3 -0
- package/lib/relation-repository/types.js.map +1 -0
- package/lib/repository.d.ts +165 -0
- package/lib/repository.js +302 -0
- package/lib/repository.js.map +1 -0
- package/lib/transaction-decorator.d.ts +1 -0
- package/lib/transaction-decorator.js +70 -0
- package/lib/transaction-decorator.js.map +1 -0
- package/lib/update-associations.d.ts +60 -0
- package/lib/update-associations.js +374 -0
- package/lib/update-associations.js.map +1 -0
- package/lib/update-guard.d.ts +26 -0
- package/lib/update-guard.js +129 -0
- package/lib/update-guard.js.map +1 -0
- package/package.json +17 -5
- package/src/__tests__/collection-importer.test.ts +21 -0
- package/src/__tests__/collection.sortable.test.ts +65 -0
- package/src/__tests__/collection.test.ts +218 -0
- package/src/__tests__/database.import.test.ts +33 -0
- package/src/__tests__/database.test.ts +229 -0
- package/src/__tests__/field-options/hidden.test.ts +302 -0
- package/src/__tests__/field-options/sort-by.test.ts +220 -0
- package/src/__tests__/fields/belongs-to-field.test.ts +162 -0
- package/src/__tests__/fields/belongs-to-many-field.test.ts +61 -0
- package/src/__tests__/fields/context-field.test.ts +140 -0
- package/src/__tests__/fields/has-many-field.test.ts +152 -0
- package/src/__tests__/fields/has-one-field.test.ts +67 -0
- package/src/__tests__/fields/password-field.test.ts +30 -0
- package/src/__tests__/fields/sort-field.test.ts +133 -0
- package/src/__tests__/fields/string-field.test.ts +77 -0
- package/src/__tests__/filter-parser.test.ts +104 -0
- package/src/__tests__/fixtures/c0/a.ts +6 -0
- package/src/__tests__/fixtures/c1/b.ts +6 -0
- package/src/__tests__/fixtures/c2/a.ts +6 -0
- package/src/__tests__/fixtures/collections/delay-extend.ts +6 -0
- package/src/__tests__/fixtures/collections/delay-extend2.ts +6 -0
- package/src/__tests__/fixtures/collections/extend.ts +6 -0
- package/src/__tests__/fixtures/collections/extend2.ts +6 -0
- package/src/__tests__/fixtures/collections/posts.ts +4 -0
- package/src/__tests__/fixtures/collections/tags.js +4 -0
- package/src/__tests__/fixtures/collections/test.jpg +0 -0
- package/src/__tests__/fixtures/collections/user.json +9 -0
- package/src/__tests__/index.ts +1 -0
- package/src/__tests__/magic-attribute-model.test.ts +103 -0
- package/src/__tests__/model.test.ts +60 -0
- package/src/__tests__/operator/array-operator.test.ts +268 -0
- package/src/__tests__/operator/association-operator.test.ts +263 -0
- package/src/__tests__/operator/date-operator.test.ts +165 -0
- package/src/__tests__/operator/empty-operator.test.ts +77 -0
- package/src/__tests__/operator/ne.test.ts +33 -0
- package/src/__tests__/operator/string-operator.test.ts +62 -0
- package/src/__tests__/option-parser.test.ts +185 -0
- package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +697 -0
- package/src/__tests__/relation-repository/has-many-repository.test.ts +414 -0
- package/src/__tests__/relation-repository/hasone-repository.test.ts +77 -0
- package/src/__tests__/repository/count.test.ts +180 -0
- package/src/__tests__/repository/create.test.ts +163 -0
- package/src/__tests__/repository/destroy.test.ts +196 -0
- package/src/__tests__/repository/find.test.ts +247 -0
- package/src/__tests__/repository/update.test.ts +60 -0
- package/src/__tests__/repository.test.ts +438 -0
- package/src/__tests__/update-associations.test.ts +412 -0
- package/src/__tests__/update-guard.test.ts +376 -0
- package/src/collection-importer.ts +49 -0
- package/src/collection.ts +282 -0
- package/src/database.ts +340 -0
- package/src/fields/array-field.ts +35 -0
- package/src/fields/belongs-to-field.ts +76 -0
- package/src/fields/belongs-to-many-field.ts +77 -0
- package/src/fields/boolean-field.ts +12 -0
- package/src/fields/context-field.ts +45 -0
- package/src/fields/date-field.ts +12 -0
- package/src/fields/field.ts +105 -0
- package/src/fields/has-inverse-field.ts +5 -0
- package/src/fields/has-many-field.ts +143 -0
- package/src/fields/has-one-field.ts +136 -0
- package/src/fields/index.ts +72 -0
- package/src/fields/json-field.ts +25 -0
- package/src/fields/number-field.ts +52 -0
- package/src/fields/password-field.ts +72 -0
- package/src/fields/radio-field.ts +50 -0
- package/src/fields/relation-field.ts +37 -0
- package/src/fields/sort-field.ts +96 -0
- package/src/fields/string-field.ts +12 -0
- package/src/fields/text-field.ts +12 -0
- package/src/fields/time-field.ts +12 -0
- package/src/fields/uid-field.ts +24 -0
- package/src/fields/virtual-field.ts +12 -0
- package/src/filter-parser.ts +243 -0
- package/src/index.ts +16 -0
- package/src/magic-attribute-model.ts +62 -0
- package/src/mock-database.ts +42 -0
- package/src/model-hook.ts +69 -0
- package/src/model.ts +114 -0
- package/src/operators/array.ts +145 -0
- package/src/operators/association.ts +14 -0
- package/src/operators/date.ts +41 -0
- package/src/operators/empty.ts +75 -0
- package/src/operators/index.ts +8 -0
- package/src/operators/ne.ts +12 -0
- package/src/operators/string.ts +40 -0
- package/src/operators/utils.ts +13 -0
- package/src/options-parser.ts +285 -0
- package/src/playground.ts +52 -0
- package/src/relation-repository/belongs-to-many-repository.ts +240 -0
- package/src/relation-repository/belongs-to-repository.ts +23 -0
- package/src/relation-repository/hasmany-repository.ts +145 -0
- package/src/relation-repository/hasone-repository.ts +23 -0
- package/src/relation-repository/multiple-relation-repository.ts +198 -0
- package/src/relation-repository/relation-repository.ts +114 -0
- package/src/relation-repository/single-relation-repository.ts +99 -0
- package/src/relation-repository/types.ts +15 -0
- package/src/repository.ts +478 -0
- package/src/transaction-decorator.ts +58 -0
- package/src/update-associations.ts +478 -0
- package/src/update-guard.ts +167 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +5 -0
- package/examples/index.ts +0 -125
- package/examples/plugins/db-driven/index.ts +0 -25
- package/examples/plugins/db-driven/tables/fields.ts +0 -78
- package/examples/plugins/db-driven/tables/tables.ts +0 -53
- package/examples/tables/bar.js +0 -26
- package/examples/tables/comments.ts +0 -19
- package/examples/tables/foo.json +0 -3
- package/examples/tables/posts.ts +0 -28
- package/examples/tables/profiles.ts +0 -23
- package/examples/tables/tags.ts +0 -15
- package/examples/tables/users.ts +0 -34
- package/lib/database.d.ts.map +0 -1
- package/lib/fields/field-types.d.ts +0 -419
- package/lib/fields/field-types.d.ts.map +0 -1
- package/lib/fields/field-types.js +0 -1222
- package/lib/fields/field-types.js.map +0 -1
- package/lib/fields/index.d.ts.map +0 -1
- package/lib/fields/option-types.d.ts +0 -105
- package/lib/fields/option-types.d.ts.map +0 -1
- package/lib/fields/option-types.js +0 -18
- package/lib/fields/option-types.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/model.d.ts.map +0 -1
- package/lib/op.d.ts +0 -45
- package/lib/op.d.ts.map +0 -1
- package/lib/op.js +0 -225
- package/lib/op.js.map +0 -1
- package/lib/table.d.ts +0 -56
- package/lib/table.d.ts.map +0 -1
- package/lib/table.js +0 -456
- package/lib/table.js.map +0 -1
- package/lib/utils.d.ts +0 -26
- package/lib/utils.d.ts.map +0 -1
- package/lib/utils.js +0 -438
- package/lib/utils.js.map +0 -1
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Model } from './model';
|
|
11
|
+
import { UpdateGuard } from './update-guard';
|
|
12
|
+
function isUndefinedOrNull(value) {
|
|
13
|
+
return typeof value === 'undefined' || value === null;
|
|
14
|
+
}
|
|
15
|
+
function isStringOrNumber(value) {
|
|
16
|
+
return typeof value === 'string' || typeof value === 'number';
|
|
17
|
+
}
|
|
18
|
+
function getKeysByPrefix(keys, prefix) {
|
|
19
|
+
return keys.filter((key) => key.startsWith(`${prefix}.`)).map((key) => key.substring(prefix.length + 1));
|
|
20
|
+
}
|
|
21
|
+
export function modelAssociations(instance) {
|
|
22
|
+
return instance.constructor.associations;
|
|
23
|
+
}
|
|
24
|
+
export function belongsToManyAssociations(instance) {
|
|
25
|
+
const associations = modelAssociations(instance);
|
|
26
|
+
return Object.entries(associations)
|
|
27
|
+
.filter((entry) => {
|
|
28
|
+
const [key, association] = entry;
|
|
29
|
+
return association.associationType == 'BelongsToMany';
|
|
30
|
+
})
|
|
31
|
+
.map((association) => {
|
|
32
|
+
return association[1];
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function modelAssociationByKey(instance, key) {
|
|
36
|
+
return modelAssociations(instance)[key];
|
|
37
|
+
}
|
|
38
|
+
export function updateModelByValues(instance, values, options) {
|
|
39
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
if (!(options === null || options === void 0 ? void 0 : options.sanitized)) {
|
|
41
|
+
const guard = new UpdateGuard();
|
|
42
|
+
//@ts-ignore
|
|
43
|
+
guard.setModel(instance.constructor);
|
|
44
|
+
guard.setBlackList(options.blacklist);
|
|
45
|
+
guard.setWhiteList(options.whitelist);
|
|
46
|
+
guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);
|
|
47
|
+
values = guard.sanitize(values);
|
|
48
|
+
}
|
|
49
|
+
yield instance.update(values, options);
|
|
50
|
+
yield updateAssociations(instance, values, options);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export function updateThroughTableValue(instance, throughName, throughValues, source, transaction = null) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
// update through table values
|
|
56
|
+
for (const belongsToMany of belongsToManyAssociations(instance)) {
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
const throughModel = belongsToMany.through.model;
|
|
59
|
+
const throughModelName = throughModel.name;
|
|
60
|
+
if (throughModelName === throughModelName) {
|
|
61
|
+
const where = {
|
|
62
|
+
[belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),
|
|
63
|
+
[belongsToMany.otherKey]: source.get(belongsToMany.targetKey),
|
|
64
|
+
};
|
|
65
|
+
return yield throughModel.update(throughValues, {
|
|
66
|
+
where,
|
|
67
|
+
transaction,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* update association of instance by values
|
|
75
|
+
* @param instance
|
|
76
|
+
* @param values
|
|
77
|
+
* @param options
|
|
78
|
+
*/
|
|
79
|
+
export function updateAssociations(instance, values, options = {}) {
|
|
80
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
// if no values set, return
|
|
82
|
+
if (!values) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let newTransaction = false;
|
|
86
|
+
let transaction = options.transaction;
|
|
87
|
+
if (!transaction) {
|
|
88
|
+
newTransaction = true;
|
|
89
|
+
transaction = yield instance.sequelize.transaction();
|
|
90
|
+
}
|
|
91
|
+
const keys = Object.keys(values);
|
|
92
|
+
for (const key of Object.keys(modelAssociations(instance))) {
|
|
93
|
+
if (keys.includes(key)) {
|
|
94
|
+
yield updateAssociation(instance, key, values[key], Object.assign(Object.assign({}, options), { transaction }));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// update through table values
|
|
98
|
+
for (const belongsToMany of belongsToManyAssociations(instance)) {
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
const throughModel = belongsToMany.through.model;
|
|
101
|
+
const throughModelName = throughModel.name;
|
|
102
|
+
if (values[throughModelName] && options.sourceModel) {
|
|
103
|
+
const where = {
|
|
104
|
+
[belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),
|
|
105
|
+
[belongsToMany.otherKey]: options.sourceModel.get(belongsToMany.targetKey),
|
|
106
|
+
};
|
|
107
|
+
yield throughModel.update(values[throughModel.name], {
|
|
108
|
+
where,
|
|
109
|
+
context: options.context,
|
|
110
|
+
transaction,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (newTransaction) {
|
|
115
|
+
yield transaction.commit();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function isReverseAssociationPair(a, b) {
|
|
120
|
+
const typeSet = new Set();
|
|
121
|
+
typeSet.add(a.associationType);
|
|
122
|
+
typeSet.add(b.associationType);
|
|
123
|
+
if (typeSet.size == 1 && typeSet.has('BelongsToMany')) {
|
|
124
|
+
return (a.through.tableName === b.through.tableName &&
|
|
125
|
+
a.target.name === b.source.name &&
|
|
126
|
+
b.target.name === a.source.name &&
|
|
127
|
+
a.foreignKey === b.otherKey &&
|
|
128
|
+
a.sourceKey === b.targetKey &&
|
|
129
|
+
a.otherKey === b.foreignKey &&
|
|
130
|
+
a.targetKey === b.sourceKey);
|
|
131
|
+
}
|
|
132
|
+
if ((typeSet.has('HasOne') && typeSet.has('BelongsTo')) || (typeSet.has('HasMany') && typeSet.has('BelongsTo'))) {
|
|
133
|
+
const sourceAssoc = a.associationType == 'BelongsTo' ? b : a;
|
|
134
|
+
const targetAssoc = sourceAssoc == a ? b : a;
|
|
135
|
+
return (sourceAssoc.source.name === targetAssoc.target.name &&
|
|
136
|
+
sourceAssoc.foreignKey === targetAssoc.foreignKey &&
|
|
137
|
+
sourceAssoc.sourceKey === targetAssoc.targetKey);
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* update model association by key
|
|
143
|
+
* @param instance
|
|
144
|
+
* @param key
|
|
145
|
+
* @param value
|
|
146
|
+
* @param options
|
|
147
|
+
*/
|
|
148
|
+
export function updateAssociation(instance, key, value, options = {}) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
const association = modelAssociationByKey(instance, key);
|
|
151
|
+
if (!association) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
if (options.associationContext && isReverseAssociationPair(association, options.associationContext)) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
switch (association.associationType) {
|
|
158
|
+
case 'HasOne':
|
|
159
|
+
case 'BelongsTo':
|
|
160
|
+
return updateSingleAssociation(instance, key, value, options);
|
|
161
|
+
case 'HasMany':
|
|
162
|
+
case 'BelongsToMany':
|
|
163
|
+
return updateMultipleAssociation(instance, key, value, options);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* update belongsTo and HasOne
|
|
169
|
+
* @param model
|
|
170
|
+
* @param key
|
|
171
|
+
* @param value
|
|
172
|
+
* @param options
|
|
173
|
+
*/
|
|
174
|
+
export function updateSingleAssociation(model, key, value, options = {}) {
|
|
175
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
+
const association = modelAssociationByKey(model, key);
|
|
177
|
+
if (!association) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
if (!['undefined', 'string', 'number', 'object'].includes(typeof value)) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
const { context, updateAssociationValues = [], transaction = yield model.sequelize.transaction() } = options;
|
|
184
|
+
const keys = getKeysByPrefix(updateAssociationValues, key);
|
|
185
|
+
try {
|
|
186
|
+
// set method of association
|
|
187
|
+
const setAccessor = association.accessors.set;
|
|
188
|
+
const removeAssociation = () => __awaiter(this, void 0, void 0, function* () {
|
|
189
|
+
yield model[setAccessor](null, { transaction });
|
|
190
|
+
model.setDataValue(key, null);
|
|
191
|
+
if (!options.transaction) {
|
|
192
|
+
yield transaction.commit();
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
});
|
|
196
|
+
if (isUndefinedOrNull(value)) {
|
|
197
|
+
return yield removeAssociation();
|
|
198
|
+
}
|
|
199
|
+
if (isStringOrNumber(value)) {
|
|
200
|
+
yield model[setAccessor](value, { context, transaction });
|
|
201
|
+
if (!options.transaction) {
|
|
202
|
+
yield transaction.commit();
|
|
203
|
+
}
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
if (value instanceof Model) {
|
|
207
|
+
yield model[setAccessor](value, { context, transaction });
|
|
208
|
+
model.setDataValue(key, value);
|
|
209
|
+
if (!options.transaction) {
|
|
210
|
+
yield transaction.commit();
|
|
211
|
+
}
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
const createAccessor = association.accessors.create;
|
|
215
|
+
let dataKey;
|
|
216
|
+
let M;
|
|
217
|
+
if (association.associationType === 'BelongsTo') {
|
|
218
|
+
M = association.target;
|
|
219
|
+
// @ts-ignore
|
|
220
|
+
dataKey = association.targetKey;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
M = association.source;
|
|
224
|
+
dataKey = M.primaryKeyAttribute;
|
|
225
|
+
}
|
|
226
|
+
if (isStringOrNumber(value[dataKey])) {
|
|
227
|
+
let instance = yield M.findOne({
|
|
228
|
+
where: {
|
|
229
|
+
[dataKey]: value[dataKey],
|
|
230
|
+
},
|
|
231
|
+
transaction,
|
|
232
|
+
});
|
|
233
|
+
if (instance) {
|
|
234
|
+
yield model[setAccessor](instance, { context, transaction });
|
|
235
|
+
if (updateAssociationValues.includes(key)) {
|
|
236
|
+
yield instance.update(value, Object.assign(Object.assign({}, options), { transaction }));
|
|
237
|
+
}
|
|
238
|
+
yield updateAssociations(instance, value, Object.assign(Object.assign({}, options), { transaction, associationContext: association, updateAssociationValues: keys }));
|
|
239
|
+
model.setDataValue(key, instance);
|
|
240
|
+
if (!options.transaction) {
|
|
241
|
+
yield transaction.commit();
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const instance = yield model[createAccessor](value, { context, transaction });
|
|
247
|
+
yield updateAssociations(instance, value, Object.assign(Object.assign({}, options), { transaction, associationContext: association, updateAssociationValues: keys }));
|
|
248
|
+
model.setDataValue(key, instance);
|
|
249
|
+
// @ts-ignore
|
|
250
|
+
if (association.targetKey) {
|
|
251
|
+
model.setDataValue(association.foreignKey, instance[dataKey]);
|
|
252
|
+
}
|
|
253
|
+
if (!options.transaction) {
|
|
254
|
+
yield transaction.commit();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
if (!options.transaction) {
|
|
259
|
+
yield transaction.rollback();
|
|
260
|
+
}
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* update multiple association of model by value
|
|
267
|
+
* @param model
|
|
268
|
+
* @param key
|
|
269
|
+
* @param value
|
|
270
|
+
* @param options
|
|
271
|
+
*/
|
|
272
|
+
export function updateMultipleAssociation(model, key, value, options = {}) {
|
|
273
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
274
|
+
const association = modelAssociationByKey(model, key);
|
|
275
|
+
if (!association) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
if (!['undefined', 'string', 'number', 'object'].includes(typeof value)) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
const { context, updateAssociationValues = [], transaction = yield model.sequelize.transaction() } = options;
|
|
282
|
+
const keys = getKeysByPrefix(updateAssociationValues, key);
|
|
283
|
+
try {
|
|
284
|
+
const setAccessor = association.accessors.set;
|
|
285
|
+
const createAccessor = association.accessors.create;
|
|
286
|
+
if (isUndefinedOrNull(value)) {
|
|
287
|
+
yield model[setAccessor](null, { transaction, context });
|
|
288
|
+
model.setDataValue(key, null);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (isStringOrNumber(value)) {
|
|
292
|
+
yield model[setAccessor](value, { transaction, context });
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (!Array.isArray(value)) {
|
|
296
|
+
value = [value];
|
|
297
|
+
}
|
|
298
|
+
const list1 = []; // to be setted
|
|
299
|
+
const list2 = []; // to be added
|
|
300
|
+
for (const item of value) {
|
|
301
|
+
if (isUndefinedOrNull(item)) {
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (isStringOrNumber(item)) {
|
|
305
|
+
list1.push(item);
|
|
306
|
+
}
|
|
307
|
+
else if (item instanceof Model) {
|
|
308
|
+
list1.push(item);
|
|
309
|
+
}
|
|
310
|
+
else if (item.sequelize) {
|
|
311
|
+
list1.push(item);
|
|
312
|
+
}
|
|
313
|
+
else if (typeof item === 'object') {
|
|
314
|
+
list2.push(item);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// associate targets in lists1
|
|
318
|
+
yield model[setAccessor](list1, { transaction, context });
|
|
319
|
+
const list3 = [];
|
|
320
|
+
for (const item of list2) {
|
|
321
|
+
const pk = association.target.primaryKeyAttribute;
|
|
322
|
+
const through = association.through ? association.through.model.name : null;
|
|
323
|
+
const accessorOptions = {
|
|
324
|
+
context,
|
|
325
|
+
transaction,
|
|
326
|
+
};
|
|
327
|
+
const throughValue = item[through];
|
|
328
|
+
if (throughValue) {
|
|
329
|
+
accessorOptions['through'] = throughValue;
|
|
330
|
+
}
|
|
331
|
+
if (isUndefinedOrNull(item[pk])) {
|
|
332
|
+
// create new record
|
|
333
|
+
const instance = yield model[createAccessor](item, accessorOptions);
|
|
334
|
+
yield updateAssociations(instance, item, Object.assign(Object.assign({}, options), { transaction, associationContext: association, updateAssociationValues: keys }));
|
|
335
|
+
list3.push(instance);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
// set & update record
|
|
339
|
+
const instance = yield association.target.findByPk(item[pk], {
|
|
340
|
+
transaction,
|
|
341
|
+
});
|
|
342
|
+
const addAccessor = association.accessors.add;
|
|
343
|
+
yield model[addAccessor](item[pk], accessorOptions);
|
|
344
|
+
if (updateAssociationValues.includes(key)) {
|
|
345
|
+
yield instance.update(item, Object.assign(Object.assign({}, options), { transaction }));
|
|
346
|
+
}
|
|
347
|
+
yield updateAssociations(instance, item, Object.assign(Object.assign({}, options), { transaction, associationContext: association, updateAssociationValues: keys }));
|
|
348
|
+
list3.push(instance);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
model.setDataValue(key, list1.concat(list3));
|
|
352
|
+
if (!options.transaction) {
|
|
353
|
+
yield transaction.commit();
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
yield transaction.rollback();
|
|
358
|
+
throw error;
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=update-associations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-associations.js","sourceRoot":"","sources":["../src/update-associations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Association,\n BelongsTo,\n BelongsToMany,\n HasMany,\n HasOne,\n Hookable,\n ModelCtor,\n Transactionable,\n} from 'sequelize';\nimport { Model } from './model';\nimport { TransactionAble } from './repository';\nimport { UpdateGuard } from './update-guard';\n\nfunction isUndefinedOrNull(value: any) {\n return typeof value === 'undefined' || value === null;\n}\n\nfunction isStringOrNumber(value: any) {\n return typeof value === 'string' || typeof value === 'number';\n}\n\nfunction getKeysByPrefix(keys: string[], prefix: string) {\n return keys.filter((key) => key.startsWith(`${prefix}.`)).map((key) => key.substring(prefix.length + 1));\n}\n\nexport function modelAssociations(instance: Model) {\n return (<typeof Model>instance.constructor).associations;\n}\n\nexport function belongsToManyAssociations(instance: Model): Array<BelongsToMany> {\n const associations = modelAssociations(instance);\n return Object.entries(associations)\n .filter((entry) => {\n const [key, association] = entry;\n return association.associationType == 'BelongsToMany';\n })\n .map((association) => {\n return <BelongsToMany>association[1];\n });\n}\n\nexport function modelAssociationByKey(instance: Model, key: string): Association {\n return modelAssociations(instance)[key] as Association;\n}\n\ntype UpdateValue = { [key: string]: any };\n\ninterface UpdateOptions extends TransactionAble {\n filter?: any;\n filterByTk?: number | string;\n // 字段白名单\n whitelist?: string[];\n // 字段黑名单\n blacklist?: string[];\n // 关系数据默认会新建并建立关联处理,如果是已存在的数据只关联,但不更新关系数据\n // 如果需要更新关联数据,可以通过 updateAssociationValues 指定\n updateAssociationValues?: string[];\n sanitized?: boolean;\n sourceModel?: Model;\n}\n\ninterface UpdateAssociationOptions extends Transactionable, Hookable {\n updateAssociationValues?: string[];\n sourceModel?: Model;\n context?: any;\n associationContext?: any;\n}\n\nexport async function updateModelByValues(instance: Model, values: UpdateValue, options?: UpdateOptions) {\n if (!options?.sanitized) {\n const guard = new UpdateGuard();\n //@ts-ignore\n guard.setModel(instance.constructor);\n guard.setBlackList(options.blacklist);\n guard.setWhiteList(options.whitelist);\n guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);\n values = guard.sanitize(values);\n }\n\n await instance.update(values, options);\n await updateAssociations(instance, values, options);\n}\n\nexport async function updateThroughTableValue(\n instance: Model,\n throughName: string,\n throughValues: any,\n source: Model,\n transaction = null,\n) {\n // update through table values\n for (const belongsToMany of belongsToManyAssociations(instance)) {\n // @ts-ignore\n const throughModel = belongsToMany.through.model;\n const throughModelName = throughModel.name;\n\n if (throughModelName === throughModelName) {\n const where = {\n [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),\n [belongsToMany.otherKey]: source.get(belongsToMany.targetKey),\n };\n\n return await throughModel.update(throughValues, {\n where,\n transaction,\n });\n }\n }\n}\n\n/**\n * update association of instance by values\n * @param instance\n * @param values\n * @param options\n */\nexport async function updateAssociations(instance: Model, values: any, options: UpdateAssociationOptions = {}) {\n // if no values set, return\n if (!values) {\n return;\n }\n\n let newTransaction = false;\n let transaction = options.transaction;\n\n if (!transaction) {\n newTransaction = true;\n transaction = await instance.sequelize.transaction();\n }\n\n const keys = Object.keys(values);\n\n for (const key of Object.keys(modelAssociations(instance))) {\n if (keys.includes(key)) {\n await updateAssociation(instance, key, values[key], {\n ...options,\n transaction,\n });\n }\n }\n\n // update through table values\n for (const belongsToMany of belongsToManyAssociations(instance)) {\n // @ts-ignore\n const throughModel = belongsToMany.through.model;\n const throughModelName = throughModel.name;\n\n if (values[throughModelName] && options.sourceModel) {\n const where = {\n [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),\n [belongsToMany.otherKey]: options.sourceModel.get(belongsToMany.targetKey),\n };\n\n await throughModel.update(values[throughModel.name], {\n where,\n context: options.context,\n transaction,\n });\n }\n }\n\n if (newTransaction) {\n await transaction.commit();\n }\n}\n\nfunction isReverseAssociationPair(a: any, b: any) {\n const typeSet = new Set();\n typeSet.add(a.associationType);\n typeSet.add(b.associationType);\n\n if (typeSet.size == 1 && typeSet.has('BelongsToMany')) {\n return (\n a.through.tableName === b.through.tableName &&\n a.target.name === b.source.name &&\n b.target.name === a.source.name &&\n a.foreignKey === b.otherKey &&\n a.sourceKey === b.targetKey &&\n a.otherKey === b.foreignKey &&\n a.targetKey === b.sourceKey\n );\n }\n\n if ((typeSet.has('HasOne') && typeSet.has('BelongsTo')) || (typeSet.has('HasMany') && typeSet.has('BelongsTo'))) {\n const sourceAssoc = a.associationType == 'BelongsTo' ? b : a;\n const targetAssoc = sourceAssoc == a ? b : a;\n\n return (\n sourceAssoc.source.name === targetAssoc.target.name &&\n sourceAssoc.foreignKey === targetAssoc.foreignKey &&\n sourceAssoc.sourceKey === targetAssoc.targetKey\n );\n }\n\n return false;\n}\n\n/**\n * update model association by key\n * @param instance\n * @param key\n * @param value\n * @param options\n */\nexport async function updateAssociation(\n instance: Model,\n key: string,\n value: any,\n options: UpdateAssociationOptions = {},\n) {\n const association = modelAssociationByKey(instance, key);\n\n if (!association) {\n return false;\n }\n\n if (options.associationContext && isReverseAssociationPair(association, options.associationContext)) {\n return false;\n }\n\n switch (association.associationType) {\n case 'HasOne':\n case 'BelongsTo':\n return updateSingleAssociation(instance, key, value, options);\n case 'HasMany':\n case 'BelongsToMany':\n return updateMultipleAssociation(instance, key, value, options);\n }\n}\n\n/**\n * update belongsTo and HasOne\n * @param model\n * @param key\n * @param value\n * @param options\n */\nexport async function updateSingleAssociation(\n model: Model,\n key: string,\n value: any,\n options: UpdateAssociationOptions = {},\n) {\n const association = <HasOne | BelongsTo>modelAssociationByKey(model, key);\n\n if (!association) {\n return false;\n }\n\n if (!['undefined', 'string', 'number', 'object'].includes(typeof value)) {\n return false;\n }\n\n const { context, updateAssociationValues = [], transaction = await model.sequelize.transaction() } = options;\n const keys = getKeysByPrefix(updateAssociationValues, key);\n\n try {\n // set method of association\n const setAccessor = association.accessors.set;\n\n const removeAssociation = async () => {\n await model[setAccessor](null, { transaction });\n model.setDataValue(key, null);\n if (!options.transaction) {\n await transaction.commit();\n }\n return true;\n };\n\n if (isUndefinedOrNull(value)) {\n return await removeAssociation();\n }\n\n if (isStringOrNumber(value)) {\n await model[setAccessor](value, { context, transaction });\n if (!options.transaction) {\n await transaction.commit();\n }\n return true;\n }\n\n if (value instanceof Model) {\n await model[setAccessor](value, { context, transaction });\n model.setDataValue(key, value);\n\n if (!options.transaction) {\n await transaction.commit();\n }\n return true;\n }\n\n const createAccessor = association.accessors.create;\n let dataKey: string;\n let M: ModelCtor<Model>;\n if (association.associationType === 'BelongsTo') {\n M = association.target as ModelCtor<Model>;\n // @ts-ignore\n dataKey = association.targetKey;\n } else {\n M = association.source as ModelCtor<Model>;\n dataKey = M.primaryKeyAttribute;\n }\n\n if (isStringOrNumber(value[dataKey])) {\n let instance: any = await M.findOne({\n where: {\n [dataKey]: value[dataKey],\n },\n transaction,\n });\n\n if (instance) {\n await model[setAccessor](instance, { context, transaction });\n\n if (updateAssociationValues.includes(key)) {\n await instance.update(value, { ...options, transaction });\n }\n\n await updateAssociations(instance, value, {\n ...options,\n transaction,\n associationContext: association,\n updateAssociationValues: keys,\n });\n model.setDataValue(key, instance);\n if (!options.transaction) {\n await transaction.commit();\n }\n return true;\n }\n }\n\n const instance = await model[createAccessor](value, { context, transaction });\n await updateAssociations(instance, value, {\n ...options,\n transaction,\n associationContext: association,\n updateAssociationValues: keys,\n });\n model.setDataValue(key, instance);\n // @ts-ignore\n if (association.targetKey) {\n model.setDataValue(association.foreignKey, instance[dataKey]);\n }\n if (!options.transaction) {\n await transaction.commit();\n }\n } catch (error) {\n if (!options.transaction) {\n await transaction.rollback();\n }\n throw error;\n }\n}\n\n/**\n * update multiple association of model by value\n * @param model\n * @param key\n * @param value\n * @param options\n */\nexport async function updateMultipleAssociation(\n model: Model,\n key: string,\n value: any,\n options: UpdateAssociationOptions = {},\n) {\n const association = <BelongsToMany | HasMany>modelAssociationByKey(model, key);\n\n if (!association) {\n return false;\n }\n\n if (!['undefined', 'string', 'number', 'object'].includes(typeof value)) {\n return false;\n }\n\n const { context, updateAssociationValues = [], transaction = await model.sequelize.transaction() } = options;\n const keys = getKeysByPrefix(updateAssociationValues, key);\n\n try {\n const setAccessor = association.accessors.set;\n\n const createAccessor = association.accessors.create;\n if (isUndefinedOrNull(value)) {\n await model[setAccessor](null, { transaction, context });\n model.setDataValue(key, null);\n return;\n }\n\n if (isStringOrNumber(value)) {\n await model[setAccessor](value, { transaction, context });\n return;\n }\n\n if (!Array.isArray(value)) {\n value = [value];\n }\n\n const list1 = []; // to be setted\n const list2 = []; // to be added\n for (const item of value) {\n if (isUndefinedOrNull(item)) {\n continue;\n }\n if (isStringOrNumber(item)) {\n list1.push(item);\n } else if (item instanceof Model) {\n list1.push(item);\n } else if (item.sequelize) {\n list1.push(item);\n } else if (typeof item === 'object') {\n list2.push(item);\n }\n }\n\n // associate targets in lists1\n await model[setAccessor](list1, { transaction, context });\n\n const list3 = [];\n for (const item of list2) {\n const pk = association.target.primaryKeyAttribute;\n\n const through = (<any>association).through ? (<any>association).through.model.name : null;\n\n const accessorOptions = {\n context,\n transaction,\n };\n\n const throughValue = item[through];\n\n if (throughValue) {\n accessorOptions['through'] = throughValue;\n }\n\n if (isUndefinedOrNull(item[pk])) {\n // create new record\n const instance = await model[createAccessor](item, accessorOptions);\n await updateAssociations(instance, item, {\n ...options,\n transaction,\n associationContext: association,\n updateAssociationValues: keys,\n });\n list3.push(instance);\n } else {\n // set & update record\n const instance = await association.target.findByPk<any>(item[pk], {\n transaction,\n });\n const addAccessor = association.accessors.add;\n\n await model[addAccessor](item[pk], accessorOptions);\n if (updateAssociationValues.includes(key)) {\n await instance.update(item, { ...options, transaction });\n }\n await updateAssociations(instance, item, {\n ...options,\n transaction,\n associationContext: association,\n updateAssociationValues: keys,\n });\n list3.push(instance);\n }\n }\n\n model.setDataValue(key, list1.concat(list3));\n if (!options.transaction) {\n await transaction.commit();\n }\n } catch (error) {\n await transaction.rollback();\n throw error;\n }\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ModelCtor } from 'sequelize';
|
|
2
|
+
import { AssociationKeysToBeUpdate, BlackList, WhiteList } from './repository';
|
|
3
|
+
declare type UpdateValueItem = string | number | UpdateValues;
|
|
4
|
+
declare type UpdateValues = {
|
|
5
|
+
[key: string]: UpdateValueItem | Array<UpdateValueItem>;
|
|
6
|
+
};
|
|
7
|
+
declare type UpdateAction = 'create' | 'update';
|
|
8
|
+
export declare class UpdateGuard {
|
|
9
|
+
model: ModelCtor<any>;
|
|
10
|
+
action: UpdateAction;
|
|
11
|
+
private associationKeysToBeUpdate;
|
|
12
|
+
private blackList;
|
|
13
|
+
private whiteList;
|
|
14
|
+
setAction(action: UpdateAction): void;
|
|
15
|
+
setModel(model: ModelCtor<any>): void;
|
|
16
|
+
setAssociationKeysToBeUpdate(associationKeysToBeUpdate: AssociationKeysToBeUpdate): void;
|
|
17
|
+
setWhiteList(whiteList: WhiteList): void;
|
|
18
|
+
setBlackList(blackList: BlackList): void;
|
|
19
|
+
/**
|
|
20
|
+
* Sanitize values by whitelist blacklist
|
|
21
|
+
* @param values
|
|
22
|
+
*/
|
|
23
|
+
sanitize(values: UpdateValues): {};
|
|
24
|
+
static fromOptions(model: any, options: any): UpdateGuard;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import lodash from 'lodash';
|
|
2
|
+
import { Model } from './model';
|
|
3
|
+
export class UpdateGuard {
|
|
4
|
+
setAction(action) {
|
|
5
|
+
this.action = action;
|
|
6
|
+
}
|
|
7
|
+
setModel(model) {
|
|
8
|
+
this.model = model;
|
|
9
|
+
}
|
|
10
|
+
setAssociationKeysToBeUpdate(associationKeysToBeUpdate) {
|
|
11
|
+
if (this.action == 'create') {
|
|
12
|
+
this.associationKeysToBeUpdate = Object.keys(this.model.associations);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.associationKeysToBeUpdate = associationKeysToBeUpdate;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
setWhiteList(whiteList) {
|
|
19
|
+
this.whiteList = whiteList;
|
|
20
|
+
}
|
|
21
|
+
setBlackList(blackList) {
|
|
22
|
+
this.blackList = blackList;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Sanitize values by whitelist blacklist
|
|
26
|
+
* @param values
|
|
27
|
+
*/
|
|
28
|
+
sanitize(values) {
|
|
29
|
+
values = lodash.clone(values);
|
|
30
|
+
if (!this.model) {
|
|
31
|
+
throw new Error('please set model first');
|
|
32
|
+
}
|
|
33
|
+
const associations = this.model.associations;
|
|
34
|
+
const associationsValues = lodash.pick(values, Object.keys(associations));
|
|
35
|
+
// build params of association update guard
|
|
36
|
+
const listOfAssociation = (list, association) => {
|
|
37
|
+
if (list) {
|
|
38
|
+
list = list
|
|
39
|
+
.filter((whiteListKey) => whiteListKey.startsWith(`${association}.`))
|
|
40
|
+
.map((whiteListKey) => whiteListKey.replace(`${association}.`, ''));
|
|
41
|
+
if (list.length == 0) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return list;
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
};
|
|
48
|
+
// sanitize association values
|
|
49
|
+
Object.keys(associationsValues).forEach((association) => {
|
|
50
|
+
let associationValues = associationsValues[association];
|
|
51
|
+
const filterAssociationToBeUpdate = (value) => {
|
|
52
|
+
const associationKeysToBeUpdate = this.associationKeysToBeUpdate || [];
|
|
53
|
+
if (associationKeysToBeUpdate.includes(association)) {
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
const associationObj = associations[association];
|
|
57
|
+
const associationKeyName = associationObj.associationType == 'BelongsTo' || associationObj.associationType == 'HasOne'
|
|
58
|
+
? associationObj.targetKey
|
|
59
|
+
: associationObj.target.primaryKeyAttribute;
|
|
60
|
+
if (value[associationKeyName]) {
|
|
61
|
+
return lodash.pick(value, [associationKeyName, ...Object.keys(associationObj.target.associations)]);
|
|
62
|
+
}
|
|
63
|
+
return value;
|
|
64
|
+
};
|
|
65
|
+
const sanitizeValue = (value) => {
|
|
66
|
+
const associationUpdateGuard = new UpdateGuard();
|
|
67
|
+
associationUpdateGuard.setModel(associations[association].target);
|
|
68
|
+
['whiteList', 'blackList', 'associationKeysToBeUpdate'].forEach((optionKey) => {
|
|
69
|
+
associationUpdateGuard[`set${lodash.upperFirst(optionKey)}`](listOfAssociation(this[optionKey], association));
|
|
70
|
+
});
|
|
71
|
+
return associationUpdateGuard.sanitize(filterAssociationToBeUpdate(value));
|
|
72
|
+
};
|
|
73
|
+
if (Array.isArray(associationValues)) {
|
|
74
|
+
associationValues = associationValues.map((value) => {
|
|
75
|
+
if (typeof value == 'string' || typeof value == 'number') {
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return sanitizeValue(value);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else if (typeof associationValues === 'object' && associationValues !== null) {
|
|
84
|
+
associationValues = sanitizeValue(associationValues);
|
|
85
|
+
}
|
|
86
|
+
// set association values to sanitized value
|
|
87
|
+
values[association] = associationValues;
|
|
88
|
+
});
|
|
89
|
+
if (values instanceof Model) {
|
|
90
|
+
return values;
|
|
91
|
+
}
|
|
92
|
+
let valuesKeys = Object.keys(values || {});
|
|
93
|
+
// handle whitelist
|
|
94
|
+
if (this.whiteList) {
|
|
95
|
+
valuesKeys = valuesKeys.filter((valueKey) => {
|
|
96
|
+
return (this.whiteList.findIndex((whiteKey) => {
|
|
97
|
+
const keyPaths = whiteKey.split('.');
|
|
98
|
+
return keyPaths[0] === valueKey;
|
|
99
|
+
}) !== -1);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// handle blacklist
|
|
103
|
+
if (this.blackList) {
|
|
104
|
+
valuesKeys = valuesKeys.filter((valueKey) => !this.blackList.includes(valueKey));
|
|
105
|
+
}
|
|
106
|
+
const result = valuesKeys.reduce((obj, key) => {
|
|
107
|
+
lodash.set(obj, key, values[key]);
|
|
108
|
+
return obj;
|
|
109
|
+
}, {});
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
static fromOptions(model, options) {
|
|
113
|
+
const guard = new UpdateGuard();
|
|
114
|
+
guard.setModel(model);
|
|
115
|
+
guard.setWhiteList(options.whitelist);
|
|
116
|
+
guard.setBlackList(options.blacklist);
|
|
117
|
+
guard.setAction(lodash.get(options, 'action', 'update'));
|
|
118
|
+
guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);
|
|
119
|
+
return guard;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=update-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-guard.js","sourceRoot":"","sources":["../src/update-guard.ts"],"names":[],"mappings":"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","sourcesContent":["import lodash from 'lodash';\nimport { ModelCtor } from 'sequelize';\nimport { Model } from './model';\nimport { AssociationKeysToBeUpdate, BlackList, WhiteList } from './repository';\n\ntype UpdateValueItem = string | number | UpdateValues;\n\ntype UpdateValues = {\n [key: string]: UpdateValueItem | Array<UpdateValueItem>;\n};\n\ntype UpdateAction = 'create' | 'update';\nexport class UpdateGuard {\n model: ModelCtor<any>;\n action: UpdateAction;\n private associationKeysToBeUpdate: AssociationKeysToBeUpdate;\n private blackList: BlackList;\n private whiteList: WhiteList;\n\n setAction(action: UpdateAction) {\n this.action = action;\n }\n\n setModel(model: ModelCtor<any>) {\n this.model = model;\n }\n\n setAssociationKeysToBeUpdate(associationKeysToBeUpdate: AssociationKeysToBeUpdate) {\n if (this.action == 'create') {\n this.associationKeysToBeUpdate = Object.keys(this.model.associations);\n } else {\n this.associationKeysToBeUpdate = associationKeysToBeUpdate;\n }\n }\n\n setWhiteList(whiteList: WhiteList) {\n this.whiteList = whiteList;\n }\n\n setBlackList(blackList: BlackList) {\n this.blackList = blackList;\n }\n\n /**\n * Sanitize values by whitelist blacklist\n * @param values\n */\n sanitize(values: UpdateValues) {\n values = lodash.clone(values);\n\n if (!this.model) {\n throw new Error('please set model first');\n }\n\n const associations = this.model.associations;\n const associationsValues = lodash.pick(values, Object.keys(associations));\n\n // build params of association update guard\n const listOfAssociation = (list, association) => {\n if (list) {\n list = list\n .filter((whiteListKey) => whiteListKey.startsWith(`${association}.`))\n .map((whiteListKey) => whiteListKey.replace(`${association}.`, ''));\n\n if (list.length == 0) {\n return undefined;\n }\n\n return list;\n }\n\n return undefined;\n };\n\n // sanitize association values\n Object.keys(associationsValues).forEach((association) => {\n let associationValues = associationsValues[association];\n\n const filterAssociationToBeUpdate = (value) => {\n const associationKeysToBeUpdate = this.associationKeysToBeUpdate || [];\n\n if (associationKeysToBeUpdate.includes(association)) {\n return value;\n }\n\n const associationObj = associations[association];\n\n const associationKeyName =\n associationObj.associationType == 'BelongsTo' || associationObj.associationType == 'HasOne'\n ? (<any>associationObj).targetKey\n : associationObj.target.primaryKeyAttribute;\n\n if (value[associationKeyName]) {\n return lodash.pick(value, [associationKeyName, ...Object.keys(associationObj.target.associations)]);\n }\n\n return value;\n };\n\n const sanitizeValue = (value) => {\n const associationUpdateGuard = new UpdateGuard();\n associationUpdateGuard.setModel(associations[association].target);\n\n ['whiteList', 'blackList', 'associationKeysToBeUpdate'].forEach((optionKey) => {\n associationUpdateGuard[`set${lodash.upperFirst(optionKey)}`](listOfAssociation(this[optionKey], association));\n });\n\n return associationUpdateGuard.sanitize(filterAssociationToBeUpdate(value));\n };\n\n if (Array.isArray(associationValues)) {\n associationValues = associationValues.map((value) => {\n if (typeof value == 'string' || typeof value == 'number') {\n return value;\n } else {\n return sanitizeValue(value);\n }\n });\n } else if (typeof associationValues === 'object' && associationValues !== null) {\n associationValues = sanitizeValue(associationValues);\n }\n\n // set association values to sanitized value\n values[association] = associationValues;\n });\n\n if (values instanceof Model) {\n return values;\n }\n\n let valuesKeys = Object.keys(values || {});\n\n // handle whitelist\n if (this.whiteList) {\n valuesKeys = valuesKeys.filter((valueKey) => {\n return (\n this.whiteList.findIndex((whiteKey) => {\n const keyPaths = whiteKey.split('.');\n return keyPaths[0] === valueKey;\n }) !== -1\n );\n });\n }\n\n // handle blacklist\n if (this.blackList) {\n valuesKeys = valuesKeys.filter((valueKey) => !this.blackList.includes(valueKey));\n }\n\n const result = valuesKeys.reduce((obj, key) => {\n lodash.set(obj, key, values[key]);\n return obj;\n }, {});\n\n return result;\n }\n\n static fromOptions(model, options) {\n const guard = new UpdateGuard();\n guard.setModel(model);\n guard.setWhiteList(options.whitelist);\n guard.setBlackList(options.blacklist);\n guard.setAction(lodash.get(options, 'action', 'update'));\n guard.setAssociationKeysToBeUpdate(options.updateAssociationValues);\n return guard;\n }\n}\n"]}
|