mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-06 20:16:57 +00:00
Merge branch 'misskey-develop' into merge/2025-03-24
# Conflicts: # .github/workflows/storybook.yml # package.json # packages/frontend/src/utility/autogen/settings-search-index.ts # pnpm-lock.yaml
This commit is contained in:
commit
7e7350eab5
65 changed files with 486 additions and 1651 deletions
|
@ -1888,6 +1888,8 @@ _role:
|
|||
descriptionOfIsExplorable: "La línia de temps d'aquest rol i la llista d'usuaris seran públics si s'activa."
|
||||
displayOrder: "Posició "
|
||||
descriptionOfDisplayOrder: "Com més gran és el número, més dalt la seva posició a la interfície."
|
||||
preserveAssignmentOnMoveAccount: "L'estat de l'assignació també es trasllada amb el compte migrat"
|
||||
preserveAssignmentOnMoveAccount_description: "Si s'activa quan es migra un compte amb aquest rol, el compte migrat també heretarà aquest rol."
|
||||
canEditMembersByModerator: "Permetre que els moderadors editin la llista d'usuaris en aquest rol"
|
||||
descriptionOfCanEditMembersByModerator: "Quan s'activa, els moderadors, així com els administradors, podran afegir i treure usuaris d'aquest rol. Si es troba desactivat, només els administradors poden assignar usuaris."
|
||||
priority: "Prioritat"
|
||||
|
|
|
@ -1888,6 +1888,8 @@ _role:
|
|||
descriptionOfIsExplorable: "This role's timeline and the list of users with this will be made public if enabled."
|
||||
displayOrder: "Position"
|
||||
descriptionOfDisplayOrder: "The higher the number, the higher its UI position."
|
||||
preserveAssignmentOnMoveAccount: "Preserve role assignment during migration"
|
||||
preserveAssignmentOnMoveAccount_description: "When turned on, this role will be carried over to the destination account when an account with this role is migrated."
|
||||
canEditMembersByModerator: "Allow moderators to edit the list of members for this role"
|
||||
descriptionOfCanEditMembersByModerator: "When turned on, moderators as well as administrators will be able to assign and unassign users to this role. When turned off, only administrators will be able to assign users."
|
||||
priority: "Priority"
|
||||
|
|
|
@ -1888,6 +1888,8 @@ _role:
|
|||
descriptionOfIsExplorable: "Selezionandolo, la timeline del ruolo diventerà accessibile pubblicamente. Tranne se il ruolo non è pubblico."
|
||||
displayOrder: "Ordine di visualizzazione"
|
||||
descriptionOfDisplayOrder: "I valori più alti vengono visualizzati per primi"
|
||||
preserveAssignmentOnMoveAccount: "Mantenere l'assegnazione alla migrazione del profilo"
|
||||
preserveAssignmentOnMoveAccount_description: "Attivando, il ruolo verrà portato sul profilo destinatario, durante la migrazione."
|
||||
canEditMembersByModerator: "Anche i Moderatori assegnano profili a questo ruolo"
|
||||
descriptionOfCanEditMembersByModerator: "Se disattivo, potranno farlo solamente gli Amministratori."
|
||||
priority: "Priorità"
|
||||
|
|
|
@ -1887,6 +1887,8 @@ _role:
|
|||
descriptionOfIsExplorable: "打开后将公开角色时间线。如果角色不是公开的,就无法公开时间线。"
|
||||
displayOrder: "显示顺序"
|
||||
descriptionOfDisplayOrder: "数字越大,显示位置越靠前。"
|
||||
preserveAssignmentOnMoveAccount: "将分配状态继承到目标账户"
|
||||
preserveAssignmentOnMoveAccount_description: "启用后,当迁移具有该角色的账户时,目标账户也会继承该角色。"
|
||||
canEditMembersByModerator: "允许监察员编辑成员"
|
||||
descriptionOfCanEditMembersByModerator: "如果选中,监察员和管理员都能够为用户分配/取消分配角色。如果未选中,则只有管理员可以执行此操作。"
|
||||
priority: "优先级"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "sharkey",
|
||||
"version": "2025.4.0-rc.0",
|
||||
"version": "2025.4.0-rc.1",
|
||||
"codename": "shonk",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -24,7 +24,6 @@
|
|||
"build": "pnpm build-pre && pnpm -r build && pnpm build-assets",
|
||||
"build-storybook": "pnpm --filter frontend build-storybook",
|
||||
"build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api",
|
||||
"build-frontend-search-index": "pnpm --filter frontend build-search-index",
|
||||
"start": "pnpm check:connect && cd packages/backend && MK_WARNED_ABOUT_CONFIG=true node ./built/boot/entry.js",
|
||||
"start:test": "cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js",
|
||||
"init": "pnpm migrate",
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
focus: ':alpha<0.3<@accent',
|
||||
bg: '#000',
|
||||
fg: '#dadada',
|
||||
fgTransparentWeak: ':alpha<0.75<@fg',
|
||||
fgTransparent: ':alpha<0.5<@fg',
|
||||
fgHighlighted: ':lighten<3<@fg',
|
||||
fgOnAccent: '#fff',
|
||||
fgOnWhite: '#333',
|
||||
|
@ -26,7 +24,6 @@
|
|||
panelHighlight: ':lighten<3<@panel',
|
||||
panelHeaderBg: ':lighten<3<@panel',
|
||||
panelHeaderFg: '@fg',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
panelBorder: '" solid 1px var(--MI_THEME-divider)',
|
||||
thread: ':lighten<12<@panel',
|
||||
windowHeader: ':alpha<0.85<@panel',
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
focus: ':alpha<0.3<@accent',
|
||||
bg: '#fff',
|
||||
fg: '#5f5f5f',
|
||||
fgTransparentWeak: ':alpha<0.75<@fg',
|
||||
fgTransparent: ':alpha<0.5<@fg',
|
||||
fgHighlighted: ':darken<3<@fg',
|
||||
fgOnAccent: '#fff',
|
||||
fgOnWhite: '#333',
|
||||
|
@ -26,7 +24,6 @@
|
|||
panelHighlight: ':darken<3<@panel',
|
||||
panelHeaderBg: ':lighten<3<@panel',
|
||||
panelHeaderFg: '@fg',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
panelBorder: '" solid 1px var(--MI_THEME-divider)',
|
||||
thread: ':darken<12<@panel',
|
||||
windowHeader: ':alpha<0.85<@panel',
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
fgOnWhite: '@accent',
|
||||
panelHighlight: ':lighten<3<@panel',
|
||||
scrollbarHandle: 'rgba(255, 255, 255, 0.2)',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
scrollbarHandleHover: 'rgba(255, 255, 255, 0.4)',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
fgOnWhite: '@accent',
|
||||
divider: 'rgba(255, 255, 255, 0.14)',
|
||||
panel: 'rgb(47, 47, 44)',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
header: ':alpha<0.7<@panel',
|
||||
navBg: '#363636',
|
||||
renote: '@accent',
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
fgOnWhite: '@accent',
|
||||
divider: 'rgba(255, 255, 255, 0.14)',
|
||||
panel: '#2d2d2d',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
header: ':alpha<0.7<@panel',
|
||||
navBg: '#363636',
|
||||
renote: '@accent',
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
fgOnWhite: '@accent',
|
||||
divider: 'rgba(255, 255, 255, 0.1)',
|
||||
panel: '#18181c',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
renote: '@accent',
|
||||
mention: '#f2c97d',
|
||||
mentionMe: '@accent',
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
fgOnWhite: '@accent',
|
||||
divider: '#e7fffb24',
|
||||
panel: '#192320',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
popup: '#293330',
|
||||
renote: '@accent',
|
||||
mentionMe: '#ffaa00',
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
fgOnWhite: '@accent',
|
||||
divider: '#e7fffb24',
|
||||
panel: '#192320',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
popup: '#293330',
|
||||
renote: '@accent',
|
||||
mentionMe: '#b4e900',
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
navIndicator: '@indicator',
|
||||
driveFolderBg: ':alpha<0.3<@accent',
|
||||
fgHighlighted: ':lighten<3<@fg',
|
||||
fgTransparent: ':alpha<0.5<@fg',
|
||||
panelHeaderBg: ':lighten<3<@panel',
|
||||
panelHeaderFg: '@fg',
|
||||
buttonGradateA: '@accent',
|
||||
|
@ -58,8 +57,6 @@
|
|||
panelHighlight: ':lighten<3<@panel',
|
||||
scrollbarHandle: 'rgba(255, 255, 255, 0.2)',
|
||||
inputBorderHover: 'rgba(255, 255, 255, 0.2)',
|
||||
fgTransparentWeak: ':alpha<0.75<@fg',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
scrollbarHandleHover: 'rgba(255, 255, 255, 0.4)',
|
||||
deckBg: '#142022',
|
||||
},
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
divider: '#cfcfcf',
|
||||
panel: '#ebe7e5',
|
||||
panelHeaderBg: '@panel',
|
||||
panelHeaderDivider: '@divider',
|
||||
header: ':alpha<0.7<@panel',
|
||||
navBg: '#ebe7e5',
|
||||
renote: '#229e92',
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
header: ':alpha<0.7<@panel',
|
||||
navBg: '#fff',
|
||||
panel: '#fff',
|
||||
panelHeaderDivider: '@divider',
|
||||
mentionMe: 'rgb(0, 179, 70)',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
fgOnWhite: '@accent',
|
||||
panel: '#fff',
|
||||
divider: 'rgb(230 233 234)',
|
||||
panelHeaderDivider: '@divider',
|
||||
renote: '@accent',
|
||||
link: '@accent',
|
||||
mention: '@accent',
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
buttonHoverBg: '#0000001a',
|
||||
driveFolderBg: ':alpha<0.3<@accent',
|
||||
fgHighlighted: ':lighten<3<@fg',
|
||||
fgTransparent: ':alpha<0.5<@fg',
|
||||
panelHeaderBg: ':lighten<3<@panel',
|
||||
panelHeaderFg: '@fg',
|
||||
buttonGradateA: '@accent',
|
||||
|
@ -60,8 +59,6 @@
|
|||
panelHighlight: ':lighten<3<@panel',
|
||||
scrollbarHandle: '#74747433',
|
||||
inputBorderHover: 'rgba(255, 255, 255, 0.2)',
|
||||
fgTransparentWeak: ':alpha<0.75<@fg',
|
||||
panelHeaderDivider: 'rgba(0, 0, 0, 0)',
|
||||
scrollbarHandleHover: 'rgba(255, 255, 255, 0.4)',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -41,15 +41,12 @@
|
|||
navIndicator: '@accent',
|
||||
driveFolderBg: ':alpha<0.3<@accent',
|
||||
fgHighlighted: ':darken<3<@fg',
|
||||
fgTransparent: ':alpha<0.5<@fg',
|
||||
fgOnWhite: '@accent',
|
||||
panelHeaderBg: ':lighten<3<@panel',
|
||||
panelHeaderFg: '@fg',
|
||||
htmlThemeColor: '@bg',
|
||||
panelHighlight: ':darken<3<@panel',
|
||||
scrollbarHandle: 'rgba(0, 0, 0, 0.2)',
|
||||
fgTransparentWeak: ':alpha<0.75<@fg',
|
||||
panelHeaderDivider: '@divider',
|
||||
scrollbarHandleHover: 'rgba(0, 0, 0, 0.4)',
|
||||
},
|
||||
}
|
||||
|
|
|
@ -4,77 +4,68 @@
|
|||
*/
|
||||
|
||||
import { parse as vueSfcParse } from 'vue/compiler-sfc';
|
||||
import type { LogOptions, Plugin } from 'vite';
|
||||
import {
|
||||
createLogger,
|
||||
EnvironmentModuleGraph,
|
||||
normalizePath,
|
||||
type LogErrorOptions,
|
||||
type LogOptions,
|
||||
type Plugin,
|
||||
type PluginOption
|
||||
} from 'vite';
|
||||
import fs from 'node:fs';
|
||||
import { glob } from 'glob';
|
||||
import JSON5 from 'json5';
|
||||
import MagicString from 'magic-string';
|
||||
import MagicString, { SourceMap } from 'magic-string';
|
||||
import path from 'node:path'
|
||||
import { hash, toBase62 } from '../vite.config';
|
||||
import { createLogger } from 'vite';
|
||||
import { minimatch } from 'minimatch';
|
||||
import type {
|
||||
AttributeNode, CompoundExpressionNode, DirectiveNode,
|
||||
ElementNode,
|
||||
RootNode, SimpleExpressionNode,
|
||||
TemplateChildNode,
|
||||
} from '@vue/compiler-core';
|
||||
import { NodeTypes } from '@vue/compiler-core';
|
||||
|
||||
interface VueAstNode {
|
||||
type: number;
|
||||
tag?: string;
|
||||
loc?: {
|
||||
start: { offset: number, line: number, column: number },
|
||||
end: { offset: number, line: number, column: number },
|
||||
source?: string
|
||||
};
|
||||
props?: Array<{
|
||||
name: string;
|
||||
type: number;
|
||||
value?: { content?: string };
|
||||
arg?: { content?: string };
|
||||
exp?: { content?: string; loc?: any };
|
||||
}>;
|
||||
children?: VueAstNode[];
|
||||
content?: any;
|
||||
__markerId?: string;
|
||||
__children?: string[];
|
||||
}
|
||||
|
||||
export type AnalysisResult = {
|
||||
export type AnalysisResult<T = SearchIndexItem> = {
|
||||
filePath: string;
|
||||
usage: SearchIndexItem[];
|
||||
usage: T[];
|
||||
}
|
||||
|
||||
export type SearchIndexItem = {
|
||||
export type SearchIndexItem = SearchIndexItemLink<SearchIndexItem>;
|
||||
export type SearchIndexStringItem = SearchIndexItemLink<string>;
|
||||
export interface SearchIndexItemLink<T> {
|
||||
id: string;
|
||||
path?: string;
|
||||
label: string;
|
||||
keywords: string | string[];
|
||||
icon?: string;
|
||||
inlining?: string[];
|
||||
children?: SearchIndexItem[];
|
||||
};
|
||||
children?: T[];
|
||||
}
|
||||
|
||||
export type Options = {
|
||||
targetFilePaths: string[],
|
||||
exportFilePath: string,
|
||||
mainVirtualModule: string,
|
||||
modulesToHmrOnUpdate: string[],
|
||||
fileVirtualModulePrefix?: string,
|
||||
fileVirtualModuleSuffix?: string,
|
||||
verbose?: boolean,
|
||||
};
|
||||
|
||||
// 関連するノードタイプの定数化
|
||||
const NODE_TYPES = {
|
||||
ELEMENT: 1,
|
||||
EXPRESSION: 2,
|
||||
TEXT: 3,
|
||||
INTERPOLATION: 5, // Mustache
|
||||
};
|
||||
|
||||
// マーカー関係を表す型
|
||||
interface MarkerRelation {
|
||||
parentId?: string;
|
||||
markerId: string;
|
||||
node: VueAstNode;
|
||||
node: ElementNode;
|
||||
}
|
||||
|
||||
// ロガー
|
||||
let logger = {
|
||||
info: (msg: string, options?: LogOptions) => { },
|
||||
warn: (msg: string, options?: LogOptions) => { },
|
||||
error: (msg: string, options?: LogOptions) => { },
|
||||
error: (msg: string, options?: LogErrorOptions) => { },
|
||||
};
|
||||
let loggerInitialized = false;
|
||||
|
||||
|
@ -99,14 +90,11 @@ function initLogger(options: Options) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析結果をTypeScriptファイルとして出力する
|
||||
*/
|
||||
function outputAnalysisResultAsTS(outputPath: string, analysisResults: AnalysisResult[]): void {
|
||||
function collectSearchItemIndexes(analysisResults: AnalysisResult<SearchIndexStringItem>[]): SearchIndexItem[] {
|
||||
logger.info(`Processing ${analysisResults.length} files for output`);
|
||||
|
||||
// 新しいツリー構造を構築
|
||||
const allMarkers = new Map<string, SearchIndexItem>();
|
||||
const allMarkers = new Map<string, SearchIndexStringItem>();
|
||||
|
||||
// 1. すべてのマーカーを一旦フラットに収集
|
||||
for (const file of analysisResults) {
|
||||
|
@ -115,10 +103,9 @@ function outputAnalysisResultAsTS(outputPath: string, analysisResults: AnalysisR
|
|||
for (const marker of file.usage) {
|
||||
if (marker.id) {
|
||||
// キーワードとchildren処理を共通化
|
||||
const processedMarker = {
|
||||
const processedMarker: SearchIndexStringItem = {
|
||||
...marker,
|
||||
keywords: processMarkerProperty(marker.keywords, 'keywords'),
|
||||
children: processMarkerProperty(marker.children || [], 'children')
|
||||
};
|
||||
|
||||
allMarkers.set(marker.id, processedMarker);
|
||||
|
@ -143,14 +130,13 @@ function outputAnalysisResultAsTS(outputPath: string, analysisResults: AnalysisR
|
|||
const { totalMarkers, totalChildren } = countMarkers(resolvedRootMarkers);
|
||||
logger.info(`Total markers in tree: ${totalMarkers} (${resolvedRootMarkers.length} roots + ${totalChildren} nested children)`);
|
||||
|
||||
// 6. 結果をTS形式で出力
|
||||
writeOutputFile(outputPath, resolvedRootMarkers);
|
||||
return resolvedRootMarkers;
|
||||
}
|
||||
|
||||
/**
|
||||
* マーカーのプロパティ(keywordsやchildren)を処理する
|
||||
*/
|
||||
function processMarkerProperty(propValue: any, propType: 'keywords' | 'children'): any {
|
||||
function processMarkerProperty(propValue: string | string[], propType: 'keywords' | 'children'): string | string[] {
|
||||
// 文字列の配列表現を解析
|
||||
if (typeof propValue === 'string' && propValue.startsWith('[') && propValue.endsWith(']')) {
|
||||
try {
|
||||
|
@ -169,7 +155,7 @@ function processMarkerProperty(propValue: any, propType: 'keywords' | 'children'
|
|||
/**
|
||||
* 全マーカーから子IDを収集する
|
||||
*/
|
||||
function collectChildIds(allMarkers: Map<string, SearchIndexItem>): Set<string> {
|
||||
function collectChildIds(allMarkers: Map<string, SearchIndexStringItem>): Set<string> {
|
||||
const childIds = new Set<string>();
|
||||
|
||||
allMarkers.forEach((marker, id) => {
|
||||
|
@ -232,10 +218,10 @@ function collectChildIds(allMarkers: Map<string, SearchIndexItem>): Set<string>
|
|||
* ルートマーカー(他の子でないマーカー)を特定する
|
||||
*/
|
||||
function identifyRootMarkers(
|
||||
allMarkers: Map<string, SearchIndexItem>,
|
||||
allMarkers: Map<string, SearchIndexStringItem>,
|
||||
childIds: Set<string>
|
||||
): SearchIndexItem[] {
|
||||
const rootMarkers: SearchIndexItem[] = [];
|
||||
): SearchIndexStringItem[] {
|
||||
const rootMarkers: SearchIndexStringItem[] = [];
|
||||
|
||||
allMarkers.forEach((marker, id) => {
|
||||
if (!childIds.has(id)) {
|
||||
|
@ -251,12 +237,12 @@ function identifyRootMarkers(
|
|||
* 子マーカーの参照をIDから実際のオブジェクトに解決する
|
||||
*/
|
||||
function resolveChildReferences(
|
||||
rootMarkers: SearchIndexItem[],
|
||||
allMarkers: Map<string, SearchIndexItem>
|
||||
rootMarkers: SearchIndexStringItem[],
|
||||
allMarkers: Map<string, SearchIndexStringItem>
|
||||
): SearchIndexItem[] {
|
||||
function resolveChildrenForMarker(marker: SearchIndexItem): SearchIndexItem {
|
||||
function resolveChildrenForMarker(marker: SearchIndexStringItem): SearchIndexItem {
|
||||
// マーカーのディープコピーを作成
|
||||
const resolvedMarker = { ...marker };
|
||||
const resolvedMarker: SearchIndexItem = { ...marker, children: [] };
|
||||
// 明示的に子マーカー配列を作成
|
||||
const resolvedChildren: SearchIndexItem[] = [];
|
||||
|
||||
|
@ -351,55 +337,19 @@ function countMarkers(markers: SearchIndexItem[]): { totalMarkers: number, total
|
|||
return { totalMarkers, totalChildren };
|
||||
}
|
||||
|
||||
/**
|
||||
* 最終的なTypeScriptファイルを出力
|
||||
*/
|
||||
function writeOutputFile(outputPath: string, resolvedRootMarkers: SearchIndexItem[]): void {
|
||||
try {
|
||||
const tsOutput = generateTypeScriptCode(resolvedRootMarkers);
|
||||
fs.writeFileSync(outputPath, tsOutput, 'utf-8');
|
||||
// 強制的に出力させるためにViteロガーを使わない
|
||||
console.log(`Successfully wrote search index to ${outputPath} with ${resolvedRootMarkers.length} root entries`);
|
||||
} catch (error) {
|
||||
logger.error('[create-search-index]: error writing output: ', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TypeScriptコード生成
|
||||
*/
|
||||
function generateTypeScriptCode(resolvedRootMarkers: SearchIndexItem[]): string {
|
||||
return `
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// This file was automatically generated by create-search-index.
|
||||
// Do not edit this file.
|
||||
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
export type SearchIndexItem = {
|
||||
id: string;
|
||||
path?: string;
|
||||
label: string;
|
||||
keywords: string[];
|
||||
icon?: string;
|
||||
children?: SearchIndexItem[];
|
||||
};
|
||||
|
||||
export const searchIndexes: SearchIndexItem[] = ${customStringify(resolvedRootMarkers)} as const;
|
||||
|
||||
export type SearchIndex = typeof searchIndexes;
|
||||
`;
|
||||
function generateJavaScriptCode(resolvedRootMarkers: SearchIndexItem[]): string {
|
||||
return `import { i18n } from '@/i18n.js';\n`
|
||||
+ `export const searchIndexes = ${customStringify(resolvedRootMarkers)};\n`;
|
||||
}
|
||||
|
||||
/**
|
||||
* オブジェクトを特殊な形式の文字列に変換する
|
||||
* i18n参照を保持しつつ適切な形式に変換
|
||||
*/
|
||||
function customStringify(obj: any, depth = 0): string {
|
||||
function customStringify(obj: unknown, depth = 0): string {
|
||||
const INDENT_STR = '\t';
|
||||
|
||||
// 配列の処理
|
||||
|
@ -441,7 +391,6 @@ function customStringify(obj: any, depth = 0): string {
|
|||
.filter(([key, value]) => {
|
||||
if (value === undefined) return false;
|
||||
if (key === 'children' && Array.isArray(value) && value.length === 0) return false;
|
||||
if (key === 'inlining') return false;
|
||||
return true;
|
||||
})
|
||||
// 各プロパティを変換
|
||||
|
@ -462,7 +411,7 @@ function customStringify(obj: any, depth = 0): string {
|
|||
/**
|
||||
* 特殊プロパティの書式設定
|
||||
*/
|
||||
function formatSpecialProperty(key: string, value: any): string {
|
||||
function formatSpecialProperty(key: string, value: unknown): string {
|
||||
// 値がundefinedの場合は空文字列を返す
|
||||
if (value === undefined) {
|
||||
return '""';
|
||||
|
@ -499,7 +448,7 @@ function formatSpecialProperty(key: string, value: any): string {
|
|||
/**
|
||||
* 配列式の文字列表現を生成
|
||||
*/
|
||||
function formatArrayForOutput(items: any[]): string {
|
||||
function formatArrayForOutput(items: unknown[]): string {
|
||||
return items.map(item => {
|
||||
// i18n.ts. 参照の文字列はそのままJavaScript式として出力
|
||||
if (typeof item === 'string' && isI18nReference(item)) {
|
||||
|
@ -516,17 +465,18 @@ function formatArrayForOutput(items: any[]): string {
|
|||
* 要素ノードからテキスト内容を抽出する
|
||||
* 各抽出方法を分離して可読性を向上
|
||||
*/
|
||||
function extractElementText(node: VueAstNode): string | null {
|
||||
function extractElementText(node: TemplateChildNode): string | null {
|
||||
if (!node) return null;
|
||||
if (node.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error("Unexpected COMPOUND_EXPRESSION");
|
||||
|
||||
logger.info(`Extracting text from node type=${node.type}, tag=${node.tag || 'unknown'}`);
|
||||
logger.info(`Extracting text from node type=${node.type}, tag=${'tag' in node ? node.tag : 'unknown'}`);
|
||||
|
||||
// 1. 直接コンテンツの抽出を試行
|
||||
const directContent = extractDirectContent(node);
|
||||
if (directContent) return directContent;
|
||||
|
||||
// 子要素がない場合は終了
|
||||
if (!node.children || !Array.isArray(node.children)) {
|
||||
if (!('children' in node) || !Array.isArray(node.children)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -548,12 +498,13 @@ function extractElementText(node: VueAstNode): string | null {
|
|||
/**
|
||||
* ノードから直接コンテンツを抽出
|
||||
*/
|
||||
function extractDirectContent(node: VueAstNode): string | null {
|
||||
if (!node.content) return null;
|
||||
function extractDirectContent(node: TemplateChildNode): string | null {
|
||||
if (!('content' in node)) return null;
|
||||
if (typeof node.content == 'object' && node.content.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error("Unexpected COMPOUND_EXPRESSION");
|
||||
|
||||
const content = typeof node.content === 'string'
|
||||
? node.content.trim()
|
||||
: (node.content.content ? node.content.content.trim() : null);
|
||||
const content = typeof node.content === 'string' ? node.content.trim()
|
||||
: node.content.type !== NodeTypes.INTERPOLATION ? node.content.content.trim()
|
||||
: null;
|
||||
|
||||
if (!content) return null;
|
||||
|
||||
|
@ -582,9 +533,9 @@ function extractDirectContent(node: VueAstNode): string | null {
|
|||
/**
|
||||
* インターポレーションノード(Mustache)からコンテンツを抽出
|
||||
*/
|
||||
function extractInterpolationContent(children: VueAstNode[]): string | null {
|
||||
function extractInterpolationContent(children: TemplateChildNode[]): string | null {
|
||||
for (const child of children) {
|
||||
if (child.type === NODE_TYPES.INTERPOLATION) {
|
||||
if (child.type === NodeTypes.INTERPOLATION) {
|
||||
logger.info(`Found interpolation node (Mustache): ${JSON.stringify(child.content).substring(0, 100)}...`);
|
||||
|
||||
if (child.content && child.content.type === 4 && child.content.content) {
|
||||
|
@ -595,6 +546,7 @@ function extractInterpolationContent(children: VueAstNode[]): string | null {
|
|||
return content;
|
||||
}
|
||||
} else if (child.content && typeof child.content === 'object') {
|
||||
if (child.content.type == NodeTypes.COMPOUND_EXPRESSION) throw new Error("Unexpected COMPOUND_EXPRESSION");
|
||||
// オブジェクト形式のcontentを探索
|
||||
logger.info(`Complex interpolation node: ${JSON.stringify(child.content).substring(0, 100)}...`);
|
||||
|
||||
|
@ -616,10 +568,10 @@ function extractInterpolationContent(children: VueAstNode[]): string | null {
|
|||
/**
|
||||
* 式ノードからコンテンツを抽出
|
||||
*/
|
||||
function extractExpressionContent(children: VueAstNode[]): string | null {
|
||||
function extractExpressionContent(children: TemplateChildNode[]): string | null {
|
||||
// i18n.ts. 参照パターンを持つものを優先
|
||||
for (const child of children) {
|
||||
if (child.type === NODE_TYPES.EXPRESSION && child.content) {
|
||||
if (child.type === NodeTypes.TEXT && child.content) {
|
||||
const expr = child.content.trim();
|
||||
|
||||
if (isI18nReference(expr)) {
|
||||
|
@ -631,7 +583,7 @@ function extractExpressionContent(children: VueAstNode[]): string | null {
|
|||
|
||||
// その他の式
|
||||
for (const child of children) {
|
||||
if (child.type === NODE_TYPES.EXPRESSION && child.content) {
|
||||
if (child.type === NodeTypes.TEXT && child.content) {
|
||||
const expr = child.content.trim();
|
||||
logger.info(`Found expression: ${expr}`);
|
||||
return expr;
|
||||
|
@ -644,9 +596,9 @@ function extractExpressionContent(children: VueAstNode[]): string | null {
|
|||
/**
|
||||
* テキストノードからコンテンツを抽出
|
||||
*/
|
||||
function extractTextContent(children: VueAstNode[]): string | null {
|
||||
function extractTextContent(children: TemplateChildNode[]): string | null {
|
||||
for (const child of children) {
|
||||
if (child.type === NODE_TYPES.TEXT && child.content) {
|
||||
if (child.type === NodeTypes.COMMENT && child.content) {
|
||||
const text = child.content.trim();
|
||||
|
||||
if (text) {
|
||||
|
@ -672,16 +624,16 @@ function extractTextContent(children: VueAstNode[]): string | null {
|
|||
/**
|
||||
* 子ノードを再帰的に探索してコンテンツを抽出
|
||||
*/
|
||||
function extractNestedContent(children: VueAstNode[]): string | null {
|
||||
function extractNestedContent(children: TemplateChildNode[]): string | null {
|
||||
for (const child of children) {
|
||||
if (child.children && Array.isArray(child.children) && child.children.length > 0) {
|
||||
if ('children' in child && Array.isArray(child.children) && child.children.length > 0) {
|
||||
const nestedContent = extractElementText(child);
|
||||
|
||||
if (nestedContent) {
|
||||
logger.info(`Found nested content: ${nestedContent}`);
|
||||
return nestedContent;
|
||||
}
|
||||
} else if (child.type === NODE_TYPES.ELEMENT) {
|
||||
} else if (child.type === NodeTypes.ELEMENT) {
|
||||
// childrenがなくても内部を調査
|
||||
const nestedContent = extractElementText(child);
|
||||
|
||||
|
@ -699,16 +651,16 @@ function extractNestedContent(children: VueAstNode[]): string | null {
|
|||
/**
|
||||
* SearchLabelとSearchKeywordを探して抽出する関数
|
||||
*/
|
||||
function extractLabelsAndKeywords(nodes: VueAstNode[]): { label: string | null, keywords: any[] } {
|
||||
function extractLabelsAndKeywords(nodes: TemplateChildNode[]): { label: string | null, keywords: string[] } {
|
||||
let label: string | null = null;
|
||||
const keywords: any[] = [];
|
||||
const keywords: string[] = [];
|
||||
|
||||
logger.info(`Extracting labels and keywords from ${nodes.length} nodes`);
|
||||
|
||||
// 再帰的にSearchLabelとSearchKeywordを探索(ネストされたSearchMarkerは処理しない)
|
||||
function findComponents(nodes: VueAstNode[]) {
|
||||
function findComponents(nodes: TemplateChildNode[]) {
|
||||
for (const node of nodes) {
|
||||
if (node.type === NODE_TYPES.ELEMENT) {
|
||||
if (node.type === NodeTypes.ELEMENT) {
|
||||
logger.info(`Checking element: ${node.tag}`);
|
||||
|
||||
// SearchMarkerの場合は、その子要素は別スコープなのでスキップ
|
||||
|
@ -730,11 +682,12 @@ function extractLabelsAndKeywords(nodes: VueAstNode[]): { label: string | null,
|
|||
logger.info(`SearchLabel found but extraction failed, trying direct children inspection`);
|
||||
|
||||
// バックアップ: 子直接確認 - type=5のMustacheインターポレーションを重点的に確認
|
||||
if (node.children && Array.isArray(node.children)) {
|
||||
{
|
||||
for (const child of node.children) {
|
||||
// Mustacheインターポレーション
|
||||
if (child.type === NODE_TYPES.INTERPOLATION && child.content) {
|
||||
if (child.type === NodeTypes.INTERPOLATION && child.content) {
|
||||
// content内の式を取り出す
|
||||
if (child.content.type == NodeTypes.COMPOUND_EXPRESSION) throw new Error("unexpected COMPOUND_EXPRESSION");
|
||||
const expression = child.content.content ||
|
||||
(child.content.type === 4 ? child.content.content : null) ||
|
||||
JSON.stringify(child.content);
|
||||
|
@ -747,13 +700,13 @@ function extractLabelsAndKeywords(nodes: VueAstNode[]): { label: string | null,
|
|||
}
|
||||
}
|
||||
// 式ノード
|
||||
else if (child.type === NODE_TYPES.EXPRESSION && child.content && isI18nReference(child.content)) {
|
||||
else if (child.type === NodeTypes.TEXT && child.content && isI18nReference(child.content)) {
|
||||
label = child.content.trim();
|
||||
logger.info(`Found i18n in expression: ${label}`);
|
||||
break;
|
||||
}
|
||||
// テキストノードでもMustache構文を探す
|
||||
else if (child.type === NODE_TYPES.TEXT && child.content) {
|
||||
else if (child.type === NodeTypes.COMMENT && child.content) {
|
||||
const mustacheMatch = child.content.trim().match(/^\s*{{\s*(.*?)\s*}}\s*$/);
|
||||
if (mustacheMatch && mustacheMatch[1] && isI18nReference(mustacheMatch[1])) {
|
||||
label = mustacheMatch[1].trim();
|
||||
|
@ -778,11 +731,12 @@ function extractLabelsAndKeywords(nodes: VueAstNode[]): { label: string | null,
|
|||
logger.info(`SearchKeyword found but extraction failed, trying direct children inspection`);
|
||||
|
||||
// バックアップ: 子直接確認 - type=5のMustacheインターポレーションを重点的に確認
|
||||
if (node.children && Array.isArray(node.children)) {
|
||||
{
|
||||
for (const child of node.children) {
|
||||
// Mustacheインターポレーション
|
||||
if (child.type === NODE_TYPES.INTERPOLATION && child.content) {
|
||||
if (child.type === NodeTypes.INTERPOLATION && child.content) {
|
||||
// content内の式を取り出す
|
||||
if (child.content.type == NodeTypes.COMPOUND_EXPRESSION) throw new Error("unexpected COMPOUND_EXPRESSION");
|
||||
const expression = child.content.content ||
|
||||
(child.content.type === 4 ? child.content.content : null) ||
|
||||
JSON.stringify(child.content);
|
||||
|
@ -796,14 +750,14 @@ function extractLabelsAndKeywords(nodes: VueAstNode[]): { label: string | null,
|
|||
}
|
||||
}
|
||||
// 式ノード
|
||||
else if (child.type === NODE_TYPES.EXPRESSION && child.content && isI18nReference(child.content)) {
|
||||
else if (child.type === NodeTypes.TEXT && child.content && isI18nReference(child.content)) {
|
||||
const keyword = child.content.trim();
|
||||
keywords.push(keyword);
|
||||
logger.info(`Found i18n keyword in expression: ${keyword}`);
|
||||
break;
|
||||
}
|
||||
// テキストノードでもMustache構文を探す
|
||||
else if (child.type === NODE_TYPES.TEXT && child.content) {
|
||||
else if (child.type === NodeTypes.COMMENT && child.content) {
|
||||
const mustacheMatch = child.content.trim().match(/^\s*{{\s*(.*?)\s*}}\s*$/);
|
||||
if (mustacheMatch && mustacheMatch[1] && isI18nReference(mustacheMatch[1])) {
|
||||
const keyword = mustacheMatch[1].trim();
|
||||
|
@ -834,23 +788,22 @@ function extractLabelsAndKeywords(nodes: VueAstNode[]): { label: string | null,
|
|||
|
||||
|
||||
function extractUsageInfoFromTemplateAst(
|
||||
templateAst: any,
|
||||
templateAst: RootNode | undefined,
|
||||
id: string,
|
||||
): SearchIndexItem[] {
|
||||
const allMarkers: SearchIndexItem[] = [];
|
||||
const markerMap = new Map<string, SearchIndexItem>();
|
||||
): SearchIndexStringItem[] {
|
||||
const allMarkers: SearchIndexStringItem[] = [];
|
||||
const markerMap = new Map<string, SearchIndexItemLink<string>>();
|
||||
const childrenIds = new Set<string>();
|
||||
const normalizedId = id.replace(/\\/g, '/');
|
||||
|
||||
if (!templateAst) return allMarkers;
|
||||
|
||||
// マーカーの基本情報を収集
|
||||
function collectMarkers(node: VueAstNode, parentId: string | null = null) {
|
||||
if (node.type === 1 && node.tag === 'SearchMarker') {
|
||||
function collectMarkers(node: TemplateChildNode | RootNode, parentId: string | null = null) {
|
||||
if (node.type === NodeTypes.ELEMENT && node.tag === 'SearchMarker') {
|
||||
// マーカーID取得
|
||||
const markerIdProp = node.props?.find((p: any) => p.name === 'markerId');
|
||||
const markerId = markerIdProp?.value?.content ||
|
||||
node.__markerId;
|
||||
const markerIdProp = node.props?.find(p => p.name === 'markerId');
|
||||
const markerId = markerIdProp?.type == NodeTypes.ATTRIBUTE ? markerIdProp.value?.content : null;
|
||||
|
||||
// SearchMarkerにマーカーIDがない場合はエラー
|
||||
if (markerId == null) {
|
||||
|
@ -859,7 +812,7 @@ function extractUsageInfoFromTemplateAst(
|
|||
}
|
||||
|
||||
// マーカー基本情報
|
||||
const markerInfo: SearchIndexItem = {
|
||||
const markerInfo: SearchIndexStringItem = {
|
||||
id: markerId,
|
||||
children: [],
|
||||
label: '', // デフォルト値
|
||||
|
@ -882,7 +835,7 @@ function extractUsageInfoFromTemplateAst(
|
|||
if (bindings.path) markerInfo.path = bindings.path;
|
||||
if (bindings.icon) markerInfo.icon = bindings.icon;
|
||||
if (bindings.label) markerInfo.label = bindings.label;
|
||||
if (bindings.children) markerInfo.children = bindings.children;
|
||||
if (bindings.children) markerInfo.children = processMarkerProperty(bindings.children, 'children') as string[];
|
||||
if (bindings.inlining) {
|
||||
markerInfo.inlining = bindings.inlining;
|
||||
logger.info(`Added inlining ${JSON.stringify(bindings.inlining)} to marker ${markerId}`);
|
||||
|
@ -946,19 +899,19 @@ function extractUsageInfoFromTemplateAst(
|
|||
}
|
||||
|
||||
// 子ノードを処理
|
||||
if (node.children && Array.isArray(node.children)) {
|
||||
node.children.forEach((child: VueAstNode) => {
|
||||
for (const child of node.children) {
|
||||
collectMarkers(child, markerId);
|
||||
});
|
||||
}
|
||||
|
||||
return markerId;
|
||||
}
|
||||
// SearchMarkerでない場合は再帰的に子ノードを処理
|
||||
else if (node.children && Array.isArray(node.children)) {
|
||||
node.children.forEach((child: VueAstNode) => {
|
||||
else if ('children' in node && Array.isArray(node.children)) {
|
||||
for (const child of node.children) {
|
||||
if (typeof child == 'object' && child.type !== NodeTypes.SIMPLE_EXPRESSION) {
|
||||
collectMarkers(child, parentId);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -969,16 +922,22 @@ function extractUsageInfoFromTemplateAst(
|
|||
return allMarkers;
|
||||
}
|
||||
|
||||
type SpecialBindings = {
|
||||
inlining: string[];
|
||||
keywords: string[] | string;
|
||||
};
|
||||
type Bindings = Partial<Omit<Record<keyof SearchIndexItem, string>, keyof SpecialBindings> & SpecialBindings>;
|
||||
// バインドプロパティの処理を修正する関数
|
||||
function extractNodeBindings(node: VueAstNode): Record<keyof SearchIndexItem, any> {
|
||||
const bindings: Record<string, any> = {};
|
||||
function extractNodeBindings(node: TemplateChildNode | RootNode): Bindings {
|
||||
const bindings: Bindings = {};
|
||||
|
||||
if (!node.props || !Array.isArray(node.props)) return bindings;
|
||||
if (node.type !== NodeTypes.ELEMENT) return bindings;
|
||||
|
||||
// バインド式を収集
|
||||
for (const prop of node.props) {
|
||||
if (prop.type === 7 && prop.name === 'bind' && prop.arg?.content) {
|
||||
if (prop.type === NodeTypes.DIRECTIVE && prop.name === 'bind' && prop.arg && 'content' in prop.arg) {
|
||||
const propName = prop.arg.content;
|
||||
if (prop.exp?.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error('unexpected COMPOUND_EXPRESSION');
|
||||
const propContent = prop.exp?.content || '';
|
||||
|
||||
logger.info(`Processing bind prop ${propName}: ${propContent}`);
|
||||
|
@ -1055,7 +1014,7 @@ function extractNodeBindings(node: VueAstNode): Record<keyof SearchIndexItem, an
|
|||
}
|
||||
|
||||
// 配列式をパースする補助関数(文字列リテラル処理を改善)
|
||||
function parseArrayExpression(expr: string): any[] {
|
||||
function parseArrayExpression(expr: string): string[] {
|
||||
try {
|
||||
// 単純なケースはJSON5でパースを試みる
|
||||
return JSON5.parse(expr.replace(/'/g, '"'));
|
||||
|
@ -1067,7 +1026,7 @@ function parseArrayExpression(expr: string): any[] {
|
|||
const content = expr.substring(1, expr.length - 1).trim();
|
||||
if (!content) return [];
|
||||
|
||||
const result: any[] = [];
|
||||
const result: string[] = [];
|
||||
let currentItem = '';
|
||||
let depth = 0;
|
||||
let inString = false;
|
||||
|
@ -1138,37 +1097,16 @@ function parseArrayExpression(expr: string): any[] {
|
|||
}
|
||||
}
|
||||
|
||||
export async function analyzeVueProps(options: Options & {
|
||||
transformedCodeCache: Record<string, string>,
|
||||
}): Promise<void> {
|
||||
initLogger(options);
|
||||
|
||||
const allMarkers: SearchIndexItem[] = [];
|
||||
|
||||
// 対象ファイルパスを glob で展開
|
||||
const filePaths = options.targetFilePaths.reduce<string[]>((acc, filePathPattern) => {
|
||||
const matchedFiles = glob.sync(filePathPattern);
|
||||
return [...acc, ...matchedFiles];
|
||||
}, []);
|
||||
|
||||
logger.info(`Found ${filePaths.length} matching files to analyze`);
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
const absolutePath = path.join(process.cwd(), filePath);
|
||||
const id = absolutePath.replace(/\\/g, '/'); // 絶対パスに変換
|
||||
const code = options.transformedCodeCache[id]; // options 経由でキャッシュ参照
|
||||
if (!code) { // キャッシュミスの場合
|
||||
logger.error(`Error: No cached code found for: ${id}.`); // エラーログ
|
||||
throw new Error(`No cached code found for: ${id}.`); // エラーを投げる
|
||||
}
|
||||
|
||||
export function collectFileMarkers(files: [id: string, code: string][]): AnalysisResult<SearchIndexStringItem> {
|
||||
const allMarkers: SearchIndexStringItem[] = [];
|
||||
for (const [id, code] of files) {
|
||||
try {
|
||||
const { descriptor, errors } = vueSfcParse(options.transformedCodeCache[id], {
|
||||
filename: filePath,
|
||||
const { descriptor, errors } = vueSfcParse(code, {
|
||||
filename: id,
|
||||
});
|
||||
|
||||
if (errors.length > 0) {
|
||||
logger.error(`Compile Error: ${filePath}, ${errors}`);
|
||||
logger.error(`Compile Error: ${id}, ${errors}`);
|
||||
continue; // エラーが発生したファイルはスキップ
|
||||
}
|
||||
|
||||
|
@ -1176,83 +1114,76 @@ export async function analyzeVueProps(options: Options & {
|
|||
|
||||
if (fileMarkers && fileMarkers.length > 0) {
|
||||
allMarkers.push(...fileMarkers); // すべてのマーカーを収集
|
||||
logger.info(`Successfully extracted ${fileMarkers.length} markers from ${filePath}`);
|
||||
logger.info(`Successfully extracted ${fileMarkers.length} markers from ${id}`);
|
||||
} else {
|
||||
logger.info(`No markers found in ${filePath}`);
|
||||
logger.info(`No markers found in ${id}`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Error analyzing file ${filePath}:`, error);
|
||||
logger.error(`Error analyzing file ${id}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
// 収集したすべてのマーカー情報を使用
|
||||
const analysisResult: AnalysisResult[] = [
|
||||
{
|
||||
return {
|
||||
filePath: "combined-markers", // すべてのファイルのマーカーを1つのエントリとして扱う
|
||||
usage: allMarkers,
|
||||
};
|
||||
}
|
||||
|
||||
type TransformedCode = {
|
||||
code: string,
|
||||
map: SourceMap,
|
||||
};
|
||||
|
||||
export class MarkerIdAssigner {
|
||||
// key: file id
|
||||
private cache: Map<string, TransformedCode>;
|
||||
|
||||
constructor() {
|
||||
this.cache = new Map();
|
||||
}
|
||||
];
|
||||
|
||||
outputAnalysisResultAsTS(options.exportFilePath, analysisResult); // すべてのマーカー情報を渡す
|
||||
}
|
||||
public onInvalidate(id: string) {
|
||||
this.cache.delete(id);
|
||||
}
|
||||
|
||||
interface MarkerRelation {
|
||||
parentId?: string;
|
||||
markerId: string;
|
||||
node: VueAstNode;
|
||||
}
|
||||
|
||||
async function processVueFile(
|
||||
code: string,
|
||||
id: string,
|
||||
options: Options,
|
||||
transformedCodeCache: Record<string, string>
|
||||
): Promise<{
|
||||
code: string,
|
||||
map: any,
|
||||
transformedCodeCache: Record<string, string>
|
||||
}> {
|
||||
const normalizedId = id.replace(/\\/g, '/'); // ファイルパスを正規化
|
||||
|
||||
// 開発モード時はコード内容に変更があれば常に再処理する
|
||||
// コード内容が同じ場合のみキャッシュを使用
|
||||
const isDevMode = process.env.NODE_ENV === 'development';
|
||||
public processFile(id: string, code: string): TransformedCode {
|
||||
// try cache first
|
||||
if (this.cache.has(id)) {
|
||||
return this.cache.get(id)!;
|
||||
}
|
||||
const transformed = this.#processImpl(id, code);
|
||||
this.cache.set(id, transformed);
|
||||
return transformed;
|
||||
}
|
||||
|
||||
#processImpl(id: string, code: string): TransformedCode {
|
||||
const s = new MagicString(code); // magic-string のインスタンスを作成
|
||||
|
||||
if (!isDevMode && transformedCodeCache[normalizedId] && transformedCodeCache[normalizedId].includes('markerId=')) {
|
||||
logger.info(`Using cached version for ${id}`);
|
||||
return {
|
||||
code: transformedCodeCache[normalizedId],
|
||||
map: s.generateMap({ source: id, includeContent: true }),
|
||||
transformedCodeCache
|
||||
};
|
||||
}
|
||||
|
||||
// すでに処理済みのファイルでコードに変更がない場合はキャッシュを返す
|
||||
if (transformedCodeCache[normalizedId] === code) {
|
||||
logger.info(`Code unchanged for ${id}, using cached version`);
|
||||
return {
|
||||
code: transformedCodeCache[normalizedId],
|
||||
map: s.generateMap({ source: id, includeContent: true }),
|
||||
transformedCodeCache
|
||||
};
|
||||
}
|
||||
|
||||
const parsed = vueSfcParse(code, { filename: id });
|
||||
if (!parsed.descriptor.template) {
|
||||
return {
|
||||
code,
|
||||
map: s.generateMap({ source: id, includeContent: true }),
|
||||
transformedCodeCache
|
||||
};
|
||||
}
|
||||
const ast = parsed.descriptor.template.ast; // テンプレート AST を取得
|
||||
const markerRelations: MarkerRelation[] = []; // MarkerRelation 配列を初期化
|
||||
|
||||
if (ast) {
|
||||
function traverse(node: any, currentParent?: any) {
|
||||
if (node.type === 1 && node.tag === 'SearchMarker') {
|
||||
if (!ast) {
|
||||
return {
|
||||
code: s.toString(), // 変更後のコードを返す
|
||||
map: s.generateMap({ source: id, includeContent: true }), // ソースマップも生成 (sourceMap: true が必要)
|
||||
};
|
||||
}
|
||||
|
||||
type SearchMarkerElementNode = ElementNode & {
|
||||
__markerId?: string,
|
||||
__children?: string[],
|
||||
};
|
||||
|
||||
function traverse(node: RootNode | TemplateChildNode | SimpleExpressionNode | CompoundExpressionNode, currentParent?: SearchMarkerElementNode) {
|
||||
if (node.type === NodeTypes.ELEMENT && node.tag === 'SearchMarker') {
|
||||
// 行番号はコード先頭からの改行数で取得
|
||||
const lineNumber = code.slice(0, node.loc.start.offset).split('\n').length;
|
||||
// ファイルパスと行番号からハッシュ値を生成
|
||||
|
@ -1261,14 +1192,14 @@ async function processVueFile(
|
|||
const generatedMarkerId = toBase62(hash(`${idKey}:${lineNumber}`));
|
||||
|
||||
const props = node.props || [];
|
||||
const hasMarkerIdProp = props.some((prop: any) => prop.type === 6 && prop.name === 'markerId');
|
||||
const hasMarkerIdProp = props.some((prop) => prop.type === NodeTypes.ATTRIBUTE && prop.name === 'markerId');
|
||||
const nodeMarkerId = hasMarkerIdProp
|
||||
? props.find((prop: any) => prop.type === 6 && prop.name === 'markerId')?.value?.content as string
|
||||
? props.find((prop): prop is AttributeNode => prop.type === NodeTypes.ATTRIBUTE && prop.name === 'markerId')?.value?.content as string
|
||||
: generatedMarkerId;
|
||||
node.__markerId = nodeMarkerId;
|
||||
(node as SearchMarkerElementNode).__markerId = nodeMarkerId;
|
||||
|
||||
// 子マーカーの場合、親ノードに __children を設定しておく
|
||||
if (currentParent && currentParent.type === 1 && currentParent.tag === 'SearchMarker') {
|
||||
if (currentParent) {
|
||||
currentParent.__children = currentParent.__children || [];
|
||||
currentParent.__children.push(nodeMarkerId);
|
||||
}
|
||||
|
@ -1313,9 +1244,13 @@ async function processVueFile(
|
|||
}
|
||||
}
|
||||
|
||||
const newParent = node.type === 1 && node.tag === 'SearchMarker' ? node : currentParent;
|
||||
if (node.children && Array.isArray(node.children)) {
|
||||
node.children.forEach(child => traverse(child, newParent));
|
||||
const newParent: SearchMarkerElementNode | undefined = node.type === NodeTypes.ELEMENT && node.tag === 'SearchMarker' ? node : currentParent;
|
||||
if ('children' in node) {
|
||||
for (const child of node.children) {
|
||||
if (typeof child == 'object') {
|
||||
traverse(child, newParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1341,7 +1276,11 @@ async function processVueFile(
|
|||
if (!parentRelation || !parentRelation.node) continue;
|
||||
|
||||
const parentNode = parentRelation.node;
|
||||
const childrenProp = parentNode.props?.find((prop: any) => prop.type === 7 && prop.name === 'bind' && prop.arg?.content === 'children');
|
||||
const childrenProp = parentNode.props?.find((prop): prop is DirectiveNode =>
|
||||
prop.type === NodeTypes.DIRECTIVE &&
|
||||
prop.name === 'bind' &&
|
||||
prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION &&
|
||||
prop.arg.content === 'children');
|
||||
|
||||
// 親ノードの開始位置を特定
|
||||
const parentNodeStart = parentNode.loc!.start.offset;
|
||||
|
@ -1416,53 +1355,64 @@ async function processVueFile(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const transformedCode = s.toString(); // 変換後のコードを取得
|
||||
transformedCodeCache[normalizedId] = transformedCode; // 変換後のコードをキャッシュに保存
|
||||
|
||||
return {
|
||||
code: transformedCode, // 変更後のコードを返す
|
||||
code: s.toString(), // 変更後のコードを返す
|
||||
map: s.generateMap({ source: id, includeContent: true }), // ソースマップも生成 (sourceMap: true が必要)
|
||||
transformedCodeCache // キャッシュも返す
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateSearchIndex(options: Options, transformedCodeCache: Record<string, string> = {}) {
|
||||
const filePaths = options.targetFilePaths.reduce<string[]>((acc, filePathPattern) => {
|
||||
const matchedFiles = glob.sync(filePathPattern);
|
||||
return [...acc, ...matchedFiles];
|
||||
}, []);
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
const id = path.resolve(filePath); // 絶対パスに変換
|
||||
const code = fs.readFileSync(filePath, 'utf-8'); // ファイル内容を読み込む
|
||||
const { transformedCodeCache: newCache } = await processVueFile(code, id, options, transformedCodeCache); // processVueFile 関数を呼び出す
|
||||
transformedCodeCache = newCache; // キャッシュを更新
|
||||
}
|
||||
|
||||
await analyzeVueProps({ ...options, transformedCodeCache }); // 開発サーバー起動時にも analyzeVueProps を実行
|
||||
async getOrLoad(id: string) {
|
||||
// if there already exists a cache, return it
|
||||
// note cahce will be invalidated on file change so the cache must be up to date
|
||||
let code = this.getCached(id)?.code;
|
||||
if (code != null) {
|
||||
return code;
|
||||
}
|
||||
|
||||
return transformedCodeCache; // キャッシュを返す
|
||||
// if no cache found, read and parse the file
|
||||
const originalCode = await fs.promises.readFile(id, 'utf-8');
|
||||
|
||||
// Other code may already parsed the file while we were waiting for the file to be read so re-check the cache
|
||||
code = this.getCached(id)?.code;
|
||||
if (code != null) {
|
||||
return code;
|
||||
}
|
||||
|
||||
// parse the file
|
||||
code = this.processFile(id, originalCode)?.code;
|
||||
return code;
|
||||
}
|
||||
|
||||
getCached(id: string) {
|
||||
return this.cache.get(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Rollup プラグインとして export
|
||||
export default function pluginCreateSearchIndex(options: Options): Plugin {
|
||||
let transformedCodeCache: Record<string, string> = {}; // キャッシュオブジェクトをプラグインスコープで定義
|
||||
const isDevServer = process.env.NODE_ENV === 'development'; // 開発サーバーかどうか
|
||||
export default function pluginCreateSearchIndex(options: Options): PluginOption {
|
||||
const assigner = new MarkerIdAssigner();
|
||||
return [
|
||||
createSearchIndex(options, assigner),
|
||||
pluginCreateSearchIndexVirtualModule(options, assigner),
|
||||
]
|
||||
}
|
||||
|
||||
function createSearchIndex(options: Options, assigner: MarkerIdAssigner): Plugin {
|
||||
initLogger(options); // ロガーを初期化
|
||||
const root = normalizePath(process.cwd());
|
||||
|
||||
return {
|
||||
name: 'createSearchIndex',
|
||||
enforce: 'pre',
|
||||
|
||||
async buildStart() {
|
||||
if (!isDevServer) {
|
||||
return;
|
||||
function isTargetFile(id: string): boolean {
|
||||
const relativePath = path.posix.relative(root, id);
|
||||
return options.targetFilePaths.some(pat => minimatch(relativePath, pat))
|
||||
}
|
||||
|
||||
transformedCodeCache = await generateSearchIndex(options, transformedCodeCache);
|
||||
return {
|
||||
name: 'autoAssignMarkerId',
|
||||
enforce: 'pre',
|
||||
|
||||
watchChange(id) {
|
||||
assigner.onInvalidate(id);
|
||||
},
|
||||
|
||||
async transform(code, id) {
|
||||
|
@ -1470,43 +1420,88 @@ export default function pluginCreateSearchIndex(options: Options): Plugin {
|
|||
return;
|
||||
}
|
||||
|
||||
// targetFilePaths にマッチするファイルのみ処理を行う
|
||||
// glob パターンでマッチング
|
||||
let isMatch = false; // isMatch の初期値を false に設定
|
||||
for (const pattern of options.targetFilePaths) { // パターンごとにマッチング確認
|
||||
const globbedFiles = glob.sync(pattern);
|
||||
for (const globbedFile of globbedFiles) {
|
||||
const normalizedGlobbedFile = path.resolve(globbedFile); // glob 結果を絶対パスに
|
||||
const normalizedId = path.resolve(id); // id を絶対パスに
|
||||
if (normalizedGlobbedFile === normalizedId) { // 絶対パス同士で比較
|
||||
isMatch = true;
|
||||
break; // マッチしたらループを抜ける
|
||||
}
|
||||
}
|
||||
if (isMatch) break; // いずれかのパターンでマッチしたら、outer loop も抜ける
|
||||
}
|
||||
|
||||
if (!isMatch) {
|
||||
if (!isTargetFile(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ファイルの内容が変更された場合は再処理を行う
|
||||
const normalizedId = id.replace(/\\/g, '/');
|
||||
const hasContentChanged = !transformedCodeCache[normalizedId] || transformedCodeCache[normalizedId] !== code;
|
||||
return assigner.processFile(id, code);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const transformed = await processVueFile(code, id, options, transformedCodeCache);
|
||||
transformedCodeCache = transformed.transformedCodeCache; // キャッシュを更新
|
||||
export function pluginCreateSearchIndexVirtualModule(options: Options, asigner: MarkerIdAssigner): Plugin {
|
||||
const searchIndexPrefix = options.fileVirtualModulePrefix ?? 'search-index-individual:';
|
||||
const searchIndexSuffix = options.fileVirtualModuleSuffix ?? '.ts';
|
||||
const allSearchIndexFile = options.mainVirtualModule;
|
||||
const root = normalizePath(process.cwd());
|
||||
|
||||
if (isDevServer && hasContentChanged) {
|
||||
await analyzeVueProps({ ...options, transformedCodeCache }); // ファイルが変更されたときのみ分析を実行
|
||||
function isTargetFile(id: string): boolean {
|
||||
const relativePath = path.posix.relative(root, id);
|
||||
return options.targetFilePaths.some(pat => minimatch(relativePath, pat))
|
||||
}
|
||||
|
||||
return transformed;
|
||||
function parseSearchIndexFileId(id: string): string | null {
|
||||
const noQuery = id.split('?')[0];
|
||||
if (noQuery.startsWith(searchIndexPrefix) && noQuery.endsWith(searchIndexSuffix)) {
|
||||
const filePath = id.slice(searchIndexPrefix.length).slice(0, -searchIndexSuffix.length);
|
||||
if (isTargetFile(filePath)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'generateSearchIndexVirtualModule',
|
||||
// hotUpdate hook を vite:vue よりもあとに実行したいため enforce: post
|
||||
enforce: 'post',
|
||||
|
||||
async resolveId(id) {
|
||||
if (id == allSearchIndexFile) {
|
||||
return '\0' + allSearchIndexFile;
|
||||
}
|
||||
|
||||
const searchIndexFilePath = parseSearchIndexFileId(id);
|
||||
if (searchIndexFilePath != null) {
|
||||
return id;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
async writeBundle() {
|
||||
await analyzeVueProps({ ...options, transformedCodeCache }); // ビルド時にも analyzeVueProps を実行
|
||||
async load(id) {
|
||||
if (id == '\0' + allSearchIndexFile) {
|
||||
const files = await Promise.all(options.targetFilePaths.map(async (filePathPattern) => await glob(filePathPattern))).then(paths => paths.flat());
|
||||
let generatedFile = '';
|
||||
let arrayElements = '';
|
||||
for (let file of files) {
|
||||
const normalizedRelative = normalizePath(file);
|
||||
const absoluteId = normalizePath(path.join(process.cwd(), normalizedRelative)) + searchIndexSuffix;
|
||||
const variableName = normalizedRelative.replace(/[\/.-]/g, '_');
|
||||
generatedFile += `import { searchIndexes as ${variableName} } from '${searchIndexPrefix}${absoluteId}';\n`;
|
||||
arrayElements += ` ...${variableName},\n`;
|
||||
}
|
||||
generatedFile += `export let searchIndexes = [\n${arrayElements}];\n`;
|
||||
return generatedFile;
|
||||
}
|
||||
|
||||
const searchIndexFilePath = parseSearchIndexFileId(id);
|
||||
if (searchIndexFilePath != null) {
|
||||
// call load to update the index file when the file is changed
|
||||
this.addWatchFile(searchIndexFilePath);
|
||||
|
||||
const code = await asigner.getOrLoad(searchIndexFilePath);
|
||||
return generateJavaScriptCode(collectSearchItemIndexes([collectFileMarkers([[id, code]])]));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
hotUpdate(this: { environment: { moduleGraph: EnvironmentModuleGraph } }, { file, modules }) {
|
||||
if (isTargetFile(file)) {
|
||||
const updateMods = options.modulesToHmrOnUpdate.map(id => this.environment.moduleGraph.getModuleById(path.posix.join(root, id))).filter(x => x != null);
|
||||
return [...modules, ...updateMods];
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
"scripts": {
|
||||
"watch": "vite",
|
||||
"build": "vite build",
|
||||
"build-search-index": "vite-node --config \"./vite-node.config.ts\" \"./scripts/generate-search-index.ts\"",
|
||||
"storybook-dev": "nodemon --verbose --watch src --ext \"mdx,ts,vue\" --ignore \"*.stories.ts\" --exec \"pnpm build-storybook-pre && pnpm exec storybook dev -p 6006 --ci\"",
|
||||
"build-storybook-pre": "(tsc -p .storybook || echo done.) && node .storybook/generate.js && node .storybook/preload-locale.js && node .storybook/preload-theme.js",
|
||||
"build-storybook": "pnpm build-storybook-pre && storybook build --webpack-stats-json storybook-static",
|
||||
|
@ -120,6 +119,7 @@
|
|||
"@typescript-eslint/eslint-plugin": "8.27.0",
|
||||
"@typescript-eslint/parser": "8.27.0",
|
||||
"@vitest/coverage-v8": "3.0.9",
|
||||
"@vue/compiler-core": "3.5.13",
|
||||
"@vue/runtime-core": "3.5.13",
|
||||
"acorn": "8.14.1",
|
||||
"cross-env": "7.0.3",
|
||||
|
@ -129,6 +129,7 @@
|
|||
"happy-dom": "17.4.4",
|
||||
"intersection-observer": "0.12.2",
|
||||
"micromatch": "4.0.8",
|
||||
"minimatch": "10.0.1",
|
||||
"msw": "2.7.3",
|
||||
"msw-storybook-addon": "2.0.4",
|
||||
"nodemon": "3.1.9",
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { searchIndexes } from '../vite.config.js';
|
||||
import { generateSearchIndex } from '../lib/vite-plugin-create-search-index.js';
|
||||
|
||||
async function main() {
|
||||
for (const searchIndex of searchIndexes) {
|
||||
await generateSearchIndex(searchIndex);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
|
@ -140,7 +140,7 @@ watch(v, newValue => {
|
|||
.caption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -60,7 +60,7 @@ const onInput = () => {
|
|||
.caption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -181,12 +181,17 @@ onUnmounted(() => {
|
|||
left: 0;
|
||||
color: var(--MI_THEME-panelHeaderFg);
|
||||
background: var(--MI_THEME-panelHeaderBg);
|
||||
border-bottom: solid 0.5px var(--MI_THEME-panelHeaderDivider);
|
||||
z-index: 2;
|
||||
line-height: 1.4em;
|
||||
background: color-mix(in srgb, var(--MI_THEME-panelHeaderBg) 35%, transparent);
|
||||
}
|
||||
|
||||
@container style(--MI_THEME-panelHeaderBg: var(--MI_THEME-panel)) {
|
||||
.header {
|
||||
box-shadow: 0 0.5px 0 0 light-dark(#0002, #fff2);
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
padding: 12px 16px;
|
||||
|
|
|
@ -175,7 +175,7 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
.headerLower {
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
font-size: .85em;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
@ -209,13 +209,13 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
.headerTextSub {
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
font-size: .85em;
|
||||
}
|
||||
|
||||
.headerRight {
|
||||
margin-left: auto;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ defineExpose({
|
|||
.caption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -78,7 +78,7 @@ export default defineComponent({
|
|||
> .caption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -213,7 +213,7 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
|
|||
> .caption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -268,7 +268,7 @@ function show() {
|
|||
.caption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -94,7 +94,7 @@ export type SuperMenuDef = {
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { useTemplateRef, ref, watch, nextTick } from 'vue';
|
||||
import type { SearchIndexItem } from '@/utility/autogen/settings-search-index.js';
|
||||
import type { SearchIndexItem } from '@/utility/settings-search-index.js';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { getScrollContainer } from '@@/js/scroll.js';
|
||||
|
|
|
@ -100,7 +100,7 @@ const toggle = () => {
|
|||
|
||||
.caption {
|
||||
margin: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
font-size: 0.85em;
|
||||
|
||||
&:empty {
|
||||
|
|
|
@ -307,6 +307,6 @@ onMounted(async () => {
|
|||
.description {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -160,7 +160,7 @@ onUnmounted(() => {
|
|||
.caption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -298,7 +298,7 @@ onMounted(() => {
|
|||
|
||||
.statusItemLabel {
|
||||
font-size: 0.7em;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
|
||||
.menu {
|
||||
|
|
|
@ -193,7 +193,7 @@ function showMenu(ev: MouseEvent) {
|
|||
}
|
||||
|
||||
.statsItemLabel {
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ const props = defineProps<{
|
|||
margin-right: 0.75em;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -49,7 +49,7 @@ defineProps<{
|
|||
|
||||
.description {
|
||||
font-size: 0.85em;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -35,7 +35,7 @@ function focus() {
|
|||
.caption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
|
@ -81,7 +81,7 @@ const emit = defineEmits<{
|
|||
const displayBackButton = props.displayBackButton && window.history.state.key !== 'index' && window.history.length > 1 && inject('shouldBackButton', true);
|
||||
|
||||
//const viewId = inject(DI.viewId);
|
||||
const injectedPageMetadata = inject(DI.pageMetadata);
|
||||
const injectedPageMetadata = inject(DI.pageMetadata, ref(null));
|
||||
const pageMetadata = computed(() => props.overridePageMetadata ?? injectedPageMetadata.value);
|
||||
|
||||
const hideTitle = computed(() => inject('shouldOmitHeaderTitle', false) || props.hideTitle);
|
||||
|
|
|
@ -10,7 +10,7 @@ export const DI = {
|
|||
routerCurrentDepth: Symbol() as InjectionKey<number>,
|
||||
router: Symbol() as InjectionKey<Router>,
|
||||
mock: Symbol() as InjectionKey<boolean>,
|
||||
pageMetadata: Symbol() as InjectionKey<Ref<Record<string, any>>>,
|
||||
pageMetadata: Symbol() as InjectionKey<Ref<Record<string, any> | null>>,
|
||||
viewId: Symbol() as InjectionKey<string>,
|
||||
currentStickyTop: Symbol() as InjectionKey<Ref<number>>,
|
||||
currentStickyBottom: Symbol() as InjectionKey<Ref<number>>,
|
||||
|
|
|
@ -724,7 +724,7 @@ definePage(() => ({
|
|||
.roleItemSub {
|
||||
padding: 6px 12px;
|
||||
font-size: 85%;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
|
||||
.roleUnassign {
|
||||
|
|
|
@ -66,7 +66,7 @@ const emit = defineEmits<{
|
|||
(ev: 'update:tab', key: string);
|
||||
}>();
|
||||
|
||||
const pageMetadata = inject(DI.pageMetadata);
|
||||
const pageMetadata = inject(DI.pageMetadata, ref(null));
|
||||
|
||||
const el = useTemplateRef('el');
|
||||
const tabHighlightEl = useTemplateRef('tabHighlightEl');
|
||||
|
|
|
@ -184,7 +184,7 @@ definePage(() => ({
|
|||
.userItemSub {
|
||||
padding: 6px 12px;
|
||||
font-size: 85%;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
|
||||
.userItemMainBody {
|
||||
|
|
|
@ -459,6 +459,6 @@ definePage(() => ({
|
|||
<style lang="scss" module>
|
||||
.subCaption {
|
||||
font-size: 0.85em;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -75,6 +75,6 @@ function onDeleteClick() {
|
|||
margin-right: 0.75em;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -247,7 +247,7 @@ definePage(() => ({
|
|||
}
|
||||
|
||||
.uiInspectorUnShown {
|
||||
color: var(--MI_THEME-fgTransparent);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.5);
|
||||
}
|
||||
|
||||
.uiInspectorType {
|
||||
|
|
|
@ -351,7 +351,7 @@ async function search() {
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
border: 2px dashed var(--MI_THEME-fgTransparent);
|
||||
border: 2px dashed color(from var(--MI_THEME-fg) srgb r g b / 0.5);
|
||||
}
|
||||
|
||||
.userSelectButtonInner {
|
||||
|
|
|
@ -161,6 +161,6 @@ function del(ev: MouseEvent) {
|
|||
.editorCaption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -285,6 +285,6 @@ definePage(() => ({
|
|||
.editorCaption {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -42,7 +42,7 @@ import { instance } from '@/instance.js';
|
|||
import { definePage, provideMetadataReceiver, provideReactiveMetadata } from '@/page.js';
|
||||
import * as os from '@/os.js';
|
||||
import { useRouter } from '@/router.js';
|
||||
import { searchIndexes } from '@/utility/autogen/settings-search-index.js';
|
||||
import { searchIndexes } from '@/utility/settings-search-index.js';
|
||||
import { enableAutoBackup, getPreferencesProfileMenu } from '@/preferences/utility.js';
|
||||
import { store } from '@/store.js';
|
||||
import { signout } from '@/signout.js';
|
||||
|
|
|
@ -308,7 +308,7 @@ definePage(() => ({
|
|||
.userItemSub {
|
||||
padding: 6px 12px;
|
||||
font-size: 85%;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
|
||||
.userItemMainBody {
|
||||
|
|
|
@ -184,6 +184,6 @@ definePage(() => ({
|
|||
.description {
|
||||
font-size: 0.85em;
|
||||
padding: 8px 0 0 0;
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -653,7 +653,7 @@ onUnmounted(() => {
|
|||
|
||||
> .heading {
|
||||
text-align: left;
|
||||
color: var(--MI_THEME-fgTransparent);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.5);
|
||||
line-height: 1.5;
|
||||
font-size: 85%;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ export function migrateOldSettings() {
|
|||
prefer.commit('collapseRenotes', store.s.collapseRenotes);
|
||||
prefer.commit('rememberNoteVisibility', store.s.rememberNoteVisibility);
|
||||
prefer.commit('uploadFolder', store.s.uploadFolder);
|
||||
prefer.commit('menu', store.s.menu);
|
||||
prefer.commit('menu', [...store.s.menu, 'chat']);
|
||||
prefer.commit('statusbars', store.s.statusbars);
|
||||
prefer.commit('pinnedUserLists', store.s.pinnedUserLists);
|
||||
prefer.commit('serverDisconnectedBehavior', store.s.serverDisconnectedBehavior);
|
||||
|
|
|
@ -413,11 +413,16 @@ function onDrop(ev) {
|
|||
font-size: 0.9em;
|
||||
color: var(--MI_THEME-panelHeaderFg);
|
||||
background: var(--MI_THEME-panelHeaderBg);
|
||||
box-shadow: 0 0.5px 0 0 var(--MI_THEME-panelHeaderDivider);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@container style(--MI_THEME-panelHeaderBg: var(--MI_THEME-panel)) {
|
||||
.header {
|
||||
box-shadow: 0 0.5px 0 0 light-dark(#0002, #fff2);
|
||||
}
|
||||
}
|
||||
|
||||
.color {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
|
|
File diff suppressed because it is too large
Load diff
43
packages/frontend/src/utility/settings-search-index.ts
Normal file
43
packages/frontend/src/utility/settings-search-index.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { searchIndexes as generated } from 'search-index:settings';
|
||||
import type { GeneratedSearchIndexItem } from 'search-index:settings';
|
||||
|
||||
export type SearchIndexItem = {
|
||||
id: string;
|
||||
path?: string;
|
||||
label: string;
|
||||
keywords: string[];
|
||||
icon?: string;
|
||||
children?: SearchIndexItem[];
|
||||
};
|
||||
|
||||
const rootMods = new Map(generated.map(item => [item.id, item]));
|
||||
|
||||
function walk(item: GeneratedSearchIndexItem) {
|
||||
if (item.inlining) {
|
||||
for (const id of item.inlining) {
|
||||
const inline = rootMods.get(id);
|
||||
if (inline) {
|
||||
(item.children ??= []).push(inline);
|
||||
rootMods.delete(id);
|
||||
} else {
|
||||
console.log('[Settings Search Index] Failed to inline', id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const child of item.children ?? []) {
|
||||
walk(child);
|
||||
}
|
||||
}
|
||||
|
||||
for (const item of generated) {
|
||||
walk(item);
|
||||
}
|
||||
|
||||
export const searchIndexes: SearchIndexItem[] = generated;
|
||||
|
18
packages/frontend/src/utility/virtual.d.ts
vendored
Normal file
18
packages/frontend/src/utility/virtual.d.ts
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
declare module 'search-index:settings' {
|
||||
export type GeneratedSearchIndexItem = {
|
||||
id: string;
|
||||
path?: string;
|
||||
label: string;
|
||||
keywords: string[];
|
||||
icon?: string;
|
||||
inlining?: string[];
|
||||
children?: GeneratedSearchIndexItem[];
|
||||
};
|
||||
|
||||
export const searchIndexes: GeneratedSearchIndexItem[];
|
||||
}
|
|
@ -73,6 +73,6 @@ defineExpose<WidgetComponentExpose>({
|
|||
}
|
||||
|
||||
.text {
|
||||
color: var(--MI_THEME-fgTransparentWeak);
|
||||
color: color(from var(--MI_THEME-fg) srgb r g b / 0.75);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -23,7 +23,8 @@ const extensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json', '.json5', '.s
|
|||
*/
|
||||
export const searchIndexes = [{
|
||||
targetFilePaths: ['src/pages/settings/*.vue'],
|
||||
exportFilePath: './src/utility/autogen/settings-search-index.ts',
|
||||
mainVirtualModule: 'search-index:settings',
|
||||
modulesToHmrOnUpdate: ['src/pages/settings/index.vue'],
|
||||
verbose: process.env.FRONTEND_SEARCH_INDEX_VERBOSE === 'true',
|
||||
}] satisfies SearchIndexOptions[];
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"type": "module",
|
||||
"name": "misskey-js",
|
||||
"version": "2025.4.0-rc.0",
|
||||
"version": "2025.4.0-rc.1",
|
||||
"description": "Misskey SDK for JavaScript",
|
||||
"license": "MIT",
|
||||
"main": "./built/index.js",
|
||||
|
|
166
pnpm-lock.yaml
generated
166
pnpm-lock.yaml
generated
|
@ -1005,6 +1005,9 @@ importers:
|
|||
'@vitest/coverage-v8':
|
||||
specifier: 3.0.9
|
||||
version: 3.0.9(vitest@3.0.9(@types/debug@4.1.12)(@types/node@22.13.11)(happy-dom@17.4.4)(jsdom@26.0.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.3(@types/node@22.13.11)(typescript@5.8.2))(sass@1.86.0)(terser@5.39.0)(tsx@4.19.3))
|
||||
'@vue/compiler-core':
|
||||
specifier: 3.5.13
|
||||
version: 3.5.13
|
||||
'@vue/runtime-core':
|
||||
specifier: 3.5.13
|
||||
version: 3.5.13
|
||||
|
@ -1032,6 +1035,9 @@ importers:
|
|||
micromatch:
|
||||
specifier: 4.0.8
|
||||
version: 4.0.8
|
||||
minimatch:
|
||||
specifier: 10.0.1
|
||||
version: 10.0.1
|
||||
msw:
|
||||
specifier: 2.7.3
|
||||
version: 2.7.3(@types/node@22.13.11)(typescript@5.8.2)
|
||||
|
@ -1358,7 +1364,7 @@ importers:
|
|||
version: 9.1.0(eslint@9.22.0)
|
||||
jest:
|
||||
specifier: ^29.7.0
|
||||
version: 29.7.0(@types/node@22.13.10)
|
||||
version: 29.7.0(@types/node@22.13.15)
|
||||
jest-worker:
|
||||
specifier: ^29.7.0
|
||||
version: 29.7.0
|
||||
|
@ -1370,7 +1376,7 @@ importers:
|
|||
version: 3.3.3
|
||||
ts-jest:
|
||||
specifier: ^29.1.1
|
||||
version: 29.1.2(@babel/core@7.24.7)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(esbuild@0.25.0)(jest@29.7.0(@types/node@22.13.10))(typescript@5.1.6)
|
||||
version: 29.1.2(@babel/core@7.23.5)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.5))(esbuild@0.25.0)(jest@29.7.0(@types/node@22.13.15))(typescript@5.1.6)
|
||||
typedoc:
|
||||
specifier: ^0.25.3
|
||||
version: 0.25.13(typescript@5.1.6)
|
||||
|
@ -8312,10 +8318,6 @@ packages:
|
|||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
|
||||
minimatch@5.1.2:
|
||||
resolution: {integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minimatch@5.1.6:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -8324,10 +8326,6 @@ packages:
|
|||
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimatch@9.0.4:
|
||||
resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
@ -11927,56 +11925,26 @@ snapshots:
|
|||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
|
@ -11987,78 +11955,36 @@ snapshots:
|
|||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
||||
'@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.7)':
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
optional: true
|
||||
|
||||
'@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
|
@ -14624,7 +14550,7 @@ snapshots:
|
|||
'@storybook/manager-api': 8.6.7(storybook@8.6.7(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))
|
||||
'@storybook/preview-api': 8.6.7(storybook@8.6.7(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))
|
||||
'@storybook/theming': 8.6.7(storybook@8.6.7(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))
|
||||
'@vue/compiler-core': 3.5.12
|
||||
'@vue/compiler-core': 3.5.13
|
||||
storybook: 8.6.7(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)
|
||||
ts-dedent: 2.2.0
|
||||
type-fest: 2.19.0
|
||||
|
@ -14650,7 +14576,7 @@ snapshots:
|
|||
'@xhmikosr/bin-wrapper': 13.0.5
|
||||
commander: 8.3.0
|
||||
fast-glob: 3.3.3
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
piscina: 4.4.0
|
||||
semver: 7.6.3
|
||||
slash: 3.0.0
|
||||
|
@ -15670,7 +15596,7 @@ snapshots:
|
|||
'@vue/compiler-dom': 3.5.12
|
||||
'@vue/shared': 3.5.12
|
||||
computeds: 0.0.1
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
path-browserify: 1.0.1
|
||||
vue-template-compiler: 2.7.14
|
||||
optionalDependencies:
|
||||
|
@ -15683,7 +15609,7 @@ snapshots:
|
|||
'@vue/compiler-vue2': 2.7.16
|
||||
'@vue/shared': 3.5.12
|
||||
alien-signals: 1.0.7
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
muggle-string: 0.4.1
|
||||
path-browserify: 1.0.1
|
||||
optionalDependencies:
|
||||
|
@ -16134,20 +16060,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
babel-jest@29.7.0(@babel/core@7.24.7):
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@jest/transform': 29.7.0
|
||||
'@types/babel__core': 7.20.0
|
||||
babel-plugin-istanbul: 6.1.1
|
||||
babel-preset-jest: 29.6.3(@babel/core@7.24.7)
|
||||
chalk: 4.1.2
|
||||
graceful-fs: 4.2.11
|
||||
slash: 3.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
babel-plugin-istanbul@6.1.1:
|
||||
dependencies:
|
||||
'@babel/helper-plugin-utils': 7.22.5
|
||||
|
@ -16181,36 +16093,12 @@ snapshots:
|
|||
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.5)
|
||||
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.5)
|
||||
|
||||
babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.7):
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7)
|
||||
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.7)
|
||||
optional: true
|
||||
|
||||
babel-preset-jest@29.6.3(@babel/core@7.23.5):
|
||||
dependencies:
|
||||
'@babel/core': 7.23.5
|
||||
babel-plugin-jest-hoist: 29.6.3
|
||||
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.5)
|
||||
|
||||
babel-preset-jest@29.6.3(@babel/core@7.24.7):
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
babel-plugin-jest-hoist: 29.6.3
|
||||
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.7)
|
||||
optional: true
|
||||
|
||||
babel-walk@3.0.0-canary-5:
|
||||
dependencies:
|
||||
'@babel/types': 7.24.7
|
||||
|
@ -18333,7 +18221,7 @@ snapshots:
|
|||
dependencies:
|
||||
foreground-child: 3.1.1
|
||||
jackspeak: 2.3.6
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
minipass: 7.1.2
|
||||
path-scurry: 1.10.1
|
||||
|
||||
|
@ -18341,7 +18229,7 @@ snapshots:
|
|||
dependencies:
|
||||
foreground-child: 3.1.1
|
||||
jackspeak: 3.4.3
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
minipass: 7.1.2
|
||||
package-json-from-dist: 1.0.0
|
||||
path-scurry: 1.11.1
|
||||
|
@ -18651,7 +18539,7 @@ snapshots:
|
|||
|
||||
ignore-walk@7.0.0:
|
||||
dependencies:
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
|
||||
ignore@5.3.1: {}
|
||||
|
||||
|
@ -20162,10 +20050,6 @@ snapshots:
|
|||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
|
||||
minimatch@5.1.2:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimatch@5.1.6:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
@ -20174,10 +20058,6 @@ snapshots:
|
|||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimatch@9.0.4:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
@ -21408,7 +21288,7 @@ snapshots:
|
|||
|
||||
readdir-glob@1.1.2:
|
||||
dependencies:
|
||||
minimatch: 5.1.2
|
||||
minimatch: 5.1.6
|
||||
|
||||
readdirp@4.1.2: {}
|
||||
|
||||
|
@ -22314,7 +22194,7 @@ snapshots:
|
|||
dependencies:
|
||||
'@istanbuljs/schema': 0.1.3
|
||||
glob: 10.4.5
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
|
||||
text-decoding@1.0.0: {}
|
||||
|
||||
|
@ -22428,11 +22308,11 @@ snapshots:
|
|||
|
||||
ts-dedent@2.2.0: {}
|
||||
|
||||
ts-jest@29.1.2(@babel/core@7.24.7)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(esbuild@0.25.0)(jest@29.7.0(@types/node@22.13.10))(typescript@5.1.6):
|
||||
ts-jest@29.1.2(@babel/core@7.23.5)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.5))(esbuild@0.25.0)(jest@29.7.0(@types/node@22.13.15))(typescript@5.1.6):
|
||||
dependencies:
|
||||
bs-logger: 0.2.6
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
jest: 29.7.0(@types/node@22.13.10)
|
||||
jest: 29.7.0(@types/node@22.13.15)
|
||||
jest-util: 29.7.0
|
||||
json5: 2.2.3
|
||||
lodash.memoize: 4.1.2
|
||||
|
@ -22441,9 +22321,9 @@ snapshots:
|
|||
typescript: 5.1.6
|
||||
yargs-parser: 21.1.1
|
||||
optionalDependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@babel/core': 7.23.5
|
||||
'@jest/types': 29.6.3
|
||||
babel-jest: 29.7.0(@babel/core@7.24.7)
|
||||
babel-jest: 29.7.0(@babel/core@7.23.5)
|
||||
esbuild: 0.25.0
|
||||
|
||||
ts-map@1.0.3: {}
|
||||
|
@ -22560,7 +22440,7 @@ snapshots:
|
|||
dependencies:
|
||||
lunr: 2.3.9
|
||||
marked: 4.3.0
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
shiki: 0.14.7
|
||||
typescript: 5.1.6
|
||||
|
||||
|
@ -22901,7 +22781,7 @@ snapshots:
|
|||
|
||||
vscode-languageclient@9.0.1:
|
||||
dependencies:
|
||||
minimatch: 5.1.2
|
||||
minimatch: 5.1.6
|
||||
semver: 7.6.3
|
||||
vscode-languageserver-protocol: 3.17.5
|
||||
|
||||
|
|
|
@ -28,3 +28,4 @@ onlyBuiltDependencies:
|
|||
- utf-8-validate
|
||||
- v-code-diff
|
||||
- vue-demi
|
||||
ignorePatchFailures: false
|
||||
|
|
31
scripts/dependency-patches/vite.patch
Normal file
31
scripts/dependency-patches/vite.patch
Normal file
|
@ -0,0 +1,31 @@
|
|||
diff --git a/dist/node/chunks/dep-DrOo5SEf.js b/dist/node/chunks/dep-DrOo5SEf.js
|
||||
index 329e68bd27e55a56d815fa6b4de2d615a8c2b343..9d9f58e90ae836f80063b698e307fec436e53e07 100644
|
||||
--- a/dist/node/chunks/dep-DrOo5SEf.js
|
||||
+++ b/dist/node/chunks/dep-DrOo5SEf.js
|
||||
@@ -45971,7 +45971,7 @@ function importAnalysisPlugin(config) {
|
||||
let isPartiallySelfAccepting = false;
|
||||
const importedBindings = enablePartialAccept ? /* @__PURE__ */ new Map() : null;
|
||||
const toAbsoluteUrl = (url) => path$d.posix.resolve(path$d.posix.dirname(importerModule.url), url);
|
||||
- const normalizeUrl = async (url, pos, forceSkipImportAnalysis = false) => {
|
||||
+ const normalizeUrl = async (url, pos, forceSkipImportAnalysis = false, stripBase2 = false) => {
|
||||
url = stripBase(url, base);
|
||||
let importerFile = importer;
|
||||
if (depsOptimizer && moduleListContains(depsOptimizer.options.exclude, url)) {
|
||||
@@ -46031,7 +46031,7 @@ function importAnalysisPlugin(config) {
|
||||
e.pos = pos;
|
||||
throw e;
|
||||
}
|
||||
- if (!ssr) url = joinUrlSegments(base, url);
|
||||
+ if (!ssr && !stripBase2) url = joinUrlSegments(base, url);
|
||||
return [url, resolved.id];
|
||||
};
|
||||
const orderedImportedUrls = new Array(imports.length);
|
||||
@@ -46288,7 +46288,7 @@ See ${colors$1.blue(
|
||||
const pluginImports = this._addedImports;
|
||||
if (pluginImports) {
|
||||
(await Promise.all(
|
||||
- [...pluginImports].map((id) => normalizeUrl(id, 0, true))
|
||||
+ [...pluginImports].map((id) => normalizeUrl(id, 0, true, true))
|
||||
)).forEach(([url]) => importedUrls.add(url));
|
||||
}
|
||||
if (ssr && importerModule.isSelfAccepting) {
|
Loading…
Add table
Reference in a new issue