Compare commits

...
91 Commits
Author SHA1 Message Date
Michael Li 2e507be454 test(e2e): Address some Admin UI test issues for 0.19.2 (#2818)
* test(e2e): Update navigation to create a storage bucket

* test(e2e): Address flake when creating host catalogs
2025-05-06 14:07:36 -04:00
dillanb-hashi dbf3617224 test(ui): Test the scope picker on the top menu bar (#2788)
* test(ui): Test the scope picker on the top menu bar
* test(ui): Fixing based on recent menu bar changes
2025-05-06 09:39:48 -07:00
Lisbet Alvarez 200a7944e6 Icu 16545 upgrade ember addons api (#2791)
* v4.12.1...v5.12.0

* chore: 🤖 yarn.lock changes from ember upgrade

* chore: 🤖 ember init blueprint changes

* chore: 🤖 yarn.lock updates

* chore: 🤖 fix build errors

* chore: 🤖 yarn.lock file changes

* refactor: 💡 undo style path change

* chore: 🤖 fix build errors

* chore: 🤖 yarn.lock file changes

* test: 💍 add @ember/string back in to fix test error

* chore: 🤖 remove eslint prettier plugin

* chore: 🤖 remove prettier eslint plugin in api addon

* docs: ✏️ add comments back in
2025-05-06 08:49:29 -07:00
Lisbet Alvarez 8dafc2b9a0 test: 💍 refactor session-recording test selectors (#2811)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16423
2025-05-05 10:41:42 -07:00
Lisbet Alvarez b7559c1f4e Icu 16542 upgrade ember addons rose (#2784)
* v4.12.2...v5.12.0

* fix: 🐛 update path name for hds styles

* chore: 🤖 ember init changes

* style: 💄 clear lint errors

* chore: 🤖 run yarn format in rose addon

* chore: 🤖 fix build failures

* chore: 🤖 yarn.lock file changes

* chore: 🤖 yarn.lock file updates

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16542
2025-05-02 15:13:45 -07:00
Lauren dd8e1864db [Replace] Rose::Form::Label and <input.field> elements (#2783)
* replace with hds::form::label

* test Hds::Form::TextInput::Field

* add event handler

* add hds text componenet to grant.value fields

* fix test failures

* replace with set-from-event

* address feedback

* add title html element to hds component
2025-05-02 11:12:30 -04:00
Lauren d85a84980f [Retire] Rose::Icon (#2807)
* remove rose::icon test

* remove .rose-icon class styling from ui/admin

* remove .rose-icon class styling from ui/desktop

* remove .rose-icon class styling from addons/

* remove @import 'icon'

* remove icon.js
2025-05-02 10:53:21 -04:00
Priya Patel 4295966b7f Rose::Dialog::Cover component cleanup (#2806)
* refactor: 💡 rose::dialog::cover cleanup

* refactor: 💡 removed cover addon file
2025-05-01 16:14:53 -06:00
Lisbet Alvarez a87c079ade refactor: 💡 convert rose/anonymous from classic to glimmer comp (#2799) 2025-05-01 10:36:34 -07:00
Cameron Perera b3604e3e40 refactor: 💡 update code tag to use Hds::Text::Code (#2805)
* refactor: 💡 update code tag to use Hds::Text::Code

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16961

* refactor: 💡 remove explicit code tag attribute

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16961

* refactor: 💡 fix extra white space

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16961

* refactor: 💡 remove color from p span style for workers

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16961
2025-05-01 11:59:10 -05:00
hashicorp-tsccr[bot]andhashicorp-tsccr[bot] 6be8130329 Result of tsccr-helper -log-level=info gha update -latest .github/ (#2809)
Co-authored-by: hashicorp-tsccr[bot] <hashicorp-tsccr[bot]@users.noreply.github.com>
2025-05-01 09:15:31 +02:00
Lisbet Alvarez ca3972c04f fix: 🐛 polyfillUUID config for ember-data (#2808) 2025-04-30 16:54:59 -07:00
Lisbet Alvarez 4d98729cde chore: 🤖 update changelog and cli version (#2801)
* chore: 🤖 update changelog and cli version
2025-04-30 11:55:56 -07:00
Priya Patel 185af6f00e refactor: 💡 remove card component from desktop (#2798) 2025-04-29 17:28:59 -06:00
Lisbet Alvarez c5353d6e5e Icu 16547 upgrade ember desktop UI (#2796)
* v4.12.2...v5.12.0

* chore: 🤖 yarn.lock file changes

* chore: 🤖 ember init blueprint updates

* chore: 🤖 yarn.lock changes

* style: 💄 run linter and formatter

* chore: 🤖 yarn.lock file changes

* chore: 🤖 remove ember-cli-app-version

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16547
2025-04-29 15:32:50 -07:00
Lisbet Alvarez 20a05dc96a style: 💄 fix formatting for long credential names & description (#2804)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16869
2025-04-29 12:17:14 -07:00
Cameron Perera 30028b5ba0 refactor: 💡 convert p tags to Hds::Text component (#2800)
* refactor: 💡 convert p tags to Hds::Text component

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16865

* style: 💄 remove comment

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16865
2025-04-29 12:26:20 -05:00
Priya Patel 3bafb708ea refactor: 💡 update Rose::Frame to use Hds::Card::Container (#2795) 2025-04-29 09:15:17 -07:00
Cameron Perera 24d86a230a refactor: 💡 use Hds::Text::Code in place of pre tag (#2802)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16956
2025-04-29 09:24:24 -05:00
Lisbet Alvarez 620f822504 Icu 16546 upgrade ember for admin UI (#2793)
* v4.12.2...v5.12.0

* chore: 🤖 yarn.lock changes

* chore: 🤖 ember init blueprint changes

* chore: 🤖 yarn.lock file changes

* style: 💄 run linter and formatter

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16546
2025-04-25 14:39:59 -07:00
Priya Patel 93a57f26ee Replace Rose::Icon with HDS::Icon (#2762)
* refactor: 💡 rose icons with hds icons

* fix: 🐛 remove child selector for h2

* fix: 🐛 removed unwanted changes

* fix: 🐛 remove unncessary change

* refactor: 💡 rose icon for rose components

* fix: 🐛 default size for doc-link, updated tests, removed TODO

* fix: 🐛 update doc-link test
2025-04-25 13:18:23 -07:00
Cameron Perera 40ec4493ea fix: 🐛 credential library serializer for SSH certificate (#2790)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16880
2025-04-25 10:23:51 -05:00
hashicc de83d59bde Add additional indexeddb-handler tests (#2786) 2025-04-24 11:05:44 -04:00
Lisbet Alvarez a937c5e8de style: 💄 remove table borders from list-wrapper component (#2787) 2025-04-22 18:11:49 -07:00
Priya Patel b820bb19d7 Refactor: Hosts-sets test - delete, read and create (#2778)
* refactor: 💡 hosts-sets test refactor - delete,read,create

* fix: 🐛 updated test selectors
2025-04-22 14:16:15 -07:00
Lauren 36db2d3f1d Replace Rose::Button with Hds::Button (#2771)
* refactor btn

* refactor scope/workers/index.hbs

* refactor add-members, add-principals

* refactor btns, fix tests

* update json-secret-skeleton btn

* remove class from app.scss
2025-04-22 16:25:12 -04:00
Cameron Perera 5786b86521 refactor: 💡 update text span elements with Hds::Text::Body (#2779)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16864
2025-04-22 11:54:00 -05:00
Priya Patel c6a5f93b44 Replace Rose::Dialog::Cover with HDS::ApplicationState (#2770)
* refactor: 💡 rose dialog cover with hds application state

* fix: 🐛 i18n key

* fix: 🐛 addressed comments

* fix: 🐛 CSP issue for svg

* docs: ✏️ added CSP issue context
2025-04-18 12:42:18 -07:00
Carlos Alcaide Corvo 8814e2eacb Ember upgrade for addons/core (#2777) 2025-04-17 13:59:14 -07:00
Lisbet Alvarez 9b1e4a8291 Icu 16541 upgrade ember addons auth (#2776)
* v4.12.2...v5.12.0

* chore: 🤖 yarn.lock file changes

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16541

* chore: 🤖 run ember init to use updated blueprints as ref

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16541

* chore: 🤖 undo node change

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16541

* style: 💄 fix lint error

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16541

* fix: 🐛 undo deleted gitkeep file

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16541

* refactor: 💡 use workspace protocol for addons

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16541

* chore: 🤖 undo removal of stylistic

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16541
2025-04-17 11:36:46 -07:00
Priya Patel 01c2468f86 Refactor: Replace Rose::Dialog with HDS::Modal for desktop client (#2766)
* refactor: 💡 rose dialog to hds modal

* fix: 🐛 dark theme hds overlay

* fix: 🐛 dark mode hds modal shadow

* fix: 🐛 move dark mode modal override to a mixin

* fix: 🐛 update exists to isVisible
2025-04-17 10:57:45 -07:00
Cameron Perera af705718ff Reveal & Toolbar::Info Component cleanup (#2782)
* refactor: 💡 remove desktop Reveal component

* refactor: 💡 remove Toolbar::Info component
2025-04-17 10:11:14 -05:00
Carlos Alcaide Corvo e22ef12529 Chore icu 16553 deprecate a like array (#2767) 2025-04-15 09:29:01 -07:00
Carlos Alcaide Corvo 62510d9243 Chore icu 16553 deprecate a like array (#2767) 2025-04-15 09:13:55 -07:00
Carlos Alcaide Corvo 0fd25a6bb4 Delete electron-squirrel-startup from electron-app (#2774) 2025-04-15 08:22:35 -07:00
Cameron Perera a268a7b75e refactor: 💡 update all header tags to use HDS::Text::Display (#2765)
* refactor: 💡 update all header tags to use HDS::Text::Display

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16863

* refactor: 💡 update minor css changes for page header

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16863

* refactor: 💡 remove duplicate title and lint hbs files

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16863
2025-04-14 21:05:37 -05:00
3dded0a7bc Llb/side nav refactor (#2763)
* feat: 🎸 scope picker component (#2646)

* feat: 🎸 scope picker component
---------

Co-authored-by: lisbet-alvarez <lisbet-alvarez@users.noreply.github.com>
Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>

* refactor: 💡 use hds side nav w/ hds frame instead of rose (#2688)

* refactor: 💡 use hds side nav w/ hds frame instead of rose

* test: 💍 clean up selectors

* fix: 🐛 specificity of style override

* refactor: 💡 use hds side nav list instead of target and portal

* refactor: 💡 revert to using portal component & update scss

* docs: ✏️ update comment

* refactor: 💡 use custom class names for containers

* refactor: 💡 pr feedback (use @hasSidebar arg)

* refactor: 💡 fix onboarding page & fix settings title

* refactor: 💡 remove unneeded template file (pr feedback)

* test: 💍 fix tests due to merge conflicts

* test: 💍 add missing test selector due to merge conflict

* test: 💍 fix more broken tests due to merge conflicts

* chore: 🤖 update yarn.lock & update hds version to 4.18.1

* chore: 🤖 fix e2e test cases due to side nav refactor (#2751)

* chore: 🤖 fix e2e test cases due to side nav refactor

* test: 💍 fix e2e test for desktop

---------

Co-authored-by: lisbet-alvarez <lisbet-alvarez@users.noreply.github.com>
Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>
2025-04-14 14:27:02 -07:00
Lauren ab3140be0a refactor: 💅 Aliases: update-test (#2760)
* refactor aliases update-test

* refactor test

* address feedback
2025-04-14 12:09:22 -04:00
Sohail 0fcd58c080 feat: Conditionally display 'Check for Updates' menu item based on CLI type (#2754) 2025-04-10 07:58:23 -07:00
Carlos Alcaide Corvo 52f0d9f9e8 Update browserslist db (#2768) 2025-04-10 07:43:24 -07:00
hashicc 6585fa8e41 Add tests for indexed db handler (#2759) 2025-04-09 14:52:02 -04:00
Carlos Alcaide Corvo bef9b3b276 Refactor test selectors for credential-store/credentials create test (#2756) 2025-04-08 15:40:08 -07:00
Dharini Jeeva af411b854a chore: 🤖 include ipv6 support in mocks (#2764)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16862
2025-04-04 16:01:47 -07:00
Cameron Perera a697dba5b9 chore: 🤖 add test selectors to roles org-scope tests (#2761) 2025-04-04 13:33:41 -05:00
Carlos Alcaide Corvo 1203081ec7 Chore icu 15394 upgrade electron (#2753)
* Upgrade electron v35
2025-04-04 09:03:19 -07:00
Zhihe Li 2db63ae2f8 feat: 🎸 Populate subject for OIDC account name displays (#2757)
OIDC accounts are guaranteed to have a subject claim which we should
display. Currently we only look at email and full_name which
are all optional for OIDC claims. Also added deep links for accounts.

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16634
2025-04-03 13:33:08 -04:00
Lisbet AlvarezandCarlos Alcaide Corvo 9dd1617b57 chore: 🤖 upgrade ember-data to v5.3.11 (#2745)
* chore: 🤖 upgrade ember-data to v5.3.11

* Add missing copyright headers

* refactor: 💡 remove comment

* chore: 🤖 update yarn.lock due to merge conflict

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16544

* fix: 🐛 undo ember-source upgrade (should be upgraded w/ ember)

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16544

* chore: 🤖 move dep to devDeps & resolve test-helper version

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16544

* fix: 🐛 unique record id error bug fix using store.push

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16544

* refactor: 💡 cleanup

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16544

* Delete old deprecation initializer (#2748)

* refactor: 💡 import from'ember-data/store'

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16544

* refactor: 💡 clean up comments

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16544

* refactor: 💡 remove compatWith comment

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16544

---------

Co-authored-by: Carlos Alcaide Corvo <ccorvo@hashicorp.com>
2025-04-03 09:32:44 -07:00
Zhihe Li 834058ff45 refactor: 💡 Batch writes to indexedDB (#2752)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16795
2025-04-01 14:04:31 -04:00
Cameron Perera 0f41a0a576 chore: 🤖 add test selectors to roles grants tests (#2749)
* chore: 🤖 add test selectors to roles list tests

* chore: 🤖 add test selectors for roles global-scope tests

* chore: 🤖 add TABLE_RESOURCE_LINK to global-scope tests

* test: 💍 change exists to isVisible

* chore: 🤖 add test selectors to roles grants tests

* refactor: 💡 create custom selector for grants tests

* refactor: 💡 use new FORM selector
2025-03-31 16:24:40 -05:00
Zhihe Li 1025cbfb87 refactor: 💡 Force requests in playwright to use controller addr (#2755) 2025-03-28 19:42:35 -04:00
Priya Patel ca3c1c7623 Refactor: Scopes tests (#2744)
* refactor: 💡 scopes test

* fix: 🐛 addressed comments

* fix: 🐛 replace exists with isVisible, use hasText

* fix: 🐛 move form to commonSelectors
2025-03-28 15:00:59 -07:00
Dharini Jeeva 69d127a89e chore: 🤖 remove rose::nav::breadcrumbs (#2750)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16790
2025-03-28 11:27:43 -07:00
Cameron Perera b4d9cd5bb7 Icu 16409 roles list & global-scope (#2747)
* chore: 🤖 add test selectors to roles list tests

* chore: 🤖 add test selectors for roles global-scope tests

* chore: 🤖 add TABLE_RESOURCE_LINK to global-scope tests

* test: 💍 change exists to isVisible
2025-03-28 13:11:33 -05:00
Carlos Alcaide Corvo 4b1327db24 Upgrade ember-electron from 4.2.2 to 6.0.0 (#2740)
* Upgrade to ember-electron 6
2025-03-27 09:08:12 -07:00
Priya Patel 2f2ceed24e Refactor: Workers test - Create-tags, list and tags (#2742)
* refactor: 💡 workers test - create-tags,list,tags

* fix: 🐛 addressed comment
2025-03-25 15:03:13 -07:00
Zhihe Li de0f20809d chore: 🤖 Fix git-cz usage for auto populating issues in hook (#2746)
✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16777
2025-03-25 13:23:31 -04:00
Dharini Jeeva b1f5857cac refactor: 💡 use test selector in host-catalog/list (#2743) 2025-03-24 14:50:09 -07:00
Cameron Perera ddbd1ca163 Icu 16406 roles read, update, delete (#2741)
* chore: 🤖 add test selectors to roles read tests

* chore: 🤖 add test selectors to roles update tests

* refactor: 💡 small test clean up

* chore: 🤖 add test selectors to roles delete tests
2025-03-21 15:34:17 -05:00
Carlos Alcaide Corvo 777e40fff8 Upgrade electron forge from 7.5.0 to 7.7.0 (#2739) 2025-03-21 11:27:04 -07:00
Priya Patel 68460331f5 Refactor: Worker tests - create, read, update and delete (#2737)
* refactor: 💡 workers test - create,delete,read,update

* fix: 🐛 address comments
2025-03-20 14:02:13 -07:00
Cameron Perera 32e9fe8b6a chore: 🤖 use test selectors for roles create tests (#2738) 2025-03-20 14:08:33 -05:00
Priya Patel b3a2460b3f Refactor: Policy tests - list and delete (#2736)
* fix: 🐛 policy test refactor - list, delete

* fix: 🐛 chain assertions

* fix: 🐛 fixed failing test
2025-03-18 15:03:53 -07:00
Dharini Jeeva 3260bf1b2a refactor: 💡 use test selector in host-catalog read, delete and update (#2734) 2025-03-18 12:06:39 -07:00
Priya Patel e69c6456d1 Refactor: Policy tests - create, read and update (#2732)
* refactor: 💡 policy tests: create, read and update

* fix: 🐛 use commonselector for table link
2025-03-18 10:47:46 -07:00
Zhihe Li f8b3792e62 Fix Searchbar debouncing in admin UI (#2735)
Applied ember-concurrency task usage to admin UI model hooks to help fix the debouncing issue.
2025-03-18 11:20:50 -04:00
Cameron Perera 01c34c0a79 Small test selector updates (#2733)
* refactor: 💡 update sidebar nav selector name

* refactor: 💡 move generic selector to common selector file
2025-03-17 11:07:21 -05:00
Priya Patel 825751239f Refactor: 💡 User acceptance tests: list, update and accounts (#2726)
* refactor: 💡 users selector tests: list, update and accounts

* fix: 🐛 follow AAA pattern

* refactor: 💡 updated common selectors
2025-03-14 16:04:56 -07:00
Dharini Jeeva 2465739060 Icu 15486 host catalogs create test (#2729) 2025-03-14 09:42:29 -07:00
Zhihe Li e6834d2033 chore: 🤖 Add chrome for self hosted runners when running tests (#2731) 2025-03-14 12:10:44 -04:00
Cameron Perera 924100df4c chore: 🤖 update session list tests with selectors (#2727)
* chore: 🤖 update session list tests with selectors

* chore: 🤖 add TABLE_ROW selector to session list
2025-03-14 10:32:44 -05:00
Zhihe Li 1ac7d1e08b feat: 🎸 Use repo vars to determine the runner size (#2724) 2025-03-14 11:15:53 -04:00
Zhihe Li 7becccd628 fix: 🐛 Fix search field race condition in DC targets (#2723)
* fix: 🐛 Fix search field race condition in DC targets
* feat: 🎸 Keep track of last search to know when to debounce

✅ Closes: ICU-14775
2025-03-13 18:50:33 -04:00
Dharini Jeeva dff5cac4fe refactor: 💡 worker filter feature flags (#2720) 2025-03-13 15:12:36 -07:00
Lisbet Alvarez ecd0c1de20 Icu 16535 refactor usage of did insert modifiers (#2722)
* refactor: 💡 remove ember-render-modifiers {{did-insert}} usage
2025-03-13 12:58:39 -07:00
Dharini Jeeva 878cb17b62 refactor: 💡 use test selector in groups/members route (#2719) 2025-03-13 09:51:37 -07:00
Carlos Alcaide Corvo 706981c231 Refactor test selectors within auth-methods oidc test (#2717)
* Refactor test selectors within auth-methods oidc test
2025-03-13 08:39:11 -07:00
Priya Patel d212cf7c40 Refactor: 💡 User acceptance tests - create, delete and read (#2718)
* refactor: 💡 user - create, delete and read tests

* fix: 🐛 removed 'this' usage, updated user create test
2025-03-12 16:49:38 -07:00
Carlos Alcaide Corvo 19b6e5154f Fix locationType deprecations. (#2721)
* Deprecated usage of locationType auto to history. Define locationType before setting configuration
2025-03-12 16:16:33 -07:00
Lisbet Alvarez 89263918ea Icu 16534 refactor usage of tracked using this args (#2711)
* refactor: 💡 remove tracked usage with this.args
2025-03-12 10:09:16 -07:00
Carlos Alcaide Corvo e8fc6d163b Deprecate import inject from @ember/service (#2716)
* Deprecate usage of import inject
2025-03-12 08:29:54 -07:00
Priya Patel 34a670f8d7 Refactor: Onboarding tests selectors refactor (#2715)
* refactor: 💡 Onboarding tests

Refactor test selectors for onboarding acceptance tests

✅ Closes: #ICU-16398, #ICU-16399

* fix: 🐛 failing test

* chore: 🤖 add copyright header

* fix: 🐛 use AAA pattern and server.schema

* fix: 🐛 moved done button to selectors

* fix: 🐛 renamed copy text btn selector
2025-03-11 14:53:32 -07:00
hashicc 6a46e2dd57 chore: 🤖 add chrome flags to keep from backgrounding (#2714)
There was an issue in tests where events fired in
Hds::FlyOut and Hds::Modal were not being dispatched.
These close events were depended on by test waiters
to know when the element was removed. In recent
versions of chrome, when ran headless and on macos,
these events were not firing. This meant the tests
waited indefinitely on developers local machines,
until the tests timed out. This issue was seen
across multiple macbooks and even on the hds repo.

This issue was *only* experienced in headless
chrome on recent macos.
It was **not** happening in:
* macos chrome headed locally
* linux chrome headless in CI

This made the issue only impact people running tests
locally, getting obscure timeouts. This issue is fixed
by the addition of this flag:
--disable-backgrounding-occluded-windows

The other flags added in this commit are not required
for the fix but should help keep a browser "active",
which was loosely what researching this bug hinted at
the cause of finding the issue fix.
2025-03-11 13:29:19 -04:00
Dharini Jeeva 5e0fa7c744 test: 💍 use test selectors for groups (#2713)
* test: 💍 use test selectors for groups
2025-03-10 13:32:32 -07:00
Zhihe LiandMichael Li 474ce17a13 Initial E2E DC setup (#2710)
* Initial setup

* refactor: 💡 Update dependency job

* refactor: 💡 Use boundary ent

* chore: 🤖 Cleanup workflow

* refactor: 💡 Adjust run condition

---------

Co-authored-by: Michael Li <michael.li@hashicorp.com>
2025-03-10 15:36:21 -04:00
Cameron Perera f00eed8633 test: 💍 fix false positive test (#2712) 2025-03-10 13:35:13 -05:00
Cameron Perera 42bcefa068 Icu 16393 managed groups read (#2709)
* chore: 🤖 update managed-groups read test selectors

* chore: 🤖 add test selectors to managed-groups delete

* chore: 🤖 use test selectors in managed-groups list tests

* chore: 🤖 refactor managed-groups members tests

* refactor: 💡 update selector name for DELETE action
2025-03-06 14:42:45 -06:00
Lisbet AlvarezandZhihe Li 29bde998ed refactor: 💡 remove usage of ember/runloop & ember-pollster (#2705)
* refactor: 💡 remove usage of ember/runloop & ember-pollster

---------

Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>
2025-03-06 12:20:48 -08:00
Michael LiandDharini Jeeva e29a83ec25 test(e2e): Enable Admin UI e2e tests to run against a local branch (#2700)
* test(e2e): decouple url used for browser vs cli

* test(e2e): Add instructions for using the UI of a local branch

* CR

* Fix typo in e2e-tests/README.md

Co-authored-by: Dharini Jeeva <dharini@hashicorp.com>

---------

Co-authored-by: Dharini Jeeva <dharini@hashicorp.com>
2025-03-05 11:38:12 -05:00
Zhihe Li ddfcbde7d4 chore: 🤖 audit security alerts (#2707)
* chore: 🤖 Update solid-js to resolve security alert

* chore: 🤖 Update path-to-regexp package for security alert

* chore: 🤖 Update nanoid to resolve security alert
2025-03-05 11:16:45 -05:00
Cameron Perera 42e31d3ece Icu 16392 managed groups create (#2704)
* chore: 🤖 update manage-gropus tests to ues selectors

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-16392

* refactor: 💡 small clean up
2025-03-04 15:09:08 -06:00
Michael Li cd8480bc67 test(e2e): Add check for credential store worker filters (#2696) 2025-03-04 14:43:01 -05:00
800 changed files with 11884 additions and 10037 deletions

No files matched your search

+16 -16
View File
@@ -9,27 +9,27 @@ on:
jobs:
dependencies:
name: Install dependencies
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: node-modules-cache
with:
path: "**/node_modules"
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
- run: yarn install
build-admin-ui-oss:
name: Build Admin UI OSS
needs: [dependencies]
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: node-modules-cache
with:
path: "**/node_modules"
@@ -37,27 +37,27 @@ jobs:
restore-keys: |
node-modules-
- name: Build
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
- run: yarn run build:ui:admin:oss
- name: Upload artifact admin-ui
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: admin-ui
path: ./ui/admin/dist/
- name: Upload artifact OSS admin UI
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: admin-ui-oss
path: ./ui/admin/dist/
build-admin-ui-enterprise:
name: Build Admin UI Enterprise
needs: [dependencies]
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: node-modules-cache
with:
path: "**/node_modules"
@@ -65,22 +65,22 @@ jobs:
restore-keys: |
node-modules-
- name: Build
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
- run: yarn run build:ui:admin:enterprise
- name: Upload artifact enterprise admin UI
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: admin-ui-ent
path: ./ui/admin/dist/
build-admin-ui-hcp:
name: Build Admin UI HCP
needs: [dependencies]
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: node-modules-cache
with:
path: "**/node_modules"
@@ -88,12 +88,12 @@ jobs:
restore-keys: |
node-modules-
- name: Build
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
- run: yarn run build:ui:admin:hcp
- name: Upload artifact HCP admin UI
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: admin-ui-hcp
path: ./ui/admin/dist/
+3 -3
View File
@@ -17,7 +17,7 @@ on:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
strategy:
fail-fast: false
@@ -34,7 +34,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a # codeql-bundle-v2.20.3
uses: github/codeql-action/init@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 # codeql-bundle-v2.20.7
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -54,4 +54,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a # codeql-bundle-v2.20.3
uses: github/codeql-action/analyze@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 # codeql-bundle-v2.20.7
+1 -1
View File
@@ -2,7 +2,7 @@ name: Add Copyright Headers
on: pull_request
jobs:
copywrite:
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
permissions:
contents: write
steps:
+1 -1
View File
@@ -11,7 +11,7 @@ name: Jira Sync
jobs:
sync:
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
name: Jira sync
steps:
- name: Check if community user
+1 -1
View File
@@ -4,7 +4,7 @@ on:
jobs:
triage:
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
with:
+15 -12
View File
@@ -4,17 +4,17 @@ jobs:
dependencies:
name: Install dependencies
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
- run: yarn install
@@ -22,17 +22,17 @@ jobs:
compliance:
name: License Compliance
needs: [dependencies]
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
- run: yarn run compliance:licenses
@@ -40,18 +40,18 @@ jobs:
lint:
name: Lint
needs: [dependencies, compliance]
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
timeout-minutes: 5
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
node-modules-
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
- run: yarn lint
@@ -59,16 +59,19 @@ jobs:
test:
name: Test
needs: [lint]
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
timeout-minutes: 15
steps:
- uses: browser-actions/setup-chrome@c785b87e244131f27c9f19c1a33e2ead956ab7ce # v1.7.3
with:
install-dependencies: true
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: node-modules-cache
with:
path: '**/node_modules'
key: node-modules-${{ hashFiles('**/yarn.lock') }}
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
- run: yarn test
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
trigger-oss-merge:
# Run this only on merge events in OSS repo
if: ${{ github.event.pull_request.merged && github.repository == 'hashicorp/boundary-ui' }}
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- name: Trigger Merge
env:
+1 -1
View File
@@ -4,7 +4,7 @@ on:
types: [ oss-merge ]
jobs:
oss-merge:
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+110
View File
@@ -0,0 +1,110 @@
name: Test E2E Desktop Client
on:
pull_request:
types: [labeled, opened, synchronize, reopened]
workflow_dispatch:
jobs:
test:
if: ${{ github.repository == 'hashicorp/boundary-ui' && contains(github.event.pull_request.labels.*.name, 'desktop')}}
name: Run Desktop E2E Tests
runs-on: ubuntu-22.04
env:
ENOS_VAR_boundary_edition: "ent"
ENOS_VAR_e2e_debug_no_run: true
ENOS_VAR_boundary_license_path: "./license.hclic"
SETUP_CLI: true
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: 20
cache: "yarn"
cache-dependency-path: |
yarn.lock
ui/desktop/electron-app/yarn.lock
- name: Set up Terraform
uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36
- name: Set up Enos
uses: hashicorp/action-setup-enos@b9fa53484a1e8fdcc7b02a118bcf01d65b9414c9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Vault CLI
run: |
wget https://releases.hashicorp.com/vault/1.12.2/vault_1.12.2_linux_amd64.zip -O /tmp/vault.zip
unzip /tmp/vault.zip -d /usr/local/bin
- name: Checkout boundary-enterprise
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
repository: hashicorp/boundary-enterprise
# ref: ${{ github.event.inputs.boundary-enterprise-branch }}
path: support/src/boundary-enterprise
token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- name: GH fix for localhost resolution
run: |
cat /etc/hosts && echo "-----------"
sudo sed -i 's/::1 *localhost ip6-localhost ip6-loopback/::1 ip6 -localhost ip6-loopback/g' /etc/hosts
cat /etc/hosts
ssh -V
echo "127.0.0.1 localhost boundary" | sudo tee -a /etc/hosts
echo "127.0.0.1 localhost worker" | sudo tee -a /etc/hosts
echo "127.0.0.1 localhost vault" | sudo tee -a /etc/hosts
# TODO: Build image ourselves in case we don't want to use latest?
- name: Get Boundary docker image
run: |
docker pull hashicorp/boundary-enterprise:latest
docker save hashicorp/boundary-enterprise:latest | gzip > /tmp/boundary-enterprise.zip
# TODO: Set up license in a better way? Use directly rather than writing to file and pull from secrets manager
- name: Set up test infra
id: infra
run: |
echo "${{ secrets.BOUNDARY_ENT_LICENSE }}" > ./support/src/boundary-enterprise/enos/license.hclic
ssh-keygen -N '' -t ed25519 -f ~/.ssh/github_enos
mkdir -p ./enos/terraform-plugin-cache
export ENOS_VAR_enos_user=$GITHUB_ACTOR && \
export ENOS_VAR_aws_ssh_private_key_path=~/.ssh/github_enos && \
export ENOS_VAR_boundary_docker_image_name=hashicorp/boundary-enterprise:latest && \
export ENOS_VAR_boundary_docker_image_file=/tmp/boundary-enterprise.zip && \
enos scenario launch --timeout 60m0s --chdir ./support/src/boundary-enterprise/enos e2e_ui_docker_ent builder:crt
- name: Install dependencies
run: |
yarn install --immutable
cd e2e-tests
yarn playwright install --with-deps
# Runner is headless so we need to enable a display to run the client
- name: Run Tests
run: |
source <(bash ./support/src/boundary-enterprise/enos/scripts/test_e2e_env.sh)
cd e2e-tests
export DISPLAY=:99
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
yarn run desktop
- name: Upload Playwright report
if: ${{ failure() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: playwright-report
path: e2e-tests/playwright-report
- name: Clean up test infra
if: ${{ always() }}
run: |
export ENOS_VAR_enos_user=$GITHUB_ACTOR && \
export ENOS_VAR_aws_ssh_private_key_path=~/.ssh/github_enos && \
enos scenario destroy --timeout 60m0s --chdir ./support/src/boundary-enterprise/enos e2e_ui_docker_ent builder:crt
+1 -1
View File
@@ -7,7 +7,7 @@ on:
jobs:
trigger-gha-release:
runs-on: ubuntu-latest
runs-on: ${{ fromJSON(vars.RUNNER) }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Release description
-1
View File
@@ -21,4 +21,3 @@ else
# This is to allow interaction with the terminal for commitizen
exec < /dev/tty && npx git-cz --hook || true
fi
+3 -3
View File
@@ -12,8 +12,8 @@ insert_final_newline = true
indent_style = space
indent_size = 2
[*.{diff,md}]
trim_trailing_whitespace = false
[*.hbs]
insert_final_newline = false
[*.{diff,md}]
trim_trailing_whitespace = false
-8
View File
@@ -1,12 +1,4 @@
{
/**
Ember CLI sends analytics information by default. The data is completely
anonymous, but there are times when you might want to disable this behavior.
Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"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.
+1 -12
View File
@@ -1,25 +1,14 @@
# unconventional js
/blueprints/*/files/
/vendor/
# compiled output
/declarations/
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/coverage/
!.*
.*/
.eslintcache
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
+1 -1
View File
@@ -56,7 +56,7 @@ module.exports = {
extends: ['plugin:n/recommended'],
},
{
// Test files:
// test files
files: ['tests/**/*-test.{js,ts}'],
extends: ['plugin:qunit/recommended'],
rules: {
+25
View File
@@ -0,0 +1,25 @@
# compiled output
/dist/
/declarations/
# dependencies
/node_modules/
# misc
/.env*
/.pnp*
/.eslintcache
/coverage/
/npm-debug.log*
/testem.log
/yarn-error.log
# ember-try
/.node_modules.ember-try/
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
# broccoli-debug
/DEBUG/
+2 -6
View File
@@ -2,11 +2,7 @@
/dist/
/tmp/
# dependencies
/bower_components/
# misc
/.bowerrc
/.editorconfig
/.ember-cli
/.env*
@@ -21,18 +17,18 @@
/.template-lintrc.js
/.travis.yml
/.watchmanconfig
/bower.json
/CONTRIBUTING.md
/ember-cli-build.js
/testem.js
/tests/
/tsconfig.declarations.json
/tsconfig.json
/yarn-error.log
/yarn.lock
.gitkeep
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
+1 -13
View File
@@ -1,25 +1,13 @@
# unconventional js
/blueprints/*/files/
/vendor/
# compiled output
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/coverage/
!.*
.eslintcache
.lint-todo/
.*/
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
+2
View File
@@ -3,6 +3,8 @@
* SPDX-License-Identifier: BUSL-1.1
*/
'use strict';
module.exports = {
overrides: [
{
+1 -1
View File
@@ -1,3 +1,3 @@
{
"ignore_dirs": ["tmp", "dist"]
"ignore_dirs": ["dist"]
}
+1 -1
View File
@@ -21,7 +21,7 @@ This addon contains the API data access layer for Boundary.
## Add API to an App
Add this addon to an Ember application's `devDependencies` as:
`"api": "*"`, for applications included in this monorepo.
`"api": "workspace:*"`, for applications included in this monorepo.
Since this addon also includes Mirage mocks, be sure to install
`ember-cli-mirage` and add the following config to your UI project:
@@ -4,7 +4,7 @@
*/
import ModelAbility from './model';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
/**
* Provides abilities for channel recordings.
@@ -4,7 +4,7 @@
*/
import ModelAbility from './model';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
/**
* Provides abilities for credential store.
*/
+1 -1
View File
@@ -4,7 +4,7 @@
*/
import ModelAbility from './model';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
class InvalidRolePrincipalTypeError extends Error {
name = 'InvalidRolePrincipalTypeError';
+7 -2
View File
@@ -115,7 +115,7 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
* @return {Promise} promise
*/
async query(store, schema, query) {
const queryObject = structuredClone(query);
const { batchLimit, ...queryObject } = query;
let result;
let data = [];
@@ -126,8 +126,10 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
result = await super.query(store, schema, query);
return prenormalizeArrayResponse(result);
}
// Run this loop as long as the response_type is delta,
// which indicates that there are more items in the list
// or the batch size has not been reached
do {
result = await super.query(store, schema, queryObject);
//add the result items to a data array
@@ -136,7 +138,10 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
//pass in the list token for subsequent calls to fetch the remaining list items
queryObject.list_token = result.list_token;
}
} while (result && result.response_type === 'delta');
} while (
result?.response_type === 'delta' &&
(!batchLimit || data.length < batchLimit)
);
result.items = data;
return prenormalizeArrayResponse(result);
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
import { getOwner, setOwner } from '@ember/application';
import { generateMQLExpression } from '../utils/mql-query';
import { paginateResults } from '../utils/paginate-results';
@@ -43,7 +43,10 @@ const fetchControllerData = async (context, next) => {
// If we get an error or cache daemon is unavailable, fall back to calling the API
context.request.data.query = remainingQuery;
const results = await next(context.request);
const models = results.content.toArray();
// As a result of https://rfcs.emberjs.com/id/0846-ember-data-deprecate-proxies/ we cannot use proxy array methods like .toArray
// use slice() instead as indicated in the RFC.
const models = results.content.slice();
const paginatedResult = paginateResults(models, page, pageSize);
paginatedResult.meta = { totalItems: models.length };
+130 -68
View File
@@ -4,7 +4,7 @@
*/
import { modelIndexes } from 'api/services/indexed-db';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
import { getOwner, setOwner } from '@ember/application';
import { queryIndexedDb } from '../utils/indexed-db-query';
import { paginateResults } from '../utils/paginate-results';
@@ -17,11 +17,15 @@ import { hashCode } from '../utils/hash-code';
export default class IndexedDbHandler {
@service indexedDb;
batchLimit = 10_000;
constructor(context) {
setOwner(this, getOwner(context));
}
async request(context, next) {
const { batchLimit } = this;
switch (context.request.op) {
case 'query': {
const { store, data } = context.request;
@@ -52,84 +56,54 @@ export default class IndexedDbHandler {
if (!peekIndexedDB) {
const tokenKey = `${type}-${hashCode(remainingQuery)}`;
let payload;
let listToken;
let writeToIndexedDbPromise;
if (storeToken) {
listToken = await indexedDb.token.get(tokenKey);
const tokenObj = await indexedDb.token.get(tokenKey);
listToken = tokenObj?.token;
}
let payload;
try {
payload = await adapter.query(store, schema, {
...remainingQuery,
list_token: listToken?.token,
});
} catch (e) {
// If we get an invalid list token, we'll delete the token and
// clear the DB and try again without a token.
if (
e?.errors[0].status === 400 &&
e?.errors[0].code === 'invalid list token'
) {
await indexedDb[type].clear();
// Delete all tokens of the same resource type so we don't keep clearing the DB.
// Even if other tokens may still be valid, we might have cleared data that they
// depended on so we should clear all tokens of the same type when clearing the DB.
const tokenKeys = await indexedDb.token
.where(':id')
.startsWith(type)
.primaryKeys();
await indexedDb.token.bulkDelete(tokenKeys);
do {
try {
payload = await adapter.query(store, schema, {
...remainingQuery,
list_token: listToken,
batchLimit: batchLimit,
});
// await the previous writeToIndexedDbPromise before writing to indexedDb again
if (writeToIndexedDbPromise) {
await writeToIndexedDbPromise;
}
} catch (err) {
payload = await this.retryQueryFailure({
err,
indexedDb,
type,
adapter,
store,
schema,
remainingQuery,
});
} else {
throw e;
}
}
listToken = payload.list_token;
// Store the token we just got back from the payload if it exists
if (payload.list_token && storeToken) {
await indexedDb.token.put({
id: tokenKey,
token: payload.list_token,
});
}
// Remove any records from the DB if the API indicates they've been deleted
if (payload.removed_ids?.length > 0) {
await indexedDb[type].bulkDelete(payload.removed_ids);
}
// This is a temporary fix of clearing the DB (specifically for auth-methods)
// since we are not storing the token we do not get back a list of removed_ids
// from the API call and we do not want deleted items from showing in list view.
if (!storeToken) {
await indexedDb[type].clear();
}
const normalizedPayload = serializer.normalizeResponse(
store,
schema,
payload,
null,
'query',
);
const { data: payloadData } = normalizedPayload;
// Store the new data we just got back from the API refresh
const items = payloadData.map((datum) =>
this.indexedDb.normalizeData({
data: datum,
cleanData: true,
schema,
// Don't await immediately and let the next query run while we write to indexedDb
writeToIndexedDbPromise = this.writeToIndexedDb({
payload,
storeToken,
indexedDb,
tokenKey,
type,
serializer,
}),
);
store,
schema,
});
} while (payload.response_type === 'delta');
await indexedDb[type].bulkPut(items);
await writeToIndexedDbPromise;
}
const indexedDbResults = await queryIndexedDb(
@@ -163,10 +137,98 @@ export default class IndexedDbHandler {
// or EmberArray since the ember store query method asserts it has to be an array
// so we can't just return an object.
records.meta = { totalItems: indexedDbResults.length };
return records;
}
default:
return next(context.request);
}
}
async retryQueryFailure({
err,
indexedDb,
type,
adapter,
store,
schema,
remainingQuery,
}) {
// If we get an invalid list token, we'll delete the token and
// clear the DB and try again without a token.
if (
err?.errors[0].status === 400 &&
err?.errors[0].code === 'invalid list token'
) {
await indexedDb[type].clear();
// Delete all tokens of the same resource type so we don't keep clearing the DB.
// Even if other tokens may still be valid, we might have cleared data that they
// depended on so we should clear all tokens of the same type when clearing the DB.
const tokenKeys = await indexedDb.token
.where(':id')
.startsWith(type)
.primaryKeys();
await indexedDb.token.bulkDelete(tokenKeys);
return await adapter.query(store, schema, {
...remainingQuery,
});
} else {
throw err;
}
}
async writeToIndexedDb({
payload,
storeToken,
indexedDb,
tokenKey,
type,
serializer,
store,
schema,
}) {
// Store the token we just got back from the payload if it exists
if (payload.list_token && storeToken) {
await indexedDb.token.put({
id: tokenKey,
token: payload.list_token,
});
}
// Remove any records from the DB if the API indicates they've been deleted
if (payload.removed_ids?.length > 0) {
await indexedDb[type].bulkDelete(payload.removed_ids);
}
// This is a temporary fix of clearing the DB (specifically for auth-methods)
// since we are not storing the token we do not get back a list of removed_ids
// from the API call and we do not want deleted items from showing in list view.
if (!storeToken) {
await indexedDb[type].clear();
}
const normalizedPayload = serializer.normalizeResponse(
store,
schema,
payload,
null,
'query',
);
const { data: payloadData } = normalizedPayload;
// Store the new data we just got back from the API refresh
const items = payloadData.map((datum) =>
this.indexedDb.normalizeData({
data: datum,
cleanData: true,
schema,
serializer,
}),
);
await indexedDb[type].bulkPut(items);
}
}
+2 -2
View File
@@ -47,8 +47,8 @@ export default class AccountModel extends GeneratedAccountModel {
* @type {string}
*/
get accountName() {
const { email, full_name, login_name } = this;
return email || full_name || login_name;
const { email, full_name, login_name, subject } = this;
return email || full_name || login_name || subject;
}
// =methods
+1 -1
View File
@@ -6,7 +6,7 @@
import Model from '@ember-data/model';
import { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
/**
* Base model class provides common functionality for all models.
+1 -1
View File
@@ -7,7 +7,7 @@ import GeneratedGroupModel from '../generated/models/group';
import { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
export default class GroupModel extends GeneratedGroupModel {
// =services
+8 -6
View File
@@ -4,6 +4,7 @@
*/
import GeneratedHostCatalogModel from '../generated/models/host-catalog';
import { tracked } from '@glimmer/tracking';
export const TYPE_HOST_CATALOG_STATIC = 'static';
export const TYPE_HOST_CATALOG_DYNAMIC = 'plugin';
@@ -40,7 +41,8 @@ export const STATIC_CREDENTIAL_FIELDS = ['access_key_id, secret_access_key'];
export default class HostCatalogModel extends GeneratedHostCatalogModel {
// =attributes
#credentialType;
@tracked _credentialTypeValue;
/**
* True if the host catalog is static.
* @type {boolean}
@@ -62,14 +64,14 @@ export default class HostCatalogModel extends GeneratedHostCatalogModel {
* @type {string}
*/
get credentialType() {
if (!this.#credentialType) {
if (!this._credentialTypeValue) {
if (DYNAMIC_CREDENTIAL_FIELDS.some((field) => this[field])) {
this.#credentialType = TYPE_CREDENTIAL_DYNAMIC;
return TYPE_CREDENTIAL_DYNAMIC;
} else {
this.#credentialType = TYPE_CREDENTIAL_STATIC;
return TYPE_CREDENTIAL_STATIC;
}
}
return this.#credentialType;
return this._credentialTypeValue;
}
/**
@@ -77,7 +79,7 @@ export default class HostCatalogModel extends GeneratedHostCatalogModel {
* @type {string}
*/
set credentialType(type) {
this.#credentialType = type;
this._credentialTypeValue = type;
}
/**
+1 -1
View File
@@ -5,7 +5,7 @@
import GeneratedRoleModel from '../generated/models/role';
import { attr } from '@ember-data/model';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
export const GRANT_SCOPE_THIS = 'this';
export const GRANT_SCOPE_CHILDREN = 'children';
+1 -1
View File
@@ -5,7 +5,7 @@
import GeneratedSessionRecordingModel from '../generated/models/session-recording';
import { hasMany } from '@ember-data/model';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
export const TYPE_SESSION_RECORDING_SSH = 'ssh';
export const TYPES_SESSION_RECORDING = Object.freeze([
+1 -1
View File
@@ -7,7 +7,7 @@ import GeneratedSessionModel from '../generated/models/session';
import { equal } from '@ember/object/computed';
import { tracked } from '@glimmer/tracking';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
import { flattenObject } from '../utils/flatten-nested-object';
import { TYPES_CREDENTIAL_LIBRARY } from 'api/models/credential-library';
import { TYPE_CREDENTIAL_JSON } from 'api/models/credential';
+9 -6
View File
@@ -4,6 +4,7 @@
*/
import GeneratedStorageBucketModel from '../generated/models/storage-bucket';
import { tracked } from '@glimmer/tracking';
export const TYPE_STORAGE_BUCKET_PLUGIN = 'plugin';
export const TYPES_STORAGE_BUCKET = Object.freeze([TYPE_STORAGE_BUCKET_PLUGIN]);
@@ -26,7 +27,8 @@ export const TYPES_CREDENTIALS = Object.freeze([
export default class StorageBucketModel extends GeneratedStorageBucketModel {
// attributes
#credentialType;
@tracked _credentialTypeValue;
/**
* True if the storage bucket is a plugin.
* @type {boolean}
@@ -40,14 +42,14 @@ export default class StorageBucketModel extends GeneratedStorageBucketModel {
* @type {string}
*/
get credentialType() {
if (!this.#credentialType) {
if (!this._credentialTypeValue) {
if (this.role_arn) {
this.#credentialType = TYPE_CREDENTIAL_DYNAMIC;
return TYPE_CREDENTIAL_DYNAMIC;
} else {
this.#credentialType = TYPE_CREDENTIAL_STATIC;
return TYPE_CREDENTIAL_STATIC;
}
}
return this.#credentialType;
return this._credentialTypeValue;
}
/**
@@ -55,8 +57,9 @@ export default class StorageBucketModel extends GeneratedStorageBucketModel {
* @type {string}
*/
set credentialType(type) {
this.#credentialType = type;
this._credentialTypeValue = type;
}
/**
* True if the storage bucket is an unknown type.
* @type {boolean}
+1 -1
View File
@@ -5,7 +5,7 @@
import GeneratedTargetModel from '../generated/models/target';
import { attr } from '@ember-data/model';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
export const TYPE_TARGET_TCP = 'tcp';
export const TYPE_TARGET_SSH = 'ssh';
+6 -10
View File
@@ -244,12 +244,10 @@ export default class ApplicationSerializer extends RESTSerializer {
* @return {object}
*/
normalizeMissingArrays(store, primaryModelClass, payload) {
const attrDefs = store
.getSchemaDefinitionService()
.attributesDefinitionFor({ type: primaryModelClass.modelName });
const attrDefs = store.schema.fields({ type: primaryModelClass.modelName });
if (attrDefs) {
Object.keys(attrDefs).forEach((key) => {
if (!payload[key] && attrDefs[key]?.options?.emptyArrayIfMissing) {
attrDefs.keys().forEach((key) => {
if (!payload[key] && attrDefs.get(key)?.options?.emptyArrayIfMissing) {
payload[key] = [];
}
});
@@ -268,12 +266,10 @@ export default class ApplicationSerializer extends RESTSerializer {
* @return {object}
*/
normalizeMissingObjects(store, primaryModelClass, payload) {
const attrDefs = store
.getSchemaDefinitionService()
.attributesDefinitionFor({ type: primaryModelClass.modelName });
const attrDefs = store.schema.fields({ type: primaryModelClass.modelName });
if (attrDefs) {
Object.keys(attrDefs).forEach((key) => {
if (!payload[key] && attrDefs[key]?.options?.emptyObjectIfMissing) {
attrDefs.keys().forEach((key) => {
if (!payload[key] && attrDefs.get(key)?.options?.emptyObjectIfMissing) {
payload[key] = {};
}
});
@@ -28,6 +28,7 @@ export default class CredentialLibrarySerializer extends ApplicationSerializer {
case TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC:
return this.serializeVaultGeneric(...arguments);
case TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE:
return this.serializeVaultSshCertificate(...arguments);
default:
return super.serialize(...arguments);
}
@@ -61,4 +62,16 @@ export default class CredentialLibrarySerializer extends ApplicationSerializer {
return serialized;
}
}
serializeVaultSshCertificate() {
const serialized = super.serialize(...arguments);
if (serialized.attributes) {
const { key_type } = serialized.attributes;
if (key_type !== 'rsa' && key_type !== 'ecdsa') {
// If the key type is not RSA or ECDSA, set key_bits to null
serialized.attributes.key_bits = null;
}
return serialized;
}
}
}
+1 -1
View File
@@ -34,7 +34,7 @@ export default class HostCatalogSerializer extends ApplicationSerializer {
) {
if (options.isNestedAttribute) {
json.attributes[key] = null;
} else if (options.isNestedSecret && json.secrets[key]) {
} else if (options.isNestedSecret && json.secrets?.[key]) {
delete json.secrets[key];
if (Object.keys(json.secrets).length === 0) {
delete json.secrets;
@@ -4,7 +4,7 @@
*/
import Service from '@ember/service';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
/**
* Takes a POJO representing a query and converts it to a boolean expression
+1 -1
View File
@@ -56,7 +56,7 @@ class MemoryStorage {
*
* @example
* import Route from '@ember/routing/route';
* import { inject as service } from '@ember/service';
* import { service } from '@ember/service';
* export default class ApplicationRoute extends Route {
* @service storage;
* afterModel() {
+5 -1
View File
@@ -3,7 +3,11 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import Store, { CacheHandler } from '@ember-data/store';
// Importing 'Store' from 'ember-data/store' to get default configuration automatically.
// TODO: Remove eslint-disable after upgrading to eslint-plugin-ember >= v12.2.1
// eslint-disable-next-line ember/use-ember-data-rfc-395-imports
import Store from 'ember-data/store';
import { CacheHandler } from '@ember-data/store';
import RequestManager from '@ember-data/request';
import { LegacyNetworkHandler } from '@ember-data/legacy-compat';
import IndexedDbHandler from 'api/handlers/indexed-db-handler';
@@ -3,9 +3,7 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import Transform from '@ember-data/serializer/transform';
export default class AccountValueMapArrayTransform extends Transform {
export default class AccountValueMapArrayTransform {
deserialize(serialized) {
const accountValues = serialized || [];
return accountValues.map((accountValueString) => ({
@@ -18,4 +16,8 @@ export default class AccountValueMapArrayTransform extends Transform {
const accountValues = deserialized || [];
return accountValues.map(({ key, value }) => `${key}=${value}`);
}
static create() {
return new this();
}
}
+5 -2
View File
@@ -3,10 +3,9 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import Transform from '@ember-data/serializer/transform';
import { TrackedArray } from 'tracked-built-ins';
export default class ArrayTransform extends Transform {
export default class ArrayTransform {
deserialize(serialized) {
const arr = new TrackedArray(serialized || []);
return arr;
@@ -16,4 +15,8 @@ export default class ArrayTransform extends Transform {
const arr = deserialized || [];
return arr;
}
static create() {
return new this();
}
}
+5 -3
View File
@@ -3,9 +3,7 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import Transform from '@ember-data/serializer/transform';
export default class DurationTransform extends Transform {
export default class DurationTransform {
/**
* Normalize a duration string in the format "3.0001s" to milliseconds.
* The backend returns a precision of nanoseconds but we round to whole
@@ -37,4 +35,8 @@ export default class DurationTransform extends Transform {
maximumFractionDigits: 9,
})}s`;
}
static create() {
return new this();
}
}
@@ -3,9 +3,7 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import Transform from '@ember-data/serializer/transform';
export default class HostSourceIdArrayTransform extends Transform {
export default class HostSourceIdArrayTransform {
deserialize(serialized) {
const stringValues = serialized || [];
return stringValues.map(({ id: host_source_id, ...obj }) => ({
@@ -18,4 +16,8 @@ export default class HostSourceIdArrayTransform extends Transform {
const strings = deserialized || [];
return strings.map(({ host_source_id: id, ...obj }) => ({ id, ...obj }));
}
static create() {
return new this();
}
}
@@ -3,13 +3,12 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import Transform from '@ember-data/serializer/transform';
export default class ObjectAsArrayTransform extends Transform {
export default class ObjectAsArrayTransform {
deserialize(serialized) {
const obj = serialized || {};
return Object.entries(obj).map(([key, value]) => ({ key, value }));
}
serialize(deserialized) {
const array = deserialized || [];
@@ -24,4 +23,8 @@ export default class ObjectAsArrayTransform extends Transform {
return result;
}, {});
}
static create() {
return new this();
}
}
+5 -2
View File
@@ -3,10 +3,9 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import Transform from '@ember-data/serializer/transform';
import { TrackedObject } from 'tracked-built-ins';
export default class ObjectTransform extends Transform {
export default class ObjectTransform {
/**
* @param serialized
* @returns {object}
@@ -26,4 +25,8 @@ export default class ObjectTransform extends Transform {
}
return deserialized;
}
static create() {
return new this();
}
}
+5 -3
View File
@@ -3,9 +3,7 @@
* SPDX-License-Identifier: BUSL-1.1
*/
import Transform from '@ember-data/serializer/transform';
export default class StringArrayTransform extends Transform {
export default class StringArrayTransform {
deserialize(serialized) {
const stringValues = serialized || [];
return stringValues.map((value) => ({ value }));
@@ -15,4 +13,8 @@ export default class StringArrayTransform extends Transform {
const strings = deserialized || [];
return strings.map(({ value }) => value);
}
static create() {
return new this();
}
}
+7
View File
@@ -0,0 +1,7 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
// Ember-data no longer automatically installs BooleanTransform for apps.
export { BooleanTransform as default } from '@ember-data/serializer/transform';
@@ -3,4 +3,4 @@
* SPDX-License-Identifier: BUSL-1.1
*/
export { default } from 'rose/components/rose/nav/breadcrumbs';
export { DateTransform as default } from '@ember-data/serializer/transform';
@@ -3,4 +3,4 @@
* SPDX-License-Identifier: BUSL-1.1
*/
export { default, initialize } from 'core/initializers/deprecations';
export { NumberTransform as default } from '@ember-data/serializer/transform';
+7
View File
@@ -0,0 +1,7 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
// Ember-data no longer automatically installs StringTransform for apps.
export { StringTransform as default } from '@ember-data/serializer/transform';
+2 -1
View File
@@ -6,7 +6,6 @@
'use strict';
const EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
const { maybeEmbroider } = require('@embroider/test-setup');
module.exports = function (defaults) {
const app = new EmberAddon(defaults, {
@@ -19,6 +18,8 @@ module.exports = function (defaults) {
This build file does *not* influence how the addon or the app using it
behave. You most likely want to be modifying `./index.js` or app's build file
*/
const { maybeEmbroider } = require('@embroider/test-setup');
return maybeEmbroider(app, {
skipBabel: [
{
+2 -1
View File
@@ -50,7 +50,8 @@ export default factory.extend({
}
case TYPE_AUTH_METHOD_OIDC:
return {
issuer: faker.internet.ip(),
issuer:
Math.random() > 0.5 ? faker.internet.ip() : faker.internet.ipv6(),
subject: 'sub',
email: faker.internet.email(),
full_name: faker.person.fullName(),
@@ -39,7 +39,8 @@ export default factory.extend({
switch (this.type) {
case 'vault':
return {
address: faker.internet.ip(),
address:
Math.random() > 0.5 ? faker.internet.ip() : faker.internet.ipv6(),
namespace: faker.word.words(1),
ca_cert: 'ca-cert-123',
tls_server_name: faker.internet.domainName(),
+5 -3
View File
@@ -43,10 +43,12 @@ export default factory.extend({
},
preferred_endpoints() {
if (this.type === 'plugin') {
const enpointsAmount = faker.number.int({ min: 1, max: 5 });
const endpointsAmount = faker.number.int({ min: 1, max: 5 });
let result = [];
for (let i = 0; i < enpointsAmount; ++i) {
result.push(faker.internet.ip());
for (let i = 0; i < endpointsAmount; ++i) {
result.push(
Math.random() > 0.5 ? faker.internet.ip() : faker.internet.ipv6(),
);
}
return result;
}
+3 -1
View File
@@ -36,7 +36,9 @@ export default factory.extend({
const addressesAmount = Math.floor(Math.random() * 6) + 1;
let result = [];
for (let i = 0; i < addressesAmount; ++i) {
result.push(faker.internet.ip());
result.push(
Math.random() > 0.5 ? faker.internet.ip() : faker.internet.ipv6(),
);
}
return result;
},
@@ -16,6 +16,9 @@ export default Factory.extend({
updated_time: () => faker.date.recent(),
version: () => faker.number.int(),
attributes: () => {
return { address: faker.internet.ipv6() };
return {
address:
Math.random() > 0.5 ? faker.internet.ip() : faker.internet.ipv6(),
};
},
});
+34 -24
View File
@@ -10,8 +10,10 @@
"scripts": {
"build:development": "ember build",
"build": "ember build --environment=production",
"lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
"lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"",
"lint": "concurrently \"yarn:lint:*(!fix)\" --names \"lint:\"",
"lint:fix": "concurrently \"yarn:lint:*:fix\" --names \"fix:\"",
"lint:hbs": "ember-template-lint .",
"lint:hbs:fix": "ember-template-lint . --fix",
"lint:js": "eslint .",
"lint:js:fix": "eslint . --fix",
"format": "concurrently \"npm:format:*\" --names \"format:\"",
@@ -23,54 +25,62 @@
"doc:toc": "doctoc README.md"
},
"dependencies": {
"@babel/core": "^7.26.10",
"@ember/string": "^4.0.0",
"dexie": "^3.2.4",
"ember-auto-import": "^2.8.1",
"ember-auto-import": "^2.10.0",
"ember-can": "^4.2.0",
"ember-cli-babel": "^8.2.0",
"ember-cli-htmlbars": "^6.2.0",
"ember-cli-htmlbars": "^6.3.0",
"ember-cli-mirage": "^3.0.3",
"ember-data": "~4.12.0",
"ember-data": "~5.3.12",
"miragejs": "^0.1.48",
"tracked-built-ins": "^3.1.1"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.21.3",
"@babel/plugin-proposal-decorators": "^7.21.0",
"@ember/optional-features": "^2.0.0",
"@ember/string": "^3.0.1",
"@ember/test-helpers": "^4.0.4",
"@embroider/test-setup": "^2.1.1",
"@babel/eslint-parser": "^7.25.1",
"@babel/plugin-proposal-decorators": "^7.24.7",
"@ember/optional-features": "^2.1.0",
"@ember/test-helpers": "^4.0.5",
"@ember/test-waiters": "^4.1.0",
"@embroider/test-setup": "^4.0.0",
"@faker-js/faker": "^8.0.2",
"@glimmer/component": "^1.1.2",
"@glimmer/tracking": "^1.1.2",
"broccoli-asset-rev": "^3.0.0",
"concurrently": "^9.1.0",
"doctoc": "^2.2.0",
"ember-cli": "^5.12.0",
"ember-cli": "~5.12.0",
"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-exam": "^8.0.0",
"ember-load-initializers": "^2.1.2",
"ember-page-title": "^7.0.0",
"ember-page-title": "^8.2.3",
"ember-qunit": "^8.1.0",
"ember-resolver": "^10.0.0",
"ember-source": "~4.12.0",
"ember-resolver": "^12.0.1",
"ember-source": "~5.12.0",
"ember-source-channel-url": "^3.0.0",
"ember-template-lint": "^5.7.2",
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-ember": "^11.11.1",
"eslint-plugin-n": "^16.3.1",
"eslint-plugin-qunit": "^8.0.1",
"ember-template-lint": "^6.0.0",
"ember-try": "^3.0.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-ember": "^12.2.1",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-qunit": "^8.1.2",
"js-bexpr": "hashicorp/js-bexpr#9b4a4b54d85eba67fdfc0990133d1518d890b1e1",
"loader.js": "^4.7.0",
"prettier": "^3.0.0",
"prettier": "^3.3.3",
"qunit": "^2.22.0",
"qunit-dom": "^3.2.1",
"webpack": "^5.94.0"
"sinon": "^19.0.2",
"webpack": "^5.95.0"
},
"peerDependencies": {
"ember-source": ">= 4.0.0",
"sinon": "^19.0.2"
},
"engines": {
"node": "20.* || 22.*"
+6
View File
@@ -17,6 +17,12 @@ module.exports = {
// --no-sandbox is needed when running Chrome inside a container
process.env.CI ? '--no-sandbox' : null,
'--headless',
// Disable backgrounding renders for occluded windows
'--disable-backgrounding-occluded-windows',
// Disable renderer process backgrounding
'--disable-renderer-backgrounding',
// Disable task throttling of timer tasks from background pages
'--disable-background-timer-throttling',
'--disable-dev-shm-usage',
'--disable-gpu',
//'--disable-software-rasterizer',
@@ -4,7 +4,7 @@
*/
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
export default class ApplicationRoute extends Route {
// =services
@@ -2,4 +2,3 @@
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@@ -5,6 +5,6 @@
{{page-title "Dummy"}}
<h2 id="title">Welcome to Ember</h2>
<Hds::Text::Display @tag="h2" id="title">Welcome to Ember</Hds::Text::Display>
{{outlet}}
@@ -3,7 +3,7 @@
"packages": [
{
"name": "ember-cli",
"version": "4.12.1",
"version": "5.12.0",
"blueprints": [
{
"name": "addon",
@@ -11,7 +11,8 @@
"codemodsSource": "ember-addon-codemods-manifest@1",
"isBaseBlueprint": true,
"options": [
"--no-welcome"
"--no-welcome",
"--yarn"
]
}
]
+4 -12
View File
@@ -12,26 +12,18 @@ module.exports = async function () {
return {
scenarios: [
{
name: 'ember-lts-4.4',
name: 'ember-lts-4.12',
npm: {
devDependencies: {
'ember-source': '~4.4.0',
'ember-source': '~4.12.0',
},
},
},
{
name: 'ember-lts-4.8',
name: 'ember-lts-5.4',
npm: {
devDependencies: {
'ember-source': '~4.8.0',
},
},
},
{
name: 'ember-lts-4.4',
npm: {
devDependencies: {
'ember-source': '~4.4.0',
'ember-source': '~5.4.0',
},
},
},
+1 -1
View File
@@ -9,7 +9,7 @@ import {
setupTest as upstreamSetupTest,
} from 'ember-qunit';
// This file exists to provide wrappers around ember-qunit's / ember-mocha's
// This file exists to provide wrappers around ember-qunit's
// test setup functions. This way, you can easily extend the setup that is
// needed per test type.
@@ -0,0 +1,371 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import IndexedDbHandler from 'api/handlers/indexed-db-handler';
import RequestManager from '@ember-data/request';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { faker } from '@faker-js/faker';
import sinon from 'sinon';
import { assert } from '@ember/debug';
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
import TargetModel from 'api/models/target';
function createPaginatedResponseHandler(mirageRecords, { pageSize }) {
assert('pageSize is required', pageSize);
const pagesCount = mirageRecords.length / pageSize;
const results = [];
for (let i = 0; i < pagesCount; i++) {
const items = mirageRecords.slice(i * pageSize, (i + 1) * pageSize);
const isLastPage = i === pagesCount - 1;
const list_token = `list-token-${faker.string.nanoid({ min: 5, max: 5 })}`;
results.push({
items,
list_token,
response_type: !isLastPage ? 'delta' : 'complete',
});
}
function nextResult(listToken) {
const index = results.findIndex(
({ list_token }) => list_token === listToken,
);
const nextResult = index === -1 ? null : results[index + 1];
return nextResult;
}
// mirage handler compatible with paginated responses
return function (_schema, request) {
const listToken = request.queryParams.list_token;
if (!listToken) {
return results[0];
}
const result = nextResult(listToken);
if (!result) {
return new Response(
404,
{},
`No results found for list token "${listToken}"`,
);
}
return result;
};
}
module('Unit | Handler | indexed-db-handler', function (hooks) {
setupTest(hooks);
setupIndexedDb(hooks);
setupMirage(hooks);
let manager,
indexeddbHandler,
store,
applicationAdapter,
indexedbHandlerSpy,
applicationAdapterSpy;
hooks.beforeEach(async function setupIndexHandler() {
store = this.owner.lookup('service:store');
manager = new RequestManager();
indexeddbHandler = new IndexedDbHandler(store);
applicationAdapter = store.adapterFor('application');
// spy on all handler and application adapter methods
indexedbHandlerSpy = sinon.spy(indexeddbHandler);
applicationAdapterSpy = sinon.spy(applicationAdapter);
store.requestManager = manager;
manager.use([indexeddbHandler]);
});
module('fetching and batch loading', function (hooks) {
// `testBatchLimit` and `serverResultPageLimit` are intentionally difference
// so that multiple calls to the server are required to fetch a single batch,
// and these multiples can be asserted in the tests individually
const testBatchLimit = 10;
const serverResultPageLimit = 5;
let aliases, aliasResponseHandlerSpy;
hooks.beforeEach(function setupMirageData() {
indexeddbHandler.batchLimit = testBatchLimit;
aliases = this.server.createList('alias', 50);
const aliasResponseHandler = createPaginatedResponseHandler(
this.server.schema.aliases.all().models,
{ pageSize: serverResultPageLimit },
);
aliasResponseHandlerSpy = sinon.spy(aliasResponseHandler);
this.server.get('aliases', aliasResponseHandlerSpy);
});
test('it returns all data for a resource from the server', async function (assert) {
const results = await store.query('alias', {});
assert.strictEqual(
aliases.length,
results.length,
'all records are returned',
);
const aliasesSortedByCreatedTime = [...aliases].sort(
(a, b) => new Date(b.created_time) - new Date(a.created_time),
);
assert.deepEqual(
aliasesSortedByCreatedTime.map(({ name }) => name),
results.map(({ name }) => name),
'`name` property matches between the returned results and the mirage records sorted by created_time',
);
});
test('supports batching requests and writes to indexedDB', async function (assert) {
await store.query('alias', {});
assert.strictEqual(
indexedbHandlerSpy.writeToIndexedDb.callCount,
aliases.length / testBatchLimit,
'handler #writeToIndexedDb is called once for each batch',
);
assert.strictEqual(
applicationAdapterSpy.query.callCount,
aliases.length / testBatchLimit,
'application adapter #query is called once for each batch',
);
assert.strictEqual(
aliasResponseHandlerSpy.callCount,
aliases.length / serverResultPageLimit,
'server handler should be called once for each page',
);
});
test('it loads from indexeddb only and does not fetch from api, when peekIndexedDB option is used', async function (assert) {
const callCounts = {
get writeToIndexedDb() {
return indexedbHandlerSpy.writeToIndexedDb.callCount;
},
get aliasResponseHandler() {
return aliasResponseHandlerSpy.callCount;
},
};
// before first query, no data has been fetched or written to indexeddb
// the call counts should therefore be 0
assert.strictEqual(callCounts.aliasResponseHandler, 0);
assert.strictEqual(callCounts.writeToIndexedDb, 0);
const results = await store.query('alias', {});
assert.strictEqual(results.length, 50);
// call counts expected after first query
const expectedWriteToIndexedDbCallCount = 5;
const expectedResponseHandlerCallCount = 10;
// first `store.query()` calls api and writes batches to indexededdb
assert.strictEqual(
callCounts.aliasResponseHandler,
expectedResponseHandlerCallCount,
);
assert.strictEqual(
callCounts.writeToIndexedDb,
expectedWriteToIndexedDbCallCount,
);
await store.query('alias', {}, { peekIndexedDB: true });
assert.strictEqual(results.length, 50);
// second run does not increase call counts to api or writes to indexeddb
assert.strictEqual(
callCounts.aliasResponseHandler,
expectedResponseHandlerCallCount,
);
assert.strictEqual(
callCounts.writeToIndexedDb,
expectedWriteToIndexedDbCallCount,
);
});
});
module('sorting', function () {
test('it sorts by descending `created_time` by default', async function (assert) {
const target2020 = this.server.create('target', {
name: 'Target 2020',
created_time: '2020-01-01T00:00:00Z',
});
const target2021 = this.server.create('target', {
name: 'Target 2021',
created_time: '2021-01-01T00:00:00Z',
});
const target2022 = this.server.create('target', {
name: 'Target 2022',
created_time: '2022-01-01T00:00:00Z',
});
const target2023 = this.server.create('target', {
name: 'Target 2023',
created_time: '2023-01-01T00:00:00Z',
});
const shuffledTargets = faker.helpers.shuffle([
target2020,
target2021,
target2022,
target2023,
]);
this.server.get(
'targets',
createPaginatedResponseHandler(shuffledTargets, {
pageSize: 1,
}),
);
const results = await store.query('target', {});
assert.deepEqual(
results.map(({ name }) => name),
['Target 2023', 'Target 2022', 'Target 2021', 'Target 2020'],
);
});
});
module('option: pushToStore', function (hooks) {
let mirageTargets;
hooks.beforeEach(function () {
mirageTargets = this.server.createList('target', 5);
});
test('it pushes fetched results to the store by default', async function (assert) {
this.server.get(
'targets',
createPaginatedResponseHandler(mirageTargets, {
pageSize: 1,
}),
);
assert.strictEqual(mirageTargets.length, 5);
assert.strictEqual(store.peekAll('target').length, 0);
const results = await store.query('target', {});
assert.strictEqual(results.length, 5);
assert.ok(
results.every((result) => result instanceof TargetModel),
'results are ember data models',
);
assert.strictEqual(store.peekAll('target').length, 5);
});
test('it pushes fethed results to the store when pushToStore is true', async function (assert) {
this.server.get(
'targets',
createPaginatedResponseHandler(mirageTargets, {
pageSize: 1,
}),
);
assert.strictEqual(mirageTargets.length, 5);
assert.strictEqual(store.peekAll('target').length, 0);
const results = await store.query('target', {}, { pushToStore: true });
assert.strictEqual(results.length, 5);
assert.ok(
results.every((result) => result instanceof TargetModel),
'results are ember data models',
);
assert.strictEqual(store.peekAll('target').length, 5);
});
test('it does not push fetched results to the store when pushToStore is false', async function (assert) {
this.server.get(
'targets',
createPaginatedResponseHandler(mirageTargets, {
pageSize: 1,
}),
);
assert.strictEqual(mirageTargets.length, 5);
assert.strictEqual(store.peekAll('target').length, 0);
const results = await store.query('target', {}, { pushToStore: false });
assert.strictEqual(results.length, 5);
assert.ok(
results.every((result) => !(result instanceof TargetModel)),
'results are not ember data models',
);
assert.strictEqual(store.peekAll('target').length, 0);
});
});
test('it supports searching', async function (assert) {
this.server.create('target', {
name: 'Magical Target',
description: 'A target',
});
this.server.create('target', {
name: 'Target 2',
description: 'Target with magic',
});
this.server.createList('target', 4);
this.server.get(
'targets',
createPaginatedResponseHandler(this.server.schema.targets.all().models, {
pageSize: 1,
}),
);
const results = await store.query('target', {
query: { search: 'magic' },
});
assert.deepEqual(
results
// search results aren't returning in a consistent order so
// the sorting is used to be able to assert
.sort((a, b) => (a.name > b.name ? 1 : -1))
.map(({ name, description }) => ({ name, description })),
[
{
description: 'A target',
name: 'Magical Target',
},
{
description: 'Target with magic',
name: 'Target 2',
},
],
);
});
test('it supports filtering', async function (assert) {
this.server.create('target', {
name: 'specific-target',
});
this.server.createList('target', 5);
this.server.get(
'targets',
createPaginatedResponseHandler(this.server.schema.targets.all().models, {
pageSize: 1,
}),
);
const results = await store.query('target', {
query: { filters: { name: [{ equals: 'specific-target' }] } },
});
assert.strictEqual(results[0].name, 'specific-target');
});
});
@@ -231,4 +231,52 @@ module('Unit | Serializer | credential library', function (hooks) {
version: 1,
});
});
test('it serializes vault_ssh_certificate correctly when changing type to ed25519', function (assert) {
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('credential-library');
store.push({
data: {
id: '1',
type: 'credential-library',
attributes: {
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
version: 1,
name: 'Name',
description: 'Description',
path: '/vault/path',
username: 'user',
key_type: 'rsa',
key_bits: 100,
ttl: '100',
key_id: 'id',
extensions: [{ key: 'key', value: 'value' }],
critical_options: [{ key: 'key', value: 'value' }],
},
},
});
const record = store.peekRecord('credential-library', '1');
record.key_type = 'ed25519';
const snapshot = record._createSnapshot();
const serializedRecord = serializer.serialize(snapshot);
assert.deepEqual(serializedRecord, {
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
credential_store_id: null,
name: 'Name',
description: 'Description',
attributes: {
path: '/vault/path',
username: 'user',
key_type: 'ed25519',
key_bits: null,
ttl: '100',
key_id: 'id',
extensions: { key: 'value' },
critical_options: { key: 'value' },
},
version: 1,
});
});
});
+3 -3
View File
@@ -12,8 +12,8 @@ insert_final_newline = true
indent_style = space
indent_size = 2
[*.{diff,md}]
trim_trailing_whitespace = false
[*.hbs]
insert_final_newline = false
[*.{diff,md}]
trim_trailing_whitespace = false
-8
View File
@@ -1,12 +1,4 @@
{
/**
Ember CLI sends analytics information by default. The data is completely
anonymous, but there are times when you might want to disable this behavior.
Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"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.
+1 -13
View File
@@ -1,26 +1,14 @@
# unconventional js
/blueprints/*/files/
/vendor/
# compiled output
/declarations/
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/coverage/
!.*
.*/
.eslintcache
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
config/ember-try
+2 -1
View File
@@ -38,6 +38,7 @@ module.exports = {
files: [
'./.eslintrc.js',
'./.prettierrc.js',
'./.stylelintrc.js',
'./.template-lintrc.js',
'./ember-cli-build.js',
'./index.js',
@@ -56,7 +57,7 @@ module.exports = {
extends: ['plugin:n/recommended'],
},
{
// Test files:
// test files
files: ['tests/**/*-test.{js,ts}'],
extends: ['plugin:qunit/recommended'],
rules: {
+25
View File
@@ -0,0 +1,25 @@
# compiled output
/dist/
/declarations/
# dependencies
/node_modules/
# misc
/.env*
/.pnp*
/.eslintcache
/coverage/
/npm-debug.log*
/testem.log
/yarn-error.log
# ember-try
/.node_modules.ember-try/
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
# broccoli-debug
/DEBUG/
+4 -6
View File
@@ -2,11 +2,7 @@
/dist/
/tmp/
# dependencies
/bower_components/
# misc
/.bowerrc
/.editorconfig
/.ember-cli
/.env*
@@ -18,21 +14,23 @@
/.gitignore
/.prettierignore
/.prettierrc.js
/.stylelintignore
/.stylelintrc.js
/.template-lintrc.js
/.travis.yml
/.watchmanconfig
/bower.json
/CONTRIBUTING.md
/ember-cli-build.js
/testem.js
/tests/
/tsconfig.declarations.json
/tsconfig.json
/yarn-error.log
/yarn.lock
.gitkeep
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
+1 -13
View File
@@ -1,25 +1,13 @@
# unconventional js
/blueprints/*/files/
/vendor/
# compiled output
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/coverage/
!.*
.eslintcache
.lint-todo/
.*/
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
+2
View File
@@ -3,6 +3,8 @@
* SPDX-License-Identifier: BUSL-1.1
*/
'use strict';
module.exports = {
singleQuote: true,
printWidth: 80,
+8
View File
@@ -0,0 +1,8 @@
# unconventional files
/blueprints/*/files/
# compiled output
/dist/
# addons
/.node_modules.ember-try/
+10
View File
@@ -0,0 +1,10 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
'use strict';
module.exports = {
extends: ['stylelint-config-standard', 'stylelint-prettier/recommended'],
};
+1 -1
View File
@@ -1,3 +1,3 @@
{
"ignore_dirs": ["tmp", "dist"]
"ignore_dirs": ["dist"]
}
+1 -1
View File
@@ -21,7 +21,7 @@ This addon contains the authentication layer for Boundary.
## Add to an App
Add this addon to an Ember application's `devDependencies` as:
`"auth": "*"`, for applications included in this monorepo.
`"auth": "workspace:*"`, for applications included in this monorepo.
## Installation
+1 -1
View File
@@ -4,7 +4,7 @@
*/
import BaseAuthenticator from './base';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
import { reject } from 'rsvp';
import { waitForPromise } from '@ember/test-waiters';
+1 -1
View File
@@ -6,7 +6,7 @@
import BaseSessionStore from 'ember-simple-auth/session-stores/base';
import { resolve, reject } from 'rsvp';
import { get } from '@ember/object';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
/**
*
+1 -1
View File
@@ -6,7 +6,6 @@
'use strict';
const EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
const { maybeEmbroider } = require('@embroider/test-setup');
module.exports = function (defaults) {
const app = new EmberAddon(defaults, {
@@ -23,6 +22,7 @@ module.exports = function (defaults) {
behave. You most likely want to be modifying `./index.js` or app's build file
*/
const { maybeEmbroider } = require('@embroider/test-setup');
return maybeEmbroider(app, {
skipBabel: [
{
+35 -26
View File
@@ -8,8 +8,12 @@
"ember-addon"
],
"scripts": {
"lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
"lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"",
"lint": "concurrently \"yarn:lint:*(!fix)\" --names \"lint:\"",
"lint:fix": "concurrently \"yarn:lint:*:fix\" --names \"fix:\"",
"lint:css": "stylelint \"**/*.css\"",
"lint:css:fix": "concurrently \"yarn:lint:css -- --fix\"",
"lint:hbs": "ember-template-lint .",
"lint:hbs:fix": "ember-template-lint . --fix",
"lint:js": "eslint .",
"lint:js:fix": "eslint . --fix",
"format": "yarn run format:js",
@@ -21,51 +25,56 @@
"doc:toc": "doctoc README.md"
},
"dependencies": {
"ember-auto-import": "2.8.1",
"@babel/core": "^7.26.10",
"@ember/test-waiters": "^4.1.0",
"ember-auto-import": "^2.10.0",
"ember-cli-babel": "^8.2.0",
"ember-cli-htmlbars": "^6.2.0",
"ember-cli-htmlbars": "^6.3.0",
"ember-simple-auth": "^6.1.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.21.3",
"@babel/plugin-proposal-decorators": "^7.21.0",
"@ember/optional-features": "^2.0.0",
"@ember/string": "^3.0.1",
"@ember/test-helpers": "^4.0.4",
"@ember/test-waiters": "^3.1.0",
"@embroider/test-setup": "^2.1.1",
"@babel/eslint-parser": "^7.25.1",
"@babel/plugin-proposal-decorators": "^7.24.7",
"@ember/optional-features": "^2.1.0",
"@ember/test-helpers": "^4.0.5",
"@embroider/test-setup": "^4.0.0",
"@glimmer/component": "^1.1.2",
"@glimmer/tracking": "^1.1.2",
"broccoli-asset-rev": "^3.0.0",
"concurrently": "^9.1.0",
"doctoc": "^2.2.0",
"ember-cli": "^5.12.0",
"ember-cli": "~5.12.0",
"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-cookies": "^1.2.0",
"ember-disable-prototype-extensions": "^1.1.3",
"ember-export-application-global": "^2.0.1",
"ember-load-initializers": "^2.1.2",
"ember-page-title": "^7.0.0",
"ember-page-title": "^8.2.3",
"ember-qunit": "^8.1.0",
"ember-resolver": "^10.0.0",
"ember-source": "~4.12.0",
"ember-resolver": "^12.0.1",
"ember-source": "~5.12.0",
"ember-source-channel-url": "^3.0.0",
"ember-template-lint": "^5.7.2",
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-ember": "^11.11.1",
"eslint-plugin-n": "^16.3.1",
"eslint-plugin-qunit": "^8.0.1",
"ember-template-lint": "^6.0.0",
"ember-try": "^3.0.0",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-ember": "^12.2.1",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-qunit": "^8.1.2",
"loader.js": "^4.7.0",
"pretender": "^3.4.3",
"prettier": "^3.0.0",
"prettier": "^3.3.3",
"qunit": "^2.22.0",
"qunit-dom": "^3.2.1",
"webpack": "^5.94.0"
"stylelint": "^15.11.0",
"stylelint-config-standard": "^34.0.0",
"stylelint-prettier": "^4.1.0",
"webpack": "^5.95.0"
},
"peerDependencies": {
"ember-source": ">= 4.0.0"
},
"engines": {
"node": "20.* || 22.*"
+6
View File
@@ -17,6 +17,12 @@ module.exports = {
// --no-sandbox is needed when running Chrome inside a container
process.env.CI ? '--no-sandbox' : null,
'--headless',
// Disable backgrounding renders for occluded windows
'--disable-backgrounding-occluded-windows',
// Disable renderer process backgrounding
'--disable-renderer-backgrounding',
// Disable task throttling of timer tasks from background pages
'--disable-background-timer-throttling',
'--disable-dev-shm-usage',
'--disable-gpu',
//'--disable-software-rasterizer',
@@ -2,4 +2,3 @@
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
@@ -5,6 +5,6 @@
{{page-title "Dummy"}}
<h2 id="title">Welcome to Ember</h2>
<Hds::Text::Display @tag="h2" id="title">Welcome to Ember</Hds::Text::Display>
{{outlet}}
@@ -3,7 +3,7 @@
"packages": [
{
"name": "ember-cli",
"version": "4.12.2",
"version": "5.12.0",
"blueprints": [
{
"name": "addon",
@@ -11,7 +11,8 @@
"codemodsSource": "ember-addon-codemods-manifest@1",
"isBaseBlueprint": true,
"options": [
"--no-welcome"
"--no-welcome",
"--yarn"
]
}
]
+4 -4
View File
@@ -12,18 +12,18 @@ module.exports = async function () {
return {
scenarios: [
{
name: 'ember-lts-4.4',
name: 'ember-lts-4.12',
npm: {
devDependencies: {
'ember-source': '~4.4.0',
'ember-source': '~4.12.0',
},
},
},
{
name: 'ember-lts-4.8',
name: 'ember-lts-5.4',
npm: {
devDependencies: {
'ember-source': '~4.8.0',
'ember-source': '~5.4.0',
},
},
},
+1 -1
View File
@@ -9,7 +9,7 @@ import {
setupTest as upstreamSetupTest,
} from 'ember-qunit';
// This file exists to provide wrappers around ember-qunit's / ember-mocha's
// This file exists to provide wrappers around ember-qunit's
// test setup functions. This way, you can easily extend the setup that is
// needed per test type.
-8
View File
@@ -1,12 +1,4 @@
{
/**
Ember CLI sends analytics information by default. The data is completely
anonymous, but there are times when you might want to disable this behavior.
Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"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.
+1 -12
View File
@@ -1,25 +1,14 @@
# unconventional js
/blueprints/*/files/
/vendor/
# compiled output
/declarations/
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/coverage/
!.*
.*/
.eslintcache
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
+2 -6
View File
@@ -2,11 +2,7 @@
/dist/
/tmp/
# dependencies
/bower_components/
# misc
/.bowerrc
/.editorconfig
/.ember-cli
/.env*
@@ -21,18 +17,18 @@
/.template-lintrc.js
/.travis.yml
/.watchmanconfig
/bower.json
/CONTRIBUTING.md
/ember-cli-build.js
/testem.js
/tests/
/tsconfig.declarations.json
/tsconfig.json
/yarn-error.log
/yarn.lock
.gitkeep
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
+1 -13
View File
@@ -1,25 +1,13 @@
# unconventional js
/blueprints/*/files/
/vendor/
# compiled output
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/coverage/
!.*
.eslintcache
.lint-todo/
.*/
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/npm-shrinkwrap.json.ember-try
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try
+3
View File
@@ -12,5 +12,8 @@ module.exports = {
'no-curly-component-invocation': {
allow: ['app-name', 'company-name', 'company-copyright'],
},
'no-implicit-this': {
allow: ['app-name', 'company-name', 'company-copyright'],
},
},
};
+1 -1
View File
@@ -1,3 +1,3 @@
{
"ignore_dirs": ["tmp", "dist"]
"ignore_dirs": ["dist"]
}
+13 -11
View File
@@ -2,25 +2,27 @@
## Installation
* `git clone <repository-url>`
* `cd core`
* `yarn install`
- `git clone <repository-url>`
- `cd core`
- `yarn install`
## Linting
* `yarn lint:hbs`
* `yarn lint:js`
* `yarn lint:js --fix`
- `yarn lint:hbs`
- `yarn lint:js`
- `yarn lint:js --fix`
- `yarn lint`
- `yarn lint:fix`
## Running tests
* `ember test` – Runs the test suite on the current Ember version
* `ember test --server` – Runs the test suite in "watch mode"
* `ember try:each` – Runs the test suite against multiple Ember versions
- `yarn test` – Runs the test suite on the current Ember version
- `yarn test:ember --server` – Runs the test suite in "watch mode"
- `yarn test:ember-compatibility` – Runs the test suite against multiple Ember versions
## Running the dummy application
* `ember serve`
* Visit the dummy application at [http://localhost:4200](http://localhost:4200).
- `yarn start`
- Visit the dummy application at [http://localhost:4200](http://localhost:4200).
For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/).
+6 -3
View File
@@ -28,7 +28,8 @@ helpers.
## Add core to an App
Add this addon to an Ember application's `devDependencies` as:
`"core": "*"`, for applications included in this monorepo.
`"core": "workspace:*"`, for applications included in this monorepo.
## Installation
@@ -97,7 +98,7 @@ To render doc links in your application, be sure to configure the links in your
Ember config (see admin). Then reference doc links by keys:
```html
<DocLink @doc="account" @iconSize="large" />
<DocLink @doc="account" @iconSize="24" />
```
## Loading Helper
@@ -121,7 +122,7 @@ This addon exposes a service to hold all active scopes (org and project where av
To make use of the service, import it and initialize it using service injection.
```js
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
export default class ExampleRoute extends Route {
@service scope;
@@ -180,10 +181,12 @@ Before submitting your work, be sure to run auto-formatters
* `yarn start`
* Visit the dummy application at [http://localhost:4200](http://localhost:4200).
## Contributing
See monorepo README for more contribution instructions.
### Building ToC
To autogenerate a ToC (table of contents) for this README,
+1 -1
View File
@@ -4,7 +4,7 @@
*/
import BaseOIDCAuthenticator from 'auth/authenticators/oidc';
import { inject as service } from '@ember/service';
import { service } from '@ember/service';
/**
* An OIDC authenticator that handles flow kick-off and polling.
Loaded 100 of 800 files, more files were not shown because too many files have changed in this diff. Show more