From 7fb485ecf2b22ffb4f3da3c7763401ba6640bda7 Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Sun, 8 Mar 2026 16:33:24 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=B7=20Adds=20CI=20for=20running=20test?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/pr-quality-check.yml | 76 +-- package.json | 16 +- tests/components/item.test.js | 805 +++++++++++++++++++++--- tests/setup.js | 110 ++-- tests/unit/config-helpers.test.js | 256 ++++---- tests/unit/config-validator.test.js | 152 ++--- tests/unit/error-handler.test.js | 48 +- tests/unit/healthcheck.test.js | 34 +- tests/unit/smoke.test.js | 230 +++---- vitest.config.js | 83 +-- yarn.lock | 824 +++++++++++++++++++++---- 11 files changed, 1913 insertions(+), 721 deletions(-) diff --git a/.github/workflows/pr-quality-check.yml b/.github/workflows/pr-quality-check.yml index 1461e62d..61c52392 100644 --- a/.github/workflows/pr-quality-check.yml +++ b/.github/workflows/pr-quality-check.yml @@ -5,16 +5,12 @@ on: branches: ['master', 'develop'] paths-ignore: - '**.md' - - 'docs/**' - - '.github/ISSUE_TEMPLATE/**' - - '.github/PULL_REQUEST_TEMPLATE/**' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: - # Job 1: Lint the code lint: name: ๐Ÿ“ Lint Code runs-on: ubuntu-latest @@ -26,15 +22,14 @@ jobs: uses: actions/setup-node@v4 with: node-version: '20' - cache: 'npm' + cache: 'yarn' - name: ๐Ÿ“ฆ Install Dependencies - run: npm ci + run: yarn install --frozen-lockfile - name: ๐Ÿ” Run ESLint - run: npm run lint + run: yarn lint - # Job 2: Run tests test: name: ๐Ÿงช Run Tests runs-on: ubuntu-latest @@ -46,23 +41,14 @@ jobs: uses: actions/setup-node@v4 with: node-version: '20' - cache: 'npm' + cache: 'yarn' - name: ๐Ÿ“ฆ Install Dependencies - run: npm ci + run: yarn install --frozen-lockfile - name: ๐Ÿงช Run Tests - run: npm test + run: yarn test - - name: ๐Ÿ“Š Upload Coverage - if: always() - uses: actions/upload-artifact@v4 - with: - name: coverage-report - path: coverage/ - retention-days: 7 - - # Job 3: Build the app build: name: ๐Ÿ—๏ธ Build Application runs-on: ubuntu-latest @@ -74,13 +60,13 @@ jobs: uses: actions/setup-node@v4 with: node-version: '20' - cache: 'npm' + cache: 'yarn' - name: ๐Ÿ“ฆ Install Dependencies - run: npm ci + run: yarn install --frozen-lockfile - name: ๐Ÿ—๏ธ Build Project - run: npm run build + run: yarn build env: NODE_OPTIONS: --openssl-legacy-provider @@ -96,10 +82,22 @@ jobs: fi echo "โœ… Build successful" - # Job 4: Security audit + docker-smoke: + name: ๐Ÿณ Docker Smoke Test + runs-on: ubuntu-latest + continue-on-error: true + steps: + - name: ๐Ÿ›Ž๏ธ Checkout Code + uses: actions/checkout@v4 + + - name: ๐Ÿณ Build & Test Docker Image + run: sh tests/docker-smoke-test.sh + timeout-minutes: 10 + security: name: ๐Ÿ”’ Security Audit runs-on: ubuntu-latest + continue-on-error: true steps: - name: ๐Ÿ›Ž๏ธ Checkout Code uses: actions/checkout@v4 @@ -108,34 +106,10 @@ jobs: uses: actions/setup-node@v4 with: node-version: '20' - cache: 'npm' + cache: 'yarn' - name: ๐Ÿ“ฆ Install Dependencies - run: npm ci + run: yarn install --frozen-lockfile - name: ๐Ÿ”’ Run Security Audit - run: npm audit --production --audit-level=high - continue-on-error: true - - # Final job that depends on all others - quality-gate: - name: โœ… Quality Gate - runs-on: ubuntu-latest - needs: [lint, test, build] - if: always() - steps: - - name: ๐ŸŽฏ Check All Jobs Passed - run: | - if [ "${{ needs.lint.result }}" != "success" ]; then - echo "โŒ Lint job failed" - exit 1 - fi - if [ "${{ needs.test.result }}" != "success" ]; then - echo "โŒ Test job failed" - exit 1 - fi - if [ "${{ needs.build.result }}" != "success" ]; then - echo "โŒ Build job failed" - exit 1 - fi - echo "โœ… All quality checks passed!" + run: yarn audit --level high diff --git a/package.json b/package.json index 3d61b6c6..6a8df093 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ }, "devDependencies": { "@babel/preset-env": "^7.17.10", + "@vitest/ui": "^1.6.0", "@vue/cli-plugin-babel": "^4.5.15", "@vue/cli-plugin-eslint": "^4.5.15", "@vue/cli-plugin-pwa": "^4.5.15", @@ -62,7 +63,6 @@ "@vue/cli-service": "^4.5.19", "@vue/eslint-config-standard": "^4.0.0", "@vue/test-utils": "^1.3.6", - "@vitest/ui": "^1.6.0", "babel-eslint": "^10.0.1", "copy-webpack-plugin": "6.4.0", "eslint": "^6.8.0", @@ -73,6 +73,7 @@ "sass": "^1.38.0", "sass-loader": "^7.1.0", "typescript": "^5.4.4", + "vite-plugin-vue2": "^2.0.3", "vitest": "^1.6.0", "vue-cli-plugin-yaml": "^1.0.2", "vue-svg-loader": "^0.16.0", @@ -99,7 +100,18 @@ }, "parserOptions": { "parser": "babel-eslint" - } + }, + "overrides": [ + { + "files": ["tests/**", "vitest.config.js"], + "rules": { + "import/no-extraneous-dependencies": "off", + "no-undef": "off", + "global-require": "off", + "no-unused-vars": "off" + } + } + ] }, "babel": { "presets": [ diff --git a/tests/components/item.test.js b/tests/components/item.test.js index 7a9d135f..d168617b 100644 --- a/tests/components/item.test.js +++ b/tests/components/item.test.js @@ -1,79 +1,726 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; -import VTooltip from 'v-tooltip'; - -const localVue = createLocalVue(); -localVue.use(Vuex); -localVue.use(VTooltip); - -// Mock the Item component dependencies -const mockItem = { - id: 'test-1', - title: 'Test Item', - description: 'Test Description', - url: 'https://example.com', - icon: 'fas fa-rocket', -}; - -describe('Item Component Structure', () => { - let store; - - beforeEach(() => { - store = new Vuex.Store({ - state: { - config: { - appConfig: {}, - }, - }, - getters: { - appConfig: (state) => state.config.appConfig, - }, - }); - }); - - it('has required props', () => { - // This test verifies the item data structure - expect(mockItem).toHaveProperty('id'); - expect(mockItem).toHaveProperty('title'); - expect(mockItem).toHaveProperty('url'); - }); - - it('url is valid format', () => { - expect(mockItem.url).toMatch(/^https?:\/\//); - }); - - it('contains expected properties', () => { - expect(mockItem.title).toBe('Test Item'); - expect(mockItem.description).toBe('Test Description'); - }); -}); - -describe('Item Data Validation', () => { - it('validates required item fields', () => { - const validItem = { - title: 'Valid Item', - url: 'https://valid.com', - }; - - expect(validItem.title).toBeTruthy(); - expect(validItem.url).toBeTruthy(); - expect(validItem.url).toMatch(/^https?:\/\//); - }); - - it('rejects items without title', () => { - const invalidItem = { - url: 'https://example.com', - }; - - expect(invalidItem.title).toBeUndefined(); - }); - - it('rejects items without url', () => { - const invalidItem = { - title: 'Test', - }; - - expect(invalidItem.url).toBeUndefined(); - }); -}); +import { + describe, it, expect, beforeEach, afterEach, vi, +} from 'vitest'; +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import Vuex from 'vuex'; +import Item from '@/components/LinkItems/Item.vue'; +import router from '@/router'; + +vi.mock('axios', () => ({ default: { get: vi.fn(() => Promise.resolve({ data: {} })) } })); +vi.mock('@/router', () => ({ default: { push: vi.fn() } })); +vi.mock('@/utils/ErrorHandler', () => ({ default: vi.fn() })); +vi.mock('@/assets/interface-icons/interactive-editor-edit-mode.svg', () => ({ + default: { template: '' }, +})); + +const localVue = createLocalVue(); +localVue.use(Vuex); +localVue.directive('tooltip', {}); +localVue.directive('longPress', {}); +localVue.directive('clickOutside', {}); + +/** Factory โ€” accepts overrides for item, props, appConfig, storeState, etc. */ +function mountItem(overrides = {}) { + const item = overrides.item || { + id: 'test-1', + title: 'Test Item', + description: 'A test description', + url: 'https://example.com', + icon: 'fas fa-rocket', + }; + + const mutations = { + SET_MODAL_OPEN: vi.fn(), + REMOVE_ITEM: vi.fn(), + ...(overrides.mutations || {}), + }; + + const storeState = { + editMode: false, + config: { appConfig: overrides.appConfig || {} }, + ...(overrides.storeState || {}), + }; + + const store = new Vuex.Store({ + state: storeState, + getters: { + appConfig: (state) => state.config.appConfig, + iconSize: () => overrides.iconSize || 'medium', + getParentSectionOfItem: () => () => overrides.parentSection || { name: 'Default' }, + }, + mutations, + }); + + const wrapper = shallowMount(Item, { + localVue, + store, + propsData: { item, ...(overrides.props || {}) }, + mocks: { + $modal: { show: vi.fn(), hide: vi.fn() }, + $toasted: { show: vi.fn() }, + $t: (key) => key, + ...(overrides.mocks || {}), + }, + stubs: { + Icon: true, + ItemOpenMethodIcon: true, + StatusIndicator: true, + ContextMenu: true, + MoveItemTo: true, + EditItem: true, + EditModeIcon: true, + }, + }); + + return { wrapper, store, mutations }; +} + +let openSpy; +let clipboardSpy; + +beforeEach(() => { + openSpy = vi.spyOn(window, 'open').mockImplementation(() => {}); + clipboardSpy = vi.fn(() => Promise.resolve()); + Object.defineProperty(navigator, 'clipboard', { + value: { writeText: clipboardSpy }, + writable: true, + configurable: true, + }); + localStorage.getItem.mockReset(); + localStorage.setItem.mockReset(); +}); + +afterEach(() => { + vi.restoreAllMocks(); +}); + +describe('Computed: itemIcon', () => { + it('returns item.icon when set', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', icon: 'my-icon', + }, + }); + expect(wrapper.vm.itemIcon).toBe('my-icon'); + }); + + it('falls back to appConfig.defaultIcon', () => { + const { wrapper } = mountItem({ + item: { id: '1', title: 'X', url: '#' }, + appConfig: { defaultIcon: 'default-icon' }, + }); + expect(wrapper.vm.itemIcon).toBe('default-icon'); + }); + + it('returns falsy when neither is set', () => { + const { wrapper } = mountItem({ item: { id: '1', title: 'X', url: '#' } }); + expect(wrapper.vm.itemIcon).toBeFalsy(); + }); +}); + +describe('Computed: size', () => { + it('returns valid itemSize prop', () => { + const { wrapper } = mountItem({ props: { itemSize: 'large' } }); + expect(wrapper.vm.size).toBe('large'); + }); + + it('ignores invalid itemSize and falls back to store', () => { + const { wrapper } = mountItem({ props: { itemSize: 'bogus' }, iconSize: 'small' }); + expect(wrapper.vm.size).toBe('small'); + }); + + it('falls back to store iconSize getter', () => { + const { wrapper } = mountItem({ iconSize: 'small' }); + expect(wrapper.vm.size).toBe('small'); + }); + + it('defaults to medium', () => { + const { wrapper } = mountItem(); + expect(wrapper.vm.size).toBe('medium'); + }); +}); + +describe('Computed: makeColumnCount', () => { + it.each([ + [300, 1], [400, 2], [600, 3], [800, 4], [1100, 5], [1500, 0], + ])('sectionWidth %i โ†’ %i columns', (width, expected) => { + const { wrapper } = mountItem({ props: { sectionWidth: width } }); + expect(wrapper.vm.makeColumnCount).toBe(expected); + }); + + it('uses sectionDisplayData.itemCountX when set', () => { + const { wrapper } = mountItem({ + props: { sectionWidth: 300, sectionDisplayData: { itemCountX: 7 } }, + }); + expect(wrapper.vm.makeColumnCount).toBe(7); + }); +}); + +describe('Computed: makeClassList', () => { + it('includes size-{size}', () => { + const { wrapper } = mountItem({ props: { itemSize: 'small' } }); + expect(wrapper.vm.makeClassList).toContain('size-small'); + }); + + it('includes "short" when no icon', () => { + const { wrapper } = mountItem({ item: { id: '1', title: 'X', url: '#' } }); + expect(wrapper.vm.makeClassList).toContain('short'); + }); + + it('includes "add-new" when isAddNew', () => { + const { wrapper } = mountItem({ props: { isAddNew: true } }); + expect(wrapper.vm.makeClassList).toContain('add-new'); + }); + + it('includes "is-edit-mode" when editMode is true', () => { + const { wrapper } = mountItem({ storeState: { editMode: true, config: { appConfig: {} } } }); + expect(wrapper.vm.makeClassList).toContain('is-edit-mode'); + }); +}); + +describe('Computed: enableStatusCheck', () => { + it('item.statusCheck boolean overrides appConfig', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', statusCheck: false, + }, + appConfig: { statusCheck: true }, + }); + expect(wrapper.vm.enableStatusCheck).toBe(false); + }); + + it('falls back to appConfig.statusCheck', () => { + const { wrapper } = mountItem({ + item: { id: '1', title: 'X', url: '#' }, + appConfig: { statusCheck: true }, + }); + expect(wrapper.vm.enableStatusCheck).toBe(true); + }); + + it('defaults to false', () => { + const { wrapper } = mountItem({ item: { id: '1', title: 'X', url: '#' } }); + expect(wrapper.vm.enableStatusCheck).toBe(false); + }); +}); + +describe('Computed: statusCheckInterval', () => { + it('reads from item', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', statusCheckInterval: 30, + }, + }); + expect(wrapper.vm.statusCheckInterval).toBe(30); + }); + + it('falls back to appConfig', () => { + const { wrapper } = mountItem({ + item: { id: '1', title: 'X', url: '#' }, + appConfig: { statusCheckInterval: 15 }, + }); + expect(wrapper.vm.statusCheckInterval).toBe(15); + }); + + it('clamps to max 60', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', statusCheckInterval: 120, + }, + }); + expect(wrapper.vm.statusCheckInterval).toBe(60); + }); + + it('clamps values less than 1 to 0', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', statusCheckInterval: 0.5, + }, + }); + expect(wrapper.vm.statusCheckInterval).toBe(0); + }); +}); + +describe('Computed: accumulatedTarget', () => { + it('uses item.target first', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', target: 'workspace', + }, + }); + expect(wrapper.vm.accumulatedTarget).toBe('workspace'); + }); + + it('falls back to appConfig.defaultOpeningMethod', () => { + const { wrapper } = mountItem({ + item: { id: '1', title: 'X', url: '#' }, + appConfig: { defaultOpeningMethod: 'sametab' }, + }); + expect(wrapper.vm.accumulatedTarget).toBe('sametab'); + }); + + it('defaults to "newtab"', () => { + const { wrapper } = mountItem({ item: { id: '1', title: 'X', url: '#' } }); + expect(wrapper.vm.accumulatedTarget).toBe('newtab'); + }); +}); + +describe('Computed: anchorTarget', () => { + it.each([ + ['sametab', '_self'], + ['newtab', '_blank'], + ['parent', '_parent'], + ['top', '_top'], + ['modal', undefined], + ])('target "%s" โ†’ %s', (target, expected) => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', target, + }, + }); + expect(wrapper.vm.anchorTarget).toBe(expected); + }); + + it('returns _self in edit mode', () => { + const { wrapper } = mountItem({ + storeState: { editMode: true, config: { appConfig: {} } }, + }); + expect(wrapper.vm.anchorTarget).toBe('_self'); + }); +}); + +describe('Computed: hyperLinkHref', () => { + it('returns "#" in edit mode', () => { + const { wrapper } = mountItem({ + storeState: { editMode: true, config: { appConfig: {} } }, + }); + expect(wrapper.vm.hyperLinkHref).toBe('#'); + }); + + it.each(['modal', 'workspace', 'clipboard'])('returns "#" for %s target', (target) => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', target, + }, + }); + expect(wrapper.vm.hyperLinkHref).toBe('#'); + }); + + it('returns URL for normal targets', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', target: 'newtab', + }, + }); + expect(wrapper.vm.hyperLinkHref).toBe('https://x.com'); + }); +}); + +describe('Computed: unicodeOpeningIcon', () => { + it.each([ + ['newtab', '"\\f360"'], + ['sametab', '"\\f24d"'], + ['parent', '"\\f3bf"'], + ['top', '"\\f102"'], + ['modal', '"\\f2d0"'], + ['workspace', '"\\f0b1"'], + ['clipboard', '"\\f0ea"'], + ])('target "%s" โ†’ correct icon', (target, expected) => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', target, + }, + }); + expect(wrapper.vm.unicodeOpeningIcon).toBe(expected); + }); + + it('returns default icon for unknown target', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', target: 'unknown', + }, + }); + expect(wrapper.vm.unicodeOpeningIcon).toBe('"\\f054"'); + }); +}); + +describe('Filter: shortUrl', () => { + const { shortUrl } = Item.filters; + + it('extracts hostname from URL', () => { + expect(shortUrl('https://www.example.com/path?q=1')).toBe('www.example.com'); + }); + + it('handles IP addresses', () => { + expect(shortUrl('192.168.1.1')).toBe('192.168.1.1'); + }); + + it('returns empty string for falsy input', () => { + expect(shortUrl(null)).toBe(''); + expect(shortUrl(undefined)).toBe(''); + expect(shortUrl('')).toBe(''); + }); + + it('returns empty string for invalid input', () => { + expect(shortUrl('not-a-url')).toBe(''); + }); +}); + +describe('Methods: getTooltipOptions', () => { + it('returns empty object when no description or provider', () => { + const { wrapper } = mountItem({ item: { id: '1', title: 'X', url: '#' } }); + expect(wrapper.vm.getTooltipOptions()).toEqual({}); + }); + + it('includes description and provider in content', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', description: 'Desc', provider: 'Prov', + }, + }); + const { content } = wrapper.vm.getTooltipOptions(); + expect(content).toContain('Desc'); + expect(content).toContain('Prov'); + }); + + it('includes hotkey in content', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', description: 'D', hotkey: 3, + }, + }); + const { content } = wrapper.vm.getTooltipOptions(); + expect(content).toContain("'3'"); + }); + + it('shows edit text in edit mode', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', description: 'D', + }, + storeState: { editMode: true, config: { appConfig: {} } }, + }); + expect(wrapper.vm.getTooltipOptions().content).toBe( + 'interactive-editor.edit-section.edit-tooltip', + ); + }); + + it('placement is "left" when statusResponse exists', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: '#', description: 'D', + }, + }); + wrapper.vm.statusResponse = { message: 'ok' }; + expect(wrapper.vm.getTooltipOptions().placement).toBe('left'); + }); +}); + +describe('Methods: openItemSettings / closeEditMenu', () => { + it('openItemSettings sets editMenuOpen, shows modal, commits SET_MODAL_OPEN', () => { + const { wrapper, mutations } = mountItem(); + wrapper.vm.openItemSettings(); + expect(wrapper.vm.editMenuOpen).toBe(true); + expect(wrapper.vm.$modal.show).toHaveBeenCalledWith('EDIT_ITEM'); + expect(mutations.SET_MODAL_OPEN).toHaveBeenCalledWith(expect.anything(), true); + }); + + it('closeEditMenu clears editMenuOpen, hides modal, commits SET_MODAL_OPEN(false)', () => { + const { wrapper, mutations } = mountItem(); + wrapper.vm.editMenuOpen = true; + wrapper.vm.closeEditMenu(); + expect(wrapper.vm.editMenuOpen).toBe(false); + expect(wrapper.vm.$modal.hide).toHaveBeenCalledWith('EDIT_ITEM'); + expect(mutations.SET_MODAL_OPEN).toHaveBeenCalledWith(expect.anything(), false); + }); +}); + +describe('Methods: openDeleteItem', () => { + it('commits REMOVE_ITEM with correct payload', () => { + const { wrapper, mutations } = mountItem({ parentSection: { name: 'MySection' } }); + wrapper.vm.openDeleteItem(); + expect(mutations.REMOVE_ITEM).toHaveBeenCalledWith( + expect.anything(), + { itemId: 'test-1', sectionName: 'MySection' }, + ); + }); +}); + +describe('Methods: itemClicked', () => { + const event = (extra = {}) => ({ + preventDefault: vi.fn(), ctrlKey: false, altKey: false, ...extra, + }); + + it('in edit mode: preventDefault + openItemSettings', () => { + const { wrapper } = mountItem({ storeState: { editMode: true, config: { appConfig: {} } } }); + const e = event(); + const spy = vi.spyOn(wrapper.vm, 'openItemSettings'); + wrapper.vm.itemClicked(e); + expect(e.preventDefault).toHaveBeenCalled(); + expect(spy).toHaveBeenCalled(); + }); + + it('ctrl key: opens in new tab', () => { + const { wrapper } = mountItem(); + wrapper.vm.itemClicked(event({ ctrlKey: true })); + expect(openSpy).toHaveBeenCalledWith('https://example.com', '_blank'); + }); + + it('alt key: emits triggerModal', () => { + const { wrapper } = mountItem(); + wrapper.vm.itemClicked(event({ altKey: true })); + expect(wrapper.emitted().triggerModal).toBeTruthy(); + }); + + it('target modal: emits triggerModal', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', target: 'modal', + }, + }); + wrapper.vm.itemClicked(event()); + expect(wrapper.emitted().triggerModal).toBeTruthy(); + }); + + it('target workspace: calls router.push', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', target: 'workspace', + }, + }); + wrapper.vm.itemClicked(event()); + expect(router.push).toHaveBeenCalledWith({ name: 'workspace', query: { url: 'https://x.com' } }); + }); + + it('target clipboard: calls copyToClipboard', () => { + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', target: 'clipboard', + }, + }); + const spy = vi.spyOn(wrapper.vm, 'copyToClipboard'); + wrapper.vm.itemClicked(event()); + expect(spy).toHaveBeenCalledWith('https://x.com'); + }); + + it('always emits itemClicked', () => { + const { wrapper } = mountItem(); + wrapper.vm.itemClicked(event()); + expect(wrapper.emitted().itemClicked).toBeTruthy(); + }); + + it('skips smart-sort when disableSmartSort is set', () => { + const { wrapper } = mountItem({ appConfig: { disableSmartSort: true } }); + const spy = vi.spyOn(wrapper.vm, 'incrementMostUsedCount'); + wrapper.vm.itemClicked(event()); + expect(spy).not.toHaveBeenCalled(); + }); +}); + +describe('Methods: launchItem', () => { + it.each([ + ['newtab', '_blank'], + ['sametab', '_self'], + ])('%s calls window.open with %s', (method, target) => { + const { wrapper } = mountItem(); + wrapper.vm.launchItem(method, 'https://test.com'); + expect(openSpy).toHaveBeenCalledWith('https://test.com', target); + }); + + it('modal emits triggerModal', () => { + const { wrapper } = mountItem(); + wrapper.vm.launchItem('modal', 'https://test.com'); + expect(wrapper.emitted().triggerModal[0]).toEqual(['https://test.com']); + }); + + it('workspace calls router.push', () => { + const { wrapper } = mountItem(); + wrapper.vm.launchItem('workspace', 'https://test.com'); + expect(router.push).toHaveBeenCalledWith({ name: 'workspace', query: { url: 'https://test.com' } }); + }); + + it('clipboard calls copyToClipboard', () => { + const { wrapper } = mountItem(); + const spy = vi.spyOn(wrapper.vm, 'copyToClipboard'); + wrapper.vm.launchItem('clipboard', 'https://test.com'); + expect(spy).toHaveBeenCalledWith('https://test.com'); + }); + + it('closes context menu', () => { + const { wrapper } = mountItem(); + wrapper.vm.contextMenuOpen = true; + wrapper.vm.launchItem('newtab'); + expect(wrapper.vm.contextMenuOpen).toBe(false); + }); + + it('falls back to item.url when no link arg', () => { + const { wrapper } = mountItem({ + item: { id: '1', title: 'X', url: 'https://fallback.com' }, + }); + wrapper.vm.launchItem('newtab'); + expect(openSpy).toHaveBeenCalledWith('https://fallback.com', '_blank'); + }); +}); + +describe('Methods: openContextMenu / closeContextMenu', () => { + it('toggles contextMenuOpen and sets position', () => { + const { wrapper } = mountItem(); + wrapper.vm.openContextMenu({ clientX: 100, clientY: 200 }); + expect(wrapper.vm.contextMenuOpen).toBe(true); + expect(wrapper.vm.contextPos.posX).toBe(100 + window.pageXOffset); + expect(wrapper.vm.contextPos.posY).toBe(200 + window.pageYOffset); + }); + + it('closeContextMenu sets false', () => { + const { wrapper } = mountItem(); + wrapper.vm.contextMenuOpen = true; + wrapper.vm.closeContextMenu(); + expect(wrapper.vm.contextMenuOpen).toBe(false); + }); +}); + +describe('Methods: copyToClipboard', () => { + it('calls navigator.clipboard.writeText and shows toast', () => { + const { wrapper } = mountItem(); + wrapper.vm.copyToClipboard('hello'); + expect(clipboardSpy).toHaveBeenCalledWith('hello'); + expect(wrapper.vm.$toasted.show).toHaveBeenCalled(); + }); + + it('shows error when clipboard unavailable', async () => { + const ErrorHandler = (await import('@/utils/ErrorHandler')).default; + Object.defineProperty(navigator, 'clipboard', { + value: undefined, writable: true, configurable: true, + }); + const { wrapper } = mountItem(); + wrapper.vm.copyToClipboard('hello'); + expect(ErrorHandler).toHaveBeenCalled(); + expect(wrapper.vm.$toasted.show).toHaveBeenCalledWith( + 'Unable to copy, see log', + expect.objectContaining({ className: 'toast-error' }), + ); + }); +}); + +describe('Methods: incrementMostUsedCount / incrementLastUsedCount', () => { + it('increments existing count', () => { + localStorage.getItem.mockReturnValue(JSON.stringify({ 'item-1': 5 })); + const { wrapper } = mountItem(); + wrapper.vm.incrementMostUsedCount('item-1'); + const saved = JSON.parse(localStorage.setItem.mock.calls[0][1]); + expect(saved['item-1']).toBe(6); + }); + + it('initializes new items to 1', () => { + localStorage.getItem.mockReturnValue('{}'); + const { wrapper } = mountItem(); + wrapper.vm.incrementMostUsedCount('new-item'); + const saved = JSON.parse(localStorage.setItem.mock.calls[0][1]); + expect(saved['new-item']).toBe(1); + }); + + it('writes last-used timestamp', () => { + localStorage.getItem.mockReturnValue('{}'); + const { wrapper } = mountItem(); + const before = Date.now(); + wrapper.vm.incrementLastUsedCount('item-1'); + const saved = JSON.parse(localStorage.setItem.mock.calls[0][1]); + expect(saved['item-1']).toBeGreaterThanOrEqual(before); + }); +}); + +describe('Lifecycle: mounted', () => { + it('calls checkWebsiteStatus when enableStatusCheck is true', () => { + const spy = vi.spyOn(Item.mixins[0].methods, 'checkWebsiteStatus'); + mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', statusCheck: true, + }, + }); + expect(spy).toHaveBeenCalled(); + spy.mockRestore(); + }); + + it('sets up interval when statusCheckInterval > 0', () => { + vi.useFakeTimers(); + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', statusCheck: true, statusCheckInterval: 5, + }, + }); + expect(wrapper.vm.intervalId).toBeDefined(); + vi.useRealTimers(); + }); + + it('does nothing when statusCheck disabled', () => { + const spy = vi.spyOn(Item.mixins[0].methods, 'checkWebsiteStatus'); + mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', statusCheck: false, + }, + }); + expect(spy).not.toHaveBeenCalled(); + spy.mockRestore(); + }); +}); + +describe('Lifecycle: beforeDestroy', () => { + it('clears interval if intervalId exists', () => { + vi.useFakeTimers(); + const clearSpy = vi.spyOn(global, 'clearInterval'); + const { wrapper } = mountItem({ + item: { + id: '1', title: 'X', url: 'https://x.com', statusCheck: true, statusCheckInterval: 5, + }, + }); + const { intervalId } = wrapper.vm; + wrapper.destroy(); + expect(clearSpy).toHaveBeenCalledWith(intervalId); + vi.useRealTimers(); + }); +}); + +describe('Template rendering', () => { + it('renders item title and description', () => { + const { wrapper } = mountItem(); + expect(wrapper.find('.text').text()).toBe('Test Item'); + expect(wrapper.find('.description').text()).toBe('A test description'); + }); + + it('has correct wrapper classes', () => { + const { wrapper } = mountItem({ props: { itemSize: 'large', sectionWidth: 800 } }); + const div = wrapper.find('.item-wrapper'); + expect(div.classes()).toContain('wrap-size-large'); + expect(div.classes()).toContain('span-4'); + }); + + it('shows StatusIndicator only when enableStatusCheck', () => { + const { wrapper: off } = mountItem({ + item: { + id: '1', title: 'X', url: '#', statusCheck: false, + }, + }); + expect(off.find('statusindicator-stub').exists()).toBe(false); + + const { wrapper: on } = mountItem({ + item: { + id: '1', title: 'X', url: '#', statusCheck: true, + }, + }); + expect(on.find('statusindicator-stub').exists()).toBe(true); + }); + + it('shows EditModeIcon only in edit mode', () => { + const { wrapper: normal } = mountItem(); + expect(normal.find('editmodeicon-stub').exists()).toBe(false); + + const { wrapper: editing } = mountItem({ + storeState: { editMode: true, config: { appConfig: {} } }, + }); + expect(editing.find('editmodeicon-stub').exists()).toBe(true); + }); + + it('sets correct id on anchor', () => { + const { wrapper } = mountItem(); + expect(wrapper.find('a.item').attributes('id')).toBe('link-test-1'); + }); +}); diff --git a/tests/setup.js b/tests/setup.js index 5113fb3e..6e5112d9 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -1,54 +1,56 @@ -/** - * Global test setup file - * This file is run before all tests to configure the testing environment - */ - -import { config } from '@vue/test-utils'; - -// Suppress Vue warnings in tests -config.silent = true; - -// Mock console methods to avoid noise in test output -global.console = { - ...console, - // Uncomment to suppress console.log in tests - // log: vi.fn(), - // Uncomment to suppress console.debug in tests - // debug: vi.fn(), - // Keep warnings and errors visible - warn: console.warn, - error: console.error, -}; - -// Mock localStorage for tests -const localStorageMock = { - getItem: vi.fn(), - setItem: vi.fn(), - removeItem: vi.fn(), - clear: vi.fn(), -}; -global.localStorage = localStorageMock; - -// Mock sessionStorage for tests -const sessionStorageMock = { - getItem: vi.fn(), - setItem: vi.fn(), - removeItem: vi.fn(), - clear: vi.fn(), -}; -global.sessionStorage = sessionStorageMock; - -// Mock window.matchMedia (for responsive design tests) -Object.defineProperty(window, 'matchMedia', { - writable: true, - value: vi.fn().mockImplementation(query => ({ - matches: false, - media: query, - onchange: null, - addListener: vi.fn(), - removeListener: vi.fn(), - addEventListener: vi.fn(), - removeEventListener: vi.fn(), - dispatchEvent: vi.fn(), - })), -}); +/** + * Global test setup file + * This file is run before all tests to configure the testing environment + */ + +import Vue from 'vue'; + +// Suppress Vue warnings in tests +Vue.config.silent = true; + +// Suppress noisy console methods in test output +// Vue dev mode prints info messages (devtools, production tips) that clutter results +global.console = { + ...console, + info: vi.fn(), + // Uncomment to suppress console.log in tests + // log: vi.fn(), + // Uncomment to suppress console.debug in tests + // debug: vi.fn(), + // Keep warnings and errors visible + warn: console.warn, + error: console.error, +}; + +// Mock localStorage for tests +const localStorageMock = { + getItem: vi.fn(), + setItem: vi.fn(), + removeItem: vi.fn(), + clear: vi.fn(), +}; +global.localStorage = localStorageMock; + +// Mock sessionStorage for tests +const sessionStorageMock = { + getItem: vi.fn(), + setItem: vi.fn(), + removeItem: vi.fn(), + clear: vi.fn(), +}; +global.sessionStorage = sessionStorageMock; + +// Mock window.matchMedia (for responsive design tests) +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: vi.fn().mockImplementation(query => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), + removeListener: vi.fn(), + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}); diff --git a/tests/unit/config-helpers.test.js b/tests/unit/config-helpers.test.js index 7ec812f8..fb75874b 100644 --- a/tests/unit/config-helpers.test.js +++ b/tests/unit/config-helpers.test.js @@ -1,128 +1,128 @@ -import { describe, it, expect } from 'vitest'; -import { - makePageName, - makePageSlug, - formatConfigPath, - componentVisibility, - getCustomKeyShortcuts, -} from '@/utils/ConfigHelpers'; - -describe('ConfigHelpers - makePageName', () => { - it('converts page name to lowercase', () => { - expect(makePageName('My Page')).toBe('my-page'); - }); - - it('replaces spaces with hyphens', () => { - expect(makePageName('Multiple Word Page')).toBe('multiple-word-page'); - }); - - it('removes .yml extension', () => { - expect(makePageName('config.yml')).toBe('config'); - }); - - it('removes special characters', () => { - expect(makePageName('Page!@#$Name')).toBe('pagename'); - }); - - it('handles undefined input', () => { - expect(makePageName(undefined)).toBe('unnamed-page'); - }); - - it('handles null input', () => { - expect(makePageName(null)).toBe('unnamed-page'); - }); - - it('handles empty string', () => { - expect(makePageName('')).toBe('unnamed-page'); - }); -}); - -describe('ConfigHelpers - makePageSlug', () => { - it('creates correct slug format', () => { - expect(makePageSlug('My Page', 'home')).toBe('/home/my-page'); - }); - - it('handles page names with special chars', () => { - expect(makePageSlug('Config! Page', 'admin')).toBe('/admin/config-page'); - }); -}); - -describe('ConfigHelpers - formatConfigPath', () => { - it('leaves http URLs unchanged', () => { - const url = 'https://example.com/config.yml'; - expect(formatConfigPath(url)).toBe(url); - }); - - it('adds leading slash to relative paths', () => { - expect(formatConfigPath('config.yml')).toBe('/config.yml'); - }); - - it('keeps absolute paths unchanged', () => { - expect(formatConfigPath('/config.yml')).toBe('/config.yml'); - }); -}); - -describe('ConfigHelpers - componentVisibility', () => { - it('returns all visible by default when no config', () => { - const result = componentVisibility({}); - expect(result.pageTitle).toBe(true); - expect(result.navigation).toBe(true); - expect(result.searchBar).toBe(true); - expect(result.settings).toBe(true); - expect(result.footer).toBe(true); - }); - - it('hides components based on config', () => { - const appConfig = { - hideComponents: { - hideHeading: true, - hideNav: true, - }, - }; - const result = componentVisibility(appConfig); - expect(result.pageTitle).toBe(false); - expect(result.navigation).toBe(false); - expect(result.searchBar).toBe(true); - }); - - it('handles partial config correctly', () => { - const appConfig = { - hideComponents: { - hideFooter: true, - }, - }; - const result = componentVisibility(appConfig); - expect(result.footer).toBe(false); - expect(result.pageTitle).toBe(true); - }); -}); - -describe('ConfigHelpers - getCustomKeyShortcuts', () => { - it('extracts hotkeys from sections', () => { - const sections = [ - { - items: [ - { hotkey: 1, url: 'https://example.com' }, - { url: 'https://example.org' }, - ], - }, - ]; - const result = getCustomKeyShortcuts(sections); - expect(result).toHaveLength(1); - expect(result[0]).toEqual({ hotkey: 1, url: 'https://example.com' }); - }); - - it('returns empty array when no hotkeys', () => { - const sections = [{ items: [{ url: 'https://example.com' }] }]; - expect(getCustomKeyShortcuts(sections)).toEqual([]); - }); - - it('flattens hotkeys from multiple sections', () => { - const sections = [ - { items: [{ hotkey: 1, url: 'https://a.com' }] }, - { items: [{ hotkey: 2, url: 'https://b.com' }] }, - ]; - const result = getCustomKeyShortcuts(sections); - expect(result).toHaveLength(2); - }); -}); +import { describe, it, expect } from 'vitest'; +import { + makePageName, + makePageSlug, + formatConfigPath, + componentVisibility, + getCustomKeyShortcuts, +} from '@/utils/ConfigHelpers'; + +describe('ConfigHelpers - makePageName', () => { + it('converts page name to lowercase', () => { + expect(makePageName('My Page')).toBe('my-page'); + }); + + it('replaces spaces with hyphens', () => { + expect(makePageName('Multiple Word Page')).toBe('multiple-word-page'); + }); + + it('removes .yml extension', () => { + expect(makePageName('config.yml')).toBe('config'); + }); + + it('removes special characters', () => { + expect(makePageName('Page!@#$Name')).toBe('pagename'); + }); + + it('handles undefined input', () => { + expect(makePageName(undefined)).toBe('unnamed-page'); + }); + + it('handles null input', () => { + expect(makePageName(null)).toBe('unnamed-page'); + }); + + it('handles empty string', () => { + expect(makePageName('')).toBe('unnamed-page'); + }); +}); + +describe('ConfigHelpers - makePageSlug', () => { + it('creates correct slug format', () => { + expect(makePageSlug('My Page', 'home')).toBe('/home/my-page'); + }); + + it('handles page names with special chars', () => { + expect(makePageSlug('Config! Page', 'admin')).toBe('/admin/config-page'); + }); +}); + +describe('ConfigHelpers - formatConfigPath', () => { + it('leaves http URLs unchanged', () => { + const url = 'https://example.com/config.yml'; + expect(formatConfigPath(url)).toBe(url); + }); + + it('adds leading slash to relative paths', () => { + expect(formatConfigPath('config.yml')).toBe('/config.yml'); + }); + + it('keeps absolute paths unchanged', () => { + expect(formatConfigPath('/config.yml')).toBe('/config.yml'); + }); +}); + +describe('ConfigHelpers - componentVisibility', () => { + it('returns all visible by default when no config', () => { + const result = componentVisibility({}); + expect(result.pageTitle).toBe(true); + expect(result.navigation).toBe(true); + expect(result.searchBar).toBe(true); + expect(result.settings).toBe(true); + expect(result.footer).toBe(true); + }); + + it('hides components based on config', () => { + const appConfig = { + hideComponents: { + hideHeading: true, + hideNav: true, + }, + }; + const result = componentVisibility(appConfig); + expect(result.pageTitle).toBe(false); + expect(result.navigation).toBe(false); + expect(result.searchBar).toBe(true); + }); + + it('handles partial config correctly', () => { + const appConfig = { + hideComponents: { + hideFooter: true, + }, + }; + const result = componentVisibility(appConfig); + expect(result.footer).toBe(false); + expect(result.pageTitle).toBe(true); + }); +}); + +describe('ConfigHelpers - getCustomKeyShortcuts', () => { + it('extracts hotkeys from sections', () => { + const sections = [ + { + items: [ + { hotkey: 1, url: 'https://example.com' }, + { url: 'https://example.org' }, + ], + }, + ]; + const result = getCustomKeyShortcuts(sections); + expect(result).toHaveLength(1); + expect(result[0]).toEqual({ hotkey: 1, url: 'https://example.com' }); + }); + + it('returns empty array when no hotkeys', () => { + const sections = [{ items: [{ url: 'https://example.com' }] }]; + expect(getCustomKeyShortcuts(sections)).toEqual([]); + }); + + it('flattens hotkeys from multiple sections', () => { + const sections = [ + { items: [{ hotkey: 1, url: 'https://a.com' }] }, + { items: [{ hotkey: 2, url: 'https://b.com' }] }, + ]; + const result = getCustomKeyShortcuts(sections); + expect(result).toHaveLength(2); + }); +}); diff --git a/tests/unit/config-validator.test.js b/tests/unit/config-validator.test.js index f8815615..75fdf21a 100644 --- a/tests/unit/config-validator.test.js +++ b/tests/unit/config-validator.test.js @@ -1,75 +1,77 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; -import fs from 'fs'; -import path from 'path'; - -describe('Config Validator', () => { - const configValidator = path.resolve(__dirname, '../../services/config-validator.js'); - - beforeEach(() => { - delete process.env.VUE_APP_CONFIG_VALID; - }); - - it('validates a correct config file', () => { - const yaml = require('js-yaml'); - const Ajv = require('ajv'); - const schema = require('../../src/utils/ConfigSchema.json'); - - const validConfig = { - pageInfo: { title: 'Test' }, - appConfig: {}, - sections: [{ name: 'Test', items: [{ title: 'Item', url: 'https://example.com' }] }], - }; - - const ajv = new Ajv({ strict: false, allowUnionTypes: true, allErrors: true }); - const valid = ajv.validate(schema, validConfig); - expect(valid).toBe(true); - }); - - it('rejects config with invalid structure', () => { - const Ajv = require('ajv'); - const schema = require('../../src/utils/ConfigSchema.json'); - - const invalidConfig = { - pageInfo: { title: 'Test' }, - sections: 'not an array', - }; - - const ajv = new Ajv({ strict: false, allowUnionTypes: true, allErrors: true }); - const valid = ajv.validate(schema, invalidConfig); - expect(valid).toBe(false); - expect(ajv.errors).toBeTruthy(); - }); - - it('requires sections to be an array', () => { - const Ajv = require('ajv'); - const schema = require('../../src/utils/ConfigSchema.json'); - - const config = { - pageInfo: { title: 'Test' }, - sections: {}, - }; - - const ajv = new Ajv({ strict: false, allowUnionTypes: true, allErrors: true }); - const valid = ajv.validate(schema, config); - expect(valid).toBe(false); - }); - - it('allows items with just title', () => { - const Ajv = require('ajv'); - const schema = require('../../src/utils/ConfigSchema.json'); - - const config = { - pageInfo: { title: 'Test' }, - sections: [ - { - name: 'Test Section', - items: [{ title: 'Item', url: 'https://example.com' }], - }, - ], - }; - - const ajv = new Ajv({ strict: false, allowUnionTypes: true, allErrors: true }); - const valid = ajv.validate(schema, config); - expect(valid).toBe(true); - }); -}); +import { + describe, it, expect, beforeEach, vi, +} from 'vitest'; +import fs from 'fs'; +import path from 'path'; + +describe('Config Validator', () => { + const configValidator = path.resolve(__dirname, '../../services/config-validator.js'); + + beforeEach(() => { + delete process.env.VUE_APP_CONFIG_VALID; + }); + + it('validates a correct config file', () => { + const yaml = require('js-yaml'); + const Ajv = require('ajv'); + const schema = require('../../src/utils/ConfigSchema.json'); + + const validConfig = { + pageInfo: { title: 'Test' }, + appConfig: {}, + sections: [{ name: 'Test', items: [{ title: 'Item', url: 'https://example.com' }] }], + }; + + const ajv = new Ajv({ strict: false, allowUnionTypes: true, allErrors: true }); + const valid = ajv.validate(schema, validConfig); + expect(valid).toBe(true); + }); + + it('rejects config with invalid structure', () => { + const Ajv = require('ajv'); + const schema = require('../../src/utils/ConfigSchema.json'); + + const invalidConfig = { + pageInfo: { title: 'Test' }, + sections: 'not an array', + }; + + const ajv = new Ajv({ strict: false, allowUnionTypes: true, allErrors: true }); + const valid = ajv.validate(schema, invalidConfig); + expect(valid).toBe(false); + expect(ajv.errors).toBeTruthy(); + }); + + it('requires sections to be an array', () => { + const Ajv = require('ajv'); + const schema = require('../../src/utils/ConfigSchema.json'); + + const config = { + pageInfo: { title: 'Test' }, + sections: {}, + }; + + const ajv = new Ajv({ strict: false, allowUnionTypes: true, allErrors: true }); + const valid = ajv.validate(schema, config); + expect(valid).toBe(false); + }); + + it('allows items with just title', () => { + const Ajv = require('ajv'); + const schema = require('../../src/utils/ConfigSchema.json'); + + const config = { + pageInfo: { title: 'Test' }, + sections: [ + { + name: 'Test Section', + items: [{ title: 'Item', url: 'https://example.com' }], + }, + ], + }; + + const ajv = new Ajv({ strict: false, allowUnionTypes: true, allErrors: true }); + const valid = ajv.validate(schema, config); + expect(valid).toBe(true); + }); +}); diff --git a/tests/unit/error-handler.test.js b/tests/unit/error-handler.test.js index 32e203ca..4e854910 100644 --- a/tests/unit/error-handler.test.js +++ b/tests/unit/error-handler.test.js @@ -1,24 +1,24 @@ -import { describe, it, expect } from 'vitest'; - -describe('ErrorHandler', () => { - it('exports InfoKeys constants', async () => { - const { InfoKeys } = await import('@/utils/ErrorHandler'); - expect(InfoKeys.AUTH).toBe('Authentication'); - expect(InfoKeys.CLOUD_BACKUP).toBe('Cloud Backup & Restore'); - expect(InfoKeys.EDITOR).toBe('Interactive Editor'); - expect(InfoKeys.RAW_EDITOR).toBe('Raw Config Editor'); - expect(InfoKeys.VISUAL).toBe('Layout & Styles'); - }); - - it('exports handler functions', async () => { - const handlers = await import('@/utils/ErrorHandler'); - expect(typeof handlers.ErrorHandler).toBe('function'); - expect(typeof handlers.InfoHandler).toBe('function'); - expect(typeof handlers.WarningInfoHandler).toBe('function'); - }); - - it('ErrorHandler can be called without throwing', async () => { - const { ErrorHandler } = await import('@/utils/ErrorHandler'); - expect(() => ErrorHandler('Test error')).not.toThrow(); - }); -}); +import { describe, it, expect } from 'vitest'; + +describe('ErrorHandler', () => { + it('exports InfoKeys constants', async () => { + const { InfoKeys } = await import('@/utils/ErrorHandler'); + expect(InfoKeys.AUTH).toBe('Authentication'); + expect(InfoKeys.CLOUD_BACKUP).toBe('Cloud Backup & Restore'); + expect(InfoKeys.EDITOR).toBe('Interactive Editor'); + expect(InfoKeys.RAW_EDITOR).toBe('Raw Config Editor'); + expect(InfoKeys.VISUAL).toBe('Layout & Styles'); + }); + + it('exports handler functions', async () => { + const handlers = await import('@/utils/ErrorHandler'); + expect(typeof handlers.ErrorHandler).toBe('function'); + expect(typeof handlers.InfoHandler).toBe('function'); + expect(typeof handlers.WarningInfoHandler).toBe('function'); + }); + + it('ErrorHandler can be called without throwing', async () => { + const { ErrorHandler } = await import('@/utils/ErrorHandler'); + expect(() => ErrorHandler('Test error')).not.toThrow(); + }); +}); diff --git a/tests/unit/healthcheck.test.js b/tests/unit/healthcheck.test.js index 25bbb291..d0e7bad5 100644 --- a/tests/unit/healthcheck.test.js +++ b/tests/unit/healthcheck.test.js @@ -1,17 +1,17 @@ -import { describe, it, expect } from 'vitest'; -import fs from 'fs'; -import path from 'path'; - -describe('Healthcheck Service', () => { - it('healthcheck script exists', () => { - const healthcheckPath = path.resolve(__dirname, '../../services/healthcheck.js'); - expect(fs.existsSync(healthcheckPath)).toBe(true); - }); - - it('healthcheck file has correct structure', () => { - const healthcheckPath = path.resolve(__dirname, '../../services/healthcheck.js'); - const content = fs.readFileSync(healthcheckPath, 'utf8'); - expect(content).toContain('healthCheck'); - expect(content).toContain('http.request'); - }); -}); +import { describe, it, expect } from 'vitest'; +import fs from 'fs'; +import path from 'path'; + +describe('Healthcheck Service', () => { + it('healthcheck script exists', () => { + const healthcheckPath = path.resolve(__dirname, '../../services/healthcheck.js'); + expect(fs.existsSync(healthcheckPath)).toBe(true); + }); + + it('healthcheck file has correct structure', () => { + const healthcheckPath = path.resolve(__dirname, '../../services/healthcheck.js'); + const content = fs.readFileSync(healthcheckPath, 'utf8'); + expect(content).toContain('healthCheck'); + expect(content).toContain('http.request'); + }); +}); diff --git a/tests/unit/smoke.test.js b/tests/unit/smoke.test.js index b3ef2342..672958f7 100644 --- a/tests/unit/smoke.test.js +++ b/tests/unit/smoke.test.js @@ -1,115 +1,115 @@ -/** - * Smoke Tests - * Basic tests to verify that the testing infrastructure is working correctly - * and that core functionality is operational - */ - -import { describe, it, expect } from 'vitest'; -import fs from 'fs'; -import path from 'path'; -import yaml from 'js-yaml'; - -describe('Smoke Tests - Testing Infrastructure', () => { - it('should run a basic test', () => { - expect(true).toBe(true); - }); - - it('should perform basic math', () => { - expect(2 + 2).toBe(4); - }); - - it('should handle strings correctly', () => { - expect('dashy').toMatch(/dash/); - }); -}); - -describe('Smoke Tests - Project Files', () => { - it('should have a package.json file', () => { - const packageJsonPath = path.resolve(__dirname, '../../package.json'); - expect(fs.existsSync(packageJsonPath)).toBe(true); - }); - - it('should have a valid package.json', () => { - const packageJsonPath = path.resolve(__dirname, '../../package.json'); - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); - - expect(packageJson.name).toBe('dashy'); - expect(packageJson.version).toBeDefined(); - expect(packageJson.license).toBe('MIT'); - }); - - it('should have a server.js file', () => { - const serverPath = path.resolve(__dirname, '../../server.js'); - expect(fs.existsSync(serverPath)).toBe(true); - }); - - it('should have src directory', () => { - const srcPath = path.resolve(__dirname, '../../src'); - expect(fs.existsSync(srcPath)).toBe(true); - }); -}); - -describe('Smoke Tests - Config Loading', () => { - it('should parse a valid YAML config file', () => { - const configPath = path.resolve(__dirname, '../fixtures/valid-config.yml'); - const configContent = fs.readFileSync(configPath, 'utf8'); - const config = yaml.load(configContent); - - expect(config).toBeDefined(); - expect(config.pageInfo).toBeDefined(); - expect(config.pageInfo.title).toBe('Test Dashboard'); - }); - - it('should have required config structure', () => { - const configPath = path.resolve(__dirname, '../fixtures/valid-config.yml'); - const configContent = fs.readFileSync(configPath, 'utf8'); - const config = yaml.load(configContent); - - // Check required top-level properties - expect(config).toHaveProperty('pageInfo'); - expect(config).toHaveProperty('appConfig'); - expect(config).toHaveProperty('sections'); - - // Check sections structure - expect(Array.isArray(config.sections)).toBe(true); - expect(config.sections.length).toBeGreaterThan(0); - - // Check first section has items - const firstSection = config.sections[0]; - expect(firstSection).toHaveProperty('name'); - expect(firstSection).toHaveProperty('items'); - expect(Array.isArray(firstSection.items)).toBe(true); - }); - - it('should validate item structure in config', () => { - const configPath = path.resolve(__dirname, '../fixtures/valid-config.yml'); - const configContent = fs.readFileSync(configPath, 'utf8'); - const config = yaml.load(configContent); - - const firstItem = config.sections[0].items[0]; - - // Each item should have required properties - expect(firstItem).toHaveProperty('title'); - expect(firstItem).toHaveProperty('url'); - - // URL should be valid - expect(firstItem.url).toMatch(/^https?:\/\//); - }); -}); - -describe('Smoke Tests - Core Dependencies', () => { - it('should load yaml parser', () => { - expect(yaml).toBeDefined(); - expect(typeof yaml.load).toBe('function'); - }); - - it('should load fs module', () => { - expect(fs).toBeDefined(); - expect(typeof fs.readFileSync).toBe('function'); - }); - - it('should have config schema file', () => { - const schemaPath = path.resolve(__dirname, '../../src/utils/ConfigSchema.json'); - expect(fs.existsSync(schemaPath)).toBe(true); - }); -}); +/** + * Smoke Tests + * Basic tests to verify that the testing infrastructure is working correctly + * and that core functionality is operational + */ + +import { describe, it, expect } from 'vitest'; +import fs from 'fs'; +import path from 'path'; +import yaml from 'js-yaml'; + +describe('Smoke Tests - Testing Infrastructure', () => { + it('should run a basic test', () => { + expect(true).toBe(true); + }); + + it('should perform basic math', () => { + expect(2 + 2).toBe(4); + }); + + it('should handle strings correctly', () => { + expect('dashy').toMatch(/dash/); + }); +}); + +describe('Smoke Tests - Project Files', () => { + it('should have a package.json file', () => { + const packageJsonPath = path.resolve(__dirname, '../../package.json'); + expect(fs.existsSync(packageJsonPath)).toBe(true); + }); + + it('should have a valid package.json', () => { + const packageJsonPath = path.resolve(__dirname, '../../package.json'); + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + + expect(packageJson.name).toBe('dashy'); + expect(packageJson.version).toBeDefined(); + expect(packageJson.license).toBe('MIT'); + }); + + it('should have a server.js file', () => { + const serverPath = path.resolve(__dirname, '../../server.js'); + expect(fs.existsSync(serverPath)).toBe(true); + }); + + it('should have src directory', () => { + const srcPath = path.resolve(__dirname, '../../src'); + expect(fs.existsSync(srcPath)).toBe(true); + }); +}); + +describe('Smoke Tests - Config Loading', () => { + it('should parse a valid YAML config file', () => { + const configPath = path.resolve(__dirname, '../fixtures/valid-config.yml'); + const configContent = fs.readFileSync(configPath, 'utf8'); + const config = yaml.load(configContent); + + expect(config).toBeDefined(); + expect(config.pageInfo).toBeDefined(); + expect(config.pageInfo.title).toBe('Test Dashboard'); + }); + + it('should have required config structure', () => { + const configPath = path.resolve(__dirname, '../fixtures/valid-config.yml'); + const configContent = fs.readFileSync(configPath, 'utf8'); + const config = yaml.load(configContent); + + // Check required top-level properties + expect(config).toHaveProperty('pageInfo'); + expect(config).toHaveProperty('appConfig'); + expect(config).toHaveProperty('sections'); + + // Check sections structure + expect(Array.isArray(config.sections)).toBe(true); + expect(config.sections.length).toBeGreaterThan(0); + + // Check first section has items + const firstSection = config.sections[0]; + expect(firstSection).toHaveProperty('name'); + expect(firstSection).toHaveProperty('items'); + expect(Array.isArray(firstSection.items)).toBe(true); + }); + + it('should validate item structure in config', () => { + const configPath = path.resolve(__dirname, '../fixtures/valid-config.yml'); + const configContent = fs.readFileSync(configPath, 'utf8'); + const config = yaml.load(configContent); + + const firstItem = config.sections[0].items[0]; + + // Each item should have required properties + expect(firstItem).toHaveProperty('title'); + expect(firstItem).toHaveProperty('url'); + + // URL should be valid + expect(firstItem.url).toMatch(/^https?:\/\//); + }); +}); + +describe('Smoke Tests - Core Dependencies', () => { + it('should load yaml parser', () => { + expect(yaml).toBeDefined(); + expect(typeof yaml.load).toBe('function'); + }); + + it('should load fs module', () => { + expect(fs).toBeDefined(); + expect(typeof fs.readFileSync).toBe('function'); + }); + + it('should have config schema file', () => { + const schemaPath = path.resolve(__dirname, '../../src/utils/ConfigSchema.json'); + expect(fs.existsSync(schemaPath)).toBe(true); + }); +}); diff --git a/vitest.config.js b/vitest.config.js index a457efc5..3f5fc181 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -1,40 +1,43 @@ -import { defineConfig } from 'vitest/config'; -import path from 'path'; - -export default defineConfig({ - test: { - // Use happy-dom for faster DOM simulation - environment: 'happy-dom', - - // Make test functions available globally (describe, it, expect, etc.) - globals: true, - - // Setup file for global test configuration - setupFiles: ['./tests/setup.js'], - - // Include patterns - include: ['tests/**/*.{test,spec}.{js,ts}', 'src/**/*.{test,spec}.{js,ts}'], - - // Coverage configuration - coverage: { - provider: 'v8', - reporter: ['text', 'json', 'html'], - exclude: [ - 'node_modules/', - 'tests/', - '*.config.js', - 'dist/', - '.github/', - 'docs/', - ], - }, - }, - - resolve: { - // Match the alias configuration from vue.config.js - alias: { - '@': path.resolve(__dirname, './src'), - 'vue': 'vue/dist/vue.esm.js', // Use the full build for tests - }, - }, -}); +import { defineConfig } from 'vitest/config'; +import { createVuePlugin } from 'vite-plugin-vue2'; +import path from 'path'; + +export default defineConfig({ + plugins: [createVuePlugin()], + test: { + // Use happy-dom for faster DOM simulation + environment: 'happy-dom', + + // Make test functions available globally (describe, it, expect, etc.) + globals: true, + + // Setup file for global test configuration + setupFiles: ['./tests/setup.js'], + + // Include patterns + include: ['tests/**/*.{test,spec}.{js,ts}', 'src/**/*.{test,spec}.{js,ts}'], + + // Coverage configuration + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html'], + exclude: [ + 'node_modules/', + 'tests/', + '*.config.js', + 'dist/', + '.github/', + 'docs/', + ], + }, + }, + + resolve: { + extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], + // Match the alias configuration from vue.config.js + alias: { + '@': path.resolve(__dirname, './src'), + vue: 'vue/dist/vue.esm.js', // Use the full build for tests + }, + }, +}); diff --git a/yarn.lock b/yarn.lock index 5d2068c9..bb81e7bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28,21 +28,21 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.7", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.8.3": - version "7.28.6" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz" - integrity sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.7", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0", "@babel/code-frame@^7.8.3": + version "7.29.0" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== dependencies: "@babel/helper-validator-identifier" "^7.28.5" js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.7": +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz" integrity sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.0", "@babel/core@^7.12.0", "@babel/core@^7.12.16", "@babel/core@^7.13.0", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.0", "@babel/core@^7.12.0", "@babel/core@^7.12.16", "@babel/core@^7.13.0", "@babel/core@^7.14.3", "@babel/core@^7.17.9", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": version "7.24.7" resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz" integrity sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g== @@ -63,22 +63,23 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz" - integrity sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA== +"@babel/generator@^7.24.7", "@babel/generator@^7.29.0": + version "7.29.1" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== dependencies: - "@babel/types" "^7.24.7" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" -"@babel/helper-annotate-as-pure@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz" - integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== +"@babel/helper-annotate-as-pure@^7.24.7", "@babel/helper-annotate-as-pure@^7.27.3": + version "7.27.3" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz" + integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg== dependencies: - "@babel/types" "^7.24.7" + "@babel/types" "^7.27.3" "@babel/helper-builder-binary-assignment-operator-visitor@^7.24.7": version "7.24.7" @@ -88,7 +89,7 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.9.6": +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.9.6": version "7.24.7" resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz" integrity sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg== @@ -99,19 +100,17 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz" - integrity sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.24.7", "@babel/helper-create-class-features-plugin@^7.28.6": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz" + integrity sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-function-name" "^7.24.7" - "@babel/helper-member-expression-to-functions" "^7.24.7" - "@babel/helper-optimise-call-expression" "^7.24.7" - "@babel/helper-replace-supers" "^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-member-expression-to-functions" "^7.28.5" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/helper-replace-supers" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/traverse" "^7.28.6" semver "^6.3.1" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.24.7": @@ -149,6 +148,11 @@ "@babel/template" "^7.24.7" "@babel/types" "^7.24.7" +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + "@babel/helper-hoist-variables@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz" @@ -156,13 +160,13 @@ dependencies: "@babel/types" "^7.24.7" -"@babel/helper-member-expression-to-functions@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz" - integrity sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w== +"@babel/helper-member-expression-to-functions@^7.28.5": + version "7.28.5" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz" + integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.24.7", "@babel/helper-module-imports@^7.8.3": version "7.24.7" @@ -190,17 +194,17 @@ "@babel/helper-split-export-declaration" "^7.24.7" "@babel/helper-validator-identifier" "^7.24.7" -"@babel/helper-optimise-call-expression@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz" - integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== +"@babel/helper-optimise-call-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz" + integrity sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw== dependencies: - "@babel/types" "^7.24.7" + "@babel/types" "^7.27.1" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz" - integrity sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.28.6", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz" + integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== "@babel/helper-remap-async-to-generator@^7.24.7": version "7.24.7" @@ -211,14 +215,14 @@ "@babel/helper-environment-visitor" "^7.24.7" "@babel/helper-wrap-function" "^7.24.7" -"@babel/helper-replace-supers@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz" - integrity sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg== +"@babel/helper-replace-supers@^7.24.7", "@babel/helper-replace-supers@^7.28.6": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz" + integrity sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg== dependencies: - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-member-expression-to-functions" "^7.24.7" - "@babel/helper-optimise-call-expression" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.28.5" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/traverse" "^7.28.6" "@babel/helper-simple-access@^7.24.7": version "7.24.7" @@ -228,13 +232,13 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-skip-transparent-expression-wrappers@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz" - integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.24.7", "@babel/helper-skip-transparent-expression-wrappers@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz" + integrity sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg== dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" "@babel/helper-split-export-declaration@^7.24.7": version "7.24.7" @@ -276,12 +280,12 @@ "@babel/template" "^7.28.6" "@babel/types" "^7.28.6" -"@babel/parser@^7.23.5", "@babel/parser@^7.23.9", "@babel/parser@^7.24.7", "@babel/parser@^7.28.6", "@babel/parser@^7.7.0": - version "7.28.6" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz" - integrity sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ== +"@babel/parser@^7.17.9", "@babel/parser@^7.23.5", "@babel/parser@^7.23.9", "@babel/parser@^7.24.7", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0", "@babel/parser@^7.7.0": + version "7.29.0" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz" + integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww== dependencies: - "@babel/types" "^7.28.6" + "@babel/types" "^7.29.0" "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.7": version "7.24.7" @@ -315,7 +319,7 @@ "@babel/helper-environment-visitor" "^7.24.7" "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-proposal-class-properties@^7.8.3": +"@babel/plugin-proposal-class-properties@^7.16.7", "@babel/plugin-proposal-class-properties@^7.8.3": version "7.18.6" resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== @@ -323,7 +327,7 @@ "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-decorators@^7.8.3": +"@babel/plugin-proposal-decorators@^7.17.9", "@babel/plugin-proposal-decorators@^7.8.3": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz" integrity sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ== @@ -332,6 +336,34 @@ "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-decorators" "^7.24.7" +"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.5", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-object-rest-spread@^7.15.6", "@babel/plugin-proposal-object-rest-spread@^7.17.3": + version "7.20.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== + dependencies: + "@babel/compat-data" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.20.7" + +"@babel/plugin-proposal-optional-chaining@^7.14.2", "@babel/plugin-proposal-optional-chaining@^7.16.7": + version "7.21.0" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz" + integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz" @@ -470,6 +502,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" +"@babel/plugin-syntax-typescript@^7.28.6": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz" + integrity sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" resolved "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz" @@ -478,7 +517,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.24.7": +"@babel/plugin-transform-arrow-functions@^7.14.5", "@babel/plugin-transform-arrow-functions@^7.16.7", "@babel/plugin-transform-arrow-functions@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz" integrity sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ== @@ -511,7 +550,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-block-scoping@^7.24.7": +"@babel/plugin-transform-block-scoping@^7.14.5", "@babel/plugin-transform-block-scoping@^7.16.7", "@babel/plugin-transform-block-scoping@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz" integrity sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ== @@ -549,7 +588,7 @@ "@babel/helper-split-export-declaration" "^7.24.7" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.24.7": +"@babel/plugin-transform-computed-properties@^7.14.5", "@babel/plugin-transform-computed-properties@^7.16.7", "@babel/plugin-transform-computed-properties@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz" integrity sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ== @@ -557,7 +596,7 @@ "@babel/helper-plugin-utils" "^7.24.7" "@babel/template" "^7.24.7" -"@babel/plugin-transform-destructuring@^7.24.7": +"@babel/plugin-transform-destructuring@^7.14.5", "@babel/plugin-transform-destructuring@^7.17.7", "@babel/plugin-transform-destructuring@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz" integrity sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw== @@ -751,7 +790,7 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-parameters@^7.24.7": +"@babel/plugin-transform-parameters@^7.14.5", "@babel/plugin-transform-parameters@^7.16.7", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz" integrity sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA== @@ -817,7 +856,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-spread@^7.24.7": +"@babel/plugin-transform-spread@^7.14.5", "@babel/plugin-transform-spread@^7.16.7", "@babel/plugin-transform-spread@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz" integrity sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng== @@ -846,6 +885,17 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.7" +"@babel/plugin-transform-typescript@^7.16.8": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz" + integrity sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-create-class-features-plugin" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-syntax-typescript" "^7.28.6" + "@babel/plugin-transform-unicode-escapes@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz" @@ -992,35 +1042,252 @@ "@babel/parser" "^7.28.6" "@babel/types" "^7.28.6" -"@babel/traverse@^7.23.9", "@babel/traverse@^7.24.7", "@babel/traverse@^7.7.0": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz" - integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA== +"@babel/traverse@^7.23.9", "@babel/traverse@^7.24.7", "@babel/traverse@^7.27.1", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6", "@babel/traverse@^7.7.0": + version "7.29.0" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.7" - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-function-name" "^7.24.7" - "@babel/helper-hoist-variables" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" - "@babel/parser" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" debug "^4.3.1" - globals "^11.1.0" -"@babel/types@^7.22.15", "@babel/types@^7.23.9", "@babel/types@^7.24.7", "@babel/types@^7.28.6", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.28.6" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz" - integrity sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg== +"@babel/types@^7.14.5", "@babel/types@^7.22.15", "@babel/types@^7.23.9", "@babel/types@^7.24.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.29.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.29.0" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== dependencies: "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz" + integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + "@esbuild/linux-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz" integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + "@formschema/native@^2.0.0-beta.6": version "2.0.0-beta.7" resolved "https://registry.npmjs.org/@formschema/native/-/native-2.0.0-beta.7.tgz" @@ -1103,13 +1370,12 @@ dependencies: "@sinclair/typebox" "^0.27.8" -"@jridgewell/gen-mapping@^0.3.5": - version "0.3.5" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz" - integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== +"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== dependencies: - "@jridgewell/set-array" "^1.2.1" - "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/sourcemap-codec" "^1.5.0" "@jridgewell/trace-mapping" "^0.3.24" "@jridgewell/resolve-uri@^3.1.0": @@ -1117,11 +1383,6 @@ resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/set-array@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz" - integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== - "@jridgewell/source-map@^0.3.3": version "0.3.6" resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz" @@ -1130,15 +1391,15 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== -"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.25" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -1215,6 +1476,99 @@ resolved "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz" integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww== +"@rollup/pluginutils@^4.2.1": + version "4.2.1" + resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz" + integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== + dependencies: + estree-walker "^2.0.1" + picomatch "^2.2.2" + +"@rollup/rollup-android-arm-eabi@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz" + integrity sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg== + +"@rollup/rollup-android-arm64@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz" + integrity sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg== + +"@rollup/rollup-darwin-arm64@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz" + integrity sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg== + +"@rollup/rollup-darwin-x64@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz" + integrity sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ== + +"@rollup/rollup-freebsd-arm64@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz" + integrity sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg== + +"@rollup/rollup-freebsd-x64@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz" + integrity sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw== + +"@rollup/rollup-linux-arm-gnueabihf@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz" + integrity sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ== + +"@rollup/rollup-linux-arm-musleabihf@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz" + integrity sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg== + +"@rollup/rollup-linux-arm64-gnu@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz" + integrity sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ== + +"@rollup/rollup-linux-arm64-musl@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz" + integrity sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA== + +"@rollup/rollup-linux-loong64-gnu@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz" + integrity sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g== + +"@rollup/rollup-linux-loong64-musl@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz" + integrity sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw== + +"@rollup/rollup-linux-ppc64-gnu@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz" + integrity sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw== + +"@rollup/rollup-linux-ppc64-musl@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz" + integrity sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw== + +"@rollup/rollup-linux-riscv64-gnu@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz" + integrity sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw== + +"@rollup/rollup-linux-riscv64-musl@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz" + integrity sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg== + +"@rollup/rollup-linux-s390x-gnu@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz" + integrity sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg== + "@rollup/rollup-linux-x64-gnu@4.55.1": version "4.55.1" resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz" @@ -1225,6 +1579,36 @@ resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz" integrity sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w== +"@rollup/rollup-openbsd-x64@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz" + integrity sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg== + +"@rollup/rollup-openharmony-arm64@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz" + integrity sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw== + +"@rollup/rollup-win32-arm64-msvc@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz" + integrity sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g== + +"@rollup/rollup-win32-ia32-msvc@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz" + integrity sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA== + +"@rollup/rollup-win32-x64-gnu@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz" + integrity sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg== + +"@rollup/rollup-win32-x64-msvc@4.55.1": + version "4.55.1" + resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz" + integrity sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw== + "@sentry-internal/feedback@7.120.4": version "7.120.4" resolved "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.120.4.tgz" @@ -1504,7 +1888,7 @@ resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz" integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== -"@types/node@*", "@types/node@^18.0.0 || >=20.0.0": +"@types/node@*", "@types/node@^18.0.0 || >=20.0.0", "@types/node@>= 14": version "20.14.2" resolved "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz" integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q== @@ -1664,7 +2048,7 @@ loupe "^2.3.7" pretty-format "^29.7.0" -"@vue/babel-helper-vue-jsx-merge-props@^1.4.0": +"@vue/babel-helper-vue-jsx-merge-props@^1.2.1", "@vue/babel-helper-vue-jsx-merge-props@^1.4.0": version "1.4.0" resolved "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz" integrity sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA== @@ -2017,7 +2401,7 @@ "@vue/compiler-dom" "3.4.28" "@vue/shared" "3.4.28" -"@vue/component-compiler-utils@^3.1.0", "@vue/component-compiler-utils@^3.1.2": +"@vue/component-compiler-utils@^3.1.0", "@vue/component-compiler-utils@^3.1.2", "@vue/component-compiler-utils@^3.3.0": version "3.3.0" resolved "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz" integrity sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ== @@ -2394,7 +2778,12 @@ acorn@^6.4.1: resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^8.11.0, acorn@^8.14.0, acorn@^8.15.0: +acorn@^8.11.0: + version "8.15.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +acorn@^8.14.0, acorn@^8.15.0: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -3068,6 +3457,13 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + bl@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" @@ -3077,7 +3473,7 @@ bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -bluebird@^3.1.1, bluebird@^3.5.5: +bluebird@^3.1.1, bluebird@^3.5.5, bluebird@^3.7.2: version "3.7.2" resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -3918,6 +4314,13 @@ consolidate@^0.15.1: dependencies: bluebird "^3.1.1" +consolidate@^0.16.0: + version "0.16.0" + resolved "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz" + integrity sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ== + dependencies: + bluebird "^3.7.2" + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz" @@ -5036,6 +5439,34 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild@^0.18.10: + version "0.18.20" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz" + integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== + optionalDependencies: + "@esbuild/android-arm" "0.18.20" + "@esbuild/android-arm64" "0.18.20" + "@esbuild/android-x64" "0.18.20" + "@esbuild/darwin-arm64" "0.18.20" + "@esbuild/darwin-x64" "0.18.20" + "@esbuild/freebsd-arm64" "0.18.20" + "@esbuild/freebsd-x64" "0.18.20" + "@esbuild/linux-arm" "0.18.20" + "@esbuild/linux-arm64" "0.18.20" + "@esbuild/linux-ia32" "0.18.20" + "@esbuild/linux-loong64" "0.18.20" + "@esbuild/linux-mips64el" "0.18.20" + "@esbuild/linux-ppc64" "0.18.20" + "@esbuild/linux-riscv64" "0.18.20" + "@esbuild/linux-s390x" "0.18.20" + "@esbuild/linux-x64" "0.18.20" + "@esbuild/netbsd-x64" "0.18.20" + "@esbuild/openbsd-x64" "0.18.20" + "@esbuild/sunos-x64" "0.18.20" + "@esbuild/win32-arm64" "0.18.20" + "@esbuild/win32-ia32" "0.18.20" + "@esbuild/win32-x64" "0.18.20" + esbuild@^0.21.3: version "0.21.5" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz" @@ -5360,7 +5791,7 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-walker@^2.0.2: +estree-walker@^2.0.1, estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== @@ -5877,6 +6308,15 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^4.0.2: version "4.0.3" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz" @@ -5932,6 +6372,19 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -7296,10 +7749,10 @@ jsbn@~0.1.0: resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== jsesc@~0.5.0: version "0.5.0" @@ -7800,6 +8253,13 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +magic-string@^0.26.1: + version "0.26.7" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz" + integrity sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow== + dependencies: + sourcemap-codec "^1.4.8" + magic-string@^0.30.10, magic-string@^0.30.5: version "0.30.10" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz" @@ -8202,6 +8662,11 @@ mz@^2.4.0: object-assign "^4.0.1" thenify-all "^1.0.0" +nan@^2.12.1: + version "2.20.0" + resolved "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz" + integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw== + nanoid@^3.3.11, nanoid@^3.3.7: version "3.3.11" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" @@ -8951,7 +9416,7 @@ picocolors@^1.0.0, picocolors@^1.1.1: resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -9395,6 +9860,15 @@ postcss@^8.4.14: picocolors "^1.0.0" source-map-js "^1.2.0" +postcss@^8.4.27: + version "8.5.8" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz" + integrity sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg== + dependencies: + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" + postcss@^8.4.38: version "8.4.38" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" @@ -9423,7 +9897,7 @@ prepend-http@^1.0.0: resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz" integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg== -"prettier@^1.18.2 || ^2.0.0": +"prettier@^1.18.2 || ^2.0.0", prettier@^2.6.2: version "2.8.8" resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== @@ -9603,6 +10077,11 @@ querystring-es3@^0.2.0: resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz" integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== +querystring@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== + querystringify@^2.1.1: version "2.2.0" resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" @@ -10014,6 +10493,20 @@ ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.3: hash-base "^3.1.2" inherits "^2.0.4" +rollup@^2.70.2: + version "2.80.0" + resolved "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz" + integrity sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ== + optionalDependencies: + fsevents "~2.3.2" + +rollup@^3.27.1: + version "3.30.0" + resolved "https://registry.npmjs.org/rollup/-/rollup-3.30.0.tgz" + integrity sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA== + optionalDependencies: + fsevents "~2.3.2" + rollup@^4.20.0: version "4.55.1" resolved "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz" @@ -10642,6 +11135,11 @@ source-map@^0.7.4: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + spdx-correct@^3.0.0: version "3.2.0" resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" @@ -11179,20 +11677,10 @@ terser@^4.1.2: source-map "~0.6.1" source-map-support "~0.5.12" -terser@^5.31.1: - version "5.44.1" - resolved "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz" - integrity sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.15.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -terser@^5.4.0: - version "5.44.1" - resolved "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz" - integrity sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw== +terser@^5.31.1, terser@^5.4.0: + version "5.46.0" + resolved "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz" + integrity sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.15.0" @@ -11793,6 +12281,52 @@ vite-node@1.6.1: picocolors "^1.0.0" vite "^5.0.0" +vite-plugin-vue2@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/vite-plugin-vue2/-/vite-plugin-vue2-2.0.3.tgz" + integrity sha512-t3Tu93GWsMHbpeIv66MTO5e/rRAo8/+/eWoUtFYuAdKDMyEnn1dqsrXh+CfG+SJAlxJvcTP8U0eXkzhLjKNyMg== + dependencies: + "@babel/core" "^7.17.9" + "@babel/parser" "^7.17.9" + "@babel/plugin-proposal-class-properties" "^7.16.7" + "@babel/plugin-proposal-decorators" "^7.17.9" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" + "@babel/plugin-proposal-object-rest-spread" "^7.17.3" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + "@babel/plugin-transform-arrow-functions" "^7.16.7" + "@babel/plugin-transform-block-scoping" "^7.16.7" + "@babel/plugin-transform-computed-properties" "^7.16.7" + "@babel/plugin-transform-destructuring" "^7.17.7" + "@babel/plugin-transform-parameters" "^7.16.7" + "@babel/plugin-transform-spread" "^7.16.7" + "@babel/plugin-transform-typescript" "^7.16.8" + "@rollup/pluginutils" "^4.2.1" + "@vue/babel-helper-vue-jsx-merge-props" "^1.2.1" + "@vue/babel-preset-jsx" "^1.2.4" + "@vue/component-compiler-utils" "^3.3.0" + consolidate "^0.16.0" + debug "^4.3.4" + fs-extra "^10.1.0" + hash-sum "^2.0.0" + magic-string "^0.26.1" + prettier "^2.6.2" + querystring "^0.2.1" + rollup "^2.70.2" + slash "^3.0.0" + source-map "^0.7.3" + vue-template-babel-compiler "^1.2.0" + +"vite@^2.0.0 || ^3.0.0 || ^4.0.0": + version "4.5.14" + resolved "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz" + integrity sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g== + dependencies: + esbuild "^0.18.10" + postcss "^8.4.27" + rollup "^3.27.1" + optionalDependencies: + fsevents "~2.3.2" + vite@^5.0.0: version "5.4.21" resolved "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz" @@ -11944,7 +12478,25 @@ vue-swatches@^2.1.1: resolved "https://registry.npmjs.org/vue-swatches/-/vue-swatches-2.1.1.tgz" integrity sha512-YugkNbByxMz1dnx1nZyHSL3VSf/TnBH3/NQD+t8JKxPSqUmX87sVGBxjEaqH5IMraOLfVmU0pHCHl2BfXNypQg== -vue-template-compiler@*, vue-template-compiler@^2.0.0, vue-template-compiler@^2.7.0, vue-template-compiler@^2.x: +vue-template-babel-compiler@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/vue-template-babel-compiler/-/vue-template-babel-compiler-1.2.0.tgz" + integrity sha512-CScBSX1/wCdmmZ/Lvj/63p2CCVTS0FMj0F69VRBo73CuJrjvPAPGmeNJ7D/cwt/VS2PduowRWbO8N4Zh4Z3b0g== + dependencies: + "@babel/core" "^7.14.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" + "@babel/plugin-proposal-object-rest-spread" "^7.15.6" + "@babel/plugin-proposal-optional-chaining" "^7.14.2" + "@babel/plugin-transform-arrow-functions" "^7.14.5" + "@babel/plugin-transform-block-scoping" "^7.14.5" + "@babel/plugin-transform-computed-properties" "^7.14.5" + "@babel/plugin-transform-destructuring" "^7.14.5" + "@babel/plugin-transform-parameters" "^7.14.5" + "@babel/plugin-transform-spread" "^7.14.5" + "@babel/types" "^7.14.5" + deepmerge "^4.2.2" + +vue-template-compiler@*, vue-template-compiler@^2.0.0, vue-template-compiler@^2.2.0, vue-template-compiler@^2.6.0, vue-template-compiler@^2.7.0, vue-template-compiler@^2.x: version "2.7.16" resolved "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz" integrity sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==