From ac14e8786d63a4a29aa51a481ff0ef9f09f82520 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Tue, 18 Jan 2022 13:44:27 -0500 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20support=20isNestedAt?= =?UTF-8?q?tribute=20in=20models?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/fragment-target-attributes.js | 9 ----- addons/api/addon/models/target.js | 13 ++++--- addons/api/addon/serializers/application.js | 36 +++++++++++++++++- .../app/models/fragment-target-attributes.js | 1 - .../api/tests/unit/serializers/target-test.js | 37 ++++++++++++++++++- ui/admin/app/components/form/target/index.hbs | 2 +- 6 files changed, 79 insertions(+), 19 deletions(-) delete mode 100644 addons/api/addon/models/fragment-target-attributes.js delete mode 100644 addons/api/app/models/fragment-target-attributes.js diff --git a/addons/api/addon/models/fragment-target-attributes.js b/addons/api/addon/models/fragment-target-attributes.js deleted file mode 100644 index 44f1a94aa..000000000 --- a/addons/api/addon/models/fragment-target-attributes.js +++ /dev/null @@ -1,9 +0,0 @@ -import Fragment from 'ember-data-model-fragments/fragment'; -import { attr } from '@ember-data/model'; - -export default class FragmentTargetAttributesModel extends Fragment { - @attr('number', { - description: 'The default port a target should use if present.', - }) - default_port; -} diff --git a/addons/api/addon/models/target.js b/addons/api/addon/models/target.js index 9b36a5749..65baaffea 100644 --- a/addons/api/addon/models/target.js +++ b/addons/api/addon/models/target.js @@ -1,15 +1,16 @@ import GeneratedTargetModel from '../generated/models/target'; -import { fragment, fragmentArray } from 'ember-data-model-fragments/attributes'; +import { attr } from '@ember-data/model'; +import { fragmentArray } from 'ember-data-model-fragments/attributes'; import { computed } from '@ember/object'; export default class TargetModel extends GeneratedTargetModel { // =attributes - /** - * Attributes of this resource, if any, represented as a JSON fragment. - * @type {FragmentTargetAttributesModel} - */ - @fragment('fragment-target-attributes', { defaultValue: {} }) attributes; + @attr('number', { + isNestedAttribute: true, + description: 'The default port a target should use if present.', + }) + default_port; /** * @type {[FragmentHostSourceModel]} diff --git a/addons/api/addon/serializers/application.js b/addons/api/addon/serializers/application.js index 08b59eebc..6223f5df8 100644 --- a/addons/api/addon/serializers/application.js +++ b/addons/api/addon/serializers/application.js @@ -50,6 +50,12 @@ export default class ApplicationSerializer extends RESTSerializer { // Do not serialize `disabled` fields. // TODO: disabled is temporarily disabled if (key === 'disabled') delete json[key]; + // Push nested attributes down into the attributes key + if (options.isNestedAttribute && json[key]) { + if (!json.attributes) json.attributes = {}; + json.attributes[key] = json[key]; + delete json[key]; + } return value; } @@ -195,9 +201,37 @@ export default class ApplicationSerializer extends RESTSerializer { * @return {Object} */ normalize(typeClass, hash) { - const normalizedHash = copy(hash, true); + let normalizedHash = copy(hash, true); const scopeID = get(normalizedHash, 'scope.id'); if (scopeID) normalizedHash.scope.scope_id = scopeID; + normalizedHash = this.normalizeNestedAttributes(typeClass, normalizedHash); return super.normalize(typeClass, normalizedHash); } + + /** + * Certain typed resources in the API have type-specific fields nested under + * an `attributes` key in the payload + * (e.g. `attributes: { fieldName: '123' }`). Since Ember Data lacks + * first-class support for nested attributes, these fields must be hoisted up + * into the main body of the payload. + * + * In order to annotate a field as being a nested attribute, add the key name + * to the `nestedAttributes` field on the serializer: + * `@attr('string', { isNestedAttribute: true }) fieldName;` + * + * @param {Model} typeClass + * @param {Object} hash + * @return {Object} + */ + normalizeNestedAttributes(typeClass, hash) { + const normalizedHash = copy(hash, true); + typeClass.attributes.forEach((attribute) => { + const { isNestedAttribute } = attribute.options; + const attributeValue = normalizedHash.attributes?.[attribute.name]; + if (isNestedAttribute && attributeValue) { + normalizedHash[attribute.name] = attributeValue; + } + }); + return normalizedHash; + } } diff --git a/addons/api/app/models/fragment-target-attributes.js b/addons/api/app/models/fragment-target-attributes.js deleted file mode 100644 index 41eb7d88f..000000000 --- a/addons/api/app/models/fragment-target-attributes.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'api/models/fragment-target-attributes'; diff --git a/addons/api/tests/unit/serializers/target-test.js b/addons/api/tests/unit/serializers/target-test.js index 0c1bd089c..d384e2cee 100644 --- a/addons/api/tests/unit/serializers/target-test.js +++ b/addons/api/tests/unit/serializers/target-test.js @@ -20,6 +20,7 @@ module('Unit | Serializer | target', function (hooks) { scope_id: 'org_1', type: 'org', }, + default_port: 1234, version: 1, type: 'tcp', }); @@ -35,7 +36,7 @@ module('Unit | Serializer | target', function (hooks) { session_max_seconds: 28800, session_connection_limit: 1, attributes: { - default_port: null, + default_port: 1234, }, }); }); @@ -123,6 +124,40 @@ module('Unit | Serializer | target', function (hooks) { }); }); + test('it normalizes records with nested attributes', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('target'); + const targetModelClass = store.createRecord('target').constructor; + const payload = { + id: '1', + name: 'Target 1', + attributes: { + default_port: 1234, + }, + }; + const normalized = serializer.normalizeSingleResponse( + store, + targetModelClass, + payload + ); + assert.deepEqual(normalized, { + included: [], + data: { + id: '1', + type: 'target', + attributes: { + application_credential_source_ids: [], + authorized_actions: [], + host_sources: [], + name: 'Target 1', + default_port: 1234, + }, + relationships: {}, + }, + }); + }); + test('it normalizes missing host_sources and application_credential_source_ids to empty array', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); diff --git a/ui/admin/app/components/form/target/index.hbs b/ui/admin/app/components/form/target/index.hbs index efdda831f..fc8757041 100644 --- a/ui/admin/app/components/form/target/index.hbs +++ b/ui/admin/app/components/form/target/index.hbs @@ -94,7 +94,7 @@ Date: Tue, 18 Jan 2022 10:48:54 -0800 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20unmet=20peer=20?= =?UTF-8?q?dependency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix unmeet peer dependency for @storybook/core-events --- addons/rose/package.json | 5 ++-- yarn.lock | 59 ++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/addons/rose/package.json b/addons/rose/package.json index 18a3d9829..5530ca39e 100644 --- a/addons/rose/package.json +++ b/addons/rose/package.json @@ -31,12 +31,12 @@ "dependencies": { "ember-cli-babel": "^7.26.8", "ember-cli-htmlbars": "^5.7.1", + "ember-composable-helpers": "^4.5.0", "ember-focus-trap": "^0.7.0", "ember-named-blocks-polyfill": "^0.2.4", "ember-radio-button": "^2.0.1", "ember-uuid": "^2.1.0", - "emberx-select": "github:adopted-ember-addons/emberx-select#bc5f774", - "ember-composable-helpers": "^4.5.0" + "emberx-select": "github:adopted-ember-addons/emberx-select#bc5f774" }, "devDependencies": { "@babel/core": "^7.16.5", @@ -53,6 +53,7 @@ "@storybook/api": "^6.3.12", "@storybook/cli": "^6.3.10", "@storybook/components": "^6.3.12", + "@storybook/core-events": "^6.3.0", "@storybook/ember": "^6.3.8", "@storybook/ember-cli-storybook": "^0.4.0", "babel-eslint": "^10.1.0", diff --git a/yarn.lock b/yarn.lock index 52a46ca22..4fe8b3dbe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4538,6 +4538,13 @@ dependencies: core-js "^3.8.2" +"@storybook/core-events@^6.3.0": + version "6.4.13" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.4.13.tgz#caf1adafd743f8d53a151bc402449f841896cb9c" + integrity sha512-zNlzNv7qVXjLf7yfvY9KfLvDY8nVskxrjmz0+21rIqUefS9+7SWBrtJJURpCaoPf/BmACqh/6c1RnuOY7TESnw== + dependencies: + core-js "^3.8.2" + "@storybook/core-server@6.3.8": version "6.3.8" resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.3.8.tgz#0d141e6f315b735a442aebc0f424f911456c769c" @@ -8141,9 +8148,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001286: - version "1.0.30001295" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001295.tgz#68a60f8f0664f342b2835c5d8898b4faea7b3d51" - integrity sha512-lSP16vcyC0FEy0R4ECc9duSPoKoZy+YkpGkue9G4D81OfPnliopaZrU10+qtPdT8PbGXad/PNx43TIQrOmJZSQ== + version "1.0.30001300" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001300.tgz#11ab6c57d3eb6f964cba950401fd00a146786468" + integrity sha512-cVjiJHWGcNlJi8TZVKNMnvMid3Z3TTdDHmLDzlOdIiZq138Exvo0G+G0wTdVYolxKb4AYwC+38pxodiInVtJSA== capture-exit@^2.0.0: version "2.0.0" @@ -9407,7 +9414,7 @@ debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: dependencies: ms "^2.1.1" -debuglog@^1.0.1: +debuglog@*, debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -13628,11 +13635,16 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.3, graceful-fs@^4.2.4: version "4.2.8" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graceful-fs@^4.2.2: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -14276,9 +14288,9 @@ ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8: integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== immer@8.0.1, immer@^9.0.6: - version "9.0.7" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.7.tgz#b6156bd7db55db7abc73fd2fdadf4e579a701075" - integrity sha512-KGllzpbamZDvOIxnmJ0jI840g7Oikx58lBPWV0hUh7dtAyZpFqqrBZdKka5GlTwMTZ1Tjc/bKKW4VSFAt6BqMA== + version "9.0.12" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.12.tgz#2d33ddf3ee1d247deab9d707ca472c8c942a0f20" + integrity sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA== import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" @@ -14298,7 +14310,7 @@ import-lazy@^4.0.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== -imurmurhash@^0.1.4: +imurmurhash@*, imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -16112,6 +16124,11 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" +lodash._baseindexof@*: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" + integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw= + lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -16120,11 +16137,16 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@^3.0.0: +lodash._bindcallback@*, lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= +lodash._cacheindexof@*: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" + integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI= + lodash._createassigner@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" @@ -16134,12 +16156,19 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" +lodash._createcache@*: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" + integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM= + dependencies: + lodash._getnative "^3.0.0" + lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= -lodash._getnative@^3.0.0: +lodash._getnative@*, lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= @@ -16357,7 +16386,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= -lodash.restparam@^3.0.0: +lodash.restparam@*, lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= @@ -19133,9 +19162,9 @@ printf@^0.6.1: integrity sha512-is0ctgGdPJ5951KulgfzvHGwJtZ5ck8l042vRkV6jrkpBzTmb/lueTqguWHy2JfVA+RY6gFVlaZgUS0j7S/dsw== prismjs@^1.21.0, prismjs@^1.25.0, prismjs@~1.24.0: - version "1.25.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756" - integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg== + version "1.26.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.26.0.tgz#16881b594828bb6b45296083a8cbab46b0accd47" + integrity sha512-HUoH9C5Z3jKkl3UunCyiD5jwk0+Hz0fIgQ2nbwU2Oo/ceuTAQAg+pPVnfdt2TJWRVLcxKh9iuoYDUSc8clb5UQ== private@^0.1.8: version "0.1.8" From d332a2126610990f8684778138659c81a30d5ac3 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Tue, 18 Jan 2022 11:30:22 -0800 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20storybook=20the?= =?UTF-8?q?ming=20unmet=20peer=20dependency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix storybook theming unmet peer dependency --- addons/rose/package.json | 1 + yarn.lock | 53 +++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/addons/rose/package.json b/addons/rose/package.json index 5530ca39e..f6ce53dfa 100644 --- a/addons/rose/package.json +++ b/addons/rose/package.json @@ -56,6 +56,7 @@ "@storybook/core-events": "^6.3.0", "@storybook/ember": "^6.3.8", "@storybook/ember-cli-storybook": "^0.4.0", + "@storybook/theming": "^6.3.0", "babel-eslint": "^10.1.0", "babel-loader": "^8.2.2", "broccoli-asset-rev": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 4fe8b3dbe..6618670af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4324,6 +4324,14 @@ core-js "^3.8.2" global "^4.4.0" +"@storybook/client-logger@6.4.13": + version "6.4.13" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.4.13.tgz#2467ee13c7f85e9f6c0d9cd64c11ee7a109b060a" + integrity sha512-VPrrgJRURztXAKTeHOpzKMAHnNupkGApUDNlPIs0Qxyn5gaSiy806q4XPoROno3mVgEe+7Chf86hRiL8pJnlCA== + dependencies: + core-js "^3.8.2" + global "^4.4.0" + "@storybook/codemod@6.3.10": version "6.3.10" resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-6.3.10.tgz#aad0ee5ca8ef59b4d134ff45e213e198d64c9974" @@ -4900,6 +4908,24 @@ resolve-from "^5.0.0" ts-dedent "^2.0.0" +"@storybook/theming@^6.3.0": + version "6.4.13" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.4.13.tgz#1a8aadeddb6c3a115f739aa1a4bbd7e65d4a3830" + integrity sha512-oWRoNnvO4QnRnplZ74DVdU4k91eqw8y0Xqn6lzZBeC8hq6mYWldgfj1LZ24gJhVtEIa7ZKoyujGUygHaH8WXHw== + dependencies: + "@emotion/core" "^10.1.1" + "@emotion/is-prop-valid" "^0.8.6" + "@emotion/styled" "^10.0.27" + "@storybook/client-logger" "6.4.13" + core-js "^3.8.2" + deep-object-diff "^1.1.0" + emotion-theming "^10.0.27" + global "^4.4.0" + memoizerific "^1.11.3" + polished "^4.0.5" + resolve-from "^5.0.0" + ts-dedent "^2.0.0" + "@storybook/ui@6.3.8": version "6.3.8" resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.3.8.tgz#9fb71befbe76f06c478925610ce998c23260a3f3" @@ -9414,7 +9440,7 @@ debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -14310,7 +14336,7 @@ import-lazy@^4.0.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -16124,11 +16150,6 @@ lodash._baseflatten@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw= - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -16137,16 +16158,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*, lodash._bindcallback@^3.0.0: +lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI= - lodash._createassigner@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" @@ -16156,19 +16172,12 @@ lodash._createassigner@^3.0.0: lodash._isiterateecall "^3.0.0" lodash.restparam "^3.0.0" -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM= - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= -lodash._getnative@*, lodash._getnative@^3.0.0: +lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= @@ -16386,7 +16395,7 @@ lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= -lodash.restparam@*, lodash.restparam@^3.0.0: +lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= From d70ff06891b7daf1afc1a16457e002eb2abfa353 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Tue, 18 Jan 2022 14:32:03 -0500 Subject: [PATCH 4/5] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20support=20for?= =?UTF-8?q?=20nested=20attributes=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/adapters/application.js | 38 +++++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/addons/api/addon/adapters/application.js b/addons/api/addon/adapters/application.js index 04a9ebe6f..1c4149511 100644 --- a/addons/api/addon/adapters/application.js +++ b/addons/api/addon/adapters/application.js @@ -263,14 +263,36 @@ export default class ApplicationAdapter extends RESTAdapter.extend( source: { pointer: '/data' }, }; // Normalize field-specific errors, if any. - const errors = fieldErrors.map((error) => ({ - detail: error.description, - // Ember Data cannot handle errors on nested attributes, so these are - // flattened (e.g. `attributes.foobar` becomes `attributes_foobar`). - // To capture these errors, add read-only fields on the model - // corresponding to the underscored field name. - source: { pointer: `/data/attributes/${error.name.replace('.', '_')}` }, - })); + const errors = fieldErrors.flatMap((error) => { + const newValue = [ + { + detail: error.description, + // Ember Data cannot handle errors on nested attributes, so these are + // flattened (e.g. `attributes.foobar` becomes `attributes_foobar`). + // To capture these errors, add read-only fields on the model + // corresponding to the underscored field name. + source: { + pointer: `/data/attributes/${error.name.replace('.', '_')}`, + }, + }, + ]; + if (error.name.includes('attributes.')) { + newValue.push({ + detail: error.description, + // Going forward, nested attributes will be hoisted. Thus "attributes." + // must be stripped from the error name key. Until all models are + // transitioned away from model fragments, however, both this and the + // prior error key mappings are necessary. + source: { + pointer: `/data/attributes/${error.name.replace( + 'attributes.', + '' + )}`, + }, + }); + } + return newValue; + }); // Return a list of JSON API errors rooted under the `errors` key. return { errors: [baseError, ...errors], From 121129ffd2594ee4fb91308a03a607bd96fcc404 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 19 Jan 2022 12:16:57 -0500 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=F0=9F=90=9B=20include=20nulls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/serializers/application.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/api/addon/serializers/application.js b/addons/api/addon/serializers/application.js index 6223f5df8..cb61f1a34 100644 --- a/addons/api/addon/serializers/application.js +++ b/addons/api/addon/serializers/application.js @@ -51,7 +51,7 @@ export default class ApplicationSerializer extends RESTSerializer { // TODO: disabled is temporarily disabled if (key === 'disabled') delete json[key]; // Push nested attributes down into the attributes key - if (options.isNestedAttribute && json[key]) { + if (options.isNestedAttribute && json[key] !== undefined) { if (!json.attributes) json.attributes = {}; json.attributes[key] = json[key]; delete json[key];