mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-10-29 04:24:14 +00:00 
			
		
		
		
	* wip * wip * wip * wip * wip * wip * wip * wip * fix * fix * fix * fix size * fix register logs * fix img autosize * fix row selection * support delete * fix border rendering * fix display:none * tweak comments * support choose pc file and drive file * support directory drag-drop * fix * fix comment * support context menu on data area * fix autogen * wip イベント整理 * イベントの整理 * refactor grid * fix cell re-render bugs * fix row remove * fix comment * fix validation * fix utils * list maximum * add mimetype check * fix * fix number cell focus * fix over 100 file drop * remove log * fix patchData * fix performance * fix * support update and delete * support remote import * fix layout * heightやめる * fix performance * add list v2 endpoint * support pagination * fix api call * fix no clickable input text * fix limit * fix paging * fix * fix * support search * tweak logs * tweak cell selection * fix range select * block delete * add comment * fix * support import log * fix dialog * refactor * add confirm dialog * fix name * fix autogen * wip * support image change and highlight row * add columns * wip * support sort * add role name * add index to emoji * refine context menu setting * support role select * remove unused buttons * fix url * fix MkRoleSelectDialog.vue * add route * refine remote page * enter key search * fix paste bugs * fix copy/paste * fix keyEvent * fix copy/paste and delete * fix comment * fix MkRoleSelectDialog.vue and storybook scenario * fix MkRoleSelectDialog.vue and storybook scenario * add MkGrid.stories.impl.ts * fix * [wip] add custom-emojis-manager2.stories.impl.ts * [wip] add custom-emojis-manager2.stories.impl.ts * wip * 課題はまだ残っているが、ひとまず完了 * fix validation and register roles * fix upload * optimize import * patch from dev * i18n * revert excess fixes * separate sort order component * add SPDX * revert excess fixes * fix pre test * fix bugs * add type column * fix types * fix CHANGELOG.md * fix lit * lint * tweak style * refactor * fix ci * autogen * Update types.ts * CSS Module化 * fix log * 縦スクロールを無効化 * MkStickyContainer化 * regenerate locales index.d.ts * fix * fix * テスト * ランダム値によるUI変更の抑制 * テスト * tableタグやめる * fix last-child css * fix overflow css * fix endpoint.ts * tweak css * 最新への追従とレイアウト微調整 * ソートキーの指定方法を他と合わせた * fix focus * fix layout * v2エンドポイントのルールに対応 * 表示条件などを微調整 * fix MkDataCell.vue * fix error code * fix error * add comment to MkModal.vue * Update index.d.ts * fix CHANGELOG.md * fix color theme * fix CHANGELOG.md * fix CHANGELOG.md * fix center * fix: テーブルにフォーカスがあり、通常状態であるときはキーイベントの伝搬を止める * fix: ロール選択用のダイアログにてコンディショナルロールを×ボタンで除外できなかったのを修正 * fix remote list folder * sticky footers * chore: fix ci error(just single line-break diff) * fix loading * fix like * comma to space * fix ci * fix ci * removed align-center --------- Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com>
		
			
				
	
	
		
			432 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			432 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /*
 | |
|  * SPDX-FileCopyrightText: syuilo and misskey-project
 | |
|  * SPDX-License-Identifier: AGPL-3.0-only
 | |
|  */
 | |
| 
 | |
| import { existsSync, readFileSync } from 'node:fs';
 | |
| import { writeFile } from 'node:fs/promises';
 | |
| import { basename, dirname } from 'node:path/posix';
 | |
| import { GENERATOR, type State, generate } from 'astring';
 | |
| import type * as estree from 'estree';
 | |
| import glob from 'fast-glob';
 | |
| import { format } from 'prettier';
 | |
| 
 | |
| interface SatisfiesExpression extends estree.BaseExpression {
 | |
| 	type: 'SatisfiesExpression';
 | |
| 	expression: estree.Expression;
 | |
| 	reference: estree.Identifier;
 | |
| }
 | |
| 
 | |
| const generator = {
 | |
| 	...GENERATOR,
 | |
| 	SatisfiesExpression(node: SatisfiesExpression, state: State) {
 | |
| 		switch (node.expression.type) {
 | |
| 			case 'ArrowFunctionExpression': {
 | |
| 				state.write('(');
 | |
| 				this[node.expression.type](node.expression, state);
 | |
| 				state.write(')');
 | |
| 				break;
 | |
| 			}
 | |
| 			default: {
 | |
| 				// @ts-ignore
 | |
| 				this[node.expression.type](node.expression, state);
 | |
| 				break;
 | |
| 			}
 | |
| 		}
 | |
| 		state.write(' satisfies ', node as unknown as estree.Expression);
 | |
| 		this[node.reference.type](node.reference, state);
 | |
| 	},
 | |
| };
 | |
| 
 | |
| type SplitCamel<
 | |
| 	T extends string,
 | |
| 	YC extends string = '',
 | |
| 	YN extends readonly string[] = []
 | |
| > = T extends `${infer XH}${infer XR}`
 | |
| 	? XR extends ''
 | |
| 		? [...YN, Uncapitalize<`${YC}${XH}`>]
 | |
| 		: XH extends Uppercase<XH>
 | |
| 		? SplitCamel<XR, Lowercase<XH>, [...YN, YC]>
 | |
| 		: SplitCamel<XR, `${YC}${XH}`, YN>
 | |
| 	: YN;
 | |
| 
 | |
| // @ts-ignore
 | |
| type SplitKebab<T extends string> = T extends `${infer XH}-${infer XR}`
 | |
| 	? [XH, ...SplitKebab<XR>]
 | |
| 	: [T];
 | |
| 
 | |
| type ToKebab<T extends readonly string[]> = T extends readonly [
 | |
| 	infer XO extends string
 | |
| ]
 | |
| 	? XO
 | |
| 	: T extends readonly [
 | |
| 			infer XH extends string,
 | |
| 			...infer XR extends readonly string[]
 | |
| 	  ]
 | |
| 	? `${XH}${XR extends readonly string[] ? `-${ToKebab<XR>}` : ''}`
 | |
| 	: '';
 | |
| 
 | |
| // @ts-ignore
 | |
| type ToPascal<T extends readonly string[]> = T extends readonly [
 | |
| 	infer XH extends string,
 | |
| 	...infer XR extends readonly string[]
 | |
| ]
 | |
| 	? `${Capitalize<XH>}${ToPascal<XR>}`
 | |
| 	: '';
 | |
| 
 | |
| function h<T extends estree.Node>(
 | |
| 	component: T['type'],
 | |
| 	props: Omit<T, 'type'>
 | |
| ): T {
 | |
| 	const type = component.replace(/(?:^|-)([a-z])/g, (_, c) => c.toUpperCase());
 | |
| 	return Object.assign(props || {}, { type }) as T;
 | |
| }
 | |
| 
 | |
| declare namespace h.JSX {
 | |
| 	type Element = estree.Node;
 | |
| 	type IntrinsicElements = {
 | |
| 		[T in keyof typeof generator as ToKebab<SplitCamel<Uncapitalize<T>>>]: {
 | |
| 			[K in keyof Omit<
 | |
| 				Parameters<(typeof generator)[T]>[0],
 | |
| 				'type'
 | |
| 			>]?: Parameters<(typeof generator)[T]>[0][K];
 | |
| 		};
 | |
| 	};
 | |
| }
 | |
| 
 | |
| function toStories(component: string): Promise<string> {
 | |
| 	const msw = `${component.slice(0, -'.vue'.length)}.msw`;
 | |
| 	const implStories = `${component.slice(0, -'.vue'.length)}.stories.impl`;
 | |
| 	const metaStories = `${component.slice(0, -'.vue'.length)}.stories.meta`;
 | |
| 	const hasMsw = existsSync(`${msw}.ts`);
 | |
| 	const hasImplStories = existsSync(`${implStories}.ts`);
 | |
| 	const hasMetaStories = existsSync(`${metaStories}.ts`);
 | |
| 	const base = basename(component);
 | |
| 	const dir = dirname(component);
 | |
| 	const literal =
 | |
| 		<literal
 | |
| 			value={component
 | |
| 				.slice('src/'.length, -'.vue'.length)
 | |
| 				.replace(/\./g, '/')}
 | |
| 		/> as estree.Literal;
 | |
| 	const identifier =
 | |
| 		<identifier
 | |
| 			name={base
 | |
| 				.slice(0, -'.vue'.length)
 | |
| 				.replace(/[-.]|^(?=\d)/g, '_')
 | |
| 				.replace(/(?<=^[^A-Z_]*$)/, '_')}
 | |
| 		/> as estree.Identifier;
 | |
| 	const parameters =
 | |
| 		<object-expression
 | |
| 			properties={[
 | |
| 				<property
 | |
| 					key={<identifier name='layout' /> as estree.Identifier}
 | |
| 					value={<literal value={`${dir}/`.startsWith('src/pages/') ? 'fullscreen' : 'centered'}/> as estree.Literal}
 | |
| 					kind={'init' as const}
 | |
| 				/> as estree.Property,
 | |
| 				...(hasMsw
 | |
| 					? [
 | |
| 							<property
 | |
| 								key={<identifier name='msw' /> as estree.Identifier}
 | |
| 								value={<identifier name='msw' /> as estree.Identifier}
 | |
| 								kind={'init' as const}
 | |
| 								shorthand
 | |
| 							/> as estree.Property,
 | |
| 					  ]
 | |
| 					: []),
 | |
| 			]}
 | |
| 		/> as estree.ObjectExpression;
 | |
| 	const program =
 | |
| 		<program
 | |
| 			body={[
 | |
| 				<import-declaration
 | |
| 					source={<literal value='@storybook/vue3' /> as estree.Literal}
 | |
| 					specifiers={[
 | |
| 						<import-specifier
 | |
| 							local={<identifier name='Meta' /> as estree.Identifier}
 | |
| 							imported={<identifier name='Meta' /> as estree.Identifier}
 | |
| 						/> as estree.ImportSpecifier,
 | |
| 						...(hasImplStories
 | |
| 							? []
 | |
| 							: [
 | |
| 									<import-specifier
 | |
| 										local={<identifier name='StoryObj' /> as estree.Identifier}
 | |
| 										imported={<identifier name='StoryObj' /> as estree.Identifier}
 | |
| 									/> as estree.ImportSpecifier,
 | |
| 								]),
 | |
| 					]}
 | |
| 				/> as estree.ImportDeclaration,
 | |
| 				...(hasMsw
 | |
| 					? [
 | |
| 							<import-declaration
 | |
| 								source={<literal value={`./${basename(msw)}`} /> as estree.Literal}
 | |
| 								specifiers={[
 | |
| 									<import-namespace-specifier
 | |
| 										local={<identifier name='msw' /> as estree.Identifier}
 | |
| 									/> as estree.ImportNamespaceSpecifier,
 | |
| 								]}
 | |
| 							/> as estree.ImportDeclaration,
 | |
| 					  ]
 | |
| 					: []),
 | |
| 				...(hasImplStories
 | |
| 					? []
 | |
| 					: [
 | |
| 							<import-declaration
 | |
| 								source={<literal value={`./${base}`} /> as estree.Literal}
 | |
| 								specifiers={[
 | |
| 									<import-default-specifier local={identifier} /> as estree.ImportDefaultSpecifier,
 | |
| 								]}
 | |
| 							/> as estree.ImportDeclaration,
 | |
| 					  ]),
 | |
| 				...(hasMetaStories
 | |
| 					? [
 | |
| 							<import-declaration
 | |
| 								source={<literal value={`./${basename(metaStories)}`} /> as estree.Literal}
 | |
| 								specifiers={[
 | |
| 									<import-namespace-specifier
 | |
| 										local={<identifier name='storiesMeta' /> as estree.Identifier}
 | |
| 									/> as estree.ImportNamespaceSpecifier,
 | |
| 								]}
 | |
| 							/> as estree.ImportDeclaration,
 | |
| 						]
 | |
| 					: []),
 | |
| 				<variable-declaration
 | |
| 					kind={'const' as const}
 | |
| 					declarations={[
 | |
| 						<variable-declarator
 | |
| 							id={<identifier name='meta' /> as estree.Identifier}
 | |
| 							init={
 | |
| 								<satisfies-expression
 | |
| 									expression={
 | |
| 										<object-expression
 | |
| 											properties={[
 | |
| 												<property
 | |
| 													key={<identifier name='title' /> as estree.Identifier}
 | |
| 													value={literal}
 | |
| 													kind={'init' as const}
 | |
| 												/> as estree.Property,
 | |
| 												<property
 | |
| 													key={<identifier name='component' /> as estree.Identifier}
 | |
| 													value={identifier}
 | |
| 													kind={'init' as const}
 | |
| 												/> as estree.Property,
 | |
| 												...(hasMetaStories
 | |
| 													? [
 | |
| 															<spread-element
 | |
| 																argument={<identifier name='storiesMeta' /> as estree.Identifier}
 | |
| 															/> as estree.SpreadElement,
 | |
| 														]
 | |
| 													: [])
 | |
| 											]}
 | |
| 										/> as estree.ObjectExpression
 | |
| 									}
 | |
| 									reference={<identifier name={`Meta<typeof ${identifier.name}>`} /> as estree.Identifier}
 | |
| 								/> as estree.Expression
 | |
| 							}
 | |
| 						/> as estree.VariableDeclarator,
 | |
| 					]}
 | |
| 				/> as estree.VariableDeclaration,
 | |
| 				...(hasImplStories
 | |
| 					? []
 | |
| 					: [
 | |
| 							<export-named-declaration
 | |
| 								declaration={
 | |
| 									<variable-declaration
 | |
| 										kind={'const' as const}
 | |
| 										declarations={[
 | |
| 											<variable-declarator
 | |
| 												id={<identifier name='Default' /> as estree.Identifier}
 | |
| 												init={
 | |
| 													<satisfies-expression
 | |
| 														expression={
 | |
| 															<object-expression
 | |
| 																properties={[
 | |
| 																	<property
 | |
| 																		key={<identifier name='render' /> as estree.Identifier}
 | |
| 																		value={
 | |
| 																			<function-expression
 | |
| 																				params={[
 | |
| 																					<identifier name='args' /> as estree.Identifier,
 | |
| 																				]}
 | |
| 																				body={
 | |
| 																					<block-statement
 | |
| 																						body={[
 | |
| 																							<return-statement
 | |
| 																								argument={
 | |
| 																									<object-expression
 | |
| 																										properties={[
 | |
| 																											<property
 | |
| 																												key={<identifier name='components' /> as estree.Identifier}
 | |
| 																												value={
 | |
| 																													<object-expression
 | |
| 																														properties={[
 | |
| 																															<property key={identifier} value={identifier} kind={'init' as const} shorthand /> as estree.Property,
 | |
| 																														]}
 | |
| 																													/> as estree.ObjectExpression
 | |
| 																												}
 | |
| 																												kind={'init' as const}
 | |
| 																											/> as estree.Property,
 | |
| 																											<property
 | |
| 																												key={<identifier name='setup' /> as estree.Identifier}
 | |
| 																												value={
 | |
| 																													<function-expression
 | |
| 																														params={[]}
 | |
| 																														body={
 | |
| 																															<block-statement
 | |
| 																																body={[
 | |
| 																																	<return-statement
 | |
| 																																		argument={
 | |
| 																																			<object-expression
 | |
| 																																				properties={[
 | |
| 																																					<property
 | |
| 																																						key={<identifier name='args' /> as estree.Identifier}
 | |
| 																																						value={<identifier name='args' /> as estree.Identifier}
 | |
| 																																						kind={'init' as const}
 | |
| 																																						shorthand
 | |
| 																																					/> as estree.Property,
 | |
| 																																				]}
 | |
| 																																			/> as estree.ObjectExpression
 | |
| 																																		}
 | |
| 																																	/> as estree.ReturnStatement,
 | |
| 																																]}
 | |
| 																															/> as estree.BlockStatement
 | |
| 																														}
 | |
| 																													/> as estree.FunctionExpression
 | |
| 																												}
 | |
| 																												method
 | |
| 																												kind={'init' as const}
 | |
| 																											/> as estree.Property,
 | |
| 																											<property
 | |
| 																												key={<identifier name='computed' /> as estree.Identifier}
 | |
| 																												value={
 | |
| 																													<object-expression
 | |
| 																														properties={[
 | |
| 																															<property
 | |
| 																																key={<identifier name='props' /> as estree.Identifier}
 | |
| 																																value={
 | |
| 																																	<function-expression
 | |
| 																																		params={[]}
 | |
| 																																		body={
 | |
| 																																			<block-statement
 | |
| 																																				body={[
 | |
| 																																					<return-statement
 | |
| 																																						argument={
 | |
| 																																							<object-expression
 | |
| 																																								properties={[
 | |
| 																																									<spread-element
 | |
| 																																										argument={
 | |
| 																																											<member-expression
 | |
| 																																												object={<this-expression /> as estree.ThisExpression}
 | |
| 																																												property={<identifier name='args' /> as estree.Identifier}
 | |
| 																																											/> as estree.MemberExpression
 | |
| 																																										}
 | |
| 																																									/> as estree.SpreadElement,
 | |
| 																																								]}
 | |
| 																																							/> as estree.ObjectExpression
 | |
| 																																						}
 | |
| 																																					/> as estree.ReturnStatement,
 | |
| 																																				]}
 | |
| 																																			/> as estree.BlockStatement
 | |
| 																																		}
 | |
| 																																	/> as estree.FunctionExpression
 | |
| 																																}
 | |
| 																																method
 | |
| 																																kind={'init' as const}
 | |
| 																															/> as estree.Property,
 | |
| 																														]}
 | |
| 																													/> as estree.ObjectExpression
 | |
| 																												}
 | |
| 																												kind={'init' as const}
 | |
| 																											/> as estree.Property,
 | |
| 																											<property
 | |
| 																												key={<identifier name='template' /> as estree.Identifier}
 | |
| 																												value={<literal value={`<${identifier.name} v-bind="props" />`} /> as estree.Literal}
 | |
| 																												kind={'init' as const}
 | |
| 																											/> as estree.Property,
 | |
| 																										]}
 | |
| 																									/> as estree.ObjectExpression
 | |
| 																								}
 | |
| 																							/> as estree.ReturnStatement,
 | |
| 																						]}
 | |
| 																					/> as estree.BlockStatement
 | |
| 																				}
 | |
| 																			/> as estree.FunctionExpression
 | |
| 																		}
 | |
| 																		method
 | |
| 																		kind={'init' as const}
 | |
| 																	/> as estree.Property,
 | |
| 																	<property
 | |
| 																		key={<identifier name='parameters' /> as estree.Identifier}
 | |
| 																		value={parameters}
 | |
| 																		kind={'init' as const}
 | |
| 																	/> as estree.Property,
 | |
| 																]}
 | |
| 															/> as estree.ObjectExpression
 | |
| 														}
 | |
| 														reference={<identifier name={`StoryObj<typeof ${identifier.name}>`} /> as estree.Identifier}
 | |
| 													/> as estree.Expression
 | |
| 												}
 | |
| 											/> as estree.VariableDeclarator,
 | |
| 										]}
 | |
| 									/> as estree.VariableDeclaration
 | |
| 								}
 | |
| 							/> as estree.ExportNamedDeclaration,
 | |
| 						]),
 | |
| 				<export-default-declaration
 | |
| 					declaration={(<identifier name='meta' />) as estree.Identifier}
 | |
| 				/> as estree.ExportDefaultDeclaration,
 | |
| 			]}
 | |
| 		/> as estree.Program;
 | |
| 	return format(
 | |
| 		'/* eslint-disable @typescript-eslint/explicit-function-return-type */\n' +
 | |
| 			'/* eslint-disable import/no-default-export */\n' +
 | |
| 			'/* eslint-disable import/no-duplicates */\n' +
 | |
| 			'/* eslint-disable import/order */\n' +
 | |
| 			generate(program, { generator }) +
 | |
| 			(hasImplStories ? readFileSync(`${implStories}.ts`, 'utf-8') : ''),
 | |
| 		{
 | |
| 			parser: 'babel-ts',
 | |
| 			singleQuote: true,
 | |
| 			useTabs: true,
 | |
| 		}
 | |
| 	);
 | |
| }
 | |
| 
 | |
| // glob('src/{components,pages,ui,widgets}/**/*.vue')
 | |
| (async () => {
 | |
| 	const globs = await Promise.all([
 | |
| 		glob('src/components/global/Mk*.vue'),
 | |
| 		glob('src/components/global/RouterView.vue'),
 | |
| 		glob('src/components/MkAbuseReportWindow.vue'),
 | |
| 		glob('src/components/MkAccountMoved.vue'),
 | |
| 		glob('src/components/MkAchievements.vue'),
 | |
| 		glob('src/components/MkAnalogClock.vue'),
 | |
| 		glob('src/components/MkAnimBg.vue'),
 | |
| 		glob('src/components/MkAnnouncementDialog.vue'),
 | |
| 		glob('src/components/MkAntennaEditor.vue'),
 | |
| 		glob('src/components/MkAntennaEditorDialog.vue'),
 | |
| 		glob('src/components/MkAsUi.vue'),
 | |
| 		glob('src/components/MkAutocomplete.vue'),
 | |
| 		glob('src/components/MkAvatars.vue'),
 | |
| 		glob('src/components/Mk[B-E]*.vue'),
 | |
| 		glob('src/components/MkFlashPreview.vue'),
 | |
| 		glob('src/components/MkGalleryPostPreview.vue'),
 | |
| 		glob('src/components/MkSignupServerRules.vue'),
 | |
| 		glob('src/components/MkUserSetupDialog.vue'),
 | |
| 		glob('src/components/MkUserSetupDialog.*.vue'),
 | |
| 		glob('src/components/MkInstanceCardMini.vue'),
 | |
| 		glob('src/components/MkInviteCode.vue'),
 | |
| 		glob('src/components/MkTagItem.vue'),
 | |
| 		glob('src/components/MkRoleSelectDialog.vue'),
 | |
| 		glob('src/components/grid/MkGrid.vue'),
 | |
| 		glob('src/pages/admin/custom-emojis-manager2.vue'),
 | |
| 		glob('src/pages/admin/overview.ap-requests.vue'),
 | |
| 		glob('src/pages/user/home.vue'),
 | |
| 		glob('src/pages/search.vue'),
 | |
| 	]);
 | |
| 	const components = globs.flat();
 | |
| 	await Promise.all(components.map(async (component) => {
 | |
| 		const stories = component.replace(/\.vue$/, '.stories.ts');
 | |
| 		await writeFile(stories, await toStories(component));
 | |
| 	}))
 | |
| })();
 |