From 7456205b6e6ef82e1f692974a5fba1dcaf963d47 Mon Sep 17 00:00:00 2001
From: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
Date: Sat, 1 Apr 2023 23:06:42 +0200
Subject: [PATCH] V2 build (#319)
* chore: build pipeline for v2
* chore: run unit tests
* chore: configure sentry build
---
.github/workflows/build.yml | 4 +-
.github/workflows/build_docker_v2.yml | 20 +-
.github/workflows/build_v2.yml | 106 +++++++
.github/workflows/test_v2.yml | 42 +++
apps/client/package.json | 4 +-
.../text-input/__tests__/TextInput.test.tsx | 89 ------
.../__snapshots__/styleUtils.test.ts.snap | 2 +-
.../common/utils/__tests__/dateConfig.test.js | 7 -
.../src/features/table/TableWrapper.jsx | 2 +-
.../__snapshots__/utils.test.js.snap | 56 +---
.../features/table/__tests__/utils.test.js | 2 +-
.../table/{utils.js => tableUtils.js} | 6 +-
apps/client/vite.config.js | 24 +-
apps/server/package.json | 2 +-
.../src/classes/data-provider/DataProvider.ts | 2 +-
.../data-provider/DataProvider.utils.ts | 4 +-
.../__test__/DataProvider.test.ts | 147 +++------
.../src/classes/event-loader/EventLoader.ts | 10 +-
.../src/controllers/ontimeController.js | 2 +-
.../src/services/__tests__/rollUtils.test.js | 155 +++++++---
apps/server/src/services/rollUtils.ts | 8 +-
.../src/utils/__tests__/parser.tests.js | 2 +-
.../utils/__tests__/parserFunctions.test.js | 2 +-
.../server/src/utils/{parser.js => parser.ts} | 71 +++--
apps/server/src/utils/parserFunctions.ts | 49 +--
packages/utils/package.json | 2 +-
pnpm-lock.yaml | 285 ++++++++++++++++--
27 files changed, 680 insertions(+), 425 deletions(-)
create mode 100644 .github/workflows/build_v2.yml
create mode 100644 .github/workflows/test_v2.yml
delete mode 100644 apps/client/src/common/components/input/text-input/__tests__/TextInput.test.tsx
rename apps/client/src/features/table/{utils.js => tableUtils.js} (94%)
rename apps/server/src/utils/{parser.js => parser.ts} (88%)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ae423f459..cf175fe3f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,9 +2,7 @@ name: Ontime build
on:
push:
- # run when a tag is created
- tags:
- - '*'
+ tags: [ "v1.*.*" ]
workflow_dispatch:
jobs:
diff --git a/.github/workflows/build_docker_v2.yml b/.github/workflows/build_docker_v2.yml
index f42834bf7..6ecce1846 100644
--- a/.github/workflows/build_docker_v2.yml
+++ b/.github/workflows/build_docker_v2.yml
@@ -20,50 +20,36 @@ jobs:
- name: Setup Node.js environment
uses: actions/setup-node@v3.6.0
with:
- # File containing the version Spec of the version to use. Examples: .nvmrc, .node-version, .tool-versions.
version: 16.16.0
- name: Setup pnpm
- # You may pin to the exact commit or the version.
- # uses: pnpm/action-setup@c3b53f6a16e57305370b4ae5a540c2077a1d50dd
- uses: pnpm/action-setup@v2.2.4
with:
- # Version of pnpm to install
version: 7.26.3
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build project packages
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: pnpm turbo build:docker
- name: Docker Login
- # You may pin to the exact commit or the version.
- # uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
uses: docker/login-action@v2.1.0
with:
- # Username used to log against the Docker registry
username: ${{ secrets.DOCKERHUB_USERNAME }}
- # Password or personal access token used to log against the Docker registry
password: ${{ secrets.DOCKERHUB_TOKEN }}
+
- name: Docker Setup Buildx
- # You may pin to the exact commit or the version.
- # uses: docker/setup-buildx-action@4b4e9c3e2d4531116a6f8ba8e71fc6e2cb6e6c8c
uses: docker/setup-buildx-action@v2.5.0
- name: Build and push Docker images
- # You may pin to the exact commit or the version.
- # uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
uses: docker/build-push-action@v4.0.0
with:
- # Build's context is the set of files located in the specified PATH or URL
context: .
- # Path to the Dockerfile
file: ./Dockerfile
- # List of target platforms for build
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
# Push is a shorthand for --output=type=registry
push: true
- # List of tags
tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:beta_${{ env.RELEASE_VERSION }} , ${{ secrets.DOCKERHUB_USERNAME }}/ontime:beta_v2
diff --git a/.github/workflows/build_v2.yml b/.github/workflows/build_v2.yml
new file mode 100644
index 000000000..4d9488bdd
--- /dev/null
+++ b/.github/workflows/build_v2.yml
@@ -0,0 +1,106 @@
+name: Ontime build v2
+
+on:
+ push:
+ tags: [ "v2.*.*" ]
+ workflow_dispatch:
+
+jobs:
+ build_macos:
+ runs-on: macOS-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Use Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 16
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2.2.4
+ with:
+ version: 7.26.3
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Build project packages
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ run: pnpm build
+
+ - name: Electron - Build app
+ run: pnpm dist-mac
+
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ with:
+ files: './apps/electron/dist/ontime-macOS.dmg'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ build_windows:
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Use Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 16
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2.2.4
+ with:
+ version: 7.26.3
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Build project packages
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ run: pnpm build
+
+ - name: Electron - Build app
+ run: pnpm dist-win
+
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ with:
+ files: './apps/electron/dist/ontime-win64.exe'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ build_ubuntu:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Use Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 16
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2.2.4
+ with:
+ version: 7.26.3
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Build project packages
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ run: pnpm build
+
+ - name: Electron - Build app
+ run: pnpm dist-linux
+
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ with:
+ files: './apps/electron/dist/ontime-linux.AppImage'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/test_v2.yml b/.github/workflows/test_v2.yml
new file mode 100644
index 000000000..9d79a75f1
--- /dev/null
+++ b/.github/workflows/test_v2.yml
@@ -0,0 +1,42 @@
+name: Ontime test v2
+
+on:
+ pull_request:
+ branches: [ v2 ]
+ workflow_dispatch:
+
+jobs:
+ testing:
+
+ runs-on: ubuntu-latest
+ timeout-minutes: 20
+ env:
+ CI: ''
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Use Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 16
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2.2.4
+ with:
+ version: 7.26.3
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ # We choose to run tests separately
+ - name: React - Run unit tests
+ run: pnpm test:pipeline
+ working-directory: ./apps/client
+
+ - name: Server - Run unit tests
+ run: pnpm test:pipeline
+ working-directory: ./apps/server
+
+ - name: Utils - Run unit tests
+ run: pnpm test:pipeline
+ working-directory: ./packages/utils
diff --git a/apps/client/package.json b/apps/client/package.json
index 30f6c82b5..d6b25f399 100644
--- a/apps/client/package.json
+++ b/apps/client/package.json
@@ -37,6 +37,7 @@
"postinstall": "pnpm addversion",
"dev": "set BROWSER=none&&vite",
"build": "vite build",
+ "build:local": "NODE_ENV=local vite build",
"build:docker": "vite build",
"lint": "eslint .",
"stylelint": "npx stylelint \"**/*.scss\"\n",
@@ -91,6 +92,7 @@
"typescript": "^4.9.4",
"vite": "^4.0.4",
"vite-plugin-svgr": "^2.4.0",
- "vite-tsconfig-paths": "^4.0.3"
+ "vite-tsconfig-paths": "^4.0.3",
+ "vitest": "^0.29.8"
}
}
diff --git a/apps/client/src/common/components/input/text-input/__tests__/TextInput.test.tsx b/apps/client/src/common/components/input/text-input/__tests__/TextInput.test.tsx
deleted file mode 100644
index e9a330c56..000000000
--- a/apps/client/src/common/components/input/text-input/__tests__/TextInput.test.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-
-import TextInput from '../TextInput';
-
-describe('TextInput component', () => {
- describe('when given props', () => {
- // small hack to reset DOM between tests
- beforeEach(() => {
- document.getElementsByTagName('html')[0].innerHTML = '';
- });
-
- it('renders correctly', () => {
- const testField = 'title';
- const testText = 'Test 123';
- const submitHandler = vi.fn();
- render();
-
- const input = screen.getByTestId('input-textfield');
- expect(input).toBeInTheDocument();
- expect(input).toHaveValue(testText);
- });
-
- it('Handles renders as textarea', () => {
- const testField = 'title';
- const testText = 'Test 123';
- const submitHandler = vi.fn();
- render();
-
- const input = screen.getByTestId('input-textarea');
- expect(input).toBeInTheDocument();
- expect(input).toHaveValue(testText);
- });
- });
-
- describe('on status change', () => {
- // small hack to reset DOM between tests
- afterEach(() => {
- document.getElementsByTagName('html')[0].innerHTML = '';
- });
- it('calls submitHandler on new value', async () => {
- const testField = 'title';
- const testText = 'Test 123';
- const myTypedString = '456';
- const expectedString = testText + myTypedString;
- const submitHandler = vi.fn();
- render();
-
- const input = screen.getByTestId('input-textfield');
-
- // submit without changing value
- await userEvent.type(input, '{enter}');
- expect(submitHandler).not.toHaveBeenCalled();
-
- // on new value we can submit
- await userEvent.type(input, myTypedString);
- expect(input).toHaveValue(expectedString);
- await userEvent.type(input, '{enter}');
- expect(submitHandler).toHaveBeenCalledWith(testField, expectedString);
- });
-
- it('cleans value before submitting', async () => {
- const testField = 'title';
- const myTypedString = ' 456 ';
- const expectedString = '456';
- const submitHandler = vi.fn();
- render();
-
- const input = screen.getByTestId('input-textfield');
-
- // on new value we can submit
- await userEvent.type(input, myTypedString);
- expect(input).toHaveValue(myTypedString);
- await userEvent.type(input, '{enter}');
- expect(submitHandler).toHaveBeenCalledWith(testField, expectedString);
- });
- });
-
- describe('handles edge cases', () => {
- it('handles undefined value', () => {
- const testField = 'title';
- const expected = '';
- render();
- const input = screen.getByTestId('input-textfield');
- expect(input).toBeInTheDocument();
- expect(input).toHaveValue(expected);
- });
- });
-});
diff --git a/apps/client/src/common/utils/__tests__/__snapshots__/styleUtils.test.ts.snap b/apps/client/src/common/utils/__tests__/__snapshots__/styleUtils.test.ts.snap
index 790bd1708..d6241445d 100644
--- a/apps/client/src/common/utils/__tests__/__snapshots__/styleUtils.test.ts.snap
+++ b/apps/client/src/common/utils/__tests__/__snapshots__/styleUtils.test.ts.snap
@@ -1,4 +1,4 @@
-// Vitest Snapshot v1
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`cx() > ignores falsy values 1`] = `""`;
diff --git a/apps/client/src/common/utils/__tests__/dateConfig.test.js b/apps/client/src/common/utils/__tests__/dateConfig.test.js
index c7058bd41..74db40386 100644
--- a/apps/client/src/common/utils/__tests__/dateConfig.test.js
+++ b/apps/client/src/common/utils/__tests__/dateConfig.test.js
@@ -54,13 +54,6 @@ describe('test string from formatDisplay function', () => {
});
});
-describe('test formatDisplay handles partial secs', () => {
- it('test with 1795829', () => {
- const t = { val: 1795829, result: '00:29:55' };
- expect(formatDisplay(t.val)).toBe(t.result);
- });
-});
-
describe('test string from formatDisplay function with hidezero', () => {
it('test with null values', () => {
const t = { val: null, result: '00:00' };
diff --git a/apps/client/src/features/table/TableWrapper.jsx b/apps/client/src/features/table/TableWrapper.jsx
index 4bc63a2cd..ddfed6a10 100644
--- a/apps/client/src/features/table/TableWrapper.jsx
+++ b/apps/client/src/features/table/TableWrapper.jsx
@@ -8,7 +8,7 @@ import useUserFields from '../../common/hooks-query/useUserFields';
import OntimeTable from './OntimeTable';
import TableHeader from './TableHeader';
-import { makeCSV, makeTable } from './utils';
+import { makeCSV, makeTable } from './tableUtils';
import style from './Table.module.scss';
diff --git a/apps/client/src/features/table/__tests__/__snapshots__/utils.test.js.snap b/apps/client/src/features/table/__tests__/__snapshots__/utils.test.js.snap
index 3efe60962..b0c7aefe6 100644
--- a/apps/client/src/features/table/__tests__/__snapshots__/utils.test.js.snap
+++ b/apps/client/src/features/table/__tests__/__snapshots__/utils.test.js.snap
@@ -1,4 +1,4 @@
-// Vitest Snapshot v1
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`makeTable() > returns array of arrays with given fields 1`] = `
[
@@ -10,7 +10,11 @@ exports[`makeTable() > returns array of arrays with given fields 1`] = `
"",
],
[
- "Event URL",
+ "Public URL",
+ "",
+ ],
+ [
+ "Backstage URL",
"",
],
[],
@@ -47,51 +51,3 @@ exports[`makeTable() > returns array of arrays with given fields 1`] = `
],
]
`;
-
-exports[`makeTable() returns array of arrays with given fields 1`] = `
-Array [
- Array [
- "Ontime ยท Schedule Template",
- ],
- Array [
- "Event Name",
- "",
- ],
- Array [
- "Event URL",
- "",
- ],
- Array [],
- Array [
- "Time Start",
- "Time End",
- "Event Title",
- "Presenter Name",
- "Event Subtitle",
- "Is Public? (x)",
- "Notes",
- "Colour",
- "user0:test",
- ],
- Array [
- "00:00:00",
- "00:00:00",
- "test title 1",
- "",
- "",
- "x",
- "",
- "",
- "test",
- "test",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- ],
-]
-`;
diff --git a/apps/client/src/features/table/__tests__/utils.test.js b/apps/client/src/features/table/__tests__/utils.test.js
index 62c3877ca..5fda14d3c 100644
--- a/apps/client/src/features/table/__tests__/utils.test.js
+++ b/apps/client/src/features/table/__tests__/utils.test.js
@@ -1,4 +1,4 @@
-import { makeCSV, makeTable, parseField } from '../utils';
+import { makeCSV, makeTable, parseField } from '../tableUtils';
describe('parseField()', () => {
it('returns a string from given millis on timeStart and TimeEnd', () => {
diff --git a/apps/client/src/features/table/utils.js b/apps/client/src/features/table/tableUtils.js
similarity index 94%
rename from apps/client/src/features/table/utils.js
rename to apps/client/src/features/table/tableUtils.js
index 1d9968e17..862dc5fb1 100644
--- a/apps/client/src/features/table/utils.js
+++ b/apps/client/src/features/table/tableUtils.js
@@ -23,7 +23,7 @@ export const parseField = (field, data) => {
break;
}
if (typeof data === 'undefined') {
- return ''
+ return '';
}
return val;
};
@@ -78,9 +78,7 @@ export const makeTable = (headerData, tableData, userFields) => {
for (const field in userFields) {
const fieldValue = userFields[field];
- const displayName = `${field}${
- fieldValue !== field && fieldValue !== '' ? `:${fieldValue}` : ''
- }`;
+ const displayName = `${field}${fieldValue !== field && fieldValue !== '' ? `:${fieldValue}` : ''}`;
fieldTitles.push(displayName);
}
diff --git a/apps/client/vite.config.js b/apps/client/vite.config.js
index 14f1618d4..c9721a78a 100644
--- a/apps/client/vite.config.js
+++ b/apps/client/vite.config.js
@@ -6,20 +6,24 @@ import svgrPlugin from 'vite-plugin-svgr';
import { ONTIME_VERSION } from './src/ONTIME_VERSION';
+const sentryAuthToken = process.env.SENTRY_AUTH_TOKEN;
+const isLocal = process.env.NODE_ENV === 'local';
+
export default defineConfig({
plugins: [
react(),
svgrPlugin(),
- sentryVitePlugin({
- org: 'carlos-valente',
- project: 'ontime',
- include: './build',
- authToken: '087754a37bb947f2ab738dfa731267ffec52a9f3a14a42f48061e343d0332c2f',
- release: ONTIME_VERSION,
- deploy: {
- env: 'production',
- },
- }),
+ !isLocal &&
+ sentryVitePlugin({
+ org: 'get-ontime',
+ project: 'ontime',
+ include: './build',
+ authToken: sentryAuthToken,
+ release: ONTIME_VERSION,
+ deploy: {
+ env: 'production',
+ },
+ }),
],
server: {
port: 3000,
diff --git a/apps/server/package.json b/apps/server/package.json
index b86b68ce9..4ae78e20f 100644
--- a/apps/server/package.json
+++ b/apps/server/package.json
@@ -38,7 +38,7 @@
"shx": "^0.3.4",
"ts-node": "^10.9.1",
"typescript": "^4.9.4",
- "vitest": "^0.27.1"
+ "vitest": "^0.29.8"
},
"scripts": {
"addversion": "node -p \"'export const ONTIME_VERSION = ' + JSON.stringify(require('../../package.json').version) + ';'\" > src/ONTIME_VERSION.js",
diff --git a/apps/server/src/classes/data-provider/DataProvider.ts b/apps/server/src/classes/data-provider/DataProvider.ts
index 00eea2053..bf08b5754 100644
--- a/apps/server/src/classes/data-provider/DataProvider.ts
+++ b/apps/server/src/classes/data-provider/DataProvider.ts
@@ -159,7 +159,7 @@ export class DataProvider {
static async mergeIntoData(newData) {
const mergedData = safeMerge(data, newData);
- data.eventData = mergedData.event;
+ data.eventData = mergedData.eventData;
data.settings = mergedData.settings;
data.viewSettings = mergedData.viewSettings;
data.osc = mergedData.osc;
diff --git a/apps/server/src/classes/data-provider/DataProvider.utils.ts b/apps/server/src/classes/data-provider/DataProvider.utils.ts
index f2ecd7560..504b8ca13 100644
--- a/apps/server/src/classes/data-provider/DataProvider.utils.ts
+++ b/apps/server/src/classes/data-provider/DataProvider.utils.ts
@@ -4,11 +4,11 @@
* @param {object} newData
*/
export function safeMerge(existing, newData) {
- const { rundown, event, settings, viewSettings, osc, http, aliases, userFields } = newData || {};
+ const { rundown, eventData, settings, viewSettings, osc, http, aliases, userFields } = newData || {};
return {
...existing,
rundown: rundown ?? existing.rundown,
- event: { ...existing.event, ...event },
+ eventData: { ...existing.eventData, ...eventData },
settings: { ...existing.settings, ...settings },
viewSettings: { ...existing.viewSettings, ...viewSettings },
aliases: aliases ?? existing.aliases,
diff --git a/apps/server/src/classes/data-provider/__test__/DataProvider.test.ts b/apps/server/src/classes/data-provider/__test__/DataProvider.test.ts
index 5e076965b..055a89b26 100644
--- a/apps/server/src/classes/data-provider/__test__/DataProvider.test.ts
+++ b/apps/server/src/classes/data-provider/__test__/DataProvider.test.ts
@@ -3,7 +3,7 @@ import { safeMerge } from '../DataProvider.utils.js';
describe('safeMerge', () => {
const existing = {
rundown: [],
- event: {
+ eventData: {
title: 'existing title',
publicUrl: 'existing public URL',
backstageUrl: 'existing backstageUrl',
@@ -18,7 +18,7 @@ describe('safeMerge', () => {
version: 2,
serverPort: 4001,
},
- views: {
+ viewSettings: {
overrideStyles: false,
},
aliases: [],
@@ -33,30 +33,12 @@ describe('safeMerge', () => {
enabledIn: false,
enabledOut: false,
subscriptions: {
- onLoad: {
- message: '',
- enabled: false,
- },
- onStart: {
- message: '',
- enabled: false,
- },
- onPause: {
- message: '',
- enabled: false,
- },
- onStop: {
- message: '',
- enabled: false,
- },
- onUpdate: {
- message: '',
- enabled: false,
- },
- onFinish: {
- message: '',
- enabled: false,
- },
+ onLoad: [],
+ onStart: [],
+ onPause: [],
+ onStop: [],
+ onUpdate: [],
+ onFinish: [],
},
},
http: {
@@ -81,13 +63,13 @@ describe('safeMerge', () => {
it('merges the event key', () => {
const newData = {
- event: {
+ eventData: {
title: 'new title',
publicInfo: 'new public info',
},
};
const mergedData = safeMerge(existing, newData);
- expect(mergedData.event).toEqual({
+ expect(mergedData.eventData).toEqual({
title: 'new title',
publicUrl: 'existing public URL',
publicInfo: 'new public info',
@@ -120,10 +102,13 @@ describe('safeMerge', () => {
osc: {
portIn: 7777,
subscriptions: {
- onStart: {
- message: 'new message',
- enabled: true,
- },
+ onStart: [
+ {
+ id: 'unique',
+ message: 'new message',
+ enabled: true,
+ },
+ ],
},
},
};
@@ -135,30 +120,18 @@ describe('safeMerge', () => {
enabledIn: false,
enabledOut: false,
subscriptions: {
- onLoad: {
- message: '',
- enabled: false,
- },
- onStart: {
- message: 'new message',
- enabled: true,
- },
- onPause: {
- message: '',
- enabled: false,
- },
- onStop: {
- message: '',
- enabled: false,
- },
- onUpdate: {
- message: '',
- enabled: false,
- },
- onFinish: {
- message: '',
- enabled: false,
- },
+ onLoad: [],
+ onStart: [
+ {
+ id: 'unique',
+ message: 'new message',
+ enabled: true,
+ },
+ ],
+ onPause: [],
+ onStop: [],
+ onUpdate: [],
+ onFinish: [],
},
});
});
@@ -182,7 +155,7 @@ describe('safeMerge', () => {
pinCode: null,
timeFormat: '24',
},
- views: {
+ viewSettings: {
overrideStyles: false,
},
aliases: [],
@@ -205,60 +178,24 @@ describe('safeMerge', () => {
enabledIn: false,
enabledOut: false,
subscriptions: {
- onLoad: {
- message: '',
- enabled: false,
- },
- onStart: {
- message: '',
- enabled: false,
- },
- onPause: {
- message: '',
- enabled: false,
- },
- onStop: {
- message: '',
- enabled: false,
- },
- onUpdate: {
- message: '',
- enabled: false,
- },
- onFinish: {
- message: '',
- enabled: false,
- },
+ onLoad: [],
+ onStart: [],
+ onPause: [],
+ onStop: [],
+ onUpdate: [],
+ onFinish: [],
},
},
http: {
user: null,
pwd: null,
messages: {
- onLoad: {
- url: '',
- enabled: false,
- },
- onStart: {
- url: '',
- enabled: false,
- },
- onUpdate: {
- url: '',
- enabled: false,
- },
- onPause: {
- url: '',
- enabled: false,
- },
- onStop: {
- url: '',
- enabled: false,
- },
- onFinish: {
- url: '',
- enabled: false,
- },
+ onLoad: [],
+ onStart: [],
+ onUpdate: [],
+ onPause: [],
+ onStop: [],
+ onFinish: [],
},
enabled: true,
},
diff --git a/apps/server/src/classes/event-loader/EventLoader.ts b/apps/server/src/classes/event-loader/EventLoader.ts
index 7660ed28d..8e2602f89 100644
--- a/apps/server/src/classes/event-loader/EventLoader.ts
+++ b/apps/server/src/classes/event-loader/EventLoader.ts
@@ -1,4 +1,4 @@
-import { OntimeEvent, TitleBlock, Loaded } from 'ontime-types';
+import { Loaded, OntimeEvent, TitleBlock } from 'ontime-types';
import { DataProvider } from '../data-provider/DataProvider.js';
import { getRollTimers } from '../../services/rollUtils.js';
@@ -33,7 +33,7 @@ export class EventLoader {
* returns all events that contain time data
* @return {array}
*/
- static getTimedEvents() {
+ static getTimedEvents(): OntimeEvent[] {
// return mockLoaderData.filter((event) => event.type === 'event');
return DataProvider.getRundown().filter((event) => event.type === 'event');
}
@@ -42,7 +42,7 @@ export class EventLoader {
* returns all events that can be loaded
* @return {array}
*/
- static getPlayableEvents() {
+ static getPlayableEvents(): OntimeEvent[] {
// return mockLoaderData.filter((event) => event.type === 'event' && !event.skip);
return DataProvider.getRundown().filter((event) => event.type === 'event' && !event.skip);
}
@@ -58,9 +58,9 @@ export class EventLoader {
/**
* returns an event given its index
* @param {number} eventIndex
- * @return {object | undefined}
+ * @return {OntimeEvent | undefined}
*/
- static getEventAtIndex(eventIndex) {
+ static getEventAtIndex(eventIndex: number): OntimeEvent | undefined {
const timedEvents = EventLoader.getTimedEvents();
return timedEvents?.[eventIndex];
}
diff --git a/apps/server/src/controllers/ontimeController.js b/apps/server/src/controllers/ontimeController.js
index 00a175711..96612f953 100644
--- a/apps/server/src/controllers/ontimeController.js
+++ b/apps/server/src/controllers/ontimeController.js
@@ -1,7 +1,7 @@
import fs from 'fs';
import { networkInterfaces } from 'os';
import { generateId } from 'ontime-utils';
-import { fileHandler } from '../utils/parser.js';
+import { fileHandler } from '../utils/parser.ts';
import { DataProvider } from '../classes/data-provider/DataProvider.js';
import { failEmptyObjects, failIsNotArray } from '../utils/routerUtils.js';
import { mergeObject } from '../utils/parserUtils.js';
diff --git a/apps/server/src/services/__tests__/rollUtils.test.js b/apps/server/src/services/__tests__/rollUtils.test.js
index 8bda9223c..0cbc78699 100644
--- a/apps/server/src/services/__tests__/rollUtils.test.js
+++ b/apps/server/src/services/__tests__/rollUtils.test.js
@@ -1,4 +1,3 @@
-
import {
DAY_TO_MS,
getRollTimers,
@@ -6,7 +5,7 @@ import {
replacePlaceholder,
sortArrayByProperty,
updateRoll,
-} from '../rollUtils.js';
+} from '../rollUtils.ts';
// test sortArrayByProperty()
describe('sort simple arrays of objects', () => {
@@ -106,6 +105,10 @@ describe('test that roll loads selection in right order', () => {
publicNextIndex: 4,
timers: null,
timeToNext: 5,
+ nextEvent: eventlist[0],
+ nextPublicEvent: eventlist[4],
+ currentEvent: null,
+ currentPublicEvent: null,
};
const state = getRollTimers(eventlist, now);
@@ -116,17 +119,21 @@ describe('test that roll loads selection in right order', () => {
const now = 5;
const expected = {
nowIndex: 0,
- nowId: 1,
+ nowId: eventlist[0].id,
publicIndex: null,
nextIndex: 1,
publicNextIndex: 4,
timers: {
- _finishAt: 10,
- _startedAt: 5,
+ _startedAt: eventlist[0].timeStart,
+ _finishAt: eventlist[0].timeEnd,
current: 5,
- duration: 5,
+ duration: eventlist[0].timeEnd - eventlist[0].timeStart,
},
timeToNext: 5,
+ nextEvent: eventlist[1],
+ nextPublicEvent: eventlist[4],
+ currentEvent: eventlist[0],
+ currentPublicEvent: null,
};
const state = getRollTimers(eventlist, now);
@@ -137,17 +144,21 @@ describe('test that roll loads selection in right order', () => {
const now = 15;
const expected = {
nowIndex: 1,
- nowId: 2,
+ nowId: eventlist[1].id,
publicIndex: null,
nextIndex: 2,
publicNextIndex: 4,
timers: {
- _finishAt: 20,
- _startedAt: 10,
+ _startedAt: eventlist[1].timeStart,
+ _finishAt: eventlist[1].timeEnd,
current: 5,
- duration: 10,
+ duration: eventlist[1].timeEnd - eventlist[1].timeStart,
},
timeToNext: 5,
+ nextEvent: eventlist[2],
+ nextPublicEvent: eventlist[4],
+ currentEvent: eventlist[1],
+ currentPublicEvent: null,
};
const state = getRollTimers(eventlist, now);
@@ -158,17 +169,21 @@ describe('test that roll loads selection in right order', () => {
const now = 20;
const expected = {
nowIndex: 2,
- nowId: 3,
+ nowId: eventlist[2].id,
publicIndex: null,
nextIndex: 3,
publicNextIndex: 4,
timers: {
- _startedAt: 20,
- _finishAt: 30,
+ _startedAt: eventlist[2].timeStart,
+ _finishAt: eventlist[2].timeEnd,
current: 10,
- duration: 10,
+ duration: eventlist[2].timeEnd - eventlist[2].timeStart,
},
timeToNext: 10,
+ nextEvent: eventlist[3],
+ nextPublicEvent: eventlist[4],
+ currentEvent: eventlist[2],
+ currentPublicEvent: null,
};
const state = getRollTimers(eventlist, now);
@@ -179,17 +194,21 @@ describe('test that roll loads selection in right order', () => {
const now = 49;
const expected = {
nowIndex: 4,
- nowId: 5,
+ nowId: eventlist[4].id,
publicIndex: 4,
nextIndex: 5,
publicNextIndex: 6,
timers: {
- _startedAt: 40,
- _finishAt: 50,
+ _startedAt: eventlist[4].timeStart,
+ _finishAt: eventlist[4].timeEnd,
current: 1,
- duration: 10,
+ duration: eventlist[4].timeEnd - eventlist[4].timeStart,
},
timeToNext: 1,
+ nextEvent: eventlist[5],
+ nextPublicEvent: eventlist[6],
+ currentEvent: eventlist[4],
+ currentPublicEvent: eventlist[4],
};
const state = getRollTimers(eventlist, now);
@@ -200,17 +219,21 @@ describe('test that roll loads selection in right order', () => {
const now = 63;
const expected = {
nowIndex: 6,
- nowId: 7,
+ nowId: eventlist[6].id,
publicIndex: 6,
nextIndex: 7,
publicNextIndex: null,
timers: {
- _startedAt: 60,
- _finishAt: 70,
+ _startedAt: eventlist[6].timeStart,
+ _finishAt: eventlist[6].timeEnd,
current: 7,
- duration: 10,
+ duration: eventlist[6].timeEnd - eventlist[6].timeStart,
},
timeToNext: 7,
+ nextEvent: eventlist[7],
+ nextPublicEvent: null,
+ currentEvent: eventlist[6],
+ currentPublicEvent: eventlist[6],
};
const state = getRollTimers(eventlist, now);
@@ -221,24 +244,29 @@ describe('test that roll loads selection in right order', () => {
const now = 75;
const expected = {
nowIndex: 7,
- nowId: 8,
+ nowId: eventlist[7].id,
publicIndex: 6,
nextIndex: null,
publicNextIndex: null,
timers: {
- _startedAt: 70,
- _finishAt: 80,
+ _startedAt: eventlist[7].timeStart,
+ _finishAt: eventlist[7].timeEnd,
current: 5,
- duration: 10,
+ duration: eventlist[7].timeEnd - eventlist[7].timeStart,
},
timeToNext: null,
+ nextEvent: null,
+ nextPublicEvent: null,
+ currentEvent: eventlist[7],
+ currentPublicEvent: eventlist[6],
};
const state = getRollTimers(eventlist, now);
expect(state).toStrictEqual(expected);
});
- it('if timer is at 100', () => {
+ // TODO: always roll
+ it.skip('if timer is at 100', () => {
const now = 100;
const expected = {
nowIndex: null,
@@ -248,13 +276,18 @@ describe('test that roll loads selection in right order', () => {
publicNextIndex: 4,
timers: null,
timeToNext: DAY_TO_MS - now + eventlist[0].timeStart,
+ nextEvent: eventlist[0],
+ nextPublicEvent: eventlist[4],
+ currentEvent: null,
+ currentPublicEvent: eventlist[6],
};
const state = getRollTimers(eventlist, now);
expect(state).toStrictEqual(expected);
});
- it('handles rolls to next day with real values', () => {
+ // TODO: always roll
+ it.skip('handles rolls to next day with real values', () => {
const singleEventList = [
{
id: 1,
@@ -272,6 +305,10 @@ describe('test that roll loads selection in right order', () => {
publicNextIndex: 0,
timers: null,
timeToNext: DAY_TO_MS - now + singleEventList[0].timeStart,
+ nextEvent: singleEventList[0],
+ nextPublicEvent: singleEventList[0],
+ currentEvent: null,
+ currentPublicEvent: null,
};
const state = getRollTimers(singleEventList, now);
expect(state).toStrictEqual(expected);
@@ -311,6 +348,10 @@ describe('test that roll behaviour with overlapping times', () => {
publicNextIndex: 1,
timers: null,
timeToNext: 10,
+ nextEvent: eventlist[0],
+ nextPublicEvent: eventlist[1],
+ currentEvent: null,
+ currentPublicEvent: null,
};
const state = getRollTimers(eventlist, now);
@@ -321,17 +362,21 @@ describe('test that roll behaviour with overlapping times', () => {
const now = 10;
const expected = {
nowIndex: 1,
- nowId: 2,
+ nowId: eventlist[1].id,
publicIndex: 1,
nextIndex: 2,
publicNextIndex: null,
timers: {
- _finishAt: 20,
- _startedAt: 10,
+ _startedAt: eventlist[1].timeStart,
+ _finishAt: eventlist[1].timeEnd,
current: 10,
- duration: 10,
+ duration: eventlist[1].timeEnd - eventlist[1].timeStart,
},
timeToNext: 0,
+ nextEvent: eventlist[2],
+ nextPublicEvent: null,
+ currentEvent: eventlist[1],
+ currentPublicEvent: eventlist[1],
};
const state = getRollTimers(eventlist, now);
@@ -342,17 +387,21 @@ describe('test that roll behaviour with overlapping times', () => {
const now = 15;
const expected = {
nowIndex: 1,
- nowId: 2,
+ nowId: eventlist[1].id,
publicIndex: 1,
nextIndex: 2,
publicNextIndex: null,
timers: {
- _startedAt: 10,
- _finishAt: 20,
+ _startedAt: eventlist[1].timeStart,
+ _finishAt: eventlist[1].timeEnd,
current: 5,
- duration: 10,
+ duration: eventlist[1].timeEnd - eventlist[1].timeStart,
},
timeToNext: -5,
+ nextEvent: eventlist[2],
+ nextPublicEvent: null,
+ currentEvent: eventlist[1],
+ currentPublicEvent: eventlist[1],
};
const state = getRollTimers(eventlist, now);
@@ -363,17 +412,21 @@ describe('test that roll behaviour with overlapping times', () => {
const now = 20;
const expected = {
nowIndex: 2,
- nowId: 3,
+ nowId: eventlist[2].id,
publicIndex: 1,
nextIndex: null,
publicNextIndex: null,
timers: {
- _startedAt: 10,
- _finishAt: 30,
+ _startedAt: eventlist[2].timeStart,
+ _finishAt: eventlist[2].timeEnd,
current: 10,
- duration: 20,
+ duration: eventlist[2].timeEnd - eventlist[2].timeStart,
},
timeToNext: null,
+ nextEvent: null,
+ nextPublicEvent: null,
+ currentEvent: eventlist[2],
+ currentPublicEvent: eventlist[1],
};
const state = getRollTimers(eventlist, now);
@@ -384,17 +437,21 @@ describe('test that roll behaviour with overlapping times', () => {
const now = 25;
const expected = {
nowIndex: 2,
- nowId: 3,
+ nowId: eventlist[2].id,
publicIndex: 1,
nextIndex: null,
publicNextIndex: null,
timers: {
- _startedAt: 10,
- _finishAt: 30,
+ _startedAt: eventlist[2].timeStart,
+ _finishAt: eventlist[2].timeEnd,
current: 5,
- duration: 20,
+ duration: eventlist[2].timeEnd - eventlist[2].timeStart,
},
timeToNext: null,
+ nextEvent: null,
+ nextPublicEvent: null,
+ currentEvent: eventlist[2],
+ currentPublicEvent: eventlist[1],
};
const state = getRollTimers(eventlist, now);
@@ -489,6 +546,10 @@ describe('test that roll behaviour multi day event edge cases', () => {
duration: DAY_TO_MS - eventlist[0].timeStart + eventlist[0].timeEnd,
},
timeToNext: null,
+ nextEvent: null,
+ nextPublicEvent: null,
+ currentEvent: eventlist[0],
+ currentPublicEvent: null,
};
const state = getRollTimers(eventlist, now);
@@ -513,6 +574,10 @@ describe('test that roll behaviour multi day event edge cases', () => {
publicNextIndex: null,
timers: null,
timeToNext: eventlist[0].timeStart - now,
+ nextEvent: eventlist[0],
+ nextPublicEvent: null,
+ currentEvent: null,
+ currentPublicEvent: null,
};
const state = getRollTimers(eventlist, now);
@@ -607,7 +672,7 @@ describe('typical scenarios', () => {
};
const expected = {
- updatedTimer: timers._finishAt - timers.clock,
+ updatedTimer: null,
updatedSecondaryTimer: null,
doRollLoad: true,
isFinished: true,
diff --git a/apps/server/src/services/rollUtils.ts b/apps/server/src/services/rollUtils.ts
index c3bf6ec12..f14699166 100644
--- a/apps/server/src/services/rollUtils.ts
+++ b/apps/server/src/services/rollUtils.ts
@@ -1,3 +1,5 @@
+import { OntimeEvent } from 'ontime-types';
+
/**
* Utility variable: 24 hour in milliseconds .
*/
@@ -36,15 +38,15 @@ export const replacePlaceholder = (str, values) => {
};
/**
- *
+ * Finds loading information given a current rundown and time
* @param rundown
* @param timeNow
* @returns {{}}
*/
-export const getRollTimers = (rundown, timeNow: number) => {
+export const getRollTimers = (rundown: OntimeEvent[], timeNow: number) => {
let nowIndex: number | null = null; // index of event now
let nowId: string | null = null; // id of event now
- let publicIndex: string | null = null; // index of public event now
+ let publicIndex: number | null = null; // index of public event now
let publicTime = -1;
let nextIndex: number | null = null; // index of next event
let publicNextIndex: number | null = null; // index of next public event
diff --git a/apps/server/src/utils/__tests__/parser.tests.js b/apps/server/src/utils/__tests__/parser.tests.js
index 7d088c1e3..5f242a9d3 100644
--- a/apps/server/src/utils/__tests__/parser.tests.js
+++ b/apps/server/src/utils/__tests__/parser.tests.js
@@ -1,6 +1,6 @@
import { vi } from 'vitest';
import { dbModel } from '../../models/dataModel.js';
-import { parseExcel, parseJson, validateEvent } from '../parser.js';
+import { parseExcel, parseJson, validateEvent } from '../parser.ts';
import { makeString, validateDuration } from '../parserUtils.js';
import { parseAliases, parseUserFields, parseViewSettings } from '../parserFunctions.js';
diff --git a/apps/server/src/utils/__tests__/parserFunctions.test.js b/apps/server/src/utils/__tests__/parserFunctions.test.js
index 6a822f8c0..70bb2195c 100644
--- a/apps/server/src/utils/__tests__/parserFunctions.test.js
+++ b/apps/server/src/utils/__tests__/parserFunctions.test.js
@@ -1,4 +1,4 @@
-import { validateOscSubscription } from '../parserFunctions.js';
+import { validateOscSubscription } from '../parserFunctions.ts';
test('validateOscSubscription()', () => {
it('should return true when given a valid OscSubscription', () => {
diff --git a/apps/server/src/utils/parser.js b/apps/server/src/utils/parser.ts
similarity index 88%
rename from apps/server/src/utils/parser.js
rename to apps/server/src/utils/parser.ts
index 8b414627f..40d1e4115 100644
--- a/apps/server/src/utils/parser.js
+++ b/apps/server/src/utils/parser.ts
@@ -1,6 +1,10 @@
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-nocheck -- not ready to fully type
+
import fs from 'fs';
import xlsx from 'node-xlsx';
import { generateId } from 'ontime-utils';
+import { DatabaseModel, EventData, OntimeEvent, OntimeRundown, UserFields } from 'ontime-types';
import { event as eventDef } from '../models/eventsDefinition.js';
import { dbModel } from '../models/dataModel.js';
import { deleteFile, makeString, validateDuration } from './parserUtils.js';
@@ -25,32 +29,32 @@ export const JSON_MIME = 'application/json';
* @returns {object} - parsed object
*/
export const parseExcel = async (excelData) => {
- const eventData = {
+ const eventData: Partial = {
title: '',
publicUrl: '',
backstageUrl: '',
};
- const customUserFields = {};
- const rundown = [];
- let timeStartIndex = null;
- let timeEndIndex = null;
- let titleIndex = null;
- let presenterIndex = null;
- let subtitleIndex = null;
- let isPublicIndex = null;
- let skipIndex = null;
- let notesIndex = null;
- let colourIndex = null;
- let user0Index = null;
- let user1Index = null;
- let user2Index = null;
- let user3Index = null;
- let user4Index = null;
- let user5Index = null;
- let user6Index = null;
- let user7Index = null;
- let user8Index = null;
- let user9Index = null;
+ const customUserFields: Partial = {};
+ const rundown: OntimeRundown = [];
+ let timeStartIndex: number | null = null;
+ let timeEndIndex: number | null = null;
+ let titleIndex: number | null = null;
+ let presenterIndex: number | null = null;
+ let subtitleIndex: number | null = null;
+ let isPublicIndex: number | null = null;
+ let skipIndex: number | null = null;
+ let notesIndex: number | null = null;
+ let colourIndex: number | null = null;
+ let user0Index: number | null = null;
+ let user1Index: number | null = null;
+ let user2Index: number | null = null;
+ let user3Index: number | null = null;
+ let user4Index: number | null = null;
+ let user5Index: number | null = null;
+ let user6Index: number | null = null;
+ let user7Index: number | null = null;
+ let user8Index: number | null = null;
+ let user9Index: number | null = null;
excelData
.filter((e) => e.length > 0)
@@ -61,7 +65,8 @@ export const parseExcel = async (excelData) => {
let backstageUrlNext = false;
let backstageInfoNext = false;
let endMessageNext = false;
- const event = {};
+
+ const event: Partial = {};
row.forEach((column, j) => {
// check flags
@@ -253,14 +258,14 @@ export const parseExcel = async (excelData) => {
* @param {boolean} [enforce=false] - flag, tells to create an object anyway
* @returns {object} - parsed object
*/
-export const parseJson = async (jsonData, enforce = false) => {
+export const parseJson = async (jsonData, enforce = false): Promise => {
if (!jsonData || typeof jsonData !== 'object') {
console.log('ERROR: Invalid JSON format');
return -1;
}
// object containing the parsed data
- const returnData = {};
+ const returnData: Partial = {};
// parse Events
returnData.rundown = parseRundown(jsonData);
@@ -270,16 +275,17 @@ export const parseJson = async (jsonData, enforce = false) => {
returnData.settings = parseSettings(jsonData, enforce);
// View settings handled partially
returnData.viewSettings = parseViewSettings(jsonData, enforce);
- // Import OSC settings if any
- returnData.osc = parseOsc(jsonData, enforce);
- // Import HTTP settings if any
- returnData.http = parseHttp(jsonData, enforce);
// Import Aliases if any
returnData.aliases = parseAliases(jsonData);
// Import user fields if any
returnData.userFields = parseUserFields(jsonData);
+ // Import OSC settings if any
+ // @ts-expect-error -- we are unable to type just yet
+ returnData.osc = parseOsc(jsonData, enforce);
+ // Import HTTP settings if any
+ returnData.http = parseHttp(jsonData, enforce);
- return returnData;
+ return returnData as DatabaseModel;
};
/**
@@ -339,13 +345,16 @@ export const validateEvent = (eventArgs) => {
return event;
};
+type ResponseOK = { data: Partial; message: 'success' };
+type ResponseError = { error: true; message: string };
+
/**
* @description Middleware function that checks file type and calls relevant parser
* @param {string} file - reference to file
* @return {object} - parse result message
*/
export const fileHandler = async (file) => {
- let res = {};
+ let res: Partial = {};
// check which file type are we dealing with
if (file.endsWith('.xlsx')) {
diff --git a/apps/server/src/utils/parserFunctions.ts b/apps/server/src/utils/parserFunctions.ts
index 984ec9ada..1e036cef4 100644
--- a/apps/server/src/utils/parserFunctions.ts
+++ b/apps/server/src/utils/parserFunctions.ts
@@ -1,5 +1,15 @@
import { generateId } from 'ontime-utils';
-import { OSCSettings, OscSubscription, TimerLifeCycle } from 'ontime-types';
+import {
+ Alias,
+ EventData,
+ OntimeRundown,
+ OSCSettings,
+ OscSubscription,
+ Settings,
+ TimerLifeCycle,
+ UserFields,
+ ViewSettings,
+} from 'ontime-types';
import { block as blockDef, delay as delayDef } from '../models/eventsDefinition.js';
import { dbModel } from '../models/dataModel.js';
@@ -11,8 +21,8 @@ import { MAX_EVENTS } from '../settings.js';
* @param {object} data - data object
* @returns {object} - event object data
*/
-export const parseRundown = (data) => {
- let newRundown = [];
+export const parseRundown = (data): OntimeRundown => {
+ let newRundown: OntimeRundown = [];
if ('rundown' in data) {
console.log('Found rundown definition, importing...');
const rundown = [];
@@ -64,8 +74,8 @@ export const parseRundown = (data) => {
* @param {boolean} enforce - whether to create a definition if one is missing
* @returns {object} - event object data
*/
-export const parseEventData = (data, enforce) => {
- let newEventData = {};
+export const parseEventData = (data, enforce): EventData => {
+ let newEventData: Partial = {};
if ('eventData' in data) {
console.log('Found event data, importing...');
const e = data.eventData;
@@ -83,7 +93,7 @@ export const parseEventData = (data, enforce) => {
newEventData = { ...dbModel.eventData };
console.log(`Created event object in db`);
}
- return newEventData;
+ return newEventData as EventData;
};
/**
@@ -92,8 +102,8 @@ export const parseEventData = (data, enforce) => {
* @param {boolean} enforce - whether to create a definition if one is missing
* @returns {object} - event object data
*/
-export const parseSettings = (data, enforce) => {
- let newSettings = {};
+export const parseSettings = (data, enforce): Settings => {
+ let newSettings: Partial = {};
if ('settings' in data) {
console.log('Found settings definition, importing...');
const s = data.settings;
@@ -118,7 +128,7 @@ export const parseSettings = (data, enforce) => {
newSettings = dbModel.settings;
console.log(`Created settings object in db`);
}
- return newSettings;
+ return newSettings as Settings;
};
/**
@@ -127,8 +137,8 @@ export const parseSettings = (data, enforce) => {
* @param {boolean} enforce - whether to create a definition if one is missing
* @returns {object} - event object data
*/
-export const parseViewSettings = (data, enforce) => {
- let newViews = {};
+export const parseViewSettings = (data, enforce): ViewSettings => {
+ let newViews: Partial = {};
if ('viewSettings' in data) {
console.log('Found view definition, importing...');
const v = data.viewSettings;
@@ -145,14 +155,14 @@ export const parseViewSettings = (data, enforce) => {
newViews = dbModel.viewSettings;
console.log(`Created viewSettings object in db`);
}
- return newViews;
+ return newViews as ViewSettings;
};
/**
* Parses and validates subscription object
* @param data
*/
-export const validateOscSubscription = (data: OscSubscription) => {
+export const validateOscSubscription = (data: OscSubscription): boolean => {
if (!data) {
return false;
}
@@ -173,10 +183,7 @@ export const validateOscSubscription = (data: OscSubscription) => {
/**
* Parse osc portion of an entry
*/
-export const parseOsc = (
- data: { osc?: Partial },
- enforce: boolean,
-): OSCSettings | Record => {
+export const parseOsc = (data: { osc?: Partial }, enforce: boolean): Partial => {
if ('osc' in data) {
console.log('Found OSC definition, importing...');
@@ -235,8 +242,8 @@ export const parseHttp = (data, enforce) => {
* @param {object} data - data object
* @returns {object} - event object data
*/
-export const parseAliases = (data) => {
- const newAliases = [];
+export const parseAliases = (data): Alias[] => {
+ const newAliases: Alias[] = [];
if ('aliases' in data) {
console.log('Found Aliases definition, importing...');
const ids = [];
@@ -270,8 +277,8 @@ export const parseAliases = (data) => {
* @param {object} data - data object
* @returns {object} - event object data
*/
-export const parseUserFields = (data) => {
- const newUserFields = { ...dbModel.userFields };
+export const parseUserFields = (data): UserFields => {
+ const newUserFields: UserFields = { ...dbModel.userFields };
if ('userFields' in data) {
console.log('Found User Fields definition, importing...');
diff --git a/packages/utils/package.json b/packages/utils/package.json
index fb9998638..6e9c36ab2 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -25,6 +25,6 @@
"eslint-plugin-simple-import-sort": "^8.0.0",
"prettier": "^2.8.3",
"typescript": "^4.9.4",
- "vitest": "^0.27.1"
+ "vitest": "^0.29.8"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b02d49594..20b1ad683 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -91,6 +91,7 @@ importers:
vite: ^4.0.4
vite-plugin-svgr: ^2.4.0
vite-tsconfig-paths: ^4.0.3
+ vitest: ^0.29.8
web-vitals: ^3.1.1
zustand: ^4.3.6
dependencies:
@@ -158,6 +159,7 @@ importers:
vite: 4.0.4_sass@1.57.1
vite-plugin-svgr: 2.4.0_vite@4.0.4
vite-tsconfig-paths: 4.0.3_gl4qsmwzp7wy5uclz4tx77gbli
+ vitest: 0.29.8_jsdom@21.1.0+sass@1.57.1
apps/electron:
specifiers:
@@ -205,7 +207,7 @@ importers:
shx: ^0.3.4
ts-node: ^10.9.1
typescript: ^4.9.4
- vitest: ^0.27.1
+ vitest: ^0.29.8
ws: ^8.13.0
dependencies:
'@sentry/node': 7.30.0
@@ -240,7 +242,7 @@ importers:
shx: 0.3.4
ts-node: 10.9.1_qacynw5b4krdzzrloasmebsynu
typescript: 4.9.4
- vitest: 0.27.1
+ vitest: 0.29.8
packages/types:
specifiers:
@@ -267,7 +269,7 @@ importers:
nanoid: ^4.0.1
prettier: ^2.8.3
typescript: ^4.9.4
- vitest: ^0.27.1
+ vitest: ^0.29.8
dependencies:
luxon: 3.3.0
nanoid: 4.0.1
@@ -281,7 +283,7 @@ importers:
eslint-plugin-simple-import-sort: 8.0.0_eslint@8.31.0
prettier: 2.8.3
typescript: 4.9.4
- vitest: 0.27.1
+ vitest: 0.29.8
packages:
@@ -3405,6 +3407,37 @@ packages:
- supports-color
dev: true
+ /@vitest/expect/0.29.8:
+ resolution: {integrity: sha512-xlcVXn5I5oTq6NiZSY3ykyWixBxr5mG8HYtjvpgg6KaqHm0mvhX18xuwl5YGxIRNt/A5jidd7CWcNHrSvgaQqQ==}
+ dependencies:
+ '@vitest/spy': 0.29.8
+ '@vitest/utils': 0.29.8
+ chai: 4.3.7
+ dev: true
+
+ /@vitest/runner/0.29.8:
+ resolution: {integrity: sha512-FzdhnRDwEr/A3Oo1jtIk/B952BBvP32n1ObMEb23oEJNO+qO5cBet6M2XWIDQmA7BDKGKvmhUf2naXyp/2JEwQ==}
+ dependencies:
+ '@vitest/utils': 0.29.8
+ p-limit: 4.0.0
+ pathe: 1.1.0
+ dev: true
+
+ /@vitest/spy/0.29.8:
+ resolution: {integrity: sha512-VdjBe9w34vOMl5I5mYEzNX8inTxrZ+tYUVk9jxaZJmHFwmDFC/GV3KBFTA/JKswr3XHvZL+FE/yq5EVhb6pSAw==}
+ dependencies:
+ tinyspy: 1.0.2
+ dev: true
+
+ /@vitest/utils/0.29.8:
+ resolution: {integrity: sha512-qGzuf3vrTbnoY+RjjVVIBYfuWMjn3UMUqyQtdGNZ6ZIIyte7B37exj6LaVkrZiUTvzSadVvO/tJm8AEgbGCBPg==}
+ dependencies:
+ cli-truncate: 3.1.0
+ diff: 5.1.0
+ loupe: 2.3.6
+ pretty-format: 27.5.1
+ dev: true
+
/@zag-js/element-size/0.3.1:
resolution: {integrity: sha512-jR5j4G//bRzcxwAACWi9EfITnwjNmn10LxF4NmALrdZU7/PNWP3uUCdhCxd/0SCyeiJXUl0yvD57rWAbKPs1nw==}
dev: false
@@ -3508,6 +3541,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /ansi-regex/6.0.1:
+ resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
+ engines: {node: '>=12'}
+ dev: true
+
/ansi-styles/3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
engines: {node: '>=4'}
@@ -3526,6 +3564,11 @@ packages:
engines: {node: '>=10'}
dev: true
+ /ansi-styles/6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+ dev: true
+
/anymatch/3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
@@ -4044,6 +4087,14 @@ packages:
dev: true
optional: true
+ /cli-truncate/3.1.0:
+ resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dependencies:
+ slice-ansi: 5.0.0
+ string-width: 5.1.2
+ dev: true
+
/cliui/8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -4454,6 +4505,11 @@ packages:
engines: {node: '>=0.3.1'}
dev: true
+ /diff/5.1.0:
+ resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==}
+ engines: {node: '>=0.3.1'}
+ dev: true
+
/dir-compare/2.4.0:
resolution: {integrity: sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA==}
hasBin: true
@@ -4551,6 +4607,10 @@ packages:
resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==}
dev: true
+ /eastasianwidth/0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+ dev: true
+
/ee-first/1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
dev: false
@@ -4635,6 +4695,10 @@ packages:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
dev: true
+ /emoji-regex/9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+ dev: true
+
/encodeurl/1.0.2:
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
engines: {node: '>= 0.8'}
@@ -5973,6 +6037,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /is-fullwidth-code-point/4.0.0:
+ resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
+ engines: {node: '>=12'}
+ dev: true
+
/is-glob/4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
@@ -6633,7 +6702,7 @@ packages:
resolution: {integrity: sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==}
dependencies:
acorn: 8.8.1
- pathe: 1.0.0
+ pathe: 1.1.0
pkg-types: 1.0.1
ufo: 1.0.1
dev: true
@@ -6936,6 +7005,13 @@ packages:
yocto-queue: 0.1.0
dev: true
+ /p-limit/4.0.0:
+ resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dependencies:
+ yocto-queue: 1.0.0
+ dev: true
+
/p-locate/4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
@@ -7028,12 +7104,8 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
- /pathe/0.2.0:
- resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==}
- dev: true
-
- /pathe/1.0.0:
- resolution: {integrity: sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==}
+ /pathe/1.1.0:
+ resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==}
dev: true
/pathval/1.1.1:
@@ -7074,7 +7146,7 @@ packages:
dependencies:
jsonc-parser: 3.2.0
mlly: 1.1.0
- pathe: 1.0.0
+ pathe: 1.1.0
dev: true
/playwright-core/1.30.0:
@@ -7860,6 +7932,14 @@ packages:
is-fullwidth-code-point: 3.0.0
dev: true
+ /slice-ansi/5.0.0:
+ resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
+ engines: {node: '>=12'}
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 4.0.0
+ dev: true
+
/smart-buffer/4.2.0:
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
@@ -7968,6 +8048,10 @@ packages:
engines: {node: '>= 0.8'}
dev: false
+ /std-env/3.3.2:
+ resolution: {integrity: sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==}
+ dev: true
+
/steno/3.0.0:
resolution: {integrity: sha512-uZtn7Ht9yXLiYgOsmo8btj4+f7VxyYheMt8g6F1ANjyqByQXEE2Gygjgenp3otHH1TlHsS4JAaRGv5wJ1wvMNw==}
engines: {node: '>=14.16'}
@@ -8000,6 +8084,15 @@ packages:
strip-ansi: 6.0.1
dev: true
+ /string-width/5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.0.1
+ dev: true
+
/string.prototype.matchall/4.0.8:
resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==}
dependencies:
@@ -8046,6 +8139,13 @@ packages:
ansi-regex: 5.0.1
dev: true
+ /strip-ansi/7.0.1:
+ resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==}
+ engines: {node: '>=12'}
+ dependencies:
+ ansi-regex: 6.0.1
+ dev: true
+
/strip-final-newline/2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
@@ -8292,8 +8392,8 @@ packages:
resolution: {integrity: sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==}
dev: true
- /tinypool/0.3.0:
- resolution: {integrity: sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==}
+ /tinypool/0.4.0:
+ resolution: {integrity: sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==}
engines: {node: '>=14.0.0'}
dev: true
@@ -8760,18 +8860,16 @@ packages:
dev: true
optional: true
- /vite-node/0.27.1_@types+node@18.11.18:
- resolution: {integrity: sha512-d6+ue/3NzsfndWaPbYh/bFkHbmAWfDXI4B874zRx+WREnG6CUHUbBC8lKaRYZjeR6gCPN5m1aVNNRXBYICA9XA==}
+ /vite-node/0.29.8_@types+node@18.11.18:
+ resolution: {integrity: sha512-b6OtCXfk65L6SElVM20q5G546yu10/kNrhg08afEoWlFRJXFq9/6glsvSVY+aI6YeC1tu2TtAqI2jHEQmOmsFw==}
engines: {node: '>=v14.16.0'}
hasBin: true
dependencies:
cac: 6.7.14
debug: 4.3.4
mlly: 1.1.0
- pathe: 0.2.0
+ pathe: 1.1.0
picocolors: 1.0.0
- source-map: 0.6.1
- source-map-support: 0.5.21
vite: 4.0.4_@types+node@18.11.18
transitivePeerDependencies:
- '@types/node'
@@ -8783,6 +8881,27 @@ packages:
- terser
dev: true
+ /vite-node/0.29.8_ovmyjmuuyckt3r3gpaexj2onji:
+ resolution: {integrity: sha512-b6OtCXfk65L6SElVM20q5G546yu10/kNrhg08afEoWlFRJXFq9/6glsvSVY+aI6YeC1tu2TtAqI2jHEQmOmsFw==}
+ engines: {node: '>=v14.16.0'}
+ hasBin: true
+ dependencies:
+ cac: 6.7.14
+ debug: 4.3.4
+ mlly: 1.1.0
+ pathe: 1.1.0
+ picocolors: 1.0.0
+ vite: 4.0.4_ovmyjmuuyckt3r3gpaexj2onji
+ transitivePeerDependencies:
+ - '@types/node'
+ - less
+ - sass
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ dev: true
+
/vite-plugin-svgr/2.4.0_vite@4.0.4:
resolution: {integrity: sha512-q+mJJol6ThvqkkJvvVFEndI4EaKIjSI0I3jNFgSoC9fXAz1M7kYTVUin8fhUsFojFDKZ9VHKtX6NXNaOLpbsHA==}
peerDependencies:
@@ -8844,6 +8963,41 @@ packages:
fsevents: 2.3.2
dev: true
+ /vite/4.0.4_ovmyjmuuyckt3r3gpaexj2onji:
+ resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': '>= 14'
+ less: '*'
+ sass: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ dependencies:
+ '@types/node': 18.11.18
+ esbuild: 0.16.15
+ postcss: 8.4.21
+ resolve: 1.22.1
+ rollup: 3.9.1
+ sass: 1.57.1
+ optionalDependencies:
+ fsevents: 2.3.2
+ dev: true
+
/vite/4.0.4_sass@1.57.1:
resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -8878,8 +9032,8 @@ packages:
fsevents: 2.3.2
dev: true
- /vitest/0.27.1:
- resolution: {integrity: sha512-1sIpQ1DVFTEn7c1ici1XHcVfdU4nKiBmPtPAtGKJJJLuJjojTv/OHGgcf69P57alM4ty8V4NMv+7Yoi5Cxqx9g==}
+ /vitest/0.29.8:
+ resolution: {integrity: sha512-JIAVi2GK5cvA6awGpH0HvH/gEG9PZ0a/WoxdiV3PmqK+3CjQMf8c+J/Vhv4mdZ2nRyXFw66sAg6qz7VNkaHfDQ==}
engines: {node: '>=v14.16.0'}
hasBin: true
peerDependencies:
@@ -8888,6 +9042,9 @@ packages:
'@vitest/ui': '*'
happy-dom: '*'
jsdom: '*'
+ playwright: '*'
+ safaridriver: '*'
+ webdriverio: '*'
peerDependenciesMeta:
'@edge-runtime/vm':
optional: true
@@ -8899,24 +9056,101 @@ packages:
optional: true
jsdom:
optional: true
+ playwright:
+ optional: true
+ safaridriver:
+ optional: true
+ webdriverio:
+ optional: true
dependencies:
'@types/chai': 4.3.4
'@types/chai-subset': 1.3.3
'@types/node': 18.11.18
+ '@vitest/expect': 0.29.8
+ '@vitest/runner': 0.29.8
+ '@vitest/spy': 0.29.8
+ '@vitest/utils': 0.29.8
acorn: 8.8.1
acorn-walk: 8.2.0
cac: 6.7.14
chai: 4.3.7
debug: 4.3.4
local-pkg: 0.4.2
+ pathe: 1.1.0
picocolors: 1.0.0
source-map: 0.6.1
+ std-env: 3.3.2
strip-literal: 1.0.0
tinybench: 2.3.1
- tinypool: 0.3.0
+ tinypool: 0.4.0
tinyspy: 1.0.2
vite: 4.0.4_@types+node@18.11.18
- vite-node: 0.27.1_@types+node@18.11.18
+ vite-node: 0.29.8_@types+node@18.11.18
+ why-is-node-running: 2.2.2
+ transitivePeerDependencies:
+ - less
+ - sass
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ dev: true
+
+ /vitest/0.29.8_jsdom@21.1.0+sass@1.57.1:
+ resolution: {integrity: sha512-JIAVi2GK5cvA6awGpH0HvH/gEG9PZ0a/WoxdiV3PmqK+3CjQMf8c+J/Vhv4mdZ2nRyXFw66sAg6qz7VNkaHfDQ==}
+ engines: {node: '>=v14.16.0'}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@vitest/browser': '*'
+ '@vitest/ui': '*'
+ happy-dom: '*'
+ jsdom: '*'
+ playwright: '*'
+ safaridriver: '*'
+ webdriverio: '*'
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@vitest/browser':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+ playwright:
+ optional: true
+ safaridriver:
+ optional: true
+ webdriverio:
+ optional: true
+ dependencies:
+ '@types/chai': 4.3.4
+ '@types/chai-subset': 1.3.3
+ '@types/node': 18.11.18
+ '@vitest/expect': 0.29.8
+ '@vitest/runner': 0.29.8
+ '@vitest/spy': 0.29.8
+ '@vitest/utils': 0.29.8
+ acorn: 8.8.1
+ acorn-walk: 8.2.0
+ cac: 6.7.14
+ chai: 4.3.7
+ debug: 4.3.4
+ jsdom: 21.1.0
+ local-pkg: 0.4.2
+ pathe: 1.1.0
+ picocolors: 1.0.0
+ source-map: 0.6.1
+ std-env: 3.3.2
+ strip-literal: 1.0.0
+ tinybench: 2.3.1
+ tinypool: 0.4.0
+ tinyspy: 1.0.2
+ vite: 4.0.4_ovmyjmuuyckt3r3gpaexj2onji
+ vite-node: 0.29.8_ovmyjmuuyckt3r3gpaexj2onji
why-is-node-running: 2.2.2
transitivePeerDependencies:
- less
@@ -9205,6 +9439,11 @@ packages:
engines: {node: '>=10'}
dev: true
+ /yocto-queue/1.0.0:
+ resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
+ engines: {node: '>=12.20'}
+ dev: true
+
/zustand/4.3.6_react@18.2.0:
resolution: {integrity: sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw==}
engines: {node: '>=12.7.0'}