diff --git a/addon/abilities/dynamic.js b/addon/abilities/dynamic.js new file mode 100644 index 0000000..b0cbdd9 --- /dev/null +++ b/addon/abilities/dynamic.js @@ -0,0 +1,39 @@ +import { Ability } from 'ember-can'; +import { tracked } from '@glimmer/tracking'; +import { inject as service } from '@ember/service'; +import { singularize } from 'ember-inflector'; + +export default class extends Ability { + @service currentUser; + @tracked service; + @tracked resource; + @tracked ability; + @tracked permissions = new Set(); + + constructor() { + super(...arguments); + this.permissions = new Set(this.currentUser.permissions.map((permission) => permission.name)); + } + + parseProperty(str) { + let [service, ability, resource] = str.split(' '); + + this.service = service; + this.ability = ability; + this.resource = singularize(resource); + + return 'can'; + } + + get can() { + if (this.currentUser.isAdmin) { + return true; + } + + const permission = [this.service, this.ability, this.resource].join(' '); + const wilcardPermission = [this.service, '*', this.resource].join(' '); + const wildcardServicePermission = [this.service, '*'].join(' '); + + return this.permissions.has(permission) || this.permissions.has(wilcardPermission) || this.permissions.has(wildcardServicePermission); + } +} diff --git a/addon/exports/host-services.js b/addon/exports/host-services.js index 9c43e44..d667f33 100644 --- a/addon/exports/host-services.js +++ b/addon/exports/host-services.js @@ -15,6 +15,7 @@ const hostServices = [ 'fileQueue', 'universe', 'intl', + 'abilities', { hostRouter: 'router' }, ]; diff --git a/addon/exports/services.js b/addon/exports/services.js index 947dc04..4c4e1cc 100644 --- a/addon/exports/services.js +++ b/addon/exports/services.js @@ -16,6 +16,7 @@ const services = [ 'fileQueue', 'universe', 'intl', + 'abilities', ]; export default services; diff --git a/addon/services/abilities.js b/addon/services/abilities.js new file mode 100644 index 0000000..656f7bb --- /dev/null +++ b/addon/services/abilities.js @@ -0,0 +1,7 @@ +import Service from 'ember-can/services/abilities'; + +export default class AbilitiesService extends Service { + parse(propertyName) { + return { propertyName, abilityName: 'dynamic' }; + } +} diff --git a/addon/services/current-user.js b/addon/services/current-user.js index 9fcc141..3681df1 100644 --- a/addon/services/current-user.js +++ b/addon/services/current-user.js @@ -54,6 +54,13 @@ export default class CurrentUserService extends Service.extend(Evented) { id: 'anon', }; + /** + * The current users permissions. + * + * @memberof CurrentUserService + */ + @tracked permissions = []; + /** * User options in localStorage * @@ -96,36 +103,82 @@ export default class CurrentUserService extends Service.extend(Evented) { */ @alias('user.company_uuid') companyId; + /** + * Alias for if user is admin. + * + * @var {Boolean} + * @memberof CurrentUserService + */ + @alias('user.is_admin') isAdmin; + + /** + * The prefix for this user options + * + * @var {String} + */ + @computed('id') get optionsPrefix() { + return `${this.id}:`; + } + + get latitude() { + return this.whois('latitude'); + } + + get longitude() { + return this.whois('longitude'); + } + + get currency() { + return this.whois('currency.code'); + } + + get city() { + return this.whois('city'); + } + + get country() { + return this.whois('country_code'); + } + /** * Loads the current authenticated user * - * @void + * @return Promise|null */ async load() { if (this.session.isAuthenticated) { let user = await this.store.findRecord('user', 'me'); this.set('user', user); this.trigger('user.loaded', user); + + // Set permissions + this.permissions = this.getUserPermissions(user); + + return user; } + + return null; } /** * Resolves a user model. * - * @return {Promise} + * @return {Promise} */ @action promiseUser(options = {}) { const NoUserAuthenticatedError = new Error('Failed to authenticate user.'); return new Promise((resolve, reject) => { if (this.session.isAuthenticated) { - return this.store - .queryRecord('user', { me: true }) - .then((user) => { + try { + this.store.queryRecord('user', { me: true }).then((user) => { // set the `current user` this.set('user', user); this.trigger('user.loaded', user); + // Set permissions + this.permissions = this.getUserPermissions(user); + // set environment from user option this.theme.setEnvironment(); @@ -135,10 +188,10 @@ export default class CurrentUserService extends Service.extend(Evented) { } resolve(user); - }) - .catch(() => { - reject(NoUserAuthenticatedError); }); + } catch (error) { + reject(NoUserAuthenticatedError); + } } else { reject(NoUserAuthenticatedError); } @@ -146,60 +199,56 @@ export default class CurrentUserService extends Service.extend(Evented) { } /** - * Loads and resolved all current users installed order configurations. + * Gets all user permissions. * - * @return {Promise} + * @param {UserModel} user + * @return {Array} + * @memberof CurrentUserService */ - @action getInstalledOrderConfigs(params = {}) { - return new Promise((resolve, reject) => { - this.fetch - .get('fleet-ops/order-configs/get-installed', params) - .then((configs) => { - const serialized = []; + getUserPermissions(user) { + const permissions = []; - for (let i = 0; i < configs.length; i++) { - const config = configs.objectAt(i); - const normalizedConfig = this.store.normalize('order-config', config); - const serializedConfig = this.store.push(normalizedConfig); + // get direct applied permissions + if (user.get('permissions')) { + permissions.pushObjects(user.get('permissions').toArray()); + } + + // get role permissions and role policies permissions + if (user.get('role')) { + if (user.get('role.permissions')) { + permissions.pushObjects(user.get('role.permissions').toArray()); + } - serialized.pushObject(serializedConfig); + if (user.get('role.policies')) { + for (let i = 0; i < user.get('role.policies').length; i++) { + const policy = user.get('role.policies').objectAt(i); + if (policy.get('permissions')) { + permissions.pushObjects(policy.get('permissions').toArray()); } + } + } + } - resolve(serialized); - }) - .catch(reject); - }); + // get direct applied policy permissions + if (user.get('policies')) { + for (let i = 0; i < user.get('policies').length; i++) { + const policy = user.get('policies').objectAt(i); + if (policy.get('permissions')) { + permissions.pushObjects(policy.get('permissions').toArray()); + } + } + } + + return permissions; } /** - * The prefix for this user options + * Alias to get a user's whois property * - * @var {String} + * @param {String} key + * @return {Mixed} + * @memberof CurrentUserService */ - @computed('id') get optionsPrefix() { - return `${this.id}:`; - } - - get latitude() { - return this.whois('latitude'); - } - - get longitude() { - return this.whois('longitude'); - } - - get currency() { - return this.whois('currency.code'); - } - - get city() { - return this.whois('city'); - } - - get country() { - return this.whois('country_code'); - } - @action whois(key) { return this.getWhoisProperty(key); } diff --git a/addon/services/universe.js b/addon/services/universe.js index 9a51ab4..93cf420 100644 --- a/addon/services/universe.js +++ b/addon/services/universe.js @@ -847,7 +847,7 @@ export default class UniverseService extends Service.extend(Evented) { // If component is a definition register to host application if (typeof component === 'function') { const owner = getOwner(this); - const widgetId = component.widgetId || widgetId || this._createUniqueWidgetHashFromDefinition(component); + widgetId = component.widgetId || widgetId || this._createUniqueWidgetHashFromDefinition(component); if (owner) { owner.register(`component:${widgetId}`, component); diff --git a/app/abilities/dynamic.js b/app/abilities/dynamic.js new file mode 100644 index 0000000..72a9546 --- /dev/null +++ b/app/abilities/dynamic.js @@ -0,0 +1 @@ +export { default } from '@fleetbase/ember-core/abilities/dynamic'; diff --git a/app/services/abilities.js b/app/services/abilities.js new file mode 100644 index 0000000..27d435b --- /dev/null +++ b/app/services/abilities.js @@ -0,0 +1 @@ +export { default } from '@fleetbase/ember-core/services/abilities'; diff --git a/index.js b/index.js index 63b6615..f319970 100644 --- a/index.js +++ b/index.js @@ -41,6 +41,7 @@ module.exports = { new Funnel(path.dirname(require.resolve('socketcluster-client')), { files: ['socketcluster-client.min.js'], destDir: '/assets', + allowEmpty: true, }) ); diff --git a/package.json b/package.json index 4870f73..da6b9c3 100644 --- a/package.json +++ b/package.json @@ -1,128 +1,126 @@ { - "name": "@fleetbase/ember-core", - "version": "0.2.14", - "description": "Provides all the core services, decorators and utilities for building a Fleetbase extension for the Console.", - "keywords": [ - "fleetbase-core", - "fleetbase-services", - "fleetbase", - "ember-addon" - ], - "repository": "https://github.com/fleetbase/ember-core", - "license": "AGPL-3.0-or-later", - "author": "Fleetbase Pte Ltd ", - "directories": { - "app": "app", - "addon": "addon", - "tests": "tests" - }, - "scripts": { - "build": "ember build --environment=production", - "lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"", - "lint:css": "stylelint \"**/*.css\"", - "lint:css:fix": "concurrently \"npm:lint:css -- --fix\"", - "lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"", - "lint:hbs": "ember-template-lint .", - "lint:hbs:fix": "ember-template-lint . --fix", - "lint:js": "eslint . --cache", - "lint:js:fix": "eslint . --fix", - "start": "ember serve", - "test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"", - "test:ember": "ember test", - "test:ember-compatibility": "ember try:each", - "publish:npm": "npm config set registry https://registry.npmjs.org/ && npm publish", - "publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish" - }, - "dependencies": { - "@babel/core": "^7.23.2", - "compress-json": "^3.0.0", - "date-fns": "^2.30.0", - "ember-auto-import": "^2.6.3", - "ember-cli-babel": "^8.2.0", - "ember-cli-htmlbars": "^6.3.0", - "ember-cli-notifications": "^9.0.0", - "ember-concurrency": "^3.1.1", - "ember-concurrency-decorators": "^2.0.3", - "ember-decorators": "^6.1.1", - "ember-get-config": "^2.1.1", - "ember-inflector": "^4.0.2", - "ember-intl": "6.3.2", - "ember-loading": "^2.0.0", - "ember-local-storage": "^2.0.4", - "ember-simple-auth": "^6.0.0", - "ember-wormhole": "^0.6.0", - "socketcluster-client": "^17.1.1" - }, - "devDependencies": { - "@babel/eslint-parser": "^7.22.15", - "@babel/plugin-proposal-decorators": "^7.23.2", - "@ember/optional-features": "^2.0.0", - "@ember/test-helpers": "^3.2.0", - "@embroider/test-setup": "^3.0.2", - "@glimmer/component": "^1.1.2", - "@glimmer/tracking": "^1.1.2", - "broccoli-asset-rev": "^3.0.0", - "broccoli-funnel": "^3.0.8", - "broccoli-merge-trees": "^4.2.0", - "broccoli-persistent-filter": "^3.1.3", - "concurrently": "^8.2.2", - "ember-cli": "~5.4.1", - "ember-cli-clean-css": "^3.0.0", - "ember-cli-dependency-checker": "^3.3.2", - "ember-cli-inject-live-reload": "^2.1.0", - "ember-cli-sri": "^2.1.1", - "ember-cli-terser": "^4.0.2", - "ember-data": "^4.12.5", - "ember-file-upload": "8.4.0", - "ember-load-initializers": "^2.1.2", - "ember-page-title": "^8.0.0", - "ember-qunit": "^8.0.1", - "ember-resolver": "^11.0.1", - "ember-source": "~5.4.0", - "ember-source-channel-url": "^3.0.0", - "ember-template-lint": "^5.11.2", - "ember-try": "^3.0.0", - "eslint": "^8.52.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-ember": "^11.11.1", - "eslint-plugin-n": "^16.2.0", - "eslint-plugin-prettier": "^5.0.1", - "eslint-plugin-qunit": "^8.0.1", - "loader.js": "^4.7.0", - "prettier": "^3.0.3", - "qunit": "^2.20.0", - "qunit-dom": "^2.0.0", - "resolve": "^1.22.2", - "stylelint": "^15.11.0", - "stylelint-config-standard": "^34.0.0", - "stylelint-prettier": "^4.0.2", - "webpack": "^5.89.0" - }, - "overrides": { - "broccoli-persistent-filter": "^3.1.3" - }, - "engines": { - "node": ">= 18" - }, - "ember": { - "edition": "octane" - }, - "ember-addon": { - "configPath": "tests/dummy/config" - }, - "prettier": { - "trailingComma": "es5", - "tabWidth": 4, - "semi": true, - "singleQuote": true, - "printWidth": 190, - "overrides": [ - { - "files": "*.hbs", - "options": { - "singleQuote": false - } - } - ] - } + "name": "@fleetbase/ember-core", + "version": "0.2.15", + "description": "Provides all the core services, decorators and utilities for building a Fleetbase extension for the Console.", + "keywords": [ + "fleetbase-core", + "fleetbase-services", + "fleetbase", + "ember-addon" + ], + "repository": "https://github.com/fleetbase/ember-core", + "license": "AGPL-3.0-or-later", + "author": "Fleetbase Pte Ltd ", + "directories": { + "app": "app", + "addon": "addon", + "tests": "tests" + }, + "scripts": { + "build": "ember build --environment=production", + "lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"", + "lint:css": "stylelint \"**/*.css\"", + "lint:css:fix": "concurrently \"npm:lint:css -- --fix\"", + "lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"", + "lint:hbs": "ember-template-lint .", + "lint:hbs:fix": "ember-template-lint . --fix", + "lint:js": "eslint . --cache", + "lint:js:fix": "eslint . --fix", + "start": "ember serve", + "test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"", + "test:ember": "ember test", + "test:ember-compatibility": "ember try:each", + "publish:npm": "npm config set registry https://registry.npmjs.org/ && npm publish", + "publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish" + }, + "dependencies": { + "@babel/core": "^7.23.2", + "compress-json": "^3.0.0", + "date-fns": "^2.30.0", + "ember-auto-import": "^2.7.4", + "ember-can": "^6.0.0", + "ember-cli-babel": "^8.2.0", + "ember-cli-htmlbars": "^6.3.0", + "ember-cli-notifications": "^9.0.0", + "ember-concurrency": "^3.1.1", + "ember-concurrency-decorators": "^2.0.3", + "ember-decorators": "^6.1.1", + "ember-get-config": "^2.1.1", + "ember-inflector": "^4.0.2", + "ember-intl": "6.3.2", + "ember-loading": "^2.0.0", + "ember-local-storage": "^2.0.4", + "ember-simple-auth": "^6.0.0", + "ember-wormhole": "^0.6.0", + "socketcluster-client": "^17.1.1" + }, + "devDependencies": { + "@babel/eslint-parser": "^7.22.15", + "@babel/plugin-proposal-decorators": "^7.23.2", + "@ember/optional-features": "^2.0.0", + "@ember/test-helpers": "^3.2.0", + "@embroider/test-setup": "^3.0.2", + "@glimmer/component": "^1.1.2", + "@glimmer/tracking": "^1.1.2", + "broccoli-asset-rev": "^3.0.0", + "broccoli-funnel": "^3.0.8", + "broccoli-merge-trees": "^4.2.0", + "broccoli-persistent-filter": "^3.1.3", + "concurrently": "^8.2.2", + "ember-cli": "~5.4.1", + "ember-cli-clean-css": "^3.0.0", + "ember-cli-dependency-checker": "^3.3.2", + "ember-cli-inject-live-reload": "^2.1.0", + "ember-cli-sri": "^2.1.1", + "ember-cli-terser": "^4.0.2", + "ember-data": "^4.12.5", + "ember-file-upload": "8.4.0", + "ember-load-initializers": "^2.1.2", + "ember-page-title": "^8.0.0", + "ember-qunit": "^8.0.1", + "ember-resolver": "^11.0.1", + "ember-source": "~5.4.0", + "ember-source-channel-url": "^3.0.0", + "ember-template-lint": "^5.11.2", + "ember-try": "^3.0.0", + "eslint": "^8.52.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-ember": "^11.11.1", + "eslint-plugin-n": "^16.2.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-qunit": "^8.0.1", + "loader.js": "^4.7.0", + "prettier": "^3.0.3", + "qunit": "^2.20.0", + "qunit-dom": "^2.0.0", + "resolve": "^1.22.2", + "stylelint": "^15.11.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-prettier": "^4.0.2", + "webpack": "^5.89.0" + }, + "engines": { + "node": ">= 18" + }, + "ember": { + "edition": "octane" + }, + "ember-addon": { + "configPath": "tests/dummy/config" + }, + "prettier": { + "trailingComma": "es5", + "tabWidth": 4, + "semi": true, + "singleQuote": true, + "printWidth": 190, + "overrides": [ + { + "files": "*.hbs", + "options": { + "singleQuote": false + } + } + ] + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c1676d2..fc73394 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,8 +18,11 @@ importers: specifier: ^2.30.0 version: 2.30.0 ember-auto-import: - specifier: ^2.6.3 - version: 2.6.3(webpack@5.89.0) + specifier: ^2.7.4 + version: 2.7.4(webpack@5.89.0) + ember-can: + specifier: ^6.0.0 + version: 6.0.0(@babel/core@7.23.2)(@ember/string@3.1.1)(ember-inflector@4.0.2)(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) ember-cli-babel: specifier: ^8.2.0 version: 8.2.0(@babel/core@7.23.2) @@ -1040,6 +1043,10 @@ packages: resolution: {integrity: sha512-JGOQNRj3UR0NdWEg8MsM2eqPLncEwSB1IX+rwntIj22TEKj8biqx7GDgSbeH+ZedijmCh354Hf2c5rthrdzUAw==} engines: {node: 12.* || 14.* || >= 16} + '@embroider/addon-shim@1.8.9': + resolution: {integrity: sha512-qyN64T1jMHZ99ihlk7VFHCWHYZHLE1DOdHi0J7lmn5waV1DoW7gD8JLi1i7FregzXtKhbDc7shyEmTmWPTs8MQ==} + engines: {node: 12.* || 14.* || >= 16} + '@embroider/macros@1.13.5': resolution: {integrity: sha512-OzYyM+bOcyV9IWma1qSraIyuBmGv6U8sCIHumHCe0oDDypvIvVA3csuDjoS3BGhUWV56VpzBSwVEDdIHXmqQ2w==} engines: {node: 12.* || 14.* || >= 16} @@ -1053,6 +1060,10 @@ packages: resolution: {integrity: sha512-jNDJ9YlV6Qp9Na9v17qirUewVuq6T0t32nn+bbnFlCRTvmllKluZdYPSC5RuRnEZKTloVYRSF0+f1rgkTIEvxQ==} engines: {node: 12.* || 14.* || >= 16} + '@embroider/shared-internals@2.6.2': + resolution: {integrity: sha512-jL3Bjn8C73AUBlTex+VixP7YmqvPNN/BZFB85odTstzLFOuR8y2mmGiuWbq17qNuFyoxc6xtndMnAeqwCXBNkA==} + engines: {node: 12.* || 14.* || >= 16} + '@embroider/test-setup@3.0.2': resolution: {integrity: sha512-cq/xp06CAB8rAGnObeJux7qALnAX2MatMVLjWyGDr3ogS5lHTNXZVCv4ltTM3pJ8EsZWpPM32dtUZqSJFkGibQ==} engines: {node: 12.* || 14.* || >= 16} @@ -1669,6 +1680,10 @@ packages: resolution: {integrity: sha512-N1ZfNprtf/37x0R05J0QCW/9pCAcuI+bjZIK9tlu0JEkwEST7ssdD++gxHRbD58AiG5QE5OuNYhRoEFsc1wESw==} engines: {node: '>= 12.*'} + babel-import-util@3.0.0: + resolution: {integrity: sha512-4YNPkuVsxAW5lnSTa6cn4Wk49RX6GAB6vX+M6LqEtN0YePqoFczv1/x0EyLK/o+4E1j9jEuYj5Su7IEPab5JHQ==} + engines: {node: '>= 12.*'} + babel-loader@8.3.0: resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==} engines: {node: '>= 8.9'} @@ -2185,6 +2200,9 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + common-ancestor-path@1.0.1: + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -2540,6 +2558,9 @@ packages: resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} engines: {node: '>=4'} + decorator-transforms@2.0.0: + resolution: {integrity: sha512-ETfQccGcotK01YJsoB0AGTdUp7kS9jI93mBzrRY5Oyo+bOJfa2UKTSjCNf+iRNwAWBmBKlbiCcyL4tkY4C4dZQ==} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -2640,12 +2661,8 @@ packages: electron-to-chromium@1.4.673: resolution: {integrity: sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==} - ember-auto-import@2.6.3: - resolution: {integrity: sha512-uLhrRDJYWCRvQ4JQ1e64XlSrqAKSd6PXaJ9ZsZI6Tlms9T4DtQFxNXasqji2ZRJBVrxEoLCRYX3RTldsQ0vNGQ==} - engines: {node: 12.* || 14.* || >= 16} - - ember-auto-import@2.7.2: - resolution: {integrity: sha512-pkWIljmJClYL17YBk8FjO7NrZPQoY9v0b+FooJvaHf/xlDQIBYVP7OaDHbNuNbpj7+wAwSDAnnwxjCoLsmm4cw==} + ember-auto-import@2.7.4: + resolution: {integrity: sha512-6CdXSegJJc8nwwK7+1lIcBUnMVrJRNd4ZdMgcKbCAwPvcGxMgRVBddSzrX/+q/UuflvTEO26Dk1g7Z6KHMXUhw==} engines: {node: 12.* || 14.* || >= 16} ember-cache-primitive-polyfill@1.0.1: @@ -2658,6 +2675,14 @@ packages: peerDependencies: ember-source: ^3.13.0 || ^4.0.0 || >= 5.0.0 + ember-can@6.0.0: + resolution: {integrity: sha512-/8TnWxU9Yu0HXCk04qCHK3nnjrNMe3j6wrJJjW9ffLsnBBHKTT8yNP1f54EsHaHoNtWd73JGSSTmtcpBHhWAyw==} + peerDependencies: + '@ember/string': ^3.1.1 || ^4.0.0 + ember-inflector: ^4.0.2 || ^5.0.1 + ember-resolver: '>= 8.0.0' + ember-source: ^3.28.0 || ^4.0.0 || >=5.0.0 + ember-cli-babel-plugin-helpers@1.1.1: resolution: {integrity: sha512-sKvOiPNHr5F/60NLd7SFzMpYPte/nnGkq/tMIfXejfKHIhaiIkYFqX8Z9UFTKWLLn+V7NOaby6niNPZUdvKCRw==} engines: {node: 6.* || 8.* || >= 10.*} @@ -6250,7 +6275,7 @@ snapshots: '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4 lodash.debounce: 4.0.8 - resolve: 1.22.2 + resolve: 1.22.8 transitivePeerDependencies: - supports-color @@ -7019,7 +7044,7 @@ snapshots: '@ember/edition-utils': 1.2.0 '@ember/string': 3.1.1 '@embroider/macros': 1.13.5 - ember-auto-import: 2.6.3(webpack@5.89.0) + ember-auto-import: 2.7.4(webpack@5.89.0) ember-cli-babel: 7.26.11 transitivePeerDependencies: - '@glint/template' @@ -7217,7 +7242,7 @@ snapshots: '@simple-dom/interface': 1.4.0 broccoli-debug: 0.6.5 broccoli-funnel: 3.0.8 - ember-auto-import: 2.6.3(webpack@5.89.0) + ember-auto-import: 2.7.4(webpack@5.89.0) ember-cli-babel: 7.26.11 ember-cli-htmlbars: 6.3.0 ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) @@ -7243,6 +7268,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@embroider/addon-shim@1.8.9': + dependencies: + '@embroider/shared-internals': 2.6.2 + broccoli-funnel: 3.0.8 + common-ancestor-path: 1.0.1 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + '@embroider/macros@1.13.5': dependencies: '@embroider/shared-internals': 2.5.2 @@ -7270,6 +7304,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@embroider/shared-internals@2.6.2': + dependencies: + babel-import-util: 2.0.1 + debug: 4.3.4 + ember-rfc176-data: 0.3.18 + fs-extra: 9.1.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + minimatch: 3.1.2 + resolve-package-path: 4.0.3 + semver: 7.6.0 + typescript-memoize: 1.1.1 + transitivePeerDependencies: + - supports-color + '@embroider/test-setup@3.0.2': dependencies: lodash: 4.17.21 @@ -8021,6 +8070,8 @@ snapshots: babel-import-util@2.0.1: {} + babel-import-util@3.0.0: {} + babel-loader@8.3.0(@babel/core@7.23.2)(webpack@5.89.0): dependencies: '@babel/core': 7.23.2 @@ -8854,6 +8905,8 @@ snapshots: commander@8.3.0: {} + common-ancestor-path@1.0.1: {} + common-tags@1.8.2: {} commondir@1.0.1: {} @@ -9047,6 +9100,13 @@ snapshots: dependencies: mimic-response: 1.0.1 + decorator-transforms@2.0.0(@babel/core@7.23.2): + dependencies: + '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.23.2) + babel-import-util: 3.0.0 + transitivePeerDependencies: + - '@babel/core' + deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -9130,45 +9190,7 @@ snapshots: electron-to-chromium@1.4.673: {} - ember-auto-import@2.6.3(webpack@5.89.0): - dependencies: - '@babel/core': 7.23.2 - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.23.2) - '@babel/plugin-proposal-decorators': 7.23.2(@babel/core@7.23.2) - '@babel/preset-env': 7.23.9(@babel/core@7.23.2) - '@embroider/macros': 1.13.5 - '@embroider/shared-internals': 2.5.2 - babel-loader: 8.3.0(@babel/core@7.23.2)(webpack@5.89.0) - babel-plugin-ember-modules-api-polyfill: 3.5.0 - babel-plugin-ember-template-compilation: 2.2.1 - babel-plugin-htmlbars-inline-precompile: 5.3.1 - babel-plugin-syntax-dynamic-import: 6.18.0 - broccoli-debug: 0.6.5 - broccoli-funnel: 3.0.8 - broccoli-merge-trees: 4.2.0 - broccoli-plugin: 4.0.7 - broccoli-source: 3.0.1 - css-loader: 5.2.7(webpack@5.89.0) - debug: 4.3.4 - fs-extra: 10.1.0 - fs-tree-diff: 2.0.1 - handlebars: 4.7.8 - js-string-escape: 1.0.1 - lodash: 4.17.21 - mini-css-extract-plugin: 2.8.0(webpack@5.89.0) - parse5: 6.0.1 - resolve: 1.22.2 - resolve-package-path: 4.0.3 - semver: 7.6.0 - style-loader: 2.0.0(webpack@5.89.0) - typescript-memoize: 1.1.1 - walk-sync: 3.0.0 - transitivePeerDependencies: - - '@glint/template' - - supports-color - - webpack - - ember-auto-import@2.7.2(webpack@5.89.0): + ember-auto-import@2.7.4(webpack@5.89.0): dependencies: '@babel/core': 7.23.2 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.23.2) @@ -9177,7 +9199,7 @@ snapshots: '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.23.2) '@babel/preset-env': 7.23.9(@babel/core@7.23.2) '@embroider/macros': 1.13.5 - '@embroider/shared-internals': 2.5.2 + '@embroider/shared-internals': 2.6.2 babel-loader: 8.3.0(@babel/core@7.23.2)(webpack@5.89.0) babel-plugin-ember-modules-api-polyfill: 3.5.0 babel-plugin-ember-template-compilation: 2.2.1 @@ -9198,7 +9220,7 @@ snapshots: mini-css-extract-plugin: 2.8.0(webpack@5.89.0) minimatch: 3.1.2 parse5: 6.0.1 - resolve: 1.22.2 + resolve: 1.22.8 resolve-package-path: 4.0.3 semver: 7.6.0 style-loader: 2.0.0(webpack@5.89.0) @@ -9233,6 +9255,18 @@ snapshots: - '@glint/template' - supports-color + ember-can@6.0.0(@babel/core@7.23.2)(@ember/string@3.1.1)(ember-inflector@4.0.2)(ember-resolver@11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)))(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): + dependencies: + '@ember/string': 3.1.1 + '@embroider/addon-shim': 1.8.9 + decorator-transforms: 2.0.0(@babel/core@7.23.2) + ember-inflector: 4.0.2 + ember-resolver: 11.0.1(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) + ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0) + transitivePeerDependencies: + - '@babel/core' + - supports-color + ember-cli-babel-plugin-helpers@1.1.1: {} ember-cli-babel@7.26.11: @@ -9791,7 +9825,7 @@ snapshots: '@embroider/macros': 1.13.5 '@glimmer/env': 0.1.7 broccoli-merge-trees: 4.2.0 - ember-auto-import: 2.6.3(webpack@5.89.0) + ember-auto-import: 2.7.4(webpack@5.89.0) ember-cli-babel: 7.26.11 ember-inflector: 4.0.2 transitivePeerDependencies: @@ -9827,7 +9861,7 @@ snapshots: '@embroider/macros': 1.13.5 '@glimmer/component': 1.1.2(@babel/core@7.23.2) '@glimmer/tracking': 1.1.2 - ember-auto-import: 2.6.3(webpack@5.89.0) + ember-auto-import: 2.7.4(webpack@5.89.0) ember-modifier: 4.1.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)) tracked-built-ins: 3.3.0 transitivePeerDependencies: @@ -9861,7 +9895,7 @@ snapshots: broccoli-stew: 3.0.0 calculate-cache-key-for-tree: 2.0.0 cldr-core: 44.1.0 - ember-auto-import: 2.7.2(webpack@5.89.0) + ember-auto-import: 2.7.4(webpack@5.89.0) ember-cli-babel: 8.2.0(@babel/core@7.23.2) ember-cli-typescript: 5.2.1 eventemitter3: 5.0.1 @@ -9912,7 +9946,7 @@ snapshots: ember-modifier@4.1.0(ember-source@5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2(@babel/core@7.23.2))(rsvp@4.8.5)(webpack@5.89.0)): dependencies: - '@embroider/addon-shim': 1.8.7 + '@embroider/addon-shim': 1.8.9 ember-cli-normalize-entity-name: 1.0.0 ember-cli-string-utils: 1.1.0 optionalDependencies: @@ -10008,7 +10042,7 @@ snapshots: broccoli-funnel: 3.0.8 broccoli-merge-trees: 4.2.0 chalk: 4.1.2 - ember-auto-import: 2.6.3(webpack@5.89.0) + ember-auto-import: 2.7.4(webpack@5.89.0) ember-cli-babel: 7.26.11 ember-cli-get-component-path-option: 1.0.0 ember-cli-is-package-missing: 1.0.0 @@ -12593,7 +12627,7 @@ snapshots: resolve-package-path@2.0.0: dependencies: path-root: 0.1.1 - resolve: 1.22.2 + resolve: 1.22.8 resolve-package-path@3.1.0: dependencies: @@ -13453,7 +13487,7 @@ snapshots: tracked-built-ins@3.3.0: dependencies: - '@embroider/addon-shim': 1.8.7 + '@embroider/addon-shim': 1.8.9 ember-tracked-storage-polyfill: 1.0.0 transitivePeerDependencies: - supports-color diff --git a/tests/unit/abilities/dynamic-test.js b/tests/unit/abilities/dynamic-test.js new file mode 100644 index 0000000..3e04439 --- /dev/null +++ b/tests/unit/abilities/dynamic-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Ability | dynamic', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const ability = this.owner.lookup('ability:dynamic'); + assert.ok(ability); + }); +}); diff --git a/tests/unit/services/abilities-test.js b/tests/unit/services/abilities-test.js new file mode 100644 index 0000000..68fd1fb --- /dev/null +++ b/tests/unit/services/abilities-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'dummy/tests/helpers'; + +module('Unit | Service | abilities', function (hooks) { + setupTest(hooks); + + // TODO: Replace this with your real tests. + test('it exists', function (assert) { + let service = this.owner.lookup('service:abilities'); + assert.ok(service); + }); +});