Compare commits

..

24 Commits

Author SHA1 Message Date
Hassan Ben Jobrane
42bd7807b2 Merge pull request #2148 from nhost/chore/increase-ci-timeout
chore: increase timeout for Publish to Docker Hub
2023-07-25 16:08:34 +01:00
Hassan Ben Jobrane
eea59bd202 chore: increase timeout for Publish to Docker Hub 2023-07-25 15:36:15 +01:00
Hassan Ben Jobrane
7248eb733f Merge pull request #2146 from nhost/changeset-release/main
chore: update versions
2023-07-25 13:12:50 +01:00
github-actions[bot]
fceb6a4a89 chore: update versions 2023-07-25 11:52:49 +00:00
Hassan Ben Jobrane
b10eca09a8 Merge pull request #2126 from nhost/renovate/turbo-monorepo
chore(deps): update dependency turbo to v1.10.11
2023-07-25 12:49:57 +01:00
Hassan Ben Jobrane
4799b65e96 Merge pull request #2144 from nhost/feat/add-run-services-to-logs
feat: add run/services to the logs
2023-07-25 12:24:13 +01:00
Hassan Ben Jobrane
067eb9d6a9 Merge pull request #2143 from nhost/feat/change-grafana-url
feat: change grafana url to point to dashboards
2023-07-25 12:24:03 +01:00
Hassan Ben Jobrane
219d5ecdcf Merge pull request #2140 from nhost/fix/create-service-form
fix: tweaking the create service form
2023-07-25 12:23:47 +01:00
Hassan Ben Jobrane
9073182d51 chore: add changeset 2023-07-25 12:20:15 +01:00
Hassan Ben Jobrane
bdb5783e79 chore: sync turbo version in Dockerfile 2023-07-25 12:19:09 +01:00
Hassan Ben Jobrane
ece717d6e0 chore: add changeset 2023-07-25 12:01:53 +01:00
Hassan Ben Jobrane
b135ef695c chore: add changeset 2023-07-25 11:38:00 +01:00
Hassan Ben Jobrane
82b3353110 chore: add changeset 2023-07-25 11:34:20 +01:00
Hassan Ben Jobrane
3f165a85e3 fix: grafana urls in generateAppServiceUrl.test 2023-07-25 11:14:58 +01:00
renovate[bot]
aa4018909f chore(deps): update dependency turbo to v1.10.11 2023-07-24 23:03:50 +00:00
Hassan Ben Jobrane
98397e3ccd feat: add run/services to the logs 2023-07-24 18:00:22 +01:00
Hassan Ben Jobrane
911e7112c9 feat: change grafana url to point to dashboards 2023-07-24 17:32:46 +01:00
Hassan Ben Jobrane
e62402ecfc feat(services): add toolip content 2023-07-24 10:24:24 +01:00
Hassan Ben Jobrane
9190dd726d Merge pull request #2138 from nhost/changeset-release/main
chore: update versions
2023-07-23 21:31:33 +01:00
github-actions[bot]
ae093283d0 chore: update versions 2023-07-23 20:13:51 +00:00
Hassan Ben Jobrane
875327fbea Merge pull request #2136 from tawsbob/bug/users-page-limit
fix: back to previous limit
2023-07-23 21:11:11 +01:00
Hassan Ben Jobrane
3d5c34f4ce chore: add changeset 2023-07-23 20:53:14 +01:00
Dellean Santos
58c2a20532 fix: back to previous limit 2023-07-23 16:17:10 -03:00
Hassan Ben Jobrane
6c90cb5024 fix: make command optional and set min replicas 0 2023-07-22 19:58:34 +01:00
16 changed files with 210 additions and 69 deletions

View File

@@ -100,7 +100,7 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push to Docker Hub
uses: docker/build-push-action@v4
timeout-minutes: 60
timeout-minutes: 90
with:
context: .
file: ./dashboard/Dockerfile

View File

@@ -1,5 +1,20 @@
# @nhost/dashboard
## 0.20.2
### Patch Changes
- 9073182d5: chore(dashboard): bump `turbo` to 1.10.11
- ece717d6e: feat(logs): show services in the logs page
- 82b335311: feat(metrics): change grafana link to point to the dashboards
- b135ef695: fix(services): set command as optional and set min replicas to 0
## 0.20.1
### Patch Changes
- 3d5c34f4c: fix(auth): fix users pagination limit
## 0.20.0
### Minor Changes

View File

@@ -3,7 +3,7 @@ RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
RUN yarn global add turbo@1.10.7
RUN yarn global add turbo@1.10.11
COPY . .
RUN turbo prune --scope="@nhost/dashboard" --docker

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/dashboard",
"version": "0.20.0",
"version": "0.20.2",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",

View File

@@ -69,7 +69,7 @@ test('should generate a per service subdomain in remote mode', () => {
);
expect(generateAppServiceUrl('test', region, 'grafana')).toBe(
'https://test.grafana.eu-west-1.nhost.run',
'https://test.grafana.eu-west-1.nhost.run/dashboards',
);
});
@@ -102,7 +102,7 @@ test('should generate staging subdomains in staging environment', () => {
);
expect(generateAppServiceUrl('test', stagingRegion, 'grafana')).toBe(
'https://test.grafana.eu-west-1.staging.nhost.run',
'https://test.grafana.eu-west-1.staging.nhost.run/dashboards',
);
});
@@ -120,7 +120,7 @@ test('should generate no slug for Hasura and Grafana neither in local mode nor i
'https://test.hasura.eu-west-1.staging.nhost.run',
);
expect(generateAppServiceUrl('test', stagingRegion, 'grafana')).toBe(
'https://test.grafana.eu-west-1.staging.nhost.run',
'https://test.grafana.eu-west-1.staging.nhost.run/dashboards',
);
process.env.NEXT_PUBLIC_ENV = 'production';
@@ -129,7 +129,7 @@ test('should generate no slug for Hasura and Grafana neither in local mode nor i
'https://test.hasura.eu-west-1.nhost.run',
);
expect(generateAppServiceUrl('test', region, 'grafana')).toBe(
'https://test.grafana.eu-west-1.nhost.run',
'https://test.grafana.eu-west-1.nhost.run/dashboards',
);
});

View File

@@ -102,5 +102,11 @@ export default function generateAppServiceUrl(
.filter(Boolean)
.join('.');
return `https://${constructedDomain}${remoteBackendSlugs[service]}`;
let url = `https://${constructedDomain}${remoteBackendSlugs[service]}`;
if (service === 'grafana') {
url = `${url}/dashboards`;
}
return url;
}

View File

@@ -10,6 +10,7 @@ import type { LogsCustomInterval } from '@/features/projects/logs/utils/constant
import { LOGS_AVAILABLE_INTERVALS } from '@/features/projects/logs/utils/constants/intervals';
import type { AvailableLogsService } from '@/features/projects/logs/utils/constants/services';
import { LOGS_AVAILABLE_SERVICES } from '@/features/projects/logs/utils/constants/services';
import { useGetRunServicesQuery } from '@/utils/__generated__/graphql';
import { subMinutes } from 'date-fns';
import { useEffect, useState } from 'react';
import { twMerge } from 'tailwind-merge';
@@ -132,6 +133,35 @@ export default function LogsHeader({
const { currentProject } = useCurrentWorkspaceAndProject();
const applicationCreationDate = new Date(currentProject.createdAt);
const [runServices, setRunServices] = useState<
{
label: string;
value: string;
}[]
>([]);
const { data, loading } = useGetRunServicesQuery({
variables: {
appID: currentProject.id,
resolve: false,
limit: 1000,
offset: 0,
},
});
useEffect(() => {
if (!loading) {
const services = data.app?.runServices ?? [];
setRunServices(
services.map((s) => ({
label: s.config.name,
value: s.config.name,
})),
);
}
}, [loading, data]);
/**
* Will subtract the `customInterval` time in minutes from the current date.
*/
@@ -181,15 +211,17 @@ export default function LogsHeader({
root: { className: 'min-h-[initial] h-9 leading-[initial]' },
}}
>
{LOGS_AVAILABLE_SERVICES.map(({ value, label }) => (
<Option
key={value}
value={value}
className="text-sm+ font-medium"
>
{label}
</Option>
))}
{[...LOGS_AVAILABLE_SERVICES, ...runServices].map(
({ value, label }) => (
<Option
key={value}
value={value}
className="text-sm+ font-medium"
>
{label}
</Option>
),
)}
</Select>
</Box>
</Box>

View File

@@ -10,9 +10,9 @@ import { Tooltip } from '@/components/ui/v2/Tooltip';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { InfoCard } from '@/features/projects/overview/components/InfoCard';
import {
MAX_SERVICE_REPLICAS,
MAX_SERVICES_CPU,
MAX_SERVICES_MEM,
MAX_SERVICE_REPLICAS,
MIN_SERVICES_CPU,
MIN_SERVICES_MEM,
} from '@/features/projects/resources/settings/utils/resourceSettingsValidationSchema';
@@ -22,13 +22,13 @@ import { PortsFormSection } from '@/features/services/components/ServiceForm/com
import { ReplicasFormSection } from '@/features/services/components/ServiceForm/components/ReplicasFormSection';
import { StorageFormSection } from '@/features/services/components/ServiceForm/components/StorageFormSection';
import type { DialogFormProps } from '@/types/common';
import { getToastStyleProps } from '@/utils/constants/settings';
import {
useInsertRunServiceConfigMutation,
useInsertRunServiceMutation,
useReplaceRunServiceConfigMutation,
type ConfigRunServiceConfigInsertInput,
} from '@/utils/__generated__/graphql';
import { getToastStyleProps } from '@/utils/constants/settings';
import type { ApolloError } from '@apollo/client';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect, useState } from 'react';
@@ -46,7 +46,7 @@ export enum PortTypes {
export const validationSchema = Yup.object({
name: Yup.string().required('The name is required.'),
image: Yup.string().label('Image to run'),
command: Yup.string().required(),
command: Yup.string(),
environment: Yup.array().of(
Yup.object().shape({
name: Yup.string().required(),
@@ -57,7 +57,7 @@ export const validationSchema = Yup.object({
cpu: Yup.number().min(MIN_SERVICES_CPU).max(MAX_SERVICES_CPU).required(),
memory: Yup.number().min(MIN_SERVICES_MEM).max(MAX_SERVICES_MEM).required(),
}),
replicas: Yup.number().min(1).max(MAX_SERVICE_REPLICAS).required(),
replicas: Yup.number().min(0).max(MAX_SERVICE_REPLICAS).required(),
ports: Yup.array().of(
Yup.object().shape({
port: Yup.number().required(),
@@ -258,10 +258,10 @@ export default function ServiceForm({
label={
<Box className="flex flex-row items-center space-x-2">
<Text>Name</Text>
<Tooltip title="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s">
<Tooltip title="Name of the service, must be unique per project.">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
@@ -282,10 +282,26 @@ export default function ServiceForm({
label={
<Box className="flex flex-row items-center space-x-2">
<Text>Image</Text>
<Tooltip title="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s">
<Tooltip
title={
<span>
Image to use, it can be hosted on any public registry or it
can use the{' '}
<a
target="_blank"
rel="noopener noreferrer"
href="https://docs.nhost.io/run/registry"
className="underline"
>
Nhost registry
</a>
. Image needs to support arm.
</span>
}
>
<InfoIcon
aria-label="Info"
className="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
@@ -313,10 +329,10 @@ export default function ServiceForm({
label={
<Box className="flex flex-row items-center space-x-2">
<Text>Command</Text>
<Tooltip title="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s">
<Tooltip title="Command to run when to start the service. This is optional as the image may already have a baked-in command.">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
@@ -343,7 +359,7 @@ export default function ServiceForm({
{createServiceFormError && (
<Alert
severity="error"
className="grid items-center justify-between grid-flow-col px-4 py-3"
className="grid grid-flow-col items-center justify-between px-4 py-3"
>
<span className="text-left">
<strong>Error:</strong> {createServiceFormError.message}

View File

@@ -45,14 +45,29 @@ export default function ComputeFormSection() {
};
return (
<Box className="p-4 space-y-4 rounded border-1">
<Box className="space-y-4 rounded border-1 p-4">
<Box className="flex flex-row items-center space-x-2">
<Text variant="h4" className="font-semibold">
CPU: {formValues.compute.cpu} / Memory: {formValues.compute.memory}
</Text>
<Tooltip title="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s">
<InfoIcon aria-label="Info" className="w-4 h-4" color="primary" />
<Tooltip
title={
<span>
Compute resources dedicated for the service. Refer to{' '}
<a
target="_blank"
rel="noopener noreferrer"
href="https://docs.nhost.io/run/resources"
className="underline"
>
resources
</a>{' '}
for more information.
</span>
}
>
<InfoIcon aria-label="Info" className="h-4 w-4" color="primary" />
</Tooltip>
</Box>
@@ -62,7 +77,7 @@ export default function ComputeFormSection() {
variant="outlined"
onClick={decrementCompute}
>
<ArrowLeftIcon className="w-4 h-4" />
<ArrowLeftIcon className="h-4 w-4" />
</Button>
<Slider
@@ -79,7 +94,7 @@ export default function ComputeFormSection() {
variant="outlined"
onClick={incrementCompute}
>
<ArrowRightIcon className="w-4 h-4" />
<ArrowRightIcon className="h-4 w-4" />
</Button>
</Box>
</Box>

View File

@@ -20,21 +20,30 @@ export default function EnvironmentFormSection() {
});
return (
<Box className="p-4 space-y-4 rounded border-1">
<Box className="space-y-4 rounded border-1 p-4">
<Box className="flex flex-row items-center justify-between ">
<Box className="flex flex-row items-center space-x-2">
<Text variant="h4" className="font-semibold">
Environment
</Text>
<Tooltip title="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s">
<InfoIcon aria-label="Info" className="w-4 h-4" color="primary" />
<Tooltip
title={
<span>
Environment variables to add to the service. Other than the ones
specified here only <code>NHOST_SUBDOMAIN</code> and{' '}
<code>NHOST_REGION</code> are added automatically to the
service.
</span>
}
>
<InfoIcon aria-label="Info" className="h-4 w-4" color="primary" />
</Tooltip>
</Box>
<Button
variant="borderless"
onClick={() => append({ name: '', value: '' })}
>
<PlusIcon className="w-5 h-5" />
<PlusIcon className="h-5 w-5" />
</Button>
</Box>
@@ -75,7 +84,7 @@ export default function EnvironmentFormSection() {
color="error"
onClick={() => remove(index)}
>
<TrashIcon className="w-4 h-4" />
<TrashIcon className="h-4 w-4" />
</Button>
</Box>
))}

View File

@@ -55,7 +55,22 @@ export default function PortsFormSection() {
<Text variant="h4" className="font-semibold">
Ports
</Text>
<Tooltip title="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s">
<Tooltip
title={
<span>
Network ports to configure for the service. Refer to{' '}
<a
target="_blank"
rel="noopener noreferrer"
href="https://docs.nhost.io/run/networking"
className="underline"
>
Networking
</a>{' '}
for more information.
</span>
}
>
<InfoIcon aria-label="Info" className="h-4 w-4" color="primary" />
</Tooltip>
</Box>

View File

@@ -26,7 +26,24 @@ export default function ReplicasFormSection() {
<Text variant="h4" className="font-semibold">
Replicas ({replicas})
</Text>
<Tooltip title="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s">
<Tooltip
title={
<span>
Number of replicas for the service. Multiple replicas can process
requests/work in parallel. You can set replicas to 0 to pause the
service. Refer to{' '}
<a
target="_blank"
rel="noopener noreferrer"
href="https://docs.nhost.io/run/resources"
className="underline"
>
resources
</a>{' '}
for more information.
</span>
}
>
<InfoIcon aria-label="Info" className="h-4 w-4" color="primary" />
</Tooltip>
</Box>

View File

@@ -41,15 +41,31 @@ export default function StorageFormSection() {
};
return (
<Box className="p-4 space-y-4 rounded border-1">
<Box className="space-y-4 rounded border-1 p-4">
<Box className="flex flex-row items-center justify-between ">
<Box className="flex flex-row items-center space-x-2">
<Text variant="h4" className="font-semibold">
Storage
</Text>
<Tooltip title="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s">
<InfoIcon aria-label="Info" className="w-4 h-4" color="primary" />
<Tooltip
title={
<span>
By default, services do not have persistent storage. You can add
SSD disks to the service here. Refer to{' '}
<a
target="_blank"
rel="noopener noreferrer"
href="https://docs.nhost.io/run/storage"
className="underline"
>
Storage
</a>{' '}
for more information.
</span>
}
>
<InfoIcon aria-label="Info" className="h-4 w-4" color="primary" />
</Tooltip>
</Box>
@@ -57,7 +73,7 @@ export default function StorageFormSection() {
variant="borderless"
onClick={() => append({ name: '', capacity: 1, path: '' })}
>
<PlusIcon className="w-5 h-5" />
<PlusIcon className="h-5 w-5" />
</Button>
</Box>
@@ -120,7 +136,7 @@ export default function StorageFormSection() {
color="error"
onClick={() => remove(index)}
>
<TrashIcon className="w-4 h-4" />
<TrashIcon className="h-4 w-4" />
</Button>
</Box>
))}

View File

@@ -30,7 +30,7 @@ export default function UsersPage() {
const remoteProjectGQLClient = useRemoteApplicationGQLClient();
const [searchString, setSearchString] = useState<string>('');
const limit = useRef(1);
const limit = useRef(25);
const router = useRouter();
const [nrOfPages, setNrOfPages] = useState(
parseInt(router.query.page as string, 10) || 1,

View File

@@ -76,7 +76,7 @@
"husky": "^8.0.1",
"npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"turbo": "1.10.7",
"turbo": "1.10.11",
"typedoc": "^0.22.18",
"typescript": "4.9.5",
"vite": "^4.3.8",

44
pnpm-lock.yaml generated
View File

@@ -87,8 +87,8 @@ importers:
specifier: ^2.7.1
version: 2.7.1
turbo:
specifier: 1.10.7
version: 1.10.7
specifier: 1.10.11
version: 1.10.11
typedoc:
specifier: ^0.22.18
version: 0.22.18(typescript@4.9.5)
@@ -31362,65 +31362,65 @@ packages:
safe-buffer: 5.2.1
dev: false
/turbo-darwin-64@1.10.7:
resolution: {integrity: sha512-N2MNuhwrl6g7vGuz4y3fFG2aR1oCs0UZ5HKl8KSTn/VC2y2YIuLGedQ3OVbo0TfEvygAlF3QGAAKKtOCmGPNKA==}
/turbo-darwin-64@1.10.11:
resolution: {integrity: sha512-pHNz6D5XUVB+bgZMKXIOegvH9GzPXucwgiHFatQcRoscAW1te1Zvn3fAWYo/mJ550AqPWQLmALZZel3z3lllLA==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/turbo-darwin-arm64@1.10.7:
resolution: {integrity: sha512-WbJkvjU+6qkngp7K4EsswOriO3xrNQag7YEGRtfLoDdMTk4O4QTeU6sfg2dKfDsBpTidTvEDwgIYJhYVGzrz9Q==}
/turbo-darwin-arm64@1.10.11:
resolution: {integrity: sha512-j3yGAvkBu0BqR+5nb9LiRs8UZsUQDOqpdP4S9OW3+W5jorJIxUxLawwk3XqoYVGhmPh84LWWOOrMgFQ/Y/3WSg==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/turbo-linux-64@1.10.7:
resolution: {integrity: sha512-x1CF2CDP1pDz/J8/B2T0hnmmOQI2+y11JGIzNP0KtwxDM7rmeg3DDTtDM/9PwGqfPotN9iVGgMiMvBuMFbsLhg==}
/turbo-linux-64@1.10.11:
resolution: {integrity: sha512-FZ+/VT3Yt188VvPuvqIwIyvosYALzu7e8ewxpl8yiYDwQbLwxMOEt2UKACsL+D7wzNtIMPRDxNmnhNvTbx9Afw==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/turbo-linux-arm64@1.10.7:
resolution: {integrity: sha512-JtnBmaBSYbs7peJPkXzXxsRGSGBmBEIb6/kC8RRmyvPAMyqF8wIex0pttsI+9plghREiGPtRWv/lfQEPRlXnNQ==}
/turbo-linux-arm64@1.10.11:
resolution: {integrity: sha512-IfxO8S1FiikunmUnlul1sd5piPlunU1QlnNNGFfhKJkMidkJ0rXsSbh2epn/pXO8RRPBnFRxYkp6gJz/FTUUTg==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/turbo-windows-64@1.10.7:
resolution: {integrity: sha512-7A/4CByoHdolWS8dg3DPm99owfu1aY/W0V0+KxFd0o2JQMTQtoBgIMSvZesXaWM57z3OLsietFivDLQPuzE75w==}
/turbo-windows-64@1.10.11:
resolution: {integrity: sha512-5qwTEk27duxYIsDycgZdpti1b41Xu2D3W+WRlg++sylwqhAgcPhfcppXMGd70h/SScgIh7IeLjzgTK7+YPE77g==}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/turbo-windows-arm64@1.10.7:
resolution: {integrity: sha512-D36K/3b6+hqm9IBAymnuVgyePktwQ+F0lSXr2B9JfAdFPBktSqGmp50JNC7pahxhnuCLj0Vdpe9RqfnJw5zATA==}
/turbo-windows-arm64@1.10.11:
resolution: {integrity: sha512-FGvWCWvii4PZqy+4VBoanKaMkqeRD146iHL67YpY5sp8z5H/Gkywtu8xxBbkgP14lBr6fAsyRarHBuR+c52cDg==}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/turbo@1.10.7:
resolution: {integrity: sha512-xm0MPM28TWx1e6TNC3wokfE5eaDqlfi0G24kmeHupDUZt5Wd0OzHFENEHMPqEaNKJ0I+AMObL6nbSZonZBV2HA==}
/turbo@1.10.11:
resolution: {integrity: sha512-6GzYbsG5Ro6dK62dJuBjA53RdpMr1PWVwN6ZZRSMgYgkvFmNDMwxzJUKuCSi+jfDSt6avwT7koNlwRPfgTFuOw==}
hasBin: true
requiresBuild: true
optionalDependencies:
turbo-darwin-64: 1.10.7
turbo-darwin-arm64: 1.10.7
turbo-linux-64: 1.10.7
turbo-linux-arm64: 1.10.7
turbo-windows-64: 1.10.7
turbo-windows-arm64: 1.10.7
turbo-darwin-64: 1.10.11
turbo-darwin-arm64: 1.10.11
turbo-linux-64: 1.10.11
turbo-linux-arm64: 1.10.11
turbo-windows-64: 1.10.11
turbo-windows-arm64: 1.10.11
dev: true
/type-check@0.3.2: