Use common Prettier configuration for umbreld and ui

Moves Prettier configuration up to the root folder so any subpackage
that uses it shares the same ruleset. Ruleset is taken from umbreld.

Also adds an UI task to CI to check formatting.
This commit is contained in:
dcode
2024-10-30 00:44:31 +07:00
committed by GitHub
parent d3125e90ad
commit 9131c0af8d
36 changed files with 181 additions and 12431 deletions
+21 -5
View File
@@ -3,11 +3,7 @@ name: Node.js CI
on: push
jobs:
ci:
# TODO: Rollout of 24.04 as ubuntu-latest has been put on hold, but we want
# 24.04 because integration tests depend on it, e.g. for `pss` support. Pin
# what we need for now, but switch back once ubuntu-latest has been updated.
# https://github.com/actions/runner-images/issues/10636
umbreld:
runs-on: ubuntu-24.04
defaults:
run:
@@ -28,3 +24,23 @@ jobs:
node-version: 18
- run: sudo npm clean-install
- run: sudo npm run ${{ matrix.task }}
ui:
runs-on: ubuntu-24.04
defaults:
run:
working-directory: packages/ui
strategy:
fail-fast: false
matrix:
task:
- format:check
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- uses: pnpm/action-setup@v4
with:
version: 8
- run: pnpm install
- run: pnpm run ${{ matrix.task }}
@@ -31,9 +31,14 @@ jobs:
with:
node-version: '18'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 8
- name: Install dependencies
run: |
npm ci
pnpm install
working-directory: packages/ui
- name: Update translations
+12
View File
@@ -0,0 +1,12 @@
/**
* @type {import('prettier').Config}
*/
export default {
"printWidth": 120,
"semi": false,
"useTabs": true,
"trailingComma": "all",
"singleQuote": true,
"bracketSpacing": false,
"jsxSingleQuote": true,
}
+1
View File
@@ -1,4 +1,5 @@
{
"type": "module",
"scripts": {
"dev": "./scripts/umbrel-dev",
"dev:help": "npm run dev help"
+3
View File
@@ -30,3 +30,6 @@ dist-ssr
/playwright-report/
/blob-report/
/playwright/.cache/
# UI uses pnpm instead of npm
package-lock.json
@@ -1,15 +1,12 @@
import baseConfig from '../../.prettierrc.js'
/**
* @type {import('prettier').Config & import("@ianvs/prettier-plugin-sort-imports").PluginConfig}
*/
export default {
printWidth: 120,
semi: false,
useTabs: true,
trailingComma: 'all', // better for git diffs
singleQuote: true,
bracketSpacing: false,
jsxSingleQuote: true,
...baseConfig,
plugins: [
...(baseConfig.plugins || []),
'@ianvs/prettier-plugin-sort-imports',
'prettier-plugin-css-order',
'prettier-plugin-style-order',
-12333
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -17,7 +17,8 @@
"lint": "eslint .",
"preview": "vite preview",
"build-remote": "ssh root@mark-dev './pull.sh'",
"format": "prettier . --write",
"format": "prettier --write .",
"format:check": "prettier --check .",
"tsc": "tsc --noEmit",
"size": "vite-bundle-visualizer",
"playwright": "playwright test",
@@ -113,7 +114,7 @@
"fast-glob": "^3.3.2",
"openai": "^4.51.0",
"postcss": "8.4.31",
"prettier": "3.0.3",
"prettier": "3.3.3",
"prettier-plugin-css-order": "2.0.1",
"prettier-plugin-style-order": "0.2.2",
"prettier-plugin-tailwindcss": "0.5.6",
+19 -19
View File
@@ -201,7 +201,7 @@ devDependencies:
version: 8.3.1
'@ianvs/prettier-plugin-sort-imports':
specifier: 4.1.1
version: 4.1.1(prettier@3.0.3)
version: 4.1.1(prettier@3.3.3)
'@playwright/test':
specifier: ^1.40.1
version: 1.40.1
@@ -266,17 +266,17 @@ devDependencies:
specifier: 8.4.31
version: 8.4.31
prettier:
specifier: 3.0.3
version: 3.0.3
specifier: 3.3.3
version: 3.3.3
prettier-plugin-css-order:
specifier: 2.0.1
version: 2.0.1([email protected])(prettier@3.0.3)
version: 2.0.1([email protected])(prettier@3.3.3)
prettier-plugin-style-order:
specifier: 0.2.2
version: 0.2.2(prettier@3.0.3)
version: 0.2.2(prettier@3.3.3)
prettier-plugin-tailwindcss:
specifier: 0.5.6
version: 0.5.6(@ianvs/[email protected])([email protected])([email protected])(prettier@3.0.3)
version: 0.5.6(@ianvs/[email protected])([email protected])([email protected])(prettier@3.3.3)
serve:
specifier: 14.2.1
version: 14.2.1
@@ -844,7 +844,7 @@ packages:
resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==}
dev: true
/@ianvs/[email protected](prettier@3.0.3):
/@ianvs/[email protected](prettier@3.3.3):
resolution: {integrity: sha512-kJhXq63ngpTQ2dxgf5GasbPJWsJA3LgoOdd7WGhpUSzLgLgI4IsIzYkbJf9kmpOHe7Vdm/o3PcRA3jmizXUuAQ==}
peerDependencies:
'@vue/compiler-sfc': '>=3.0.0'
@@ -858,7 +858,7 @@ packages:
'@babel/parser': 7.23.0
'@babel/traverse': 7.23.2
'@babel/types': 7.23.0
prettier: 3.0.3
prettier: 3.3.3
semver: 7.5.4
transitivePeerDependencies:
- supports-color
@@ -5847,7 +5847,7 @@ packages:
engines: {node: '>= 0.8.0'}
dev: true
/[email protected]([email protected])(prettier@3.0.3):
/[email protected]([email protected])(prettier@3.3.3):
resolution: {integrity: sha512-Y+wZ0wI7/qFUritirJksQn13KqbcNC3OZXSxGh1ui/X39hAeMW9md+Mp7fjk8H4ZQQ8c5CTYZxShoBfAal/79A==}
engines: {node: '>=16'}
peerDependencies:
@@ -5856,22 +5856,22 @@ packages:
css-declaration-sorter: 7.1.1([email protected])
postcss-less: 6.0.0([email protected])
postcss-scss: 4.0.9([email protected])
prettier: 3.0.3
prettier: 3.3.3
transitivePeerDependencies:
- postcss
dev: true
/[email protected](prettier@3.0.3):
/[email protected](prettier@3.3.3):
resolution: {integrity: sha512-4rASdHONhHLNX0arKqEvjGOEAbkSZE3+GQPSaS8mf3en/spjeN0le5fV1yKltWwQeM4UPn7CkKzeD97a4Az/6w==}
peerDependencies:
prettier: '>= 1.13'
dependencies:
postcss-sorting: 5.0.1
prettier: 3.0.3
prettier: 3.3.3
resolve-cwd: 3.0.0
dev: true
/[email protected](@ianvs/[email protected])([email protected])([email protected])(prettier@3.0.3):
/[email protected](@ianvs/[email protected])([email protected])([email protected])(prettier@3.3.3):
resolution: {integrity: sha512-2Xgb+GQlkPAUCFi3sV+NOYcSI5XgduvDBL2Zt/hwJudeKXkyvRS65c38SB0yb9UB40+1rL83I6m0RtlOQ8eHdg==}
engines: {node: '>=14.21.3'}
peerDependencies:
@@ -5923,14 +5923,14 @@ packages:
prettier-plugin-twig-melody:
optional: true
dependencies:
'@ianvs/prettier-plugin-sort-imports': 4.1.1(prettier@3.0.3)
prettier: 3.0.3
prettier-plugin-css-order: 2.0.1([email protected])(prettier@3.0.3)
prettier-plugin-style-order: 0.2.2(prettier@3.0.3)
'@ianvs/prettier-plugin-sort-imports': 4.1.1(prettier@3.3.3)
prettier: 3.3.3
prettier-plugin-css-order: 2.0.1([email protected])(prettier@3.3.3)
prettier-plugin-style-order: 0.2.2(prettier@3.3.3)
dev: true
/prettier@3.0.3:
resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==}
/prettier@3.3.3:
resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
engines: {node: '>=14'}
hasBin: true
dev: true
@@ -38,7 +38,7 @@ export function CopyableField({
ref={ref}
onClick={() => setTimeout(() => ref.current?.select())}
className={cn(
'block flex-1 appearance-none truncate bg-transparent py-1.5 pl-2.5 font-mono outline-none min-w-0',
'block min-w-0 flex-1 appearance-none truncate bg-transparent py-1.5 pl-2.5 font-mono outline-none',
narrow && 'py-0.5',
)}
type={isPassword && !focused ? 'password' : 'text'}
+1 -1
View File
@@ -124,7 +124,7 @@ export function useAppInstall(id: string) {
const restart = async () => restartMut.mutate({appId: id})
// Ready means the app can be installed
const state: AppStateOrLoading = appStateQ.isLoading ? 'loading' : appState ?? 'not-installed'
const state: AppStateOrLoading = appStateQ.isLoading ? 'loading' : (appState ?? 'not-installed')
return {
start,
+2 -2
View File
@@ -60,11 +60,11 @@ export function useDeviceInfo(): DeviceInfoT {
? {
icon: hostEnvironmentMap[umbrelHostEnvironment].icon,
title: device || LOADING_DASH,
}
}
: {
icon: undefined,
title: UNKNOWN(),
},
},
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
import i18next from 'i18next'
import {arrayIncludes} from 'ts-extras'
import {trpcReact} from '@/trpc/trpc'
import {SupportedLanguageCode, supportedLanguageCodes} from '@/utils/language'
@@ -9,7 +10,7 @@ export function useLanguage(): [code: SupportedLanguageCode, setCode: (code: Sup
onSuccess() {
ctx.user.get.invalidate()
ctx.user.language.invalidate()
}
},
})
const setCode = (language: SupportedLanguageCode) => {
@@ -9,7 +9,11 @@ export type ScrollRestorationAction = 'restore' | 'reset' | 'ignore'
* Handler function testing if scroll position should be restored, reset to zero
* or ignored.
*/
export type ScrollRestorationHandler = (thisPathname: string, prevPathname: string, navigationType: NavigationType) => ScrollRestorationAction
export type ScrollRestorationHandler = (
thisPathname: string,
prevPathname: string,
navigationType: NavigationType,
) => ScrollRestorationAction
/**
* Given a ref to a scrolling container element, keep track of its scroll
@@ -55,9 +59,9 @@ export function useScrollRestoration(container: React.RefObject<HTMLElement>, ha
const y = Math.round(scrollElement?.scrollTop ?? 0)
setScrollPosition(cacheKey, y ?? 0)
}
scrollElement?.addEventListener('scroll'/*end*/, handleScrollEnd)
scrollElement?.addEventListener('scroll' /*end*/, handleScrollEnd)
return () => {
scrollElement?.removeEventListener('scroll'/*end*/, handleScrollEnd)
scrollElement?.removeEventListener('scroll' /*end*/, handleScrollEnd)
}
}, [cacheKey, state, container, thisPathname, prevPathname, navigationType])
}
@@ -1,7 +1,7 @@
import {SupportedLanguageCode} from '@/utils/language'
import {useLanguage} from '@/hooks/use-language'
import {keyBy} from '@/utils/misc'
import {trpcReact} from '@/trpc/trpc'
import {SupportedLanguageCode} from '@/utils/language'
import {keyBy} from '@/utils/misc'
const languageCodesWithFahrenheitTemperature: SupportedLanguageCode[] = ['en']
@@ -14,13 +14,15 @@ export type TemperatureUnit = (typeof temperatureDescriptions)[number]['id']
export const temperatureDescriptionsKeyed = keyBy(temperatureDescriptions, 'id')
export function useTemperatureUnit(optionalUnit?: TemperatureUnit): [unit: TemperatureUnit, setTemp: (unit: TemperatureUnit) => void] {
export function useTemperatureUnit(
optionalUnit?: TemperatureUnit,
): [unit: TemperatureUnit, setTemp: (unit: TemperatureUnit) => void] {
const ctx = trpcReact.useContext()
const userGetQ = trpcReact.user.get.useQuery()
const userSetMut = trpcReact.user.set.useMutation({
onSuccess() {
ctx.user.get.invalidate()
}
},
})
const setUnit = (temperatureUnit: TemperatureUnit) => {
@@ -34,7 +36,9 @@ export function useTemperatureUnit(optionalUnit?: TemperatureUnit): [unit: Tempe
// Use preferred unit stored on the backend once set
const preferredUnit = userGetQ.data?.temperatureUnit
const unit = temperatureDescriptions.some((description) => preferredUnit === description.id) ? preferredUnit as TemperatureUnit : defaultUnit
const unit = temperatureDescriptions.some((description) => preferredUnit === description.id)
? (preferredUnit as TemperatureUnit)
: defaultUnit
return [unit, setUnit]
}
+1 -1
View File
@@ -21,7 +21,7 @@ const scrollRestorationHandler = (thisPathname: string, prevPathname: string, na
return 'ignore'
}
// Reset scroll position to zero unless going back in history
if (navigationType !== "POP") {
if (navigationType !== 'POP') {
return 'reset'
}
// In app store, restore position when navigating back from an app
+1 -1
View File
@@ -4,8 +4,8 @@ import {init} from '@/init'
import {initTokenRenewal} from '@/modules/auth/shared'
import {GlobalSystemStateProvider} from '@/providers/global-system-state/index'
import {RemoteWallpaperInjector, WallpaperProviderConnected} from './providers/wallpaper'
import {RemoteLanguageInjector} from './providers/language'
import {RemoteWallpaperInjector, WallpaperProviderConnected} from './providers/wallpaper'
import {router} from './router'
import {TrpcProvider} from './trpc/trpc-provider'
@@ -37,9 +37,7 @@ const Dependency = ({app, installed = false}: {app: RegistryApp; installed: bool
{installed ? (
<TbCircleCheckFilled className='h-[18px] w-[18px] text-success-light' />
) : (
<span className='text-15 font-medium text-brand-lighter'>
{t('app.view')}
</span>
<span className='text-15 font-medium text-brand-lighter'>{t('app.view')}</span>
)}
</Link>
)
@@ -17,7 +17,7 @@ import {RegistryApp} from '@/trpc/trpc'
export function AppsGridSection({overline, title, apps}: {overline: string; title: ReactNode; apps?: RegistryApp[]}) {
const isMobile = useIsMobile()
const appsToShow = isMobile ? (apps ?? []).slice(0, 6) : apps ?? []
const appsToShow = isMobile ? (apps ?? []).slice(0, 6) : (apps ?? [])
return (
<div className={cardClass}>
<SectionTitle overline={overline} title={title} />
@@ -97,7 +97,7 @@ export function DockItem({
backgroundImage: bg
? `url(${bg})`
: // TODO: use a better default
`linear-gradient(to bottom right, white, black)`,
`linear-gradient(to bottom right, white, black)`,
scale: transform,
...style,
}}
@@ -125,7 +125,7 @@ export function AppDropdown({
: {
icon: undefined,
name: t('app-picker.select-app'),
}
}
const appResults = matchSorter(apps.userApps, query, {
keys: ['name'],
@@ -130,9 +130,9 @@ export type WidgetConfig<T extends WidgetType = WidgetType> = Extract<AnyWidgetC
export type ExampleWidgetConfig<T extends WidgetType = WidgetType> = T extends 'text-with-buttons'
? // Omit the `type` (and `link` from buttons) by omitting `buttons` and then adding it without the `link`
Omit<TextWithButtonsWidget, 'type' | 'buttons'> & {buttons: Omit<TextWithButtonsWidget['buttons'], 'link'>}
Omit<TextWithButtonsWidget, 'type' | 'buttons'> & {buttons: Omit<TextWithButtonsWidget['buttons'], 'link'>}
: // Otherwise, just omit the `type`
Omit<WidgetConfig<T>, 'type'>
Omit<WidgetConfig<T>, 'type'>
// Adding `= WidgetType` to `T` makes it so that if `T` is not provided, it defaults to `WidgetType`. Prevents us from always having to write `RegistryWidget<WidgetType>` when referring to the type.
export type RegistryWidget<T extends WidgetType = WidgetType> = {
+3 -2
View File
@@ -1,6 +1,7 @@
import i18next from 'i18next'
import {trpcReact} from "@/trpc/trpc";
import {supportedLanguageCodes} from '@/utils/language';
import {trpcReact} from '@/trpc/trpc'
import {supportedLanguageCodes} from '@/utils/language'
export function RemoteLanguageInjector() {
const languageQ = trpcReact.user.language.useQuery()
@@ -14,7 +14,7 @@ import {t} from '@/utils/i18n'
import {useDiscoverQuery} from './use-discover-query'
const getAppById = (appId, apps) => apps.find(app => app.id === appId);
const getAppById = (appId, apps) => apps.find((app) => app.id === appId)
export default function Discover() {
return (
@@ -53,7 +53,7 @@ function DiscoverContent() {
key={section.heading + section.subheading}
title={section.heading}
overline={section.subheading}
apps={section.apps.map(appId => getAppById(appId, apps)).filter(app => app !== undefined)}
apps={section.apps.map((appId) => getAppById(appId, apps)).filter((app) => app !== undefined)}
/>
)
}
@@ -64,7 +64,7 @@ function DiscoverContent() {
key={section.heading + section.subheading}
overline={section.subheading}
title={section.heading}
apps={section.apps.map(appId => getAppById(appId, apps)).filter(app => app !== undefined)}
apps={section.apps.map((appId) => getAppById(appId, apps)).filter((app) => app !== undefined)}
/>
)
}
@@ -73,7 +73,7 @@ function DiscoverContent() {
return (
<AppsThreeColumnSection
key={section.heading + section.subheading}
apps={section.apps.map(appId => getAppById(appId, apps)).filter(app => app !== undefined)}
apps={section.apps.map((appId) => getAppById(appId, apps)).filter((app) => app !== undefined)}
overline={section.subheading}
title={section.heading}
textLocation={section.textLocation}
@@ -1,7 +1,12 @@
import {AnimatedNumber} from '@/components/ui/animated-number'
import {SegmentedControl} from '@/components/ui/segmented-control'
import {useIsMobile} from '@/hooks/use-is-mobile'
import {temperatureDescriptions, temperatureDescriptionsKeyed, TemperatureUnit, useTemperatureUnit} from '@/hooks/use-temperature-unit'
import {
temperatureDescriptions,
temperatureDescriptionsKeyed,
TemperatureUnit,
useTemperatureUnit,
} from '@/hooks/use-temperature-unit'
import {cn} from '@/shadcn-lib/utils'
import {t} from '@/utils/i18n'
import {isCpuTooHot} from '@/utils/system'
@@ -1,9 +1,8 @@
import {useState} from 'react'
import {TbLanguage} from 'react-icons/tb'
import {useState} from 'react'
import {ChevronDown} from '@/assets/chevron-down'
import {IconButton} from '@/components/ui/icon-button'
import {languages, SupportedLanguageCode} from '@/utils/language'
import {useLanguage} from '@/hooks/use-language'
import {
DropdownMenu,
@@ -11,6 +10,7 @@ import {
DropdownMenuContent,
DropdownMenuTrigger,
} from '@/shadcn-components/ui/dropdown-menu'
import {languages, SupportedLanguageCode} from '@/utils/language'
export function LanguageDropdown() {
return (
@@ -47,7 +47,12 @@ export function LanguageDropdownContent() {
return (
<DropdownMenuContent align='end'>
{languages.map(({code, name}) => (
<DropdownMenuCheckboxItem key={code} checked={temporaryCode === code} onSelect={() => changeLanguage(code)} disabled={temporaryCode !== activeCode}>
<DropdownMenuCheckboxItem
key={code}
checked={temporaryCode === code}
onSelect={() => changeLanguage(code)}
disabled={temporaryCode !== activeCode}
>
{name}
</DropdownMenuCheckboxItem>
))}
@@ -124,7 +124,10 @@ export function SettingsContentMobile() {
</Link>
<Card>
<CpuTemperatureCardContent warning={cpuTemperature.warning} temperatureInCelcius={cpuTemperature.temperature} />
<CpuTemperatureCardContent
warning={cpuTemperature.warning}
temperatureInCelcius={cpuTemperature.temperature}
/>
</Card>
</div>
@@ -26,7 +26,7 @@ export function SettingsSummary() {
<dt className='opacity-40'>{t('device')}</dt>
<dd>{deviceInfo.data?.device || LOADING_DASH}</dd>
<dt className='opacity-40'>{t('umbrelos')}</dt>
<dd>{osVersionQ.isLoading ? LOADING_DASH : `${osVersionQ.data?.name}` ?? UNKNOWN()}</dd>
<dd>{osVersionQ.isLoading ? LOADING_DASH : (`${osVersionQ.data?.name}` ?? UNKNOWN())}</dd>
<dt className='opacity-40'>{t('local-ip')}</dt>
<dd>
{ipAddresses.data?.length
@@ -37,7 +37,7 @@ export function SettingsSummary() {
</Link>
{index < ipAddresses.data.length - 1 && ', '}
</Fragment>
))
))
: LOADING_DASH}
</dd>
<dt className='opacity-40'>{t('uptime')}</dt>
@@ -30,7 +30,7 @@ const WallpaperItem = forwardRef(
'h-6 shrink-0 bg-white/10 bg-cover bg-center outline-none ring-white/50 transition-all duration-200 focus-visible:ring-1',
active
? // NOTE: `mx-3` or whatever horizontal marging needs to be big enough to not cause the ring to get clipped from scrolling container
'mx-3 rounded-5 ring-2 ring-white/50'
'mx-3 rounded-5 ring-2 ring-white/50'
: 'rounded-3',
className,
)}
@@ -1,7 +1,6 @@
import {useId, useState} from 'react'
import {listClass, ListRadioItem} from '@/components/ui/list'
import {languages, SupportedLanguageCode} from '@/utils/language'
import {useLanguage} from '@/hooks/use-language'
import {useSettingsDialogProps} from '@/routes/settings/_components/shared'
import {
@@ -13,6 +12,7 @@ import {
DrawerTitle,
} from '@/shadcn-components/ui/drawer'
import {t} from '@/utils/i18n'
import {languages, SupportedLanguageCode} from '@/utils/language'
import {sleep} from '@/utils/misc'
export function LanguageDrawer() {
+16 -4
View File
@@ -3,9 +3,21 @@
// https://github.com/lokesh/color-thief/issues/188#issuecomment-1166887824
declare module 'colorthief' {
export type RGBColor = [number, number, number];
export type RGBColor = [number, number, number]
export default class ColorThief {
getColor: (img: HTMLImageElement | null, quality: number=10) => RGBColor | null;
getPalette: (img: HTMLImageElement | null, colorCount: number=10, quality: number=10) => RGBColor[] | null;
getColor: (
/** The HTML image element. */
img: HTMLImageElement | null,
/** The quality level (default: 10). */
quality?: number,
) => RGBColor | null
getPalette: (
/** The HTML image element. */
img: HTMLImageElement | null,
/** The number of colors in the palette (default: 10). */
colorCount?: number,
/** The quality level (default: 10). */
quality?: number,
) => RGBColor[] | null
}
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
import {formatDistanceStrict, Locale} from 'date-fns'
import {de, enUS, es, fr, hu, it, ja, nl, pt, uk, tr} from 'date-fns/locale'
import {de, enUS, es, fr, hu, it, ja, nl, pt, tr, uk} from 'date-fns/locale'
import {UNKNOWN} from '@/constants'
import {SupportedLanguageCode} from '@/utils/language'
+32 -9
View File
@@ -76,7 +76,7 @@
"node-git-server": "^1.0.0",
"nodemon": "^2.0.20",
"opentimestamps": "^0.4.9",
"prettier": "^2.8.1",
"prettier": "3.3.3",
"typescript": "^5.3.3",
"vitest": "^2.1.2",
"wait-port": "^1.0.4",
@@ -8030,15 +8030,16 @@
}
},
"node_modules/prettier": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
"integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin-prettier.js"
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=10.13.0"
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
@@ -11461,6 +11462,22 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/xo/node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/xo/node_modules/queue-microtask": {
"version": "1.2.3",
"dev": true,
@@ -17421,9 +17438,9 @@
"dev": true
},
"prettier": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
"integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
"dev": true
},
"prettier-linter-helpers": {
@@ -19624,6 +19641,12 @@
"bundled": true,
"dev": true
},
"prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true
},
"queue-microtask": {
"version": "1.2.3",
"bundled": true,
+1 -9
View File
@@ -33,14 +33,6 @@
"generate-release-notes": "tsx scripts/generate-release-notes.ts",
"todo": "git grep --line-number TODO -- ':!package.json'"
},
"prettier": {
"printWidth": 120,
"semi": false,
"useTabs": true,
"trailingComma": "all",
"singleQuote": true,
"bracketSpacing": false
},
"xo": {
"prettier": true,
"rules": {
@@ -86,7 +78,7 @@
"node-git-server": "^1.0.0",
"nodemon": "^2.0.20",
"opentimestamps": "^0.4.9",
"prettier": "^2.8.1",
"prettier": "3.3.3",
"typescript": "^5.3.3",
"vitest": "^2.1.2",
"wait-port": "^1.0.4",
@@ -12,8 +12,8 @@ type DotProp<T, P extends string> = P extends `${infer K}.${infer R}`
? DotProp<T[K], R>
: never
: P extends keyof T
? T[P]
: never
? T[P]
: never
type StorePath<T, P extends string> = DotProp<T, P> extends never ? 'The provided path does not exist in the store' : P
@@ -2,7 +2,7 @@ import chalkTemplate from 'chalk-template'
const logLevels = ['silent', 'normal', 'verbose'] as const
export type LogLevel = typeof logLevels[number]
export type LogLevel = (typeof logLevels)[number]
function value(logLevel: LogLevel) {
return logLevels.indexOf(logLevel)