Compare commits

...

22 Commits

Author SHA1 Message Date
DrJKL
71df03b1ac chore: update unplugin-vue-components, unplugin-icons, vite-plugin-dts majors
unplugin-vue-components 30 -> 32, unplugin-icons 22 -> 23,
vite-plugin-dts 4 -> 5. Both the app build and the types bundle
(vite.types.config.mts, which exercises unplugin-dts) pass.
2026-07-17 02:57:30 -07:00
DrJKL
751979bb23 chore: update jsdom to v29, globals to v17, @types/node to v25
Test-environment and type-definition majors; no code changes required.
@types/node 25.x matches the repo's node >=25 <26 engines pin.
2026-07-17 02:51:46 -07:00
DrJKL
2e46923ac8 chore: update stylelint to v17
- selector-max-type now counts type selectors inside :deep(); the
  WhatsNewPopup markdown selector gets an inline exception (generated
  content has no class hooks)
- migrate deprecated typesSyntax rule option to root languageOptions
2026-07-17 02:41:58 -07:00
DrJKL
4621969f02 chore: update vue-router to v5
No code changes required: typecheck, router/view tests, composables
sweep (1598 tests), and production build all green.
2026-07-17 02:36:41 -07:00
DrJKL
ebb995eada chore: update pinia to v4 and @pinia/testing to v2
- useCoreCommands.test: build the setting-store mock with fromPartial;
  pinia 4's Store type gained required internal fields (_p, _hotUpdate,
  _hmrPayload) that a hand-rolled satisfies mock would have to fake
- useChart: hold the Chart instance in a shallowRef; deep-unwrapping
  chart.js's generics now exceeds TS instantiation depth, and a class
  instance updated via chart.update() should not be deeply reactive
2026-07-17 02:29:28 -07:00
DrJKL
5ffdaf4b46 chore: update typescript to 6.0.3
TypeScript 7 (native/tsgo) is blocked: vue-tsc crashes on the v7
package layout (ERR_PACKAGE_PATH_NOT_EXPORTED) and typescript-eslint
caps its peer range at <6.1.0. 6.0.3 is the last JS-based major and
passes the whole toolchain.

Cast typegpu's vendored GPUDevice to @webgpu/types' GPUDevice where
they disagree on adapterInfo.subgroupMaxSize optionality.
2026-07-17 02:03:04 -07:00
DrJKL
d28394e62b test: guard te() active-locale-only contract 2026-07-17 01:10:12 -07:00
DrJKL
8f94684c64 fix: fall back to command id for unlabeled keybinding rows
vue-i18n 11 returns the default message verbatim, so t(key, '') renders
an empty command cell for commands without a label or translation (v9
fell back to the key text). Default to command.id so the row stays
visible and clickable.
2026-07-17 00:50:10 -07:00
DrJKL
6ba4801663 fix: default te() to the active locale
vue-i18n 11's te() consults the fallback locale, which broke every
raw-fallback path built on the exported te (error catalog raw API copy,
st/stRaw custom-node strings, sidebar titles). Wrap the export to
preserve the v9 active-locale semantics instead of patching call sites,
so existing @/i18n test mocks keep working.
2026-07-17 00:18:31 -07:00
DrJKL
c9b5647773 fix: scope error catalog te() checks to the active locale
vue-i18n 11's te() consults the fallback locale, which defeated the
catalog's raw-API-copy fallback for locales missing a key.
2026-07-16 23:57:24 -07:00
DrJKL
0cea758dfa chore: restore screenshot expectations to main's bytes
The regenerated goldens were pixel-identical to main's (re-encoded
only); drop the churn to match the base branch.
2026-07-16 23:34:09 -07:00
DrJKL
7fd38c9144 Merge branch 'drjkl/update-deps' into drjkl/update-vue-i18n 2026-07-16 23:33:50 -07:00
DrJKL
5e2ce2099d Merge branch 'drjkl/update-deps' into drjkl/update-vue-i18n 2026-07-16 21:39:08 -07:00
DrJKL
a0d3379b98 fix: clipboard copy and industry normalization regressions
- useCopyToClipboard: use navigator.clipboard.writeText directly.
  vueuse 14.3's useClipboard copy() no longer rejects on failure (it
  swallows errors into an internal legacy path gated on an async
  permission query), which bypassed our execCommand fallback and left
  the clipboard empty in the error-dialog e2e tests.
- Pin fuse.js to 7.0.0: 7.5 enforces minMatchCharLength strictly, so
  4-char queries like 'film' stopped matching survey industry
  categories. Retuning the fuzzy config for 7.5 is follow-up work.
2026-07-16 21:23:21 -07:00
DrJKL
31fa8fe952 ci: don't fail website screenshot regen on label cleanup
The restricted pull_request token can't always remove the trigger
label; that 403 was failing otherwise-successful runs.
2026-07-16 20:59:59 -07:00
DrJKL
62ffad0c3c Merge branch 'drjkl/update-deps' into drjkl/update-vue-i18n 2026-07-16 20:58:06 -07:00
DrJKL
a0be6ac430 ci: bump website Playwright image to v1.61.1
Match @playwright/test 1.61.1 from the catalog; the stale v1.58.1 image
broke website-e2e and made screenshot regeneration a no-op.
2026-07-16 20:52:09 -07:00
DrJKL
d15ee851f0 [automated] Update test expectations 2026-07-16 20:45:22 -07:00
DrJKL
5e7629560b Merge branch 'drjkl/update-deps' into drjkl/update-vue-i18n 2026-07-16 18:03:01 -07:00
DrJKL
66e5d8c5f0 Merge branch 'drjkl/update-deps' into drjkl/update-vue-i18n 2026-07-16 17:58:27 -07:00
DrJKL
d833ffcc89 Merge branch 'drjkl/update-deps' into drjkl/update-vue-i18n 2026-07-16 17:13:33 -07:00
DrJKL
f6811a5f57 chore: update vue-i18n to v11
Two-major jump 9.14 -> 11.4.6. App is pure composition API
(legacy: false, no $tc/v-t), so no code changes required.
2026-07-16 16:33:41 -07:00
10 changed files with 1155 additions and 801 deletions

View File

@@ -6,15 +6,19 @@
"customSyntax": "postcss-html"
}
],
"languageOptions": {
"syntax": {
"types": {
"radial-gradient()": "| <any-value>"
}
}
},
"rules": {
"import-notation": "string",
"font-family-no-missing-generic-family-keyword": true,
"declaration-property-value-no-unknown": [
true,
{
"typesSyntax": {
"radial-gradient()": "| <any-value>"
},
"ignoreProperties": {
"speak": ["none"],
"app-region": ["drag", "no-drag"],

1885
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,7 @@ catalog:
'@intlify/eslint-plugin-vue-i18n': ^4.5.1
'@lobehub/i18n-cli': ^1.26.1
'@lucide/vue': ^1.17.0
'@pinia/testing': ^1.0.3
'@pinia/testing': ^2.0.1
'@playwright/test': ^1.61.1
'@primeuix/forms': 0.0.2
'@primeuix/styled': 0.3.2
@@ -59,7 +59,7 @@ catalog:
'@total-typescript/shoehorn': ^0.1.2
'@types/fs-extra': ^11.0.4
'@types/jsdom': ^21.1.7
'@types/node': ^24.1.0
'@types/node': ^25.9.5
'@types/semver': ^7.7.0
'@types/three': ^0.184.1
'@vee-validate/zod': ^4.15.1
@@ -93,12 +93,12 @@ catalog:
fast-check: ^4.5.3
firebase: ^11.6.0
glob: ^13.0.6
globals: ^16.5.0
globals: ^17.7.0
gsap: ^3.14.2
happy-dom: 20.9.0
husky: ^9.1.7
jiti: 2.7.0
jsdom: ^27.4.0
jsdom: ^29.1.1
jsonata: ^2.1.0
knip: ^6.27.0
lenis: ^1.3.21
@@ -111,7 +111,7 @@ catalog:
oxlint: ^1.74.0
oxlint-tsgolint: ^0.24.0
picocolors: ^1.1.1
pinia: ^3.0.4
pinia: ^4.0.2
postcss-html: ^1.8.0
posthog-js: ^1.358.1
pretty-bytes: ^7.1.0
@@ -120,30 +120,30 @@ catalog:
reka-ui: 2.5.0
rollup-plugin-visualizer: ^6.0.4
storybook: ^10.5.0
stylelint: ^16.26.1
stylelint: ^17.14.0
tailwindcss: ^4.3.2
tailwindcss-primeui: ^0.6.1
three: ^0.184.0
tsx: ^4.15.6
tw-animate-css: ^1.3.8
typegpu: ^0.8.2
typescript: ^5.9.3
typescript: ^6.0.3
typescript-eslint: ^8.64.0
unplugin-icons: ^22.5.0
unplugin-icons: ^23.0.1
unplugin-typegpu: 0.8.0
unplugin-vue-components: ^30.0.0
unplugin-vue-components: ^32.1.0
uuid: ^11.1.1
vee-validate: ^4.15.1
vite: ^8.1.4
vite-plugin-dts: ^4.5.4
vite-plugin-dts: ^5.0.3
vite-plugin-html: ^3.2.2
vite-plugin-vue-devtools: ^8.1.5
vitest: ^4.1.10
vue: ^3.5.39
vue-component-type-helpers: ^3.3.7
vue-eslint-parser: ^10.4.1
vue-i18n: ^9.14.5
vue-router: ^4.4.3
vue-i18n: ^11.4.6
vue-router: ^5.2.0
vue-tsc: ^3.3.7
vuefire: ^3.2.1
wwobjloader2: ^6.2.1

View File

@@ -429,7 +429,7 @@ const commandsData = computed<ICommandData[]>(() => {
id: command.id,
label: t(
`commands.${normalizeI18nKey(command.id)}.label`,
command.label ?? ''
command.label ?? command.id
),
keybindings: keybindingStore.getKeybindingsByCommandId(command.id),
source: command.source,

View File

@@ -12,7 +12,7 @@ import {
PointElement,
Tooltip
} from 'chart.js'
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'
import type { Ref } from 'vue'
@@ -129,7 +129,7 @@ export function useChart(
data: Ref<ChartData>,
options?: Ref<ChartOptions | undefined>
) {
const chartInstance = ref<Chart | null>(null)
const chartInstance = shallowRef<Chart | null>(null)
function createChart() {
if (!canvasRef.value) return

View File

@@ -207,7 +207,8 @@ export function useGPUResources() {
async function initTypeGPU(): Promise<void> {
if (store.tgpuRoot) {
/* c8 ignore start */
device = store.tgpuRoot.device
// typegpu vendors its own WebGPU types; align with @webgpu/types
device = store.tgpuRoot.device as GPUDevice
return
/* c8 ignore stop */
}
@@ -215,7 +216,7 @@ export function useGPUResources() {
/* c8 ignore start — requires functional WebGPU hardware */
const root = await tgpu.init()
store.tgpuRoot = root
device = root.device
device = root.device as GPUDevice
console.warn('✅ TypeGPU initialized! Root:', root)
console.warn('Device info:', root.device.limits)
/* c8 ignore stop */

View File

@@ -260,7 +260,7 @@ describe('useCoreCommands', () => {
function createMockSettingStore(
getReturnValue: boolean
): ReturnType<typeof useSettingStore> {
return {
return fromPartial<ReturnType<typeof useSettingStore>>({
get: vi.fn().mockReturnValue(getReturnValue),
addSetting: vi.fn(),
load: vi.fn(),
@@ -287,7 +287,7 @@ describe('useCoreCommands', () => {
$onAction: vi.fn(),
$dispose: vi.fn(),
_customProperties: new Set()
} satisfies ReturnType<typeof useSettingStore>
})
}
beforeEach(() => {

View File

@@ -7,6 +7,7 @@ let loadLocale: typeof I18nModule.loadLocale
let mergeCustomNodesI18n: typeof I18nModule.mergeCustomNodesI18n
let resolveSupportedLocale: typeof I18nModule.resolveSupportedLocale
let setActiveLocale: typeof I18nModule.setActiveLocale
let te: typeof I18nModule.te
async function importI18nModule() {
const i18nModule = await import('./i18n')
@@ -15,10 +16,13 @@ async function importI18nModule() {
mergeCustomNodesI18n = i18nModule.mergeCustomNodesI18n
resolveSupportedLocale = i18nModule.resolveSupportedLocale
setActiveLocale = i18nModule.setActiveLocale
te = i18nModule.te
}
// Mock the JSON imports before importing i18n module
vi.mock('./locales/en/main.json', () => ({ default: { welcome: 'Welcome' } }))
vi.mock('./locales/en/main.json', () => ({
default: { welcome: 'Welcome', enOnly: 'English only' }
}))
vi.mock('./locales/en/nodeDefs.json', () => ({
default: { testNode: 'Test Node' }
}))
@@ -228,6 +232,16 @@ describe('i18n', () => {
})
})
describe('te', () => {
it('checks only the active locale, never the fallback locale', async () => {
expect(te('enOnly')).toBe(true)
await setActiveLocale('zh')
expect(te('welcome')).toBe(true)
expect(te('enOnly')).toBe(false)
})
})
describe('resolveSupportedLocale', () => {
it('returns the canonical tag when the input is shipped', () => {
expect(resolveSupportedLocale('en')).toBe('en')

View File

@@ -155,7 +155,10 @@ export const i18n = createI18n({
/** Convenience shorthand: i18n.global */
export const t: (typeof i18n.global)['t'] = i18n.global.t
export const te: (typeof i18n.global)['te'] = i18n.global.te
// vue-i18n 11's te() consults the fallback locale; default to the active
// locale to preserve the v9 behavior our fallback paths rely on.
export const te: (typeof i18n.global)['te'] = (key, locale) =>
i18n.global.te(key, locale ?? i18n.global.locale.value)
export const d: (typeof i18n.global)['d'] = i18n.global.d
const tm = i18n.global.tm

View File

@@ -231,6 +231,7 @@ defineExpose({
/* What's new title - targets h2 or strong text after h1 */
.content-text :deep(h2),
/* stylelint-disable-next-line selector-max-type -- generated markdown offers no class hooks */
.content-text :deep(h1 + p strong) {
color: var(--text-primary);
font-family: Inter, sans-serif;