Upgrade api to ember 4.12 (#1833) (#1839)

* chore: 🤖 Upgrade API layer to ember 4.12

* chore: 🤖 Upgrade ember-data to 4.12

* fix: 🐛 Fix breaking change from usage of internal method

* chore: 🤖 Remove stylelint in API addon

* test: 💍 Fix broken API tests

* chore: 🤖 get rid of toArray

* test: 💍 Fix tests broken by ember data changes

---------

Co-authored-by: dharini <dharini@hashicorp.com>
This commit is contained in:
Zhihe Lianddharini authored and GitHub committed 2023-08-14 17:03:59 -04:00
1 parent 77b47e2cb3
commit 0e9042f588
21 files changed
+1338 -284

No files matched your search

+2 -2
View File
@@ -8,8 +8,8 @@
"disableAnalytics": false,
/**
Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript
rather than JavaScript by default, when a TypeScript version of a given blueprint is available.
Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript
rather than JavaScript by default, when a TypeScript version of a given blueprint is available.
*/
"isTypeScriptProject": false
}
+6 -4
View File
@@ -9,12 +9,14 @@ module.exports = {
root: true,
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 2018,
ecmaVersion: 'latest',
sourceType: 'module',
// This is specific babel-config. If grows consider creating a babel config file
requireConfigFile: false,
babelOptions: {
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
plugins: [
['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }],
],
},
// end of babel-config
},
@@ -36,6 +38,7 @@ module.exports = {
files: [
'./.eslintrc.js',
'./.prettierrc.js',
'./.stylelintrc.js',
'./.template-lintrc.js',
'./ember-cli-build.js',
'./index.js',
@@ -51,8 +54,7 @@ module.exports = {
browser: false,
node: true,
},
plugins: ['node'],
extends: ['plugin:node/recommended'],
extends: ['plugin:n/recommended'],
},
{
// Test files:
View File
Whitespace-only changes.
-1
View File
@@ -22,7 +22,6 @@
/.travis.yml
/.watchmanconfig
/bower.json
/config/ember-try.js
/CONTRIBUTING.md
/ember-cli-build.js
/testem.js
+8 -1
View File
@@ -4,5 +4,12 @@
*/
module.exports = {
singleQuote: true,
overrides: [
{
files: '*.{js,ts}',
options: {
singleQuote: true,
},
},
],
};
+6 -2
View File
@@ -20,8 +20,12 @@ export default class HostCatalogAdapter extends ApplicationAdapter {
buildURL(modelName, id, snapshot, requestType) {
let url = super.buildURL(...arguments);
if (requestType === 'createRecord') {
const pluginName = snapshot.attr('plugin')?.name;
if (pluginName) url = `${url}?plugin_name=${pluginName}`;
try {
const pluginName = snapshot.attr('plugin')?.name;
if (pluginName) url = `${url}?plugin_name=${pluginName}`;
} catch (e) {
// Ignore any adapter errors here
}
}
return url;
}
@@ -20,7 +20,12 @@ export default class SessionRecordingAdapter extends ApplicationAdapter {
*/
buildURL(modelName, id, snapshot, requestType, query) {
let url = super.buildURL(...arguments);
const method = snapshot?.adapterOptions?.method;
let method;
try {
method = snapshot?.adapterOptions?.method;
} catch (e) {
// Ignore any adapter errors here
}
if (method === 'download') {
const queryParams = new URLSearchParams(query).toString();
if (queryParams) url = `${url}?${queryParams}`;
+6 -1
View File
@@ -19,7 +19,12 @@ export default class StorageBucketAdapter extends ApplicationAdapter {
*/
buildURL(modelName, id, snapshot, requestType) {
let url = super.buildURL(...arguments);
const pluginName = snapshot?.attr('plugin')?.name;
let pluginName;
try {
pluginName = snapshot?.attr('plugin')?.name;
} catch (e) {
// Ignore any adapter errors here
}
if (requestType === 'createRecord' && pluginName) {
url = `${url}?plugin_name=${pluginName}`;
}
+3 -3
View File
@@ -209,9 +209,9 @@ export default class ApplicationSerializer extends RESTSerializer {
* @return {object}
*/
normalizeMissingArrays(store, primaryModelClass, payload) {
const attrDefs = store._attributesDefinitionFor(
primaryModelClass.modelName
);
const attrDefs = store
.getSchemaDefinitionService()
.attributesDefinitionFor({ type: primaryModelClass.modelName });
if (attrDefs) {
Object.keys(attrDefs).forEach((key) => {
if (!payload[key] && attrDefs[key]?.options?.emptyArrayIfMissing) {
+1 -1
View File
@@ -9,7 +9,7 @@ const EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
const { maybeEmbroider } = require('@embroider/test-setup');
module.exports = function (defaults) {
let app = new EmberAddon(defaults, {
const app = new EmberAddon(defaults, {
// Add options here
});
+28 -25
View File
@@ -10,8 +10,8 @@
"scripts": {
"build:development": "ember build",
"build": "ember build --environment=production",
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
"lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
"lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
"lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"",
"lint:js": "eslint .",
"lint:js:fix": "eslint . --fix",
"format": "yarn run format:js",
@@ -25,52 +25,55 @@
"dependencies": {
"ember-can": "^4.2.0",
"ember-cli-babel": "^7.26.10",
"ember-cli-htmlbars": "^6.1.0",
"ember-cli-htmlbars": "^6.2.0",
"ember-cli-mirage": "^2.4.0",
"ember-data": "~4.4.0",
"ember-data": "~4.12.0",
"ember-fetch": "^8.1.1"
},
"devDependencies": {
"@babel/eslint-parser": "^7.18.2",
"@babel/plugin-proposal-decorators": "^7.18.6",
"@babel/core": "^7.18.5",
"@babel/eslint-parser": "^7.21.3",
"@babel/plugin-proposal-decorators": "^7.21.0",
"@ember/optional-features": "^2.0.0",
"@ember/test-helpers": "^2.8.1",
"@ember/string": "^3.0.1",
"@ember/test-helpers": "^2.9.3",
"@embroider/test-setup": "^2.1.1",
"@glimmer/component": "^1.1.2",
"@glimmer/tracking": "^1.1.2",
"broccoli-asset-rev": "^3.0.0",
"concurrently": "^8.0.1",
"doctoc": "^2.2.0",
"ember-auto-import": "^2.4.3",
"ember-cli": "^4.4.1",
"ember-auto-import": "^2.6.3",
"ember-cli": "^4.12.1",
"ember-cli-dependency-checker": "^3.3.1",
"ember-cli-inject-live-reload": "^2.1.0",
"ember-cli-sri": "^2.1.1",
"ember-cli-terser": "^4.0.2",
"ember-disable-prototype-extensions": "^1.1.3",
"ember-exam": "^8.0.0",
"ember-export-application-global": "^2.0.1",
"ember-load-initializers": "^2.1.2",
"ember-page-title": "^7.0.0",
"ember-qunit": "^6.0.0",
"ember-resolver": "^8.0.3",
"ember-source": "~4.4.0",
"ember-qunit": "^6.2.0",
"ember-resolver": "^10.0.0",
"ember-source": "~4.12.0",
"ember-source-channel-url": "^3.0.0",
"ember-template-lint": "^4.14.0",
"eslint": "^8.18.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-ember": "^10.6.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-qunit": "^7.3.0",
"ember-template-lint": "^5.7.2",
"eslint": "^8.37.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-ember": "^11.5.0",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-qunit": "^7.3.4",
"js-bexpr": "hashicorp/js-bexpr#9b4a4b54d85eba67fdfc0990133d1518d890b1e1",
"loader.js": "^4.7.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.6.2",
"qunit": "^2.19.1",
"prettier": "^2.8.7",
"qunit": "^2.19.4",
"qunit-dom": "^2.0.0",
"webpack": "^5.76.0"
"webpack": "^5.78.0"
},
"peerDependencies": {
"ember-source": "^4.0.0"
},
"engines": {
"node": "12.* || 14.* || 16.*"
"node": "14.* || 16.* || >= 18"
},
"ember": {
"edition": "octane"
@@ -3,7 +3,7 @@
"packages": [
{
"name": "ember-cli",
"version": "4.4.1",
"version": "4.12.1",
"blueprints": [
{
"name": "addon",
@@ -12,10 +12,18 @@ module.exports = async function () {
return {
scenarios: [
{
name: 'ember-lts-3.28',
name: 'ember-lts-4.4',
npm: {
devDependencies: {
'ember-source': '~3.28.0',
'ember-source': '~4.4.0',
},
},
},
{
name: 'ember-lts-4.8',
npm: {
devDependencies: {
'ember-source': '~4.8.0',
},
},
},
+2 -5
View File
@@ -6,20 +6,17 @@
'use strict';
module.exports = function (environment) {
let ENV = {
const ENV = {
modulePrefix: 'dummy',
environment,
rootURL: '/',
locationType: 'history',
EmberENV: {
EXTEND_PROTOTYPES: false,
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
},
EXTEND_PROTOTYPES: {
// Prevent Ember Data from overriding Date.parse.
Date: false,
},
},
APP: {
+8 -10
View File
@@ -85,7 +85,7 @@ module('Unit | Model | base', function (hooks) {
});
this.server.patch('/v1/users/1', () => {
assert.ok(true, 'Correctly scoped update record URL was requested.');
return {};
return { id: 1 };
});
const model = store.peekRecord('user', '1');
assert.false(model.canSave);
@@ -117,19 +117,18 @@ module('Unit | Model | base', function (hooks) {
const model = store.createRecord('user', { scopeID: 'o_123' });
this.server.post('/v1/users', () => {
assert.ok(true, 'Correctly scoped create record URL was requested.');
return {};
return { id: 'u_123' };
});
await model.save();
this.server.patch('/v1/users', () => {
this.server.patch('/v1/users/u_123', () => {
assert.ok(true, 'Correctly scoped update record URL was requested.');
return {};
return { id: 'u_123' };
});
await model.save();
this.server.delete('/v1/users/u_123', () => {
assert.ok(true, 'Correctly scoped delete record URL was requested.');
return {};
});
model.id = 'u_123';
await model.destroyRecord();
});
@@ -141,19 +140,18 @@ module('Unit | Model | base', function (hooks) {
const model = store.createRecord('user', { scope });
this.server.post('/v1/users', () => {
assert.ok(true, 'Correctly scoped create record URL was requested.');
return {};
return { id: 'u_123' };
});
await model.save({ adapterOptions: { scopeID: customScopeID } });
this.server.patch('/v1/users', () => {
this.server.patch('/v1/users/u_123', () => {
assert.ok(true, 'Correctly scoped update record URL was requested.');
return {};
return { id: 'u_123' };
});
await model.save({ adapterOptions: { scopeID: customScopeID } });
this.server.delete('/v1/users/u_123', () => {
assert.ok(true, 'Correctly scoped delete record URL was requested.');
return {};
});
model.id = 'u_123';
await model.destroyRecord({ adapterOptions: { scopeID: customScopeID } });
});
@@ -165,7 +163,7 @@ module('Unit | Model | base', function (hooks) {
const model = store.createRecord('user', { scope });
this.server.post(`/v1/users:${method}`, () => {
assert.ok(true, 'Correctly scoped create record URL was requested.');
return {};
return { id: 'u_123' };
});
await model.save({ adapterOptions: { method } });
});
+3 -2
View File
@@ -36,7 +36,7 @@
"test:addons-rose": "yarn --cwd addons/rose test",
"test:ui-admin": "yarn --cwd ui/admin test",
"test:ui-desktop": "yarn --cwd ui/desktop test",
"compliance:licenses": "license-checker --onlyAllow 'Apache*;Apache License, Version 2.0;Apache-2.0;Apache 2.0;Artistic-2.0;BSD;BSD-3-Clause;CC-BY-3.0;CC-BY-4.0;CC0-1.0;ISC;MIT;MPL-2.0;Public Domain;Python-2.0;Unicode-TOU;Unlicense;WTFPL' --excludePackages 'boundary-ui;admin@0.0.0;desktop@0.0.0;base64-js@0.0.2;cycle@1.0.3;cldr-core@43.1.0;make-plural@7.2.0;@hashicorp/ember-asciinema-player@0.0.0'",
"compliance:licenses": "license-checker --onlyAllow 'Apache*;Apache License, Version 2.0;Apache-2.0;Apache 2.0;Artistic-2.0;BSD;BSD-3-Clause;CC-BY-3.0;CC-BY-4.0;CC0-1.0;ISC;MIT;MPL-2.0;Public Domain;Python-2.0;Unicode-TOU;Unlicense;WTFPL' --excludePackages 'boundary-ui;admin@0.0.0;desktop@0.0.0;base64-js@0.0.2;cycle@1.0.3;cldr-core@43.1.0;make-plural@7.2.0;@hashicorp/ember-asciinema-player@0.0.0;path-scurry@1.10.1'",
"doc:toc": "doctoc README.md",
"prepare": "husky install"
},
@@ -82,7 +82,8 @@
"**/@storybook/**/ansi-regex": "^5.0.1",
"**/jsprim/json-schema": "^0.4.0",
"**/@storybook/**/yuidocjs/markdown-it": "^12.3.2",
"**/ember-cli/markdown-it-terminal/markdown-it": "^12.3.2"
"**/ember-cli/markdown-it-terminal/markdown-it": "^12.3.2",
"**/ember-cli-mirage/@embroider/macros": "^1.0.0"
},
"config": {
"commitizen": {
@@ -22,7 +22,7 @@ export default class ScopesScopeGroupsGroupAddMembersRoute extends Route {
// =attributes
@resourceFilter({
allowed: (route) => route.store.peekAll('scope').toArray(),
allowed: (route) => route.store.peekAll('scope'),
serialize: ({ id }) => id,
findBySerialized: ({ id }, value) => id === value,
})
@@ -48,8 +48,7 @@ export default class ScopesScopeGroupsGroupAddMembersRoute extends Route {
// filter out projects, since the user resource exists only on org and above
const scopes = this.store
.peekAll('scope')
.filter((scope) => !scope.isProject)
.toArray();
.filter((scope) => !scope.isProject);
const scopeIDs = this.scope?.map((scope) => scope.id);
const users = scopeIDs?.length
? this.resourceFilterStore.queryBy(
@@ -23,7 +23,7 @@ export default class ScopesScopeRolesRoleAddPrincipalsRoute extends Route {
// =attributes
@resourceFilter({
allowed: (route) => route.store.peekAll('scope').toArray(),
allowed: (route) => route.store.peekAll('scope'),
serialize: ({ id }) => id,
findBySerialized: ({ id }, value) => id === value,
})
@@ -18,7 +18,6 @@ export default class ScopesScopeWorkersIndexRoute extends Route {
allowed: (route) => {
const configTags = route
.modelFor('scopes.scope.workers')
.toArray()
.flatMap((worker) => worker.getConfigTagList())
.filter(Boolean);
@@ -12,7 +12,6 @@ import {
find,
findAll,
getRootElement,
setupOnerror,
} from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
@@ -124,10 +123,7 @@ module('Acceptance | authentication', function (hooks) {
test('visiting auth method when the scope cannot be loaded is still allowed', async function (assert) {
assert.expect(1);
setupOnerror(() => {
// do nothing, otherwise an uncaught adapter error will fail the test
});
this.server.get('/scopes', () => {
this.server.get(authMethodAuthenticateURL, () => {
return new Response(404);
});
await visit(authMethodAuthenticateURL);
+1244 -213
View File
File diff suppressed because it is too large. Load diff