commit
ad0fa21174
14 changed files with 81 additions and 69 deletions
4
.github/workflows/e2e-tests.yml
vendored
4
.github/workflows/e2e-tests.yml
vendored
|
|
@ -105,7 +105,9 @@ jobs:
|
|||
run: make cluster/up
|
||||
|
||||
- name: Install Playwright deps
|
||||
uses: docker://mcr.microsoft.com/playwright:next-jammy
|
||||
shell: bash
|
||||
working-directory: grafana-plugin
|
||||
run: yarn playwright install
|
||||
|
||||
# ---------- Expensive e2e tests steps start -----------
|
||||
- name: Install Go
|
||||
|
|
|
|||
5
Tiltfile
5
Tiltfile
|
|
@ -61,9 +61,8 @@ docker_build_sub(
|
|||
|
||||
|
||||
def load_oncall_helm():
|
||||
helm_oncall_values = ["./dev/helm-local.yml", "./dev/helm-local.dev.yml"]
|
||||
if is_ci:
|
||||
helm_oncall_values = helm_oncall_values + ["./.github/helm-ci.yml"]
|
||||
helm_oncall_values = ["./dev/helm-local.yml"]
|
||||
helm_oncall_values += ["./.github/helm-ci.yml"] if is_ci else ["./dev/helm-local.dev.yml"]
|
||||
yaml = helm("helm/oncall", name=HELM_PREFIX, values=helm_oncall_values, set=twilio_values, namespace="default")
|
||||
k8s_yaml(yaml)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class Tenant:
|
|||
service_tenant_id: str
|
||||
service_type: str
|
||||
cluster_slug: str
|
||||
stack_id: int
|
||||
stack_slug: str
|
||||
slack_links: List[SlackLink] = field(default_factory=list)
|
||||
msteams_links: List[MSTeamsLink] = field(default_factory=list)
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,24 @@ def test_get_shift_swap_requests_to_notify(make_organization, make_user, make_sc
|
|||
assert _get_shift_swap_requests_to_notify(swap_start) == []
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_get_shift_swap_requests_to_notify_deleted_organization(
|
||||
make_organization, make_user, make_schedule, make_shift_swap_request
|
||||
):
|
||||
organization = make_organization()
|
||||
user = make_user(organization=organization)
|
||||
schedule = make_schedule(organization, schedule_class=OnCallScheduleWeb)
|
||||
|
||||
swap_start = timezone.now()
|
||||
swap_end = swap_start + timezone.timedelta(days=1)
|
||||
make_shift_swap_request(
|
||||
schedule, user, swap_start=swap_start, swap_end=swap_end, created_at=swap_start - timezone.timedelta(days=27)
|
||||
)
|
||||
|
||||
organization.delete()
|
||||
assert _get_shift_swap_requests_to_notify(swap_start - timezone.timedelta(days=28)) == []
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_notify_shift_swap_requests(make_organization, make_user, make_schedule, make_shift_swap_request):
|
||||
organization = make_organization()
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ class ShiftSwapRequestManager(models.Manager):
|
|||
return self.get_queryset().hard_delete()
|
||||
|
||||
def get_open_requests(self, now):
|
||||
return self.get_queryset().filter(benefactor__isnull=True, swap_start__gt=now)
|
||||
return self.get_queryset().filter(
|
||||
schedule__organization__deleted_at__isnull=True, benefactor__isnull=True, swap_start__gt=now
|
||||
)
|
||||
|
||||
|
||||
class ShiftSwapRequest(models.Model):
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import { KeyValue } from '@grafana/data';
|
|||
import type { Page } from '@playwright/test';
|
||||
import qs from 'query-string';
|
||||
|
||||
import { getPluginId } from 'utils/consts';
|
||||
|
||||
import { BASE_URL } from './constants';
|
||||
|
||||
type OnCallPage =
|
||||
|
|
@ -21,7 +23,7 @@ export const goToGrafanaPage = async (page: Page, url = '') => _goToPage(page, u
|
|||
|
||||
export const goToOnCallPage = async (page: Page, onCallPage: OnCallPage, queryParams?: KeyValue) => {
|
||||
const queryParamsString = queryParams ? `?${qs.stringify(queryParams)}` : '';
|
||||
await _goToPage(page, `/a/grafana-oncall-app/${onCallPage}${queryParamsString}`);
|
||||
await _goToPage(page, `/a/${getPluginId()}/${onCallPage}${queryParamsString}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@
|
|||
"labels:unlink": "yarn --cwd ../../gops-labels/frontend unlink",
|
||||
"test-utc": "TZ=UTC jest --verbose --testNamePattern '^((?!@london-tz).)*$'",
|
||||
"test-london-tz": "TZ=Europe/London jest --verbose --testNamePattern '@london-tz'",
|
||||
"test": "yarn test-utc && yarn test-london-tz",
|
||||
"test:ci": "yarn test",
|
||||
"test": "PLUGIN_ID=grafana-oncall-app yarn test-utc && yarn test-london-tz",
|
||||
"test:ci": "PLUGIN_ID=grafana-oncall-app pnpm test-utc && pnpm test-london-tz",
|
||||
"test:report": "HTML_REPORT_ENABLED=true yarn test",
|
||||
"test:silent": "yarn test --silent",
|
||||
"test:e2e": "yarn playwright test --grep-invert @expensive",
|
||||
"test:e2e-expensive": "yarn playwright test --grep @expensive",
|
||||
"test:e2e": "PLUGIN_ID=grafana-oncall-app yarn playwright test --grep-invert @expensive",
|
||||
"test:e2e-expensive": "PLUGIN_ID=grafana-oncall-app yarn playwright test --grep @expensive",
|
||||
"test:e2e:watch": "yarn test:e2e --ui",
|
||||
"test:e2e-expensive:watch": "yarn test:e2e-expensive --ui",
|
||||
"test:e2e:gen": "yarn playwright codegen http://localhost:3000",
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
"@grafana/eslint-config": "^6.0.0",
|
||||
"@grafana/tsconfig": "^1.2.0-rc1",
|
||||
"@jest/globals": "^27.5.1",
|
||||
"@playwright/test": "^1.41.0",
|
||||
"@playwright/test": "1.46.0",
|
||||
"@swc/core": "^1.3.90",
|
||||
"@swc/helpers": "^0.5.0",
|
||||
"@swc/jest": "^0.2.26",
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.7.3",
|
||||
"dompurify": "^2.3.12",
|
||||
"dotenv": "^16.0.3",
|
||||
"dotenv": "^16.4.0",
|
||||
"eslint": "^8.25.0",
|
||||
"eslint-plugin-deprecation": "^2.0.0",
|
||||
"eslint-plugin-jsdoc": "^44.2.4",
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import path from 'path';
|
|||
*/
|
||||
require('dotenv').config({ path: path.resolve(process.cwd(), 'e2e-tests/.env') });
|
||||
|
||||
export const VIEWER_USER_STORAGE_STATE = path.join(__dirname, 'e2e-tests/.auth/viewer.json');
|
||||
export const EDITOR_USER_STORAGE_STATE = path.join(__dirname, 'e2e-tests/.auth/editor.json');
|
||||
export const ADMIN_USER_STORAGE_STATE = path.join(__dirname, 'e2e-tests/.auth/admin.json');
|
||||
export const VIEWER_USER_STORAGE_STATE = path.join(process.cwd(), 'e2e-tests/.auth/viewer.json');
|
||||
export const EDITOR_USER_STORAGE_STATE = path.join(process.cwd(), 'e2e-tests/.auth/editor.json');
|
||||
export const ADMIN_USER_STORAGE_STATE = path.join(process.cwd(), 'e2e-tests/.auth/admin.json');
|
||||
|
||||
const IS_CI = !!process.env.CI;
|
||||
const BROWSERS = process.env.BROWSERS || 'chromium';
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export const ShiftSwapForm = (props: ShiftSwapFormProps) => {
|
|||
const {
|
||||
scheduleStore,
|
||||
userStore: { currentUserPk },
|
||||
timezoneStore: { selectedTimezoneOffset },
|
||||
} = store;
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -87,7 +88,7 @@ export const ShiftSwapForm = (props: ShiftSwapFormProps) => {
|
|||
...shiftSwap,
|
||||
});
|
||||
}
|
||||
}, [shiftSwap, store.timezoneStore.calendarStartDate, store.timezoneStore.selectedTimezoneOffset]);
|
||||
}, [shiftSwap, store.timezoneStore.calendarStartDate, selectedTimezoneOffset]);
|
||||
|
||||
const handleDescriptionChange = useCallback(
|
||||
(event) => {
|
||||
|
|
@ -171,6 +172,7 @@ export const ShiftSwapForm = (props: ShiftSwapFormProps) => {
|
|||
<Field label="Swap start">
|
||||
<DateTimePicker
|
||||
disabled={!isNew}
|
||||
utcOffset={selectedTimezoneOffset}
|
||||
value={dayjs(shiftSwap.swap_start)}
|
||||
onChange={handleShiftSwapStartChange}
|
||||
/>
|
||||
|
|
@ -178,6 +180,7 @@ export const ShiftSwapForm = (props: ShiftSwapFormProps) => {
|
|||
<Field label="Swap end">
|
||||
<DateTimePicker
|
||||
disabled={!isNew}
|
||||
utcOffset={selectedTimezoneOffset}
|
||||
value={dayjs(shiftSwap.swap_end)}
|
||||
onChange={handleShiftSwapEndChange}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,12 @@ import { isUserActionAllowed, UserActions } from 'utils/authorization/authorizat
|
|||
import { PLUGIN_ROOT } from 'utils/consts';
|
||||
import { PropsWithRouter, withRouter } from 'utils/hoc';
|
||||
|
||||
import { getCalendarStartDate, getNewCalendarStartDate, getUTCString } from './Schedule.helpers';
|
||||
import {
|
||||
getCalendarStartDate,
|
||||
getNewCalendarStartDate,
|
||||
getUTCString,
|
||||
toDateWithTimezoneOffset,
|
||||
} from './Schedule.helpers';
|
||||
import { getScheduleStyles } from './Schedule.styles';
|
||||
|
||||
interface RouteProps {
|
||||
|
|
@ -647,7 +652,7 @@ class _SchedulePage extends React.Component<SchedulePageProps, SchedulePageState
|
|||
store,
|
||||
store: {
|
||||
userStore: { currentUserPk },
|
||||
timezoneStore: { currentDateInSelectedTimezone },
|
||||
timezoneStore: { currentDateInSelectedTimezone, selectedTimezoneOffset },
|
||||
},
|
||||
router: {
|
||||
params: { id: scheduleId },
|
||||
|
|
@ -671,11 +676,14 @@ class _SchedulePage extends React.Component<SchedulePageProps, SchedulePageState
|
|||
|
||||
const layers = getLayersFromStore(store, scheduleId, store.timezoneStore.calendarStartDate);
|
||||
const closestEvent = findClosestUserEvent(dayjs(), currentUserPk, layers);
|
||||
|
||||
const swapStart = closestEvent
|
||||
? dayjs(closestEvent.start)
|
||||
? toDateWithTimezoneOffset(dayjs(closestEvent.start), selectedTimezoneOffset)
|
||||
: currentDateInSelectedTimezone.startOf('day').add(1, 'day');
|
||||
|
||||
const swapEnd = closestEvent ? dayjs(closestEvent.end) : swapStart.add(1, 'day');
|
||||
const swapEnd = closestEvent
|
||||
? toDateWithTimezoneOffset(dayjs(closestEvent.end), selectedTimezoneOffset)
|
||||
: swapStart.add(1, 'day');
|
||||
|
||||
const params = {
|
||||
swap_start: getUTCString(swapStart),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { OrgRole } from '@grafana/data';
|
|||
import { config } from '@grafana/runtime';
|
||||
import { contextSrv } from 'grafana/app/core/core';
|
||||
|
||||
import { getPluginId } from 'utils/consts';
|
||||
import { PluginId } from 'utils/consts';
|
||||
|
||||
export type UserAction = {
|
||||
permission: string;
|
||||
|
|
@ -110,7 +110,7 @@ export const generateMissingPermissionMessage = (permission: UserAction): string
|
|||
`You are missing the ${determineRequiredAuthString(permission)}`;
|
||||
|
||||
export const generatePermissionString = (resource: Resource, action: Action, includePrefix: boolean): string =>
|
||||
`${includePrefix ? `${getPluginId()}.` : ''}${resource}:${action}`;
|
||||
`${includePrefix ? `${PluginId.OnCall}.` : ''}${resource}:${action}`;
|
||||
|
||||
const constructAction = (
|
||||
resource: Resource,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export const getIsDevelopmentEnv = () => {
|
|||
|
||||
export const getPluginId = (): PluginId => {
|
||||
try {
|
||||
return (process.env.PLUGIN_ID as PluginId) || PluginId.OnCall;
|
||||
return (process.env.PLUGIN_ID as PluginId) || PluginId.Irm;
|
||||
} catch (error) {
|
||||
return PluginId.Irm;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2397,12 +2397,12 @@
|
|||
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
|
||||
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
|
||||
|
||||
"@playwright/test@^1.41.0":
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.41.2.tgz#bd9db40177f8fd442e16e14e0389d23751cdfc54"
|
||||
integrity sha512-qQB9h7KbibJzrDpkXkYvsmiDJK14FULCCZgEcoe2AvFAS64oCirWTwzTlAYEbKaRxWs5TFesE1Na6izMv3HfGg==
|
||||
"@playwright/test@1.46.0":
|
||||
version "1.46.0"
|
||||
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.46.0.tgz#ccea6d22c40ee7fa567e4192fafbdf2a907e2714"
|
||||
integrity sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==
|
||||
dependencies:
|
||||
playwright "1.41.2"
|
||||
playwright "1.46.0"
|
||||
|
||||
"@pnpm/constants@7.1.1":
|
||||
version "7.1.1"
|
||||
|
|
@ -6456,10 +6456,10 @@ dot-case@^3.0.4:
|
|||
no-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
dotenv@^16.0.3:
|
||||
version "16.0.3"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07"
|
||||
integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==
|
||||
dotenv@^16.4.0:
|
||||
version "16.4.5"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
|
||||
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
|
||||
|
||||
duplexer@^0.1.2:
|
||||
version "0.1.2"
|
||||
|
|
@ -11527,17 +11527,17 @@ pkg-dir@^4.2.0:
|
|||
dependencies:
|
||||
find-up "^4.0.0"
|
||||
|
||||
playwright-core@1.41.2:
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.41.2.tgz#db22372c708926c697acc261f0ef8406606802d9"
|
||||
integrity sha512-VaTvwCA4Y8kxEe+kfm2+uUUw5Lubf38RxF7FpBxLPmGe5sdNkSg5e3ChEigaGrX7qdqT3pt2m/98LiyvU2x6CA==
|
||||
playwright-core@1.46.0:
|
||||
version "1.46.0"
|
||||
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.46.0.tgz#2336ac453a943abf0dc95a76c117f9d3ebd390eb"
|
||||
integrity sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==
|
||||
|
||||
playwright@1.41.2:
|
||||
version "1.41.2"
|
||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.41.2.tgz#4e760b1c79f33d9129a8c65cc27953be6dd35042"
|
||||
integrity sha512-v0bOa6H2GJChDL8pAeLa/LZC4feoAMbSQm1/jF/ySsWWoaNItvrMP7GEkvEEFyCTUYKMxjQKaTSg5up7nR6/8A==
|
||||
playwright@1.46.0:
|
||||
version "1.46.0"
|
||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.46.0.tgz#c7ff490deae41fc1e814bf2cb62109dd9351164d"
|
||||
integrity sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==
|
||||
dependencies:
|
||||
playwright-core "1.41.2"
|
||||
playwright-core "1.46.0"
|
||||
optionalDependencies:
|
||||
fsevents "2.3.2"
|
||||
|
||||
|
|
@ -13967,16 +13967,7 @@ string-template@~0.2.1:
|
|||
resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
|
||||
integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
|
|
@ -14094,7 +14085,7 @@ stringify-object@^3.3.0:
|
|||
is-obj "^1.0.1"
|
||||
is-regexp "^1.0.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
|
|
@ -14115,13 +14106,6 @@ strip-ansi@^5.2.0:
|
|||
dependencies:
|
||||
ansi-regex "^4.1.0"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^7.0.1:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
|
||||
|
|
@ -15477,7 +15461,8 @@ wordwrap@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||
name wrap-ansi-cjs
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
|
|
@ -15495,15 +15480,6 @@ wrap-ansi@^6.2.0:
|
|||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue