🚧 Refactor basic services

This commit is contained in:
2025-12-14 02:19:50 +08:00
parent d16905c0a3
commit cc4c2189dc
126 changed files with 18164 additions and 4247 deletions

View File

@@ -0,0 +1,4 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export * from "./models.js";

View File

@@ -0,0 +1,302 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as theme$0 from "./theme/models.js";
/**
* Document is the model entity for the Document schema.
*/
export class Document {
/**
* ID of the ent.
*/
"id"?: number;
/**
* 创建时间
*/
"created_at": string;
/**
* 最后更新时间
*/
"updated_at": string;
/**
* 删除时间NULL表示未删除
*/
"deleted_at"?: string | null;
/**
* 文档标题
*/
"title": string;
/**
* 文档内容
*/
"content": string;
/**
* 是否锁定
*/
"locked": boolean;
/** Creates a new Document instance. */
constructor($$source: Partial<Document> = {}) {
if (!("created_at" in $$source)) {
this["created_at"] = "";
}
if (!("updated_at" in $$source)) {
this["updated_at"] = "";
}
if (!("title" in $$source)) {
this["title"] = "";
}
if (!("content" in $$source)) {
this["content"] = "";
}
if (!("locked" in $$source)) {
this["locked"] = false;
}
Object.assign(this, $$source);
}
/**
* Creates a new Document instance from a string or object.
*/
static createFrom($$source: any = {}): Document {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new Document($$parsedSource as Partial<Document>);
}
}
/**
* Extension is the model entity for the Extension schema.
*/
export class Extension {
/**
* ID of the ent.
*/
"id"?: number;
/**
* 创建时间
*/
"created_at": string;
/**
* 最后更新时间
*/
"updated_at": string;
/**
* 删除时间NULL表示未删除
*/
"deleted_at"?: string | null;
/**
* 扩展标识符
*/
"key": string;
/**
* 是否启用
*/
"enabled": boolean;
/**
* 扩展配置
*/
"config": { [_: string]: any };
/** Creates a new Extension instance. */
constructor($$source: Partial<Extension> = {}) {
if (!("created_at" in $$source)) {
this["created_at"] = "";
}
if (!("updated_at" in $$source)) {
this["updated_at"] = "";
}
if (!("key" in $$source)) {
this["key"] = "";
}
if (!("enabled" in $$source)) {
this["enabled"] = false;
}
if (!("config" in $$source)) {
this["config"] = {};
}
Object.assign(this, $$source);
}
/**
* Creates a new Extension instance from a string or object.
*/
static createFrom($$source: any = {}): Extension {
const $$createField6_0 = $$createType0;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("config" in $$parsedSource) {
$$parsedSource["config"] = $$createField6_0($$parsedSource["config"]);
}
return new Extension($$parsedSource as Partial<Extension>);
}
}
/**
* KeyBinding is the model entity for the KeyBinding schema.
*/
export class KeyBinding {
/**
* ID of the ent.
*/
"id"?: number;
/**
* 创建时间
*/
"created_at": string;
/**
* 最后更新时间
*/
"updated_at": string;
/**
* 删除时间NULL表示未删除
*/
"deleted_at"?: string | null;
/**
* 快捷键标识符
*/
"key": string;
/**
* 快捷键命令
*/
"command": string;
/**
* 所属扩展标识符
*/
"extension"?: string;
/**
* 是否启用
*/
"enabled": boolean;
/** Creates a new KeyBinding instance. */
constructor($$source: Partial<KeyBinding> = {}) {
if (!("created_at" in $$source)) {
this["created_at"] = "";
}
if (!("updated_at" in $$source)) {
this["updated_at"] = "";
}
if (!("key" in $$source)) {
this["key"] = "";
}
if (!("command" in $$source)) {
this["command"] = "";
}
if (!("enabled" in $$source)) {
this["enabled"] = false;
}
Object.assign(this, $$source);
}
/**
* Creates a new KeyBinding instance from a string or object.
*/
static createFrom($$source: any = {}): KeyBinding {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new KeyBinding($$parsedSource as Partial<KeyBinding>);
}
}
/**
* Theme is the model entity for the Theme schema.
*/
export class Theme {
/**
* ID of the ent.
*/
"id"?: number;
/**
* 创建时间
*/
"created_at": string;
/**
* 最后更新时间
*/
"updated_at": string;
/**
* 删除时间NULL表示未删除
*/
"deleted_at"?: string | null;
/**
* 主题标识符
*/
"key": string;
/**
* 主题类型
*/
"type": theme$0.Type;
/**
* 主题颜色配置
*/
"colors": { [_: string]: any };
/** Creates a new Theme instance. */
constructor($$source: Partial<Theme> = {}) {
if (!("created_at" in $$source)) {
this["created_at"] = "";
}
if (!("updated_at" in $$source)) {
this["updated_at"] = "";
}
if (!("key" in $$source)) {
this["key"] = "";
}
if (!("type" in $$source)) {
this["type"] = ("" as theme$0.Type);
}
if (!("colors" in $$source)) {
this["colors"] = {};
}
Object.assign(this, $$source);
}
/**
* Creates a new Theme instance from a string or object.
*/
static createFrom($$source: any = {}): Theme {
const $$createField6_0 = $$createType0;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("colors" in $$parsedSource) {
$$parsedSource["colors"] = $$createField6_0($$parsedSource["colors"]);
}
return new Theme($$parsedSource as Partial<Theme>);
}
}
// Private type creation functions
const $$createType0 = $Create.Map($Create.Any, $Create.Any);

View File

@@ -0,0 +1,4 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export * from "./models.js";

View File

@@ -0,0 +1,22 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Create as $Create} from "@wailsio/runtime";
/**
* Type defines the type for the "type" enum field.
*/
export enum Type {
/**
* The Go zero value for the underlying type of the enum.
*/
$zero = "",
/**
* Type values.
*/
TypeDark = "dark",
TypeLight = "light",
};

View File

@@ -193,58 +193,6 @@ export class ConfigMetadata {
} }
} }
/**
* Document represents a document in the system
*/
export class Document {
"id": number;
"title": string;
"content": string;
"createdAt": string;
"updatedAt": string;
"is_deleted": boolean;
/**
* 锁定标志,锁定的文档无法被删除
*/
"is_locked": boolean;
/** Creates a new Document instance. */
constructor($$source: Partial<Document> = {}) {
if (!("id" in $$source)) {
this["id"] = 0;
}
if (!("title" in $$source)) {
this["title"] = "";
}
if (!("content" in $$source)) {
this["content"] = "";
}
if (!("createdAt" in $$source)) {
this["createdAt"] = "";
}
if (!("updatedAt" in $$source)) {
this["updatedAt"] = "";
}
if (!("is_deleted" in $$source)) {
this["is_deleted"] = false;
}
if (!("is_locked" in $$source)) {
this["is_locked"] = false;
}
Object.assign(this, $$source);
}
/**
* Creates a new Document instance from a string or object.
*/
static createFrom($$source: any = {}): Document {
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
return new Document($$parsedSource as Partial<Document>);
}
}
/** /**
* EditingConfig 编辑设置配置 * EditingConfig 编辑设置配置
*/ */
@@ -332,40 +280,21 @@ export class EditingConfig {
} }
/** /**
* Extension 单个扩展配置 * Extension 扩展配置
*/ */
export class Extension { export class Extension {
/** "key": ExtensionKey;
* 扩展唯一标识
*/
"id": ExtensionID;
/**
* 是否启用
*/
"enabled": boolean; "enabled": boolean;
/**
* 是否为默认扩展
*/
"isDefault": boolean;
/**
* 扩展配置项
*/
"config": ExtensionConfig; "config": ExtensionConfig;
/** Creates a new Extension instance. */ /** Creates a new Extension instance. */
constructor($$source: Partial<Extension> = {}) { constructor($$source: Partial<Extension> = {}) {
if (!("id" in $$source)) { if (!("key" in $$source)) {
this["id"] = ("" as ExtensionID); this["key"] = ("" as ExtensionKey);
} }
if (!("enabled" in $$source)) { if (!("enabled" in $$source)) {
this["enabled"] = false; this["enabled"] = false;
} }
if (!("isDefault" in $$source)) {
this["isDefault"] = false;
}
if (!("config" in $$source)) { if (!("config" in $$source)) {
this["config"] = ({} as ExtensionConfig); this["config"] = ({} as ExtensionConfig);
} }
@@ -377,10 +306,10 @@ export class Extension {
* Creates a new Extension instance from a string or object. * Creates a new Extension instance from a string or object.
*/ */
static createFrom($$source: any = {}): Extension { static createFrom($$source: any = {}): Extension {
const $$createField3_0 = $$createType6; const $$createField2_0 = $$createType6;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source; let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("config" in $$parsedSource) { if ("config" in $$parsedSource) {
$$parsedSource["config"] = $$createField3_0($$parsedSource["config"]); $$parsedSource["config"] = $$createField2_0($$parsedSource["config"]);
} }
return new Extension($$parsedSource as Partial<Extension>); return new Extension($$parsedSource as Partial<Extension>);
} }
@@ -392,9 +321,9 @@ export class Extension {
export type ExtensionConfig = { [_: string]: any }; export type ExtensionConfig = { [_: string]: any };
/** /**
* ExtensionID 扩展标识符 * ExtensionKey 扩展标识符
*/ */
export enum ExtensionID { export enum ExtensionKey {
/** /**
* The Go zero value for the underlying type of the enum. * The Go zero value for the underlying type of the enum.
*/ */
@@ -442,7 +371,6 @@ export enum ExtensionID {
ExtensionHighlightTrailingWhitespace = "highlightTrailingWhitespace", ExtensionHighlightTrailingWhitespace = "highlightTrailingWhitespace",
/** /**
* UI增强扩展
* 小地图 * 小地图
*/ */
ExtensionMinimap = "minimap", ExtensionMinimap = "minimap",
@@ -458,16 +386,14 @@ export enum ExtensionID {
ExtensionContextMenu = "contextMenu", ExtensionContextMenu = "contextMenu",
/** /**
* 工具扩展
* 搜索功能 * 搜索功能
*/ */
ExtensionSearch = "search", ExtensionSearch = "search",
/** /**
* 核心扩展 * HTTP 客户端
* 编辑器核心功能
*/ */
ExtensionEditor = "editor", ExtensionHttpClient = "httpClient",
}; };
/** /**
@@ -758,48 +684,25 @@ export class HotkeyCombo {
* KeyBinding 单个快捷键绑定 * KeyBinding 单个快捷键绑定
*/ */
export class KeyBinding { export class KeyBinding {
/** "key": KeyBindingKey;
* 快捷键动作 "command": string;
*/ "extension": ExtensionKey;
"command": KeyBindingCommand;
/**
* 所属扩展
*/
"extension": ExtensionID;
/**
* 快捷键组合(如 "Mod-f", "Ctrl-Shift-p"
*/
"key": string;
/**
* 是否启用
*/
"enabled": boolean; "enabled": boolean;
/**
* 是否为默认快捷键
*/
"isDefault": boolean;
/** Creates a new KeyBinding instance. */ /** Creates a new KeyBinding instance. */
constructor($$source: Partial<KeyBinding> = {}) { constructor($$source: Partial<KeyBinding> = {}) {
if (!("key" in $$source)) {
this["key"] = ("" as KeyBindingKey);
}
if (!("command" in $$source)) { if (!("command" in $$source)) {
this["command"] = ("" as KeyBindingCommand); this["command"] = "";
} }
if (!("extension" in $$source)) { if (!("extension" in $$source)) {
this["extension"] = ("" as ExtensionID); this["extension"] = ("" as ExtensionKey);
}
if (!("key" in $$source)) {
this["key"] = "";
} }
if (!("enabled" in $$source)) { if (!("enabled" in $$source)) {
this["enabled"] = false; this["enabled"] = false;
} }
if (!("isDefault" in $$source)) {
this["isDefault"] = false;
}
Object.assign(this, $$source); Object.assign(this, $$source);
} }
@@ -814,263 +717,258 @@ export class KeyBinding {
} }
/** /**
* KeyBindingCommand 快捷键命令 * KeyBindingKey 快捷键命令
*/ */
export enum KeyBindingCommand { export enum KeyBindingKey {
/** /**
* The Go zero value for the underlying type of the enum. * The Go zero value for the underlying type of the enum.
*/ */
$zero = "", $zero = "",
/** /**
* 搜索扩展相关
* 显示搜索 * 显示搜索
*/ */
ShowSearchCommand = "showSearch", ShowSearchKeyBindingKey = "showSearch",
/** /**
* 隐藏搜索 * 隐藏搜索
*/ */
HideSearchCommand = "hideSearch", HideSearchKeyBindingKey = "hideSearch",
/** /**
* 代码块扩展相关
* 块内选择全部 * 块内选择全部
*/ */
BlockSelectAllCommand = "blockSelectAll", BlockSelectAllKeyBindingKey = "blockSelectAll",
/** /**
* 在当前块后添加新块 * 在当前块后添加新块
*/ */
BlockAddAfterCurrentCommand = "blockAddAfterCurrent", BlockAddAfterCurrentKeyBindingKey = "blockAddAfterCurrent",
/** /**
* 在最后添加新块 * 在最后添加新块
*/ */
BlockAddAfterLastCommand = "blockAddAfterLast", BlockAddAfterLastKeyBindingKey = "blockAddAfterLast",
/** /**
* 在当前块前添加新块 * 在当前块前添加新块
*/ */
BlockAddBeforeCurrentCommand = "blockAddBeforeCurrent", BlockAddBeforeCurrentKeyBindingKey = "blockAddBeforeCurrent",
/** /**
* 跳转到上一个块 * 跳转到上一个块
*/ */
BlockGotoPreviousCommand = "blockGotoPrevious", BlockGotoPreviousKeyBindingKey = "blockGotoPrevious",
/** /**
* 跳转到下一个块 * 跳转到下一个块
*/ */
BlockGotoNextCommand = "blockGotoNext", BlockGotoNextKeyBindingKey = "blockGotoNext",
/** /**
* 选择上一个块 * 选择上一个块
*/ */
BlockSelectPreviousCommand = "blockSelectPrevious", BlockSelectPreviousKeyBindingKey = "blockSelectPrevious",
/** /**
* 选择下一个块 * 选择下一个块
*/ */
BlockSelectNextCommand = "blockSelectNext", BlockSelectNextKeyBindingKey = "blockSelectNext",
/** /**
* 删除当前块 * 删除当前块
*/ */
BlockDeleteCommand = "blockDelete", BlockDeleteKeyBindingKey = "blockDelete",
/** /**
* 向上移动当前块 * 向上移动当前块
*/ */
BlockMoveUpCommand = "blockMoveUp", BlockMoveUpKeyBindingKey = "blockMoveUp",
/** /**
* 向下移动当前块 * 向下移动当前块
*/ */
BlockMoveDownCommand = "blockMoveDown", BlockMoveDownKeyBindingKey = "blockMoveDown",
/** /**
* 删除行 * 删除行
*/ */
BlockDeleteLineCommand = "blockDeleteLine", BlockDeleteLineKeyBindingKey = "blockDeleteLine",
/** /**
* 向上移动行 * 向上移动行
*/ */
BlockMoveLineUpCommand = "blockMoveLineUp", BlockMoveLineUpKeyBindingKey = "blockMoveLineUp",
/** /**
* 向下移动行 * 向下移动行
*/ */
BlockMoveLineDownCommand = "blockMoveLineDown", BlockMoveLineDownKeyBindingKey = "blockMoveLineDown",
/** /**
* 字符转置 * 字符转置
*/ */
BlockTransposeCharsCommand = "blockTransposeChars", BlockTransposeCharsKeyBindingKey = "blockTransposeChars",
/** /**
* 格式化代码块 * 格式化代码块
*/ */
BlockFormatCommand = "blockFormat", BlockFormatKeyBindingKey = "blockFormat",
/** /**
* 复制 * 复制
*/ */
BlockCopyCommand = "blockCopy", BlockCopyKeyBindingKey = "blockCopy",
/** /**
* 剪切 * 剪切
*/ */
BlockCutCommand = "blockCut", BlockCutKeyBindingKey = "blockCut",
/** /**
* 粘贴 * 粘贴
*/ */
BlockPasteCommand = "blockPaste", BlockPasteKeyBindingKey = "blockPaste",
/** /**
* 代码折叠扩展相关
* 折叠代码 * 折叠代码
*/ */
FoldCodeCommand = "foldCode", FoldCodeKeyBindingKey = "foldCode",
/** /**
* 展开代码 * 展开代码
*/ */
UnfoldCodeCommand = "unfoldCode", UnfoldCodeKeyBindingKey = "unfoldCode",
/** /**
* 折叠全部 * 折叠全部
*/ */
FoldAllCommand = "foldAll", FoldAllKeyBindingKey = "foldAll",
/** /**
* 展开全部 * 展开全部
*/ */
UnfoldAllCommand = "unfoldAll", UnfoldAllKeyBindingKey = "unfoldAll",
/** /**
* 通用编辑扩展相关
* 光标按语法左移 * 光标按语法左移
*/ */
CursorSyntaxLeftCommand = "cursorSyntaxLeft", CursorSyntaxLeftKeyBindingKey = "cursorSyntaxLeft",
/** /**
* 光标按语法右移 * 光标按语法右移
*/ */
CursorSyntaxRightCommand = "cursorSyntaxRight", CursorSyntaxRightKeyBindingKey = "cursorSyntaxRight",
/** /**
* 按语法选择左侧 * 按语法选择左侧
*/ */
SelectSyntaxLeftCommand = "selectSyntaxLeft", SelectSyntaxLeftKeyBindingKey = "selectSyntaxLeft",
/** /**
* 按语法选择右侧 * 按语法选择右侧
*/ */
SelectSyntaxRightCommand = "selectSyntaxRight", SelectSyntaxRightKeyBindingKey = "selectSyntaxRight",
/** /**
* 向上复制行 * 向上复制行
*/ */
CopyLineUpCommand = "copyLineUp", CopyLineUpKeyBindingKey = "copyLineUp",
/** /**
* 向下复制行 * 向下复制行
*/ */
CopyLineDownCommand = "copyLineDown", CopyLineDownKeyBindingKey = "copyLineDown",
/** /**
* 插入空行 * 插入空行
*/ */
InsertBlankLineCommand = "insertBlankLine", InsertBlankLineKeyBindingKey = "insertBlankLine",
/** /**
* 选择行 * 选择行
*/ */
SelectLineCommand = "selectLine", SelectLineKeyBindingKey = "selectLine",
/** /**
* 选择父级语法 * 选择父级语法
*/ */
SelectParentSyntaxCommand = "selectParentSyntax", SelectParentSyntaxKeyBindingKey = "selectParentSyntax",
/** /**
* 减少缩进 * 减少缩进
*/ */
IndentLessCommand = "indentLess", IndentLessKeyBindingKey = "indentLess",
/** /**
* 增加缩进 * 增加缩进
*/ */
IndentMoreCommand = "indentMore", IndentMoreKeyBindingKey = "indentMore",
/** /**
* 缩进选择 * 缩进选择
*/ */
IndentSelectionCommand = "indentSelection", IndentSelectionKeyBindingKey = "indentSelection",
/** /**
* 光标到匹配括号 * 光标到匹配括号
*/ */
CursorMatchingBracketCommand = "cursorMatchingBracket", CursorMatchingBracketKeyBindingKey = "cursorMatchingBracket",
/** /**
* 切换注释 * 切换注释
*/ */
ToggleCommentCommand = "toggleComment", ToggleCommentKeyBindingKey = "toggleComment",
/** /**
* 切换块注释 * 切换块注释
*/ */
ToggleBlockCommentCommand = "toggleBlockComment", ToggleBlockCommentKeyBindingKey = "toggleBlockComment",
/** /**
* 插入新行并缩进 * 插入新行并缩进
*/ */
InsertNewlineAndIndentCommand = "insertNewlineAndIndent", InsertNewlineAndIndentKeyBindingKey = "insertNewlineAndIndent",
/** /**
* 向后删除字符 * 向后删除字符
*/ */
DeleteCharBackwardCommand = "deleteCharBackward", DeleteCharBackwardKeyBindingKey = "deleteCharBackward",
/** /**
* 向前删除字符 * 向前删除字符
*/ */
DeleteCharForwardCommand = "deleteCharForward", DeleteCharForwardKeyBindingKey = "deleteCharForward",
/** /**
* 向后删除组 * 向后删除组
*/ */
DeleteGroupBackwardCommand = "deleteGroupBackward", DeleteGroupBackwardKeyBindingKey = "deleteGroupBackward",
/** /**
* 向前删除组 * 向前删除组
*/ */
DeleteGroupForwardCommand = "deleteGroupForward", DeleteGroupForwardKeyBindingKey = "deleteGroupForward",
/** /**
* 历史记录扩展相关
* 撤销 * 撤销
*/ */
HistoryUndoCommand = "historyUndo", HistoryUndoKeyBindingKey = "historyUndo",
/** /**
* 重做 * 重做
*/ */
HistoryRedoCommand = "historyRedo", HistoryRedoKeyBindingKey = "historyRedo",
/** /**
* 撤销选择 * 撤销选择
*/ */
HistoryUndoSelectionCommand = "historyUndoSelection", HistoryUndoSelectionKeyBindingKey = "historyUndoSelection",
/** /**
* 重做选择 * 重做选择
*/ */
HistoryRedoSelectionCommand = "historyRedoSelection", HistoryRedoSelectionKeyBindingKey = "historyRedoSelection",
}; };
/** /**
@@ -1138,76 +1036,6 @@ export enum TabType {
TabTypeTab = "tab", TabTypeTab = "tab",
}; };
/**
* Theme 主题数据库模型
*/
export class Theme {
"id": number;
"name": string;
"type": ThemeType;
"colors": ThemeColorConfig;
"isDefault": boolean;
"createdAt": string;
"updatedAt": string;
/** Creates a new Theme instance. */
constructor($$source: Partial<Theme> = {}) {
if (!("id" in $$source)) {
this["id"] = 0;
}
if (!("name" in $$source)) {
this["name"] = "";
}
if (!("type" in $$source)) {
this["type"] = ("" as ThemeType);
}
if (!("colors" in $$source)) {
this["colors"] = ({} as ThemeColorConfig);
}
if (!("isDefault" in $$source)) {
this["isDefault"] = false;
}
if (!("createdAt" in $$source)) {
this["createdAt"] = "";
}
if (!("updatedAt" in $$source)) {
this["updatedAt"] = "";
}
Object.assign(this, $$source);
}
/**
* Creates a new Theme instance from a string or object.
*/
static createFrom($$source: any = {}): Theme {
const $$createField3_0 = $$createType9;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("colors" in $$parsedSource) {
$$parsedSource["colors"] = $$createField3_0($$parsedSource["colors"]);
}
return new Theme($$parsedSource as Partial<Theme>);
}
}
/**
* ThemeColorConfig 使用与前端 ThemeColors 相同的结构,存储任意主题键值
*/
export type ThemeColorConfig = { [_: string]: any };
/**
* ThemeType 主题类型枚举
*/
export enum ThemeType {
/**
* The Go zero value for the underlying type of the enum.
*/
$zero = "",
ThemeTypeDark = "dark",
ThemeTypeLight = "light",
};
/** /**
* UpdateSourceType 更新源类型 * UpdateSourceType 更新源类型
*/ */
@@ -1306,8 +1134,8 @@ export class UpdatesConfig {
* Creates a new UpdatesConfig instance from a string or object. * Creates a new UpdatesConfig instance from a string or object.
*/ */
static createFrom($$source: any = {}): UpdatesConfig { static createFrom($$source: any = {}): UpdatesConfig {
const $$createField6_0 = $$createType10; const $$createField6_0 = $$createType9;
const $$createField7_0 = $$createType11; const $$createField7_0 = $$createType10;
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source; let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
if ("github" in $$parsedSource) { if ("github" in $$parsedSource) {
$$parsedSource["github"] = $$createField6_0($$parsedSource["github"]); $$parsedSource["github"] = $$createField6_0($$parsedSource["github"]);
@@ -1334,11 +1162,5 @@ var $$createType6 = (function $$initCreateType6(...args): any {
}); });
const $$createType7 = $Create.Map($Create.Any, $Create.Any); const $$createType7 = $Create.Map($Create.Any, $Create.Any);
const $$createType8 = HotkeyCombo.createFrom; const $$createType8 = HotkeyCombo.createFrom;
var $$createType9 = (function $$initCreateType9(...args): any { const $$createType9 = GithubConfig.createFrom;
if ($$createType9 === $$initCreateType9) { const $$createType10 = GiteaConfig.createFrom;
$$createType9 = $$createType7;
}
return $$createType9(...args);
});
const $$createType10 = GithubConfig.createFrom;
const $$createType11 = GiteaConfig.createFrom;

View File

@@ -2,7 +2,7 @@
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
/** /**
* DatabaseService provides shared database functionality * DatabaseService 数据库服务
* @module * @module
*/ */
@@ -15,15 +15,7 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime";
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js"; import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
/** /**
* RegisterModel 注册模型与表的映射关系 * ServiceShutdown 服务关闭
*/
export function RegisterModel(tableName: string, model: any): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(175397515, tableName, model) as any;
return $resultPromise;
}
/**
* ServiceShutdown shuts down the service when the application closes
*/ */
export function ServiceShutdown(): Promise<void> & { cancel(): void } { export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3907893632) as any; let $resultPromise = $Call.ByID(3907893632) as any;
@@ -31,7 +23,7 @@ export function ServiceShutdown(): Promise<void> & { cancel(): void } {
} }
/** /**
* ServiceStartup initializes the service when the application starts * ServiceStartup 服务启动
*/ */
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } { export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2067840771, options) as any; let $resultPromise = $Call.ByID(2067840771, options) as any;

View File

@@ -2,7 +2,7 @@
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
/** /**
* DocumentService provides document management functionality * DocumentService 文档服务
* @module * @module
*/ */
@@ -15,12 +15,12 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime";
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js"; import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports // @ts-ignore: Unused imports
import * as models$0 from "../models/models.js"; import * as ent$0 from "../models/ent/models.js";
/** /**
* CreateDocument creates a new document and returns the created document with ID * CreateDocument 创建文档
*/ */
export function CreateDocument(title: string): Promise<models$0.Document | null> & { cancel(): void } { export function CreateDocument(title: string): Promise<ent$0.Document | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(3360680842, title) as any; let $resultPromise = $Call.ByID(3360680842, title) as any;
let $typingPromise = $resultPromise.then(($result: any) => { let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result); return $$createType1($result);
@@ -30,7 +30,7 @@ export function CreateDocument(title: string): Promise<models$0.Document | null>
} }
/** /**
* DeleteDocument marks a document as deleted (default document with ID=1 cannot be deleted) * DeleteDocument 删除文档
*/ */
export function DeleteDocument(id: number): Promise<void> & { cancel(): void } { export function DeleteDocument(id: number): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(412287269, id) as any; let $resultPromise = $Call.ByID(412287269, id) as any;
@@ -38,9 +38,9 @@ export function DeleteDocument(id: number): Promise<void> & { cancel(): void } {
} }
/** /**
* GetDocumentByID gets a document by ID * GetDocumentByID 根据ID获取文档
*/ */
export function GetDocumentByID(id: number): Promise<models$0.Document | null> & { cancel(): void } { export function GetDocumentByID(id: number): Promise<ent$0.Document | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(3468193232, id) as any; let $resultPromise = $Call.ByID(3468193232, id) as any;
let $typingPromise = $resultPromise.then(($result: any) => { let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result); return $$createType1($result);
@@ -50,9 +50,9 @@ export function GetDocumentByID(id: number): Promise<models$0.Document | null> &
} }
/** /**
* ListAllDocumentsMeta lists all active (non-deleted) document metadata * ListAllDocumentsMeta 列出所有文档
*/ */
export function ListAllDocumentsMeta(): Promise<(models$0.Document | null)[]> & { cancel(): void } { export function ListAllDocumentsMeta(): Promise<(ent$0.Document | null)[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(3073950297) as any; let $resultPromise = $Call.ByID(3073950297) as any;
let $typingPromise = $resultPromise.then(($result: any) => { let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result); return $$createType2($result);
@@ -62,19 +62,7 @@ export function ListAllDocumentsMeta(): Promise<(models$0.Document | null)[]> &
} }
/** /**
* ListDeletedDocumentsMeta lists all deleted document metadata * LockDocument 锁定文档
*/
export function ListDeletedDocumentsMeta(): Promise<(models$0.Document | null)[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(490143787) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* LockDocument 锁定文档,防止删除
*/ */
export function LockDocument(id: number): Promise<void> & { cancel(): void } { export function LockDocument(id: number): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1889494473, id) as any; let $resultPromise = $Call.ByID(1889494473, id) as any;
@@ -82,15 +70,7 @@ export function LockDocument(id: number): Promise<void> & { cancel(): void } {
} }
/** /**
* RestoreDocument restores a deleted document * ServiceStartup 服务启动
*/
export function RestoreDocument(id: number): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(784200778, id) as any;
return $resultPromise;
}
/**
* ServiceStartup initializes the service when the application starts
*/ */
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } { export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1474135487, options) as any; let $resultPromise = $Call.ByID(1474135487, options) as any;
@@ -106,7 +86,7 @@ export function UnlockDocument(id: number): Promise<void> & { cancel(): void } {
} }
/** /**
* UpdateDocumentContent updates the content of a document * UpdateDocumentContent 更新文档内容
*/ */
export function UpdateDocumentContent(id: number, content: string): Promise<void> & { cancel(): void } { export function UpdateDocumentContent(id: number, content: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(3251897116, id, content) as any; let $resultPromise = $Call.ByID(3251897116, id, content) as any;
@@ -114,7 +94,7 @@ export function UpdateDocumentContent(id: number, content: string): Promise<void
} }
/** /**
* UpdateDocumentTitle updates the title of a document * UpdateDocumentTitle 更新文档标题
*/ */
export function UpdateDocumentTitle(id: number, title: string): Promise<void> & { cancel(): void } { export function UpdateDocumentTitle(id: number, title: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2045530459, id, title) as any; let $resultPromise = $Call.ByID(2045530459, id, title) as any;
@@ -122,6 +102,6 @@ export function UpdateDocumentTitle(id: number, title: string): Promise<void> &
} }
// Private type creation functions // Private type creation functions
const $$createType0 = models$0.Document.createFrom; const $$createType0 = ent$0.Document.createFrom;
const $$createType1 = $Create.Nullable($$createType0); const $$createType1 = $Create.Nullable($$createType0);
const $$createType2 = $Create.Array($$createType1); const $$createType2 = $Create.Array($$createType1);

View File

@@ -2,7 +2,7 @@
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
/** /**
* ExtensionService 扩展管理服务 * ExtensionService 扩展服务
* @module * @module
*/ */
@@ -16,12 +16,39 @@ import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/applic
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports // @ts-ignore: Unused imports
import * as models$0 from "../models/models.js"; import * as models$0 from "../models/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as ent$0 from "../models/ent/models.js";
/** /**
* GetAllExtensions 获取所有扩展配置 * GetAllExtensions 获取所有扩展
*/ */
export function GetAllExtensions(): Promise<models$0.Extension[]> & { cancel(): void } { export function GetAllExtensions(): Promise<(ent$0.Extension | null)[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(3094292124) as any; let $resultPromise = $Call.ByID(3094292124) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* GetDefaultExtensions 获取默认扩展配置(用于前端绑定生成)
*/
export function GetDefaultExtensions(): Promise<models$0.Extension[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(4036328166) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType4($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* GetExtensionByKey 根据Key获取扩展
*/
export function GetExtensionByKey(key: string): Promise<ent$0.Extension | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(2551065776, key) as any;
let $typingPromise = $resultPromise.then(($result: any) => { let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result); return $$createType1($result);
}) as any; }) as any;
@@ -30,23 +57,15 @@ export function GetAllExtensions(): Promise<models$0.Extension[]> & { cancel():
} }
/** /**
* ResetAllExtensionsToDefault 重置所有扩展到默认状态 * ResetExtensionConfig 重置单个扩展到默认状态
*/ */
export function ResetAllExtensionsToDefault(): Promise<void> & { cancel(): void } { export function ResetExtensionConfig(key: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(270611949) as any; let $resultPromise = $Call.ByID(3990780299, key) as any;
return $resultPromise; return $resultPromise;
} }
/** /**
* ResetExtensionToDefault 重置扩展到默认状态 * ServiceStartup 服务启动
*/
export function ResetExtensionToDefault(id: models$0.ExtensionID): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(868308101, id) as any;
return $resultPromise;
}
/**
* ServiceStartup 启动时调用
*/ */
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } { export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(40324057, options) as any; let $resultPromise = $Call.ByID(40324057, options) as any;
@@ -54,21 +73,32 @@ export function ServiceStartup(options: application$0.ServiceOptions): Promise<v
} }
/** /**
* UpdateExtensionEnabled 更新扩展启用状态 * SyncExtensions 同步扩展配置
*/ */
export function UpdateExtensionEnabled(id: models$0.ExtensionID, enabled: boolean): Promise<void> & { cancel(): void } { export function SyncExtensions(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1067300094, id, enabled) as any; let $resultPromise = $Call.ByID(167560004) as any;
return $resultPromise; return $resultPromise;
} }
/** /**
* UpdateExtensionState 更新扩展状态 * UpdateExtensionConfig 更新扩展配置
*/ */
export function UpdateExtensionState(id: models$0.ExtensionID, enabled: boolean, config: models$0.ExtensionConfig): Promise<void> & { cancel(): void } { export function UpdateExtensionConfig(key: string, config: { [_: string]: any }): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2917946454, id, enabled, config) as any; let $resultPromise = $Call.ByID(3184142503, key, config) as any;
return $resultPromise;
}
/**
* UpdateExtensionEnabled 更新扩展启用状态
*/
export function UpdateExtensionEnabled(key: string, enabled: boolean): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1067300094, key, enabled) as any;
return $resultPromise; return $resultPromise;
} }
// Private type creation functions // Private type creation functions
const $$createType0 = models$0.Extension.createFrom; const $$createType0 = ent$0.Extension.createFrom;
const $$createType1 = $Create.Array($$createType0); const $$createType1 = $Create.Nullable($$createType0);
const $$createType2 = $Create.Array($$createType1);
const $$createType3 = models$0.Extension.createFrom;
const $$createType4 = $Create.Array($$createType3);

View File

@@ -17,7 +17,6 @@ import * as SystemService from "./systemservice.js";
import * as TestService from "./testservice.js"; import * as TestService from "./testservice.js";
import * as ThemeService from "./themeservice.js"; import * as ThemeService from "./themeservice.js";
import * as TranslationService from "./translationservice.js"; import * as TranslationService from "./translationservice.js";
import * as TrayService from "./trayservice.js";
import * as WindowService from "./windowservice.js"; import * as WindowService from "./windowservice.js";
export { export {
BackupService, BackupService,
@@ -36,7 +35,6 @@ export {
TestService, TestService,
ThemeService, ThemeService,
TranslationService, TranslationService,
TrayService,
WindowService WindowService
}; };

View File

@@ -2,7 +2,7 @@
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
/** /**
* KeyBindingService 快捷键管理服务 * KeyBindingService 快捷键服务
* @module * @module
*/ */
@@ -16,12 +16,39 @@ import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/applic
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports // @ts-ignore: Unused imports
import * as models$0 from "../models/models.js"; import * as models$0 from "../models/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import * as ent$0 from "../models/ent/models.js";
/** /**
* GetAllKeyBindings 获取所有快捷键配置 * GetAllKeyBindings 获取所有快捷键
*/ */
export function GetAllKeyBindings(): Promise<models$0.KeyBinding[]> & { cancel(): void } { export function GetAllKeyBindings(): Promise<(ent$0.KeyBinding | null)[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(1633502882) as any; let $resultPromise = $Call.ByID(1633502882) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType2($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* GetDefaultKeyBindings 获取默认快捷键配置
*/
export function GetDefaultKeyBindings(): Promise<models$0.KeyBinding[]> & { cancel(): void } {
let $resultPromise = $Call.ByID(3843471588) as any;
let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType4($result);
}) as any;
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
return $typingPromise;
}
/**
* GetKeyBindingByKey 根据Key获取快捷键
*/
export function GetKeyBindingByKey(key: string): Promise<ent$0.KeyBinding | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(852938650, key) as any;
let $typingPromise = $resultPromise.then(($result: any) => { let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result); return $$createType1($result);
}) as any; }) as any;
@@ -30,13 +57,40 @@ export function GetAllKeyBindings(): Promise<models$0.KeyBinding[]> & { cancel()
} }
/** /**
* ServiceStartup 启动时调用 * ServiceStartup 服务启动
*/ */
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } { export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2057121990, options) as any; let $resultPromise = $Call.ByID(2057121990, options) as any;
return $resultPromise; return $resultPromise;
} }
/**
* SyncKeyBindings 同步快捷键配置
*/
export function SyncKeyBindings(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1522202638) as any;
return $resultPromise;
}
/**
* UpdateKeyBindingCommand 更新快捷键命令
*/
export function UpdateKeyBindingCommand(key: string, command: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1293670628, key, command) as any;
return $resultPromise;
}
/**
* UpdateKeyBindingEnabled 更新快捷键启用状态
*/
export function UpdateKeyBindingEnabled(key: string, enabled: boolean): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(843626124, key, enabled) as any;
return $resultPromise;
}
// Private type creation functions // Private type creation functions
const $$createType0 = models$0.KeyBinding.createFrom; const $$createType0 = ent$0.KeyBinding.createFrom;
const $$createType1 = $Create.Array($$createType0); const $$createType1 = $Create.Nullable($$createType0);
const $$createType2 = $Create.Array($$createType1);
const $$createType3 = models$0.KeyBinding.createFrom;
const $$createType4 = $Create.Array($$createType3);

View File

@@ -191,15 +191,14 @@ export class MemoryStats {
* MigrationProgress 迁移进度信息 * MigrationProgress 迁移进度信息
*/ */
export class MigrationProgress { export class MigrationProgress {
"status": MigrationStatus; /**
* 0-100
*/
"progress": number; "progress": number;
"error"?: string; "error"?: string;
/** Creates a new MigrationProgress instance. */ /** Creates a new MigrationProgress instance. */
constructor($$source: Partial<MigrationProgress> = {}) { constructor($$source: Partial<MigrationProgress> = {}) {
if (!("status" in $$source)) {
this["status"] = ("" as MigrationStatus);
}
if (!("progress" in $$source)) { if (!("progress" in $$source)) {
this["progress"] = 0; this["progress"] = 0;
} }
@@ -216,20 +215,6 @@ export class MigrationProgress {
} }
} }
/**
* MigrationStatus 迁移状态
*/
export enum MigrationStatus {
/**
* The Go zero value for the underlying type of the enum.
*/
$zero = "",
MigrationStatusMigrating = "migrating",
MigrationStatusCompleted = "completed",
MigrationStatusFailed = "failed",
};
/** /**
* OSInfo 操作系统信息 * OSInfo 操作系统信息
*/ */

View File

@@ -15,13 +15,13 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime";
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js"; import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports // @ts-ignore: Unused imports
import * as models$0 from "../models/models.js"; import * as ent$0 from "../models/ent/models.js";
/** /**
* GetThemeByName 通过名称获取主题覆盖,若不存在则返回 nil * GetThemeByKey 根据Key获取主题
*/ */
export function GetThemeByName(name: string): Promise<models$0.Theme | null> & { cancel(): void } { export function GetThemeByKey(key: string): Promise<ent$0.Theme | null> & { cancel(): void } {
let $resultPromise = $Call.ByID(1938954770, name) as any; let $resultPromise = $Call.ByID(808794256, key) as any;
let $typingPromise = $resultPromise.then(($result: any) => { let $typingPromise = $resultPromise.then(($result: any) => {
return $$createType1($result); return $$createType1($result);
}) as any; }) as any;
@@ -30,18 +30,10 @@ export function GetThemeByName(name: string): Promise<models$0.Theme | null> & {
} }
/** /**
* ResetTheme 删除指定主题的覆盖配置 * ResetTheme 删除主题
*/ */
export function ResetTheme(name: string): Promise<void> & { cancel(): void } { export function ResetTheme(key: string): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1806334457, name) as any; let $resultPromise = $Call.ByID(1806334457, key) as any;
return $resultPromise;
}
/**
* ServiceShutdown 服务关闭
*/
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1676749034) as any;
return $resultPromise; return $resultPromise;
} }
@@ -54,13 +46,13 @@ export function ServiceStartup(options: application$0.ServiceOptions): Promise<v
} }
/** /**
* UpdateTheme 保存或更新主题覆盖 * UpdateTheme 保存或更新主题
*/ */
export function UpdateTheme(name: string, colors: models$0.ThemeColorConfig): Promise<void> & { cancel(): void } { export function UpdateTheme(key: string, colors: { [_: string]: any }): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(70189749, name, colors) as any; let $resultPromise = $Call.ByID(70189749, key, colors) as any;
return $resultPromise; return $resultPromise;
} }
// Private type creation functions // Private type creation functions
const $$createType0 = models$0.Theme.createFrom; const $$createType0 = ent$0.Theme.createFrom;
const $$createType1 = $Create.Nullable($$createType0); const $$createType1 = $Create.Nullable($$createType0);

View File

@@ -1,59 +0,0 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
/**
* TrayService 系统托盘服务
* @module
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Unused imports
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
/**
* AutoShowHide 自动显示/隐藏主窗口
*/
export function AutoShowHide(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(4044219428) as any;
return $resultPromise;
}
/**
* HandleWindowClose 处理窗口关闭事件
*/
export function HandleWindowClose(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1824247204) as any;
return $resultPromise;
}
/**
* HandleWindowMinimize 处理窗口最小化事件
*/
export function HandleWindowMinimize(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(178686624) as any;
return $resultPromise;
}
/**
* MinimizeButtonClicked 处理标题栏最小化按钮点击
*/
export function MinimizeButtonClicked(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(2477618539) as any;
return $resultPromise;
}
/**
* ShouldMinimizeToTray 检查是否应该最小化到托盘
*/
export function ShouldMinimizeToTray(): Promise<boolean> & { cancel(): void } {
let $resultPromise = $Call.ByID(3403884012) as any;
return $resultPromise;
}
/**
* ShowWindow 显示主窗口
*/
export function ShowWindow(): Promise<void> & { cancel(): void } {
let $resultPromise = $Call.ByID(1315913255) as any;
return $resultPromise;
}

View File

@@ -19,13 +19,13 @@ onBeforeMount(async () => {
// 并行初始化配置、系统信息和快捷键配置 // 并行初始化配置、系统信息和快捷键配置
await Promise.all([ await Promise.all([
configStore.initConfig(), configStore.initConfig(),
systemStore.initializeSystemInfo(), systemStore.initSystemInfo(),
keybindingStore.loadKeyBindings(), keybindingStore.loadKeyBindings(),
]); ]);
// 初始化语言和主题 // 初始化语言和主题
await configStore.initializeLanguage(); await configStore.initLanguage();
await themeStore.initializeTheme(); await themeStore.initTheme();
await translationStore.loadTranslators(); await translationStore.loadTranslators();
// 启动时检查更新 // 启动时检查更新

View File

@@ -1,7 +0,0 @@
/**
* 翻译图标SVG
*/
export const TRANSLATION_ICON_SVG = `
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path d="M599.68 485.056h-8l30.592 164.672c20.352-7.04 38.72-17.344 54.912-31.104a271.36 271.36 0 0 1-40.704-64.64l32.256-4.032c8.896 17.664 19.072 33.28 30.592 46.72 23.872-27.968 42.24-65.152 55.04-111.744l-154.688 0.128z m121.92 133.76c18.368 15.36 39.36 26.56 62.848 33.472l14.784 4.416-8.64 30.336-14.72-4.352a205.696 205.696 0 0 1-76.48-41.728c-20.672 17.92-44.928 31.552-71.232 40.064l20.736 110.912H519.424l-9.984 72.512h385.152c18.112 0 32.704-14.144 32.704-31.616V295.424a32.128 32.128 0 0 0-32.704-31.552H550.528l35.2 189.696h79.424v-31.552h61.44v31.552h102.4v31.616h-42.688c-14.272 55.488-35.712 100.096-64.64 133.568zM479.36 791.68H193.472c-36.224 0-65.472-28.288-65.472-63.168V191.168C128 156.16 157.312 128 193.472 128h327.68l20.544 104.32h352.832c36.224 0 65.472 28.224 65.472 63.104v537.408c0 34.944-29.312 63.168-65.472 63.168H468.608l10.688-104.32zM337.472 548.352v-33.28H272.768v-48.896h60.16V433.28h-60.16v-41.728h64.704v-32.896h-102.4v189.632h102.4z m158.272 0V453.76c0-17.216-4.032-30.272-12.16-39.488-8.192-9.152-20.288-13.696-36.032-13.696a55.04 55.04 0 0 0-24.768 5.376 39.04 39.04 0 0 0-17.088 15.936h-1.984l-5.056-18.56h-28.352V548.48h37.12V480c0-17.088 2.304-29.376 6.912-36.736 4.608-7.424 12.16-11.072 22.528-11.072 7.616 0 13.248 2.56 16.64 7.872 3.52 5.248 5.312 13.056 5.312 23.488v84.736h36.928z" fill="currentColor"></path>
</svg>`;

View File

@@ -0,0 +1,65 @@
/**
* Formatter utility functions
*/
export interface DateTimeFormatOptions {
locale?: string;
includeTime?: boolean;
hour12?: boolean;
}
/**
* Format date time string to localized format
* @param dateString - ISO date string or null
* @param options - Formatting options
* @returns Formatted date string or error message
*/
export const formatDateTime = (
dateString: string | null,
options: DateTimeFormatOptions = {}
): string => {
const {
locale = 'en-US',
includeTime = true,
hour12 = false
} = options;
if (!dateString) {
return 'Unknown time';
}
try {
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return 'Invalid date';
}
const formatOptions: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: '2-digit',
day: '2-digit',
};
if (includeTime) {
formatOptions.hour = '2-digit';
formatOptions.minute = '2-digit';
formatOptions.hour12 = hour12;
}
return date.toLocaleString(locale, formatOptions);
} catch {
return 'Time error';
}
};
/**
* Truncate string with ellipsis
* @param str - String to truncate
* @param maxLength - Maximum length before truncation
* @returns Truncated string with ellipsis if needed
*/
export const truncateString = (str: string, maxLength: number): string => {
if (!str) return '';
return str.length > maxLength ? str.substring(0, maxLength) + '...' : str;
};

View File

@@ -0,0 +1,42 @@
/**
* Validation utility functions
*/
/**
* Validate document title
* @param title - The title to validate
* @param maxLength - Maximum allowed length (default: 50)
* @returns Error message if invalid, null if valid
*/
export const validateDocumentTitle = (title: string, maxLength: number = 50): string | null => {
const trimmed = title.trim();
if (!trimmed) {
return 'Document name cannot be empty';
}
if (trimmed.length > maxLength) {
return `Document name cannot exceed ${maxLength} characters`;
}
return null;
};
/**
* Check if a string is empty or whitespace only
* @param value - The string to check
* @returns true if empty or whitespace only
*/
export const isEmpty = (value: string | null | undefined): boolean => {
return !value || value.trim().length === 0;
};
/**
* Check if a string exceeds max length
* @param value - The string to check
* @param maxLength - Maximum allowed length
* @returns true if exceeds max length
*/
export const exceedsMaxLength = (value: string, maxLength: number): boolean => {
return value.trim().length > maxLength;
};

View File

@@ -1,35 +1,40 @@
<template> <template>
<div <div
v-if="visible && canClose" v-if="visible && canClose"
class="tab-context-menu" v-click-outside="handleClose"
:style="{ class="tab-context-menu"
left: position.x + 'px', :style="{
top: position.y + 'px' left: position.x + 'px',
}" top: position.y + 'px'
@click.stop }"
@click.stop
> >
<div v-if="canClose" class="menu-item" @click="handleMenuClick('close')"> <div v-if="canClose" class="menu-item" @click="handleMenuClick('close')">
<svg class="menu-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg class="menu-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 6L6 18M6 6l12 12"/> <path d="M18 6L6 18M6 6l12 12"/>
</svg> </svg>
<span class="menu-text">{{ t('tabs.contextMenu.closeTab') }}</span> <span class="menu-text">{{ t('tabs.contextMenu.closeTab') }}</span>
</div> </div>
<div v-if="hasOtherTabs" class="menu-item" @click="handleMenuClick('closeOthers')"> <div v-if="hasOtherTabs" class="menu-item" @click="handleMenuClick('closeOthers')">
<svg class="menu-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg class="menu-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/> <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
<path d="M9 9l6 6M15 9l-6 6"/> <path d="M9 9l6 6M15 9l-6 6"/>
</svg> </svg>
<span class="menu-text">{{ t('tabs.contextMenu.closeOthers') }}</span> <span class="menu-text">{{ t('tabs.contextMenu.closeOthers') }}</span>
</div> </div>
<div v-if="hasTabsToLeft" class="menu-item" @click="handleMenuClick('closeLeft')"> <div v-if="hasTabsToLeft" class="menu-item" @click="handleMenuClick('closeLeft')">
<svg class="menu-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg class="menu-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 18l-6-6 6-6"/> <path d="M15 18l-6-6 6-6"/>
<path d="M9 18l-6-6 6-6"/> <path d="M9 18l-6-6 6-6"/>
</svg> </svg>
<span class="menu-text">{{ t('tabs.contextMenu.closeLeft') }}</span> <span class="menu-text">{{ t('tabs.contextMenu.closeLeft') }}</span>
</div> </div>
<div v-if="hasTabsToRight" class="menu-item" @click="handleMenuClick('closeRight')"> <div v-if="hasTabsToRight" class="menu-item" @click="handleMenuClick('closeRight')">
<svg class="menu-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg class="menu-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 18l6-6-6-6"/> <path d="M9 18l6-6-6-6"/>
<path d="M15 18l6-6-6-6"/> <path d="M15 18l6-6-6-6"/>
</svg> </svg>
@@ -39,9 +44,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, onUnmounted } from 'vue'; import {computed, onMounted, onUnmounted} from 'vue';
import { useI18n } from 'vue-i18n'; import {useI18n} from 'vue-i18n';
import { useTabStore } from '@/stores/tabStore'; import {useTabStore} from '@/stores/tabStore';
interface Props { interface Props {
visible: boolean; visible: boolean;
@@ -54,7 +59,7 @@ const emit = defineEmits<{
close: []; close: [];
}>(); }>();
const { t } = useI18n(); const {t} = useI18n();
const tabStore = useTabStore(); const tabStore = useTabStore();
// 计算属性 // 计算属性
@@ -79,6 +84,9 @@ const hasTabsToLeft = computed(() => {
return index > 0; return index > 0;
}); });
const handleClose = () => {
emit('close');
};
// 处理菜单项点击 // 处理菜单项点击
const handleMenuClick = (action: string) => { const handleMenuClick = (action: string) => {
if (!props.targetDocumentId) return; if (!props.targetDocumentId) return;
@@ -98,33 +106,8 @@ const handleMenuClick = (action: string) => {
break; break;
} }
emit('close'); handleClose();
}; };
// 处理外部点击
const handleClickOutside = (_event: MouseEvent) => {
if (props.visible) {
emit('close');
}
};
// 处理ESC键
const handleEscapeKey = (event: KeyboardEvent) => {
if (event.key === 'Escape' && props.visible) {
emit('close');
}
};
// 生命周期
onMounted(() => {
document.addEventListener('click', handleClickOutside);
document.addEventListener('keydown', handleEscapeKey);
});
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
document.removeEventListener('keydown', handleEscapeKey);
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -1,13 +1,15 @@
<template> <template>
<div class="linux-titlebar" style="--wails-draggable:drag" @contextmenu.prevent> <div class="linux-titlebar" style="--wails-draggable:drag" @contextmenu.prevent>
<div class="titlebar-content" @dblclick="toggleMaximize" @contextmenu.prevent> <div class="titlebar-content" @dblclick="handleToggleMaximize" @contextmenu.prevent>
<div class="titlebar-icon"> <div class="titlebar-icon">
<img src="/appicon.png" alt="voidraft"/> <img src="/appicon.png" alt="voidraft"/>
</div> </div>
<div v-if="!tabStore.isTabsEnabled && !isInSettings" class="titlebar-title" :title="fullTitleText">{{ titleText }}</div> <div v-if="!tabStore.isTabsEnabled && !isInSettings" class="titlebar-title" :title="fullTitleText">
{{ titleText }}
</div>
<!-- 标签页容器区域 --> <!-- 标签页容器区域 -->
<div class="titlebar-tabs" v-if="tabStore.isTabsEnabled && !isInSettings" style="--wails-draggable:drag"> <div class="titlebar-tabs" v-if="tabStore.isTabsEnabled && !isInSettings" style="--wails-draggable:drag">
<TabContainer /> <TabContainer/>
</div> </div>
<!-- 设置页面标题 --> <!-- 设置页面标题 -->
<div v-if="isInSettings" class="titlebar-title" :title="fullTitleText">{{ titleText }}</div> <div v-if="isInSettings" class="titlebar-title" :title="fullTitleText">{{ titleText }}</div>
@@ -26,7 +28,7 @@
<button <button
class="titlebar-button maximize-button" class="titlebar-button maximize-button"
@click="toggleMaximize" @click="handleToggleMaximize"
:title="isMaximized ? t('titlebar.restore') : t('titlebar.maximize')" :title="isMaximized ? t('titlebar.restore') : t('titlebar.maximize')"
> >
<svg width="16" height="16" viewBox="0 0 16 16" v-if="!isMaximized"> <svg width="16" height="16" viewBox="0 0 16 16" v-if="!isMaximized">
@@ -55,81 +57,43 @@
import {computed, onMounted, ref} from 'vue'; import {computed, onMounted, ref} from 'vue';
import {useI18n} from 'vue-i18n'; import {useI18n} from 'vue-i18n';
import {useRoute} from 'vue-router'; import {useRoute} from 'vue-router';
import * as runtime from '@wailsio/runtime';
import {useDocumentStore} from '@/stores/documentStore'; import {useDocumentStore} from '@/stores/documentStore';
import {useTabStore} from '@/stores/tabStore';
import TabContainer from '@/components/tabs/TabContainer.vue'; import TabContainer from '@/components/tabs/TabContainer.vue';
import {useTabStore} from "@/stores/tabStore"; import {
minimizeWindow,
toggleMaximize,
closeWindow,
getMaximizedState,
generateTitleText,
generateFullTitleText
} from './index';
const tabStore = useTabStore();
const {t} = useI18n(); const {t} = useI18n();
const route = useRoute(); const route = useRoute();
const isMaximized = ref(false); const tabStore = useTabStore();
const documentStore = useDocumentStore(); const documentStore = useDocumentStore();
// 判断是否在设置页面 const isMaximized = ref(false);
const isInSettings = computed(() => route.path.startsWith('/settings')); const isInSettings = computed(() => route.path.startsWith('/settings'));
// 计算标题文本
const titleText = computed(() => { const titleText = computed(() => {
if (isInSettings.value) { if (isInSettings.value) return `voidraft - ${t('settings.title')}`;
return `voidraft - ` + t('settings.title'); return generateTitleText(documentStore.currentDocument?.title);
}
const currentDoc = documentStore.currentDocument;
if (currentDoc) {
// 限制文档标题长度,避免标题栏换行
const maxTitleLength = 30;
const truncatedTitle = currentDoc.title.length > maxTitleLength
? currentDoc.title.substring(0, maxTitleLength) + '...'
: currentDoc.title;
return `voidraft - ${truncatedTitle}`;
}
return 'voidraft';
}); });
// 计算完整标题文本用于tooltip
const fullTitleText = computed(() => { const fullTitleText = computed(() => {
if (isInSettings.value) { if (isInSettings.value) return `voidraft - ${t('settings.title')}`;
return `voidraft - ` + t('settings.title'); return generateFullTitleText(documentStore.currentDocument?.title);
}
const currentDoc = documentStore.currentDocument;
return currentDoc ? `voidraft - ${currentDoc.title}` : 'voidraft';
}); });
const minimizeWindow = async () => { const handleToggleMaximize = async () => {
try { await toggleMaximize();
await runtime.Window.Minimise(); isMaximized.value = await getMaximizedState();
} catch (error) {
console.error(error);
}
};
const toggleMaximize = async () => {
try {
await runtime.Window.ToggleMaximise();
await checkMaximizedState();
} catch (error) {
console.error(error);
}
};
const closeWindow = async () => {
try {
await runtime.Window.Close();
} catch (error) {
console.error(error);
}
};
const checkMaximizedState = async () => {
try {
isMaximized.value = await runtime.Window.IsMaximised();
} catch (error) {
console.error(error);
}
}; };
onMounted(async () => { onMounted(async () => {
await checkMaximizedState(); isMaximized.value = await getMaximizedState();
}); });
</script> </script>
@@ -160,7 +124,7 @@ onMounted(async () => {
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 500;
cursor: default; cursor: default;
min-width: 0; /* 允许内容收缩 */ min-width: 0;
-webkit-context-menu: none; -webkit-context-menu: none;
-moz-context-menu: none; -moz-context-menu: none;

View File

@@ -2,9 +2,9 @@
<div class="macos-titlebar" style="--wails-draggable:drag" @contextmenu.prevent> <div class="macos-titlebar" style="--wails-draggable:drag" @contextmenu.prevent>
<div class="titlebar-controls" style="--wails-draggable:no-drag" @contextmenu.prevent> <div class="titlebar-controls" style="--wails-draggable:no-drag" @contextmenu.prevent>
<button <button
class="titlebar-button close-button" class="titlebar-button close-button"
@click="closeWindow" @click="closeWindow"
:title="t('titlebar.close')" :title="t('titlebar.close')"
> >
<div class="button-icon"> <div class="button-icon">
<svg width="6" height="6" viewBox="0 0 6 6" v-show="showControlIcons"> <svg width="6" height="6" viewBox="0 0 6 6" v-show="showControlIcons">
@@ -14,9 +14,9 @@
</button> </button>
<button <button
class="titlebar-button minimize-button" class="titlebar-button minimize-button"
@click="minimizeWindow" @click="minimizeWindow"
:title="t('titlebar.minimize')" :title="t('titlebar.minimize')"
> >
<div class="button-icon"> <div class="button-icon">
<svg width="8" height="1" viewBox="0 0 8 1" v-show="showControlIcons"> <svg width="8" height="1" viewBox="0 0 8 1" v-show="showControlIcons">
@@ -26,9 +26,9 @@
</button> </button>
<button <button
class="titlebar-button maximize-button" class="titlebar-button maximize-button"
@click="toggleMaximize" @click="handleToggleMaximize"
:title="isMaximized ? t('titlebar.restore') : t('titlebar.maximize')" :title="isMaximized ? t('titlebar.restore') : t('titlebar.maximize')"
> >
<div class="button-icon"> <div class="button-icon">
<svg width="6" height="6" viewBox="0 0 6 6" v-show="showControlIcons && !isMaximized"> <svg width="6" height="6" viewBox="0 0 6 6" v-show="showControlIcons && !isMaximized">
@@ -45,95 +45,58 @@
<!-- 标签页容器区域 --> <!-- 标签页容器区域 -->
<div class="titlebar-tabs" v-if="tabStore.isTabsEnabled && !isInSettings" style="--wails-draggable:drag"> <div class="titlebar-tabs" v-if="tabStore.isTabsEnabled && !isInSettings" style="--wails-draggable:drag">
<TabContainer /> <TabContainer/>
</div> </div>
<div class="titlebar-content" @dblclick="toggleMaximize" @contextmenu.prevent v-if="!tabStore.isTabsEnabled || isInSettings"> <div class="titlebar-content" @dblclick="handleToggleMaximize" @contextmenu.prevent
v-if="!tabStore.isTabsEnabled || isInSettings">
<div class="titlebar-title" :title="fullTitleText">{{ titleText }}</div> <div class="titlebar-title" :title="fullTitleText">{{ titleText }}</div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, computed } from 'vue'; import {computed, onMounted, ref} from 'vue';
import { useI18n } from 'vue-i18n'; import {useI18n} from 'vue-i18n';
import { useRoute } from 'vue-router'; import {useRoute} from 'vue-router';
import * as runtime from '@wailsio/runtime'; import {useDocumentStore} from '@/stores/documentStore';
import { useDocumentStore } from '@/stores/documentStore'; import {useTabStore} from '@/stores/tabStore';
import TabContainer from '@/components/tabs/TabContainer.vue'; import TabContainer from '@/components/tabs/TabContainer.vue';
import { useTabStore } from "@/stores/tabStore"; import {
minimizeWindow,
toggleMaximize,
closeWindow,
getMaximizedState,
generateTitleText,
generateFullTitleText
} from './index';
const tabStore = useTabStore(); const {t} = useI18n();
const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const isMaximized = ref(false); const tabStore = useTabStore();
const showControlIcons = ref(false);
const documentStore = useDocumentStore(); const documentStore = useDocumentStore();
// 判断是否在设置页面 const isMaximized = ref(false);
const showControlIcons = ref(false);
const isInSettings = computed(() => route.path.startsWith('/settings')); const isInSettings = computed(() => route.path.startsWith('/settings'));
const minimizeWindow = async () => {
try {
await runtime.Window.Minimise();
} catch (error) {
console.error(error);
}
};
const toggleMaximize = async () => {
try {
await runtime.Window.ToggleMaximise();
await checkMaximizedState();
} catch (error) {
console.error(error);
}
};
const closeWindow = async () => {
try {
await runtime.Window.Close();
} catch (error) {
console.error(error);
}
};
const checkMaximizedState = async () => {
try {
isMaximized.value = await runtime.Window.IsMaximised();
} catch (error) {
console.error(error);
}
};
// 计算标题文本
const titleText = computed(() => { const titleText = computed(() => {
if (isInSettings.value) { if (isInSettings.value) return `voidraft - ${t('settings.title')}`;
return `voidraft - ` + t('settings.title'); return generateTitleText(documentStore.currentDocument?.title);
}
const currentDoc = documentStore.currentDocument;
if (currentDoc) {
// 限制文档标题长度,避免标题栏换行
const maxTitleLength = 30;
const truncatedTitle = currentDoc.title.length > maxTitleLength
? currentDoc.title.substring(0, maxTitleLength) + '...'
: currentDoc.title;
return `voidraft - ${truncatedTitle}`;
}
return 'voidraft';
}); });
// 计算完整标题文本用于tooltip
const fullTitleText = computed(() => { const fullTitleText = computed(() => {
if (isInSettings.value) { if (isInSettings.value) return `voidraft - ${t('settings.title')}`;
return `voidraft - ` + t('settings.title'); return generateFullTitleText(documentStore.currentDocument?.title);
}
const currentDoc = documentStore.currentDocument;
return currentDoc ? `voidraft - ${currentDoc.title}` : 'voidraft';
}); });
const handleToggleMaximize = async () => {
await toggleMaximize();
isMaximized.value = await getMaximizedState();
};
onMounted(async () => { onMounted(async () => {
await checkMaximizedState(); isMaximized.value = await getMaximizedState();
}); });
</script> </script>
@@ -261,9 +224,8 @@ onMounted(async () => {
margin-left: 8px; margin-left: 8px;
margin-right: 8px; margin-right: 8px;
min-width: 0; min-width: 0;
overflow: visible; /* 允许TabContainer内部处理滚动 */ overflow: visible;
/* 确保TabContainer能够正确处理滚动 */
:deep(.tab-container) { :deep(.tab-container) {
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -285,7 +247,6 @@ onMounted(async () => {
} }
} }
/* 确保底部线条能够正确显示 */
:deep(.tab-item) { :deep(.tab-item) {
position: relative; position: relative;

View File

@@ -1,13 +1,15 @@
<template> <template>
<div class="windows-titlebar" style="--wails-draggable:drag"> <div class="windows-titlebar" style="--wails-draggable:drag">
<div class="titlebar-content" @dblclick="toggleMaximize" @contextmenu.prevent> <div class="titlebar-content" @dblclick="handleToggleMaximize" @contextmenu.prevent>
<div class="titlebar-icon"> <div class="titlebar-icon">
<img src="/appicon.png" alt="voidraft"/> <img src="/appicon.png" alt="voidraft"/>
</div> </div>
<div v-if="!tabStore.isTabsEnabled && !isInSettings" class="titlebar-title" :title="fullTitleText">{{ titleText }}</div> <div v-if="!tabStore.isTabsEnabled && !isInSettings" class="titlebar-title" :title="fullTitleText">
{{ titleText }}
</div>
<!-- 标签页容器区域 --> <!-- 标签页容器区域 -->
<div class="titlebar-tabs" v-if="tabStore.isTabsEnabled && !isInSettings" style="--wails-draggable:drag"> <div class="titlebar-tabs" v-if="tabStore.isTabsEnabled && !isInSettings" style="--wails-draggable:drag">
<TabContainer /> <TabContainer/>
</div> </div>
<!-- 设置页面标题 --> <!-- 设置页面标题 -->
<div v-if="isInSettings" class="titlebar-title" :title="fullTitleText">{{ titleText }}</div> <div v-if="isInSettings" class="titlebar-title" :title="fullTitleText">{{ titleText }}</div>
@@ -24,7 +26,7 @@
<button <button
class="titlebar-button maximize-button" class="titlebar-button maximize-button"
@click="toggleMaximize" @click="handleToggleMaximize"
:title="isMaximized ? t('titlebar.restore') : t('titlebar.maximize')" :title="isMaximized ? t('titlebar.restore') : t('titlebar.maximize')"
> >
<span class="titlebar-icon" v-html="maximizeIcon"></span> <span class="titlebar-icon" v-html="maximizeIcon"></span>
@@ -45,84 +47,44 @@
import {computed, onMounted, ref} from 'vue'; import {computed, onMounted, ref} from 'vue';
import {useI18n} from 'vue-i18n'; import {useI18n} from 'vue-i18n';
import {useRoute} from 'vue-router'; import {useRoute} from 'vue-router';
import * as runtime from '@wailsio/runtime';
import {useDocumentStore} from '@/stores/documentStore'; import {useDocumentStore} from '@/stores/documentStore';
import {useTabStore} from '@/stores/tabStore';
import TabContainer from '@/components/tabs/TabContainer.vue'; import TabContainer from '@/components/tabs/TabContainer.vue';
import {useTabStore} from "@/stores/tabStore"; import {
minimizeWindow,
toggleMaximize,
closeWindow,
getMaximizedState,
generateTitleText,
generateFullTitleText
} from './index';
const tabStore = useTabStore();
const {t} = useI18n(); const {t} = useI18n();
const route = useRoute(); const route = useRoute();
const isMaximized = ref(false); const tabStore = useTabStore();
const documentStore = useDocumentStore(); const documentStore = useDocumentStore();
// 计算属性用于图标,减少重复渲染 const isMaximized = ref(false);
const maximizeIcon = computed(() => isMaximized.value ? '&#xE923;' : '&#xE922;'); const maximizeIcon = computed(() => isMaximized.value ? '&#xE923;' : '&#xE922;');
// 判断是否在设置页面
const isInSettings = computed(() => route.path.startsWith('/settings')); const isInSettings = computed(() => route.path.startsWith('/settings'));
// 计算标题文本
const titleText = computed(() => { const titleText = computed(() => {
if (isInSettings.value) { if (isInSettings.value) return `voidraft - ${t('settings.title')}`;
return `voidraft - ` + t('settings.title'); return generateTitleText(documentStore.currentDocument?.title);
}
const currentDoc = documentStore.currentDocument;
if (currentDoc) {
// 限制文档标题长度,避免标题栏换行
const maxTitleLength = 30;
const truncatedTitle = currentDoc.title.length > maxTitleLength
? currentDoc.title.substring(0, maxTitleLength) + '...'
: currentDoc.title;
return `voidraft - ${truncatedTitle}`;
}
return 'voidraft';
}); });
// 计算完整标题文本用于tooltip
const fullTitleText = computed(() => { const fullTitleText = computed(() => {
if (isInSettings.value) { if (isInSettings.value) return `voidraft - ${t('settings.title')}`;
return `voidraft - ` + t('settings.title'); return generateFullTitleText(documentStore.currentDocument?.title);
}
const currentDoc = documentStore.currentDocument;
return currentDoc ? `voidraft - ${currentDoc.title}` : 'voidraft';
}); });
const minimizeWindow = async () => { const handleToggleMaximize = async () => {
try { await toggleMaximize();
await runtime.Window.Minimise(); isMaximized.value = await getMaximizedState();
} catch (error) {
console.error(error);
}
};
const toggleMaximize = async () => {
try {
await runtime.Window.ToggleMaximise();
await checkMaximizedState();
} catch (error) {
console.error(error);
}
};
const closeWindow = async () => {
try {
await runtime.Window.Close();
} catch (error) {
console.error(error);
}
};
const checkMaximizedState = async () => {
try {
isMaximized.value = await runtime.Window.IsMaximised();
} catch (error) {
console.error(error);
}
}; };
onMounted(async () => { onMounted(async () => {
await checkMaximizedState(); isMaximized.value = await getMaximizedState();
}); });
</script> </script>
@@ -152,7 +114,7 @@ onMounted(async () => {
font-size: 12px; font-size: 12px;
font-weight: 400; font-weight: 400;
cursor: default; cursor: default;
min-width: 0; /* 允许内容收缩 */ min-width: 0;
-webkit-context-menu: none; -webkit-context-menu: none;
-moz-context-menu: none; -moz-context-menu: none;
@@ -178,7 +140,6 @@ onMounted(async () => {
overflow: hidden; overflow: hidden;
margin-left: 8px; margin-left: 8px;
min-width: 0; min-width: 0;
//margin-right: 8px;
} }
.titlebar-controls { .titlebar-controls {

View File

@@ -0,0 +1,60 @@
import * as runtime from '@wailsio/runtime';
/**
* Titlebar utility functions
*/
// Window control functions
export const minimizeWindow = async () => {
try {
await runtime.Window.Minimise();
} catch (error) {
console.error('Failed to minimize window:', error);
}
};
export const toggleMaximize = async () => {
try {
await runtime.Window.ToggleMaximise();
} catch (error) {
console.error('Failed to toggle maximize:', error);
}
};
export const closeWindow = async () => {
try {
await runtime.Window.Close();
} catch (error) {
console.error('Failed to close window:', error);
}
};
export const getMaximizedState = async (): Promise<boolean> => {
try {
return await runtime.Window.IsMaximised();
} catch (error) {
console.error('Failed to check maximized state:', error);
return false;
}
};
/**
* Generate title text with optional truncation
*/
export const generateTitleText = (
title: string | undefined,
maxLength: number = 30
): string => {
if (!title) return 'voidraft';
const truncated = title.length > maxLength
? title.substring(0, maxLength) + '...'
: title;
return `voidraft - ${truncated}`;
};
/**
* Generate full title text (no truncation)
*/
export const generateFullTitleText = (title: string | undefined): string => {
return title ? `voidraft - ${title}` : 'voidraft';
};

View File

@@ -1,49 +1,63 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'; import {computed, nextTick, reactive, ref, watch} from 'vue';
import { useDocumentStore } from '@/stores/documentStore'; import {useDocumentStore} from '@/stores/documentStore';
import { useTabStore } from '@/stores/tabStore'; import {useTabStore} from '@/stores/tabStore';
import { useWindowStore } from '@/stores/windowStore'; import {useWindowStore} from '@/stores/windowStore';
import { useI18n } from 'vue-i18n'; import {useI18n} from 'vue-i18n';
import type { Document } from '@/../bindings/voidraft/internal/models/models'; import {useConfirm} from '@/composables';
import {validateDocumentTitle} from '@/common/utils/validation';
import {formatDateTime, truncateString} from '@/common/utils/formatter';
import type {Document} from '@/../bindings/voidraft/internal/models/ent/models';
// 类型定义
interface DocumentItem extends Document {
isCreateOption?: boolean;
}
const documentStore = useDocumentStore(); const documentStore = useDocumentStore();
const tabStore = useTabStore(); const tabStore = useTabStore();
const windowStore = useWindowStore(); const windowStore = useWindowStore();
const { t } = useI18n(); const {t} = useI18n();
// DOM 引用
const inputRef = ref<HTMLInputElement>();
const editInputRef = ref<HTMLInputElement>();
// 组件状态 // 组件状态
const inputValue = ref(''); const state = reactive({
const inputRef = ref<HTMLInputElement>(); isLoaded: false,
const editingId = ref<number | null>(null); searchQuery: '',
const editingTitle = ref(''); editing: {
const editInputRef = ref<HTMLInputElement>(); id: null as number | null,
const deleteConfirmId = ref<number | null>(null); title: ''
}
});
// 常量 // 常量
const MAX_TITLE_LENGTH = 50; const MAX_TITLE_LENGTH = 50;
const DELETE_CONFIRM_TIMEOUT = 3000;
// 计算属性 // 计算属性
const currentDocName = computed(() => { const currentDocName = computed(() => {
if (!documentStore.currentDocument) return t('toolbar.selectDocument'); if (!documentStore.currentDocument) return t('toolbar.selectDocument');
const title = documentStore.currentDocument.title; return truncateString(documentStore.currentDocument.title || '', 12);
return title.length > 12 ? title.substring(0, 12) + '...' : title;
}); });
const filteredItems = computed(() => { const filteredItems = computed<DocumentItem[]>(() => {
const docs = documentStore.documentList; const docs = documentStore.documentList;
const query = inputValue.value.trim(); const query = state.searchQuery.trim();
if (!query) return docs; if (!query) return docs;
const filtered = docs.filter(doc => const filtered = docs.filter(doc =>
doc.title.toLowerCase().includes(query.toLowerCase()) (doc.title || '').toLowerCase().includes(query.toLowerCase())
); );
// 如果输入的不是已存在文档的完整标题,添加创建选项 // 如果输入的不是已存在文档的完整标题,添加创建选项
const exactMatch = docs.some(doc => doc.title.toLowerCase() === query.toLowerCase()); const exactMatch = docs.some(doc => (doc.title || '').toLowerCase() === query.toLowerCase());
if (!exactMatch && query.length > 0) { if (!exactMatch && query.length > 0) {
return [ return [
{ id: -1, title: t('toolbar.createDocument') + ` "${query}"`, isCreateOption: true } as any, {id: -1, title: t('toolbar.createDocument') + ` "${query}"`, isCreateOption: true} as DocumentItem,
...filtered ...filtered
]; ];
} }
@@ -51,53 +65,32 @@ const filteredItems = computed(() => {
return filtered; return filtered;
}); });
// 工具函数
const validateTitle = (title: string): string | null => {
if (!title.trim()) return t('toolbar.documentNameRequired');
if (title.trim().length > MAX_TITLE_LENGTH) {
return t('toolbar.documentNameTooLong', { max: MAX_TITLE_LENGTH });
}
return null;
};
const formatTime = (dateString: string | null) => {
if (!dateString) return t('toolbar.unknownTime');
try {
const date = new Date(dateString);
if (isNaN(date.getTime())) return t('toolbar.invalidDate');
const locale = t('locale') === 'zh-CN' ? 'zh-CN' : 'en-US';
return date.toLocaleString(locale, {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false
});
} catch {
return t('toolbar.timeError');
}
};
// 核心操作 // 核心操作
const openMenu = async () => { const openMenu = async () => {
documentStore.openDocumentSelector();
await documentStore.getDocumentMetaList(); await documentStore.getDocumentMetaList();
documentStore.openDocumentSelector();
state.isLoaded = true;
await nextTick(); await nextTick();
inputRef.value?.focus(); inputRef.value?.focus();
}; };
// 删除确认
const {isConfirming: isDeleting, startConfirm: startDeleteConfirm, reset: resetDeleteConfirm} = useConfirm({
timeout: DELETE_CONFIRM_TIMEOUT
});
const closeMenu = () => { const closeMenu = () => {
state.isLoaded = false;
documentStore.closeDocumentSelector(); documentStore.closeDocumentSelector();
inputValue.value = ''; state.searchQuery = '';
editingId.value = null; state.editing.id = null;
editingTitle.value = ''; state.editing.title = '';
deleteConfirmId.value = null; resetDeleteConfirm();
}; };
const selectDoc = async (doc: Document) => { const selectDoc = async (doc: Document) => {
if (doc.id === undefined) return;
// 如果选择的就是当前文档,直接关闭菜单 // 如果选择的就是当前文档,直接关闭菜单
if (documentStore.currentDocument?.id === doc.id) { if (documentStore.currentDocument?.id === doc.id) {
closeMenu(); closeMenu();
@@ -121,7 +114,7 @@ const selectDoc = async (doc: Document) => {
const createDoc = async (title: string) => { const createDoc = async (title: string) => {
const trimmedTitle = title.trim(); const trimmedTitle = title.trim();
const error = validateTitle(trimmedTitle); const error = validateDocumentTitle(trimmedTitle, MAX_TITLE_LENGTH);
if (error) return; if (error) return;
try { try {
@@ -132,20 +125,28 @@ const createDoc = async (title: string) => {
} }
}; };
const selectItem = async (item: any) => { const selectDocItem = async (item: any) => {
if (item.isCreateOption) { if (item.isCreateOption) {
await createDoc(inputValue.value.trim()); await createDoc(state.searchQuery.trim());
} else { } else {
await selectDoc(item); await selectDoc(item);
} }
}; };
// 搜索框回车处理
const handleSearchEnter = () => {
const query = state.searchQuery.trim();
if (query && filteredItems.value.length > 0) {
selectDocItem(filteredItems.value[0]);
}
};
// 编辑操作 // 编辑操作
const startRename = (doc: Document, event: Event) => { const renameDoc = (doc: Document, event: Event) => {
event.stopPropagation(); event.stopPropagation();
editingId.value = doc.id; state.editing.id = doc.id ?? null;
editingTitle.value = doc.title; state.editing.title = doc.title || '';
deleteConfirmId.value = null; resetDeleteConfirm();
nextTick(() => { nextTick(() => {
editInputRef.value?.focus(); editInputRef.value?.focus();
editInputRef.value?.select(); editInputRef.value?.select();
@@ -153,35 +154,41 @@ const startRename = (doc: Document, event: Event) => {
}; };
const saveEdit = async () => { const saveEdit = async () => {
if (!editingId.value || !editingTitle.value.trim()) { if (!state.editing.id || !state.editing.title.trim()) {
editingId.value = null; state.editing.id = null;
editingTitle.value = ''; state.editing.title = '';
return; return;
} }
const trimmedTitle = editingTitle.value.trim(); const trimmedTitle = state.editing.title.trim();
const error = validateTitle(trimmedTitle); const error = validateDocumentTitle(trimmedTitle, MAX_TITLE_LENGTH);
if (error) return; if (error) return;
try { try {
await documentStore.updateDocumentMetadata(editingId.value, trimmedTitle); await documentStore.updateDocumentMetadata(state.editing.id, trimmedTitle);
await documentStore.getDocumentMetaList(); await documentStore.getDocumentMetaList();
// 如果tabs功能开启且该文档有标签页更新标签页标题 // 如果tabs功能开启且该文档有标签页更新标签页标题
if (tabStore.isTabsEnabled && tabStore.hasTab(editingId.value)) { if (tabStore.isTabsEnabled && tabStore.hasTab(state.editing.id)) {
tabStore.updateTabTitle(editingId.value, trimmedTitle); tabStore.updateTabTitle(state.editing.id, trimmedTitle);
} }
} catch (error) { } catch (error) {
console.error('Failed to update document:', error); console.error('Failed to update document:', error);
} finally { } finally {
editingId.value = null; state.editing.id = null;
editingTitle.value = ''; state.editing.title = '';
} }
}; };
const cancelEdit = () => {
state.editing.id = null;
state.editing.title = '';
};
// 其他操作 // 其他操作
const openInNewWindow = async (doc: Document, event: Event) => { const openInNewWindow = async (doc: Document, event: Event) => {
event.stopPropagation(); event.stopPropagation();
if (doc.id === undefined) return;
try { try {
await documentStore.openDocumentInNewWindow(doc.id); await documentStore.openDocumentInNewWindow(doc.id);
} catch (error) { } catch (error) {
@@ -191,13 +198,14 @@ const openInNewWindow = async (doc: Document, event: Event) => {
const handleDelete = async (doc: Document, event: Event) => { const handleDelete = async (doc: Document, event: Event) => {
event.stopPropagation(); event.stopPropagation();
if (doc.id === undefined) return;
if (deleteConfirmId.value === doc.id) { if (isDeleting(doc.id)) {
// 确认删除前检查文档是否在其他窗口打开 // 确认删除前检查文档是否在其他窗口打开
const hasOpen = await windowStore.isDocumentWindowOpen(doc.id); const hasOpen = await windowStore.isDocumentWindowOpen(doc.id);
if (hasOpen) { if (hasOpen) {
documentStore.setError(doc.id, t('toolbar.alreadyOpenInNewWindow')); documentStore.setError(doc.id, t('toolbar.alreadyOpenInNewWindow'));
deleteConfirmId.value = null; resetDeleteConfirm();
return; return;
} }
@@ -210,228 +218,181 @@ const handleDelete = async (doc: Document, event: Event) => {
if (firstDoc) await selectDoc(firstDoc); if (firstDoc) await selectDoc(firstDoc);
} }
} }
deleteConfirmId.value = null; resetDeleteConfirm();
} else { } else {
// 进入确认状态 // 进入确认状态
deleteConfirmId.value = doc.id; startDeleteConfirm(doc.id);
editingId.value = null; state.editing.id = null;
// 3秒后自动取消确认状态
setTimeout(() => {
if (deleteConfirmId.value === doc.id) {
deleteConfirmId.value = null;
}
}, 3000);
} }
}; };
// 键盘事件处理 // 切换菜单
const createKeyHandler = (handlers: Record<string, () => void>) => (event: KeyboardEvent) => { const toggleMenu = () => {
const handler = handlers[event.key]; if (documentStore.showDocumentSelector) {
if (handler) {
event.preventDefault();
event.stopPropagation();
handler();
}
};
const handleGlobalKeydown = createKeyHandler({
Escape: () => {
if (editingId.value) {
editingId.value = null;
editingTitle.value = '';
} else if (deleteConfirmId.value) {
deleteConfirmId.value = null;
} else {
closeMenu();
}
}
});
const handleInputKeydown = createKeyHandler({
Enter: () => {
const query = inputValue.value.trim();
if (query && filteredItems.value.length > 0) {
selectItem(filteredItems.value[0]);
}
},
Escape: closeMenu
});
const handleEditKeydown = createKeyHandler({
Enter: saveEdit,
Escape: () => {
editingId.value = null;
editingTitle.value = '';
}
});
// 点击外部关闭
const handleClickOutside = (event: Event) => {
const target = event.target as HTMLElement;
if (!target.closest('.document-selector')) {
closeMenu(); closeMenu();
} else {
openMenu();
} }
}; };
// 生命周期
onMounted(() => {
document.addEventListener('click', handleClickOutside);
document.addEventListener('keydown', handleGlobalKeydown);
});
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
document.removeEventListener('keydown', handleGlobalKeydown);
});
// 监听菜单状态变化 // 监听菜单状态变化
watch(() => documentStore.showDocumentSelector, (isOpen) => { watch(() => documentStore.showDocumentSelector, (isOpen) => {
if (isOpen) { if (isOpen && !state.isLoaded) {
openMenu(); openMenu();
} }
}); });
</script> </script>
<template> <template>
<div class="document-selector"> <div class="document-selector" v-click-outside="closeMenu">
<!-- 选择器按钮 --> <!-- 选择器按钮 -->
<button class="doc-btn" @click="documentStore.toggleDocumentSelector"> <button class="doc-btn" @click="toggleMenu">
<span class="doc-icon"> <span class="doc-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path> <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path>
<polyline points="14,2 14,8 20,8"></polyline> <polyline points="14,2 14,8 20,8"></polyline>
</svg> </svg>
</span> </span>
<span class="doc-name">{{ currentDocName }}</span> <span class="doc-name">{{ currentDocName }}</span>
<span class="arrow" :class="{ open: documentStore.showDocumentSelector }"></span> <span class="arrow" :class="{ open: state.isLoaded }"></span>
</button> </button>
<!-- 菜单 --> <!-- 菜单 -->
<div v-if="documentStore.showDocumentSelector" class="doc-menu"> <Transition name="slide-up">
<!-- 输入框 --> <div v-if="state.isLoaded" class="doc-menu">
<div class="input-box"> <!-- 输入框 -->
<input <div class="input-box">
ref="inputRef" <input
v-model="inputValue" ref="inputRef"
type="text" v-model="state.searchQuery"
class="main-input" type="text"
:placeholder="t('toolbar.searchOrCreateDocument')" class="main-input"
:maxlength="MAX_TITLE_LENGTH" :placeholder="t('toolbar.searchOrCreateDocument')"
@keydown="handleInputKeydown" :maxlength="MAX_TITLE_LENGTH"
/> @keydown.enter="handleSearchEnter"
<svg class="input-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" @keydown.esc="closeMenu"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> />
<circle cx="11" cy="11" r="8"></circle> <svg class="input-icon" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"
<path d="m21 21-4.35-4.35"></path> fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
</svg> <circle cx="11" cy="11" r="8"></circle>
</div> <path d="m21 21-4.35-4.35"></path>
</svg>
</div>
<!-- 项目列表 --> <!-- 项目列表 -->
<div class="item-list"> <div class="item-list">
<div <div
v-for="item in filteredItems" v-for="item in filteredItems"
:key="item.id" :key="item.id"
class="list-item" class="list-item"
:class="{ :class="{
'active': !item.isCreateOption && documentStore.currentDocument?.id === item.id, 'active': !item.isCreateOption && documentStore.currentDocument?.id === item.id,
'create-item': item.isCreateOption 'create-item': item.isCreateOption
}" }"
@click="selectItem(item)" @click="selectDocItem(item)"
> >
<!-- 创建选项 --> <!-- 创建选项 -->
<div v-if="item.isCreateOption" class="create-option"> <div v-if="item.isCreateOption" class="create-option">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h14"></path> <path d="M5 12h14"></path>
<path d="M12 5v14"></path> <path d="M12 5v14"></path>
</svg> </svg>
<span>{{ item.title }}</span> <span>{{ item.title }}</span>
</div>
<!-- 文档项 -->
<div v-else class="doc-item-content">
<!-- 普通显示 -->
<div v-if="editingId !== item.id" class="doc-info">
<div class="doc-title">{{ item.title }}</div>
<!-- 根据状态显示错误信息或时间 -->
<div v-if="documentStore.selectorError?.docId === item.id" class="doc-error">
{{ documentStore.selectorError?.message }}
</div>
<div v-else class="doc-date">{{ formatTime(item.updatedAt) }}</div>
</div> </div>
<!-- 编辑状态 --> <!-- 文档项 -->
<div v-else class="doc-edit"> <div v-else class="doc-item-content">
<input <!-- 普通显示 -->
:ref="el => editInputRef = el as HTMLInputElement" <div v-if="state.editing.id !== item.id" class="doc-info">
v-model="editingTitle" <div class="doc-title">{{ item.title }}</div>
type="text" <!-- 根据状态显示错误信息或时间 -->
class="edit-input" <div v-if="documentStore.selectorError?.docId === item.id" class="doc-error">
:maxlength="MAX_TITLE_LENGTH" {{ documentStore.selectorError?.message }}
@keydown="handleEditKeydown" </div>
@blur="saveEdit" <div v-else class="doc-date">{{ formatDateTime(item.updated_at) }}</div>
@click.stop </div>
/>
</div>
<!-- 操作按钮 --> <!-- 编辑状态 -->
<div v-if="editingId !== item.id" class="doc-actions"> <div v-else class="doc-edit">
<!-- 只有非当前文档才显示在新窗口打开按钮 --> <input
<button :ref="el => editInputRef = el as HTMLInputElement"
v-if="documentStore.currentDocument?.id !== item.id" v-model="state.editing.title"
class="action-btn" type="text"
@click="openInNewWindow(item, $event)" class="edit-input"
:title="t('toolbar.openInNewWindow')" :maxlength="MAX_TITLE_LENGTH"
> @keydown.enter="saveEdit"
<svg width="12" height="12" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" @keydown.esc="cancelEdit"
fill="currentColor"> @blur="saveEdit"
<path @click.stop
d="M172.8 1017.6c-89.6 0-166.4-70.4-166.4-166.4V441.6c0-89.6 70.4-166.4 166.4-166.4h416c89.6 0 166.4 70.4 166.4 166.4v416c0 89.6-70.4 166.4-166.4 166.4l-416-6.4z m0-659.2c-51.2 0-89.6 38.4-89.6 89.6v416c0 51.2 38.4 89.6 89.6 89.6h416c51.2 0 89.6-38.4 89.6-89.6V441.6c0-51.2-38.4-89.6-89.6-89.6H172.8z"></path> />
<path </div>
d="M851.2 19.2H435.2C339.2 19.2 268.8 96 268.8 185.6v25.6h70.4v-25.6c0-51.2 38.4-89.6 89.6-89.6h409.6c51.2 0 89.6 38.4 89.6 89.6v409.6c0 51.2-38.4 89.6-89.6 89.6h-38.4V768h51.2c96 0 166.4-76.8 166.4-166.4V185.6c0-96-76.8-166.4-166.4-166.4z"></path>
</svg> <!-- 操作按钮 -->
</button> <div v-if="state.editing.id !== item.id" class="doc-actions">
<button class="action-btn" @click="startRename(item, $event)" :title="t('toolbar.rename')"> <!-- 只有非当前文档才显示在新窗口打开按钮 -->
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" <button
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> v-if="documentStore.currentDocument?.id !== item.id"
<path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"></path> class="action-btn"
</svg> @click="openInNewWindow(item, $event)"
</button> :title="t('toolbar.openInNewWindow')"
<button >
v-if="documentStore.documentList.length > 1 && item.id !== 1" <svg width="12" height="12" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
class="action-btn delete-btn" fill="currentColor">
:class="{ 'delete-confirm': deleteConfirmId === item.id }" <path
@click="handleDelete(item, $event)" d="M172.8 1017.6c-89.6 0-166.4-70.4-166.4-166.4V441.6c0-89.6 70.4-166.4 166.4-166.4h416c89.6 0 166.4 70.4 166.4 166.4v416c0 89.6-70.4 166.4-166.4 166.4l-416-6.4z m0-659.2c-51.2 0-89.6 38.4-89.6 89.6v416c0 51.2 38.4 89.6 89.6 89.6h416c51.2 0 89.6-38.4 89.6-89.6V441.6c0-51.2-38.4-89.6-89.6-89.6H172.8z"></path>
:title="deleteConfirmId === item.id ? t('toolbar.confirmDelete') : t('toolbar.delete')" <path
> d="M851.2 19.2H435.2C339.2 19.2 268.8 96 268.8 185.6v25.6h70.4v-25.6c0-51.2 38.4-89.6 89.6-89.6h409.6c51.2 0 89.6 38.4 89.6 89.6v409.6c0 51.2-38.4 89.6-89.6 89.6h-38.4V768h51.2c96 0 166.4-76.8 166.4-166.4V185.6c0-96-76.8-166.4-166.4-166.4z"></path>
<svg v-if="deleteConfirmId !== item.id" xmlns="http://www.w3.org/2000/svg" width="12" height="12" </svg>
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" </button>
stroke-linejoin="round"> <button class="action-btn" @click="renameDoc(item, $event)" :title="t('toolbar.rename')">
<polyline points="3,6 5,6 21,6"></polyline> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path> stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
</svg> <path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"></path>
<span v-else class="confirm-text">{{ t('toolbar.confirm') }}</span> </svg>
</button> </button>
<button
v-if="documentStore.documentList.length > 1 && item.id !== 1"
class="action-btn delete-btn"
:class="{ 'delete-confirm': isDeleting(item.id!) }"
@click="handleDelete(item, $event)"
:title="isDeleting(item.id!) ? t('toolbar.confirmDelete') : t('toolbar.delete')"
>
<svg v-if="!isDeleting(item.id!)" xmlns="http://www.w3.org/2000/svg" width="12" height="12"
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<polyline points="3,6 5,6 21,6"></polyline>
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
</svg>
<span v-else class="confirm-text">{{ t('toolbar.confirm') }}</span>
</button>
</div>
</div> </div>
</div> </div>
</div>
<!-- 空状态 --> <!-- 空状态 -->
<div v-if="filteredItems.length === 0" class="empty"> <div v-if="filteredItems.length === 0" class="empty">
{{ t('toolbar.noDocumentFound') }} {{ t('toolbar.noDocumentFound') }}
</div> </div>
<!-- 加载状态 -->
<div v-if="documentStore.isLoading" class="loading">
{{ t('toolbar.loading') }}
</div> </div>
</div> </div>
</div> </Transition>
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.slide-up-enter-active,
.slide-up-leave-active {
transition: opacity 0.15s ease, transform 0.15s ease;
}
.slide-up-enter-from,
.slide-up-leave-to {
opacity: 0;
transform: translateY(8px);
}
.document-selector { .document-selector {
position: relative; position: relative;
@@ -483,8 +444,8 @@ watch(() => documentStore.showDocumentSelector, (isOpen) => {
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
border-radius: 3px; border-radius: 3px;
margin-bottom: 4px; margin-bottom: 4px;
width: 260px; width: 300px;
max-height: calc(100vh - 40px); // 限制最大高度留出titlebar空间(32px)和一些边距 max-height: calc(100vh - 40px);
z-index: 1000; z-index: 1000;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
overflow: hidden; overflow: hidden;
@@ -527,7 +488,7 @@ watch(() => documentStore.showDocumentSelector, (isOpen) => {
} }
.item-list { .item-list {
max-height: calc(100vh - 100px); // 为输入框和边距预留空间 max-height: calc(100vh - 100px);
overflow-y: auto; overflow-y: auto;
flex: 1; flex: 1;
@@ -669,7 +630,7 @@ watch(() => documentStore.showDocumentSelector, (isOpen) => {
} }
} }
.empty, .loading { .empty {
padding: 16px 8px; padding: 16px 8px;
text-align: center; text-align: center;
font-size: 11px; font-size: 11px;
@@ -680,9 +641,17 @@ watch(() => documentStore.showDocumentSelector, (isOpen) => {
} }
@keyframes fadeInOut { @keyframes fadeInOut {
0% { opacity: 0; } 0% {
10% { opacity: 1; } opacity: 0;
90% { opacity: 1; } }
100% { opacity: 0; } 10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
opacity: 0;
}
} }
</style> </style>

View File

@@ -0,0 +1,5 @@
export { useConfirm } from './useConfirm';
export type { UseConfirmOptions } from './useConfirm';
export { usePolling } from './usePolling';
export type { UsePollingOptions, UsePollingReturn } from './usePolling';

View File

@@ -0,0 +1,174 @@
import { ref, readonly, onUnmounted, type Ref, type DeepReadonly } from 'vue';
export interface UseConfirmOptions<T extends string | number = string | number> {
/** Auto cancel timeout in ms (default: 3000, set 0 to disable) */
timeout?: number;
/** Callback when confirmed */
onConfirm?: (id: T) => void | Promise<void>;
/** Callback when cancelled (timeout or manual) */
onCancel?: (id: T) => void;
}
export interface UseConfirmReturn<T extends string | number = string | number> {
/** Current confirming id (readonly) */
confirmId: DeepReadonly<Ref<T | null>>;
/** Whether confirm action is executing */
isPending: DeepReadonly<Ref<boolean>>;
/** Check if a specific id is in confirming state */
isConfirming: (id: T) => boolean;
/** Start confirming state (with auto timeout) */
startConfirm: (id: T) => void;
/** Request confirmation (toggle between request and execute) */
requestConfirm: (id: T) => Promise<boolean>;
/** Manually confirm current id */
confirm: () => Promise<void>;
/** Cancel confirmation */
cancel: () => void;
/** Reset without triggering callbacks */
reset: () => void;
}
/**
* Composable for handling confirm actions (e.g., delete confirmation)
*
* @example
* ```ts
* // Basic usage
* const { isConfirming, requestConfirm } = useConfirm({
* timeout: 3000,
* onConfirm: async (id) => { await deleteItem(id) }
* })
*
* // In template
* <button @click="requestConfirm('delete')">
* {{ isConfirming('delete') ? 'Confirm?' : 'Delete' }}
* </button>
*
* // With loading state
* const { isPending, requestConfirm } = useConfirm({ ... })
* <button :disabled="isPending" @click="requestConfirm('id')">
* {{ isPending ? 'Processing...' : 'Delete' }}
* </button>
* ```
*/
export function useConfirm<T extends string | number = string | number>(
options: UseConfirmOptions<T> = {}
): UseConfirmReturn<T> {
const { timeout = 3000, onConfirm, onCancel } = options;
const confirmId = ref<T | null>(null) as Ref<T | null>;
const isPending = ref(false);
let timeoutId: ReturnType<typeof setTimeout> | null = null;
const clearTimer = (): void => {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
};
/**
* Check if a specific id is in confirming state
*/
const isConfirming = (id: T): boolean => {
return confirmId.value === id;
};
/**
* Start confirming state for an id (with auto timeout)
*/
const startConfirm = (id: T): void => {
clearTimer();
confirmId.value = id;
// Auto cancel after timeout (0 = disabled)
if (timeout > 0) {
timeoutId = setTimeout(() => {
if (confirmId.value === id) {
confirmId.value = null;
onCancel?.(id);
}
}, timeout);
}
};
/**
* Request confirmation for an id
* - First click: enter confirming state
* - Second click: execute confirm action
* @returns true if confirmed, false if entered confirming state
*/
const requestConfirm = async (id: T): Promise<boolean> => {
// Prevent action while pending
if (isPending.value) return false;
if (confirmId.value === id) {
// Already confirming, execute action
clearTimer();
isPending.value = true;
try {
await onConfirm?.(id);
return true;
} finally {
confirmId.value = null;
isPending.value = false;
}
} else {
// Enter confirming state
startConfirm(id);
return false;
}
};
/**
* Manually confirm the current id
*/
const confirm = async (): Promise<void> => {
if (confirmId.value === null || isPending.value) return;
clearTimer();
const id = confirmId.value;
isPending.value = true;
try {
await onConfirm?.(id);
} finally {
confirmId.value = null;
isPending.value = false;
}
};
/**
* Cancel the confirming state
*/
const cancel = (): void => {
if (confirmId.value === null) return;
const id = confirmId.value;
clearTimer();
confirmId.value = null;
onCancel?.(id);
};
/**
* Reset state without triggering callbacks
*/
const reset = (): void => {
clearTimer();
confirmId.value = null;
isPending.value = false;
};
// Cleanup on unmount
onUnmounted(clearTimer);
return {
confirmId: readonly(confirmId),
isPending: readonly(isPending),
isConfirming,
startConfirm,
requestConfirm,
confirm,
cancel,
reset
};
}

View File

@@ -0,0 +1,147 @@
import { ref, readonly, onUnmounted, type Ref, type DeepReadonly } from 'vue';
export interface UsePollingOptions<T> {
/** Polling interval in ms (default: 500) */
interval?: number;
/** Execute immediately when started (default: true) */
immediate?: boolean;
/** Auto-stop condition, return true to stop polling */
shouldStop?: (data: T) => boolean;
/** Callback on each successful poll */
onSuccess?: (data: T) => void;
/** Callback when error occurs */
onError?: (error: unknown) => void;
/** Callback when polling stops (either manual or auto) */
onStop?: () => void;
}
export interface UsePollingReturn<T> {
/** Latest fetched data (readonly) */
data: DeepReadonly<Ref<T | null>>;
/** Error message if any (readonly) */
error: DeepReadonly<Ref<string>>;
/** Whether polling is active (readonly) */
isActive: DeepReadonly<Ref<boolean>>;
/** Start polling */
start: () => void;
/** Stop polling */
stop: () => void;
/** Reset all state (also stops polling) */
reset: () => void;
}
/**
* Composable for polling async operations with auto-stop support
*
* @example
* ```ts
* // Basic usage
* const { data, isActive, start, stop } = usePolling(
* () => api.getProgress(),
* {
* interval: 200,
* shouldStop: (d) => d.progress >= 100 || !!d.error,
* onSuccess: (d) => console.log('Progress:', d.progress)
* }
* )
*
* // Start polling
* start()
*
* // With reactive data binding
* <div>{{ isActive ? `${data?.progress}%` : 'Idle' }}</div>
* ```
*/
export function usePolling<T>(
fetcher: () => Promise<T>,
options: UsePollingOptions<T> = {}
): UsePollingReturn<T> {
const {
interval = 500,
immediate = true,
shouldStop,
onSuccess,
onError,
onStop
} = options;
const data = ref<T | null>(null) as Ref<T | null>;
const error = ref('');
const isActive = ref(false);
let timerId = 0;
const clearTimer = (): void => {
if (timerId) {
clearInterval(timerId);
timerId = 0;
}
};
const poll = async (): Promise<void> => {
try {
const result = await fetcher();
data.value = result;
error.value = '';
onSuccess?.(result);
// Check auto-stop condition
if (shouldStop?.(result)) {
stop();
}
} catch (e) {
error.value = e instanceof Error ? e.message : String(e);
onError?.(e);
stop();
}
};
/**
* Start polling
*/
const start = (): void => {
if (isActive.value) return;
isActive.value = true;
error.value = '';
// Execute immediately if configured
if (immediate) {
poll();
}
timerId = window.setInterval(poll, interval);
};
/**
* Stop polling
*/
const stop = (): void => {
if (!isActive.value) return;
clearTimer();
isActive.value = false;
onStop?.();
};
/**
* Reset all state to initial values
*/
const reset = (): void => {
clearTimer();
data.value = null;
error.value = '';
isActive.value = false;
};
// Cleanup on unmount
onUnmounted(clearTimer);
return {
data: readonly(data),
error: readonly(error),
isActive: readonly(isActive),
start,
stop,
reset
};
}

View File

@@ -0,0 +1,37 @@
import type { Directive, DirectiveBinding } from 'vue';
type ClickOutsideHandler = (event: MouseEvent) => void;
interface ClickOutsideElement extends HTMLElement {
_clickOutsideHandler?: (event: MouseEvent) => void;
}
/**
* v-click-outside directive
* Triggers a callback when clicking outside the element
*
* Usage:
* <div v-click-outside="handleClickOutside">...</div>
*/
export const clickOutside: Directive<ClickOutsideElement, ClickOutsideHandler> = {
mounted(el: ClickOutsideElement, binding: DirectiveBinding<ClickOutsideHandler>) {
const handler = (event: MouseEvent) => {
const target = event.target as Node;
if (el && !el.contains(target)) {
binding.value(event);
}
};
el._clickOutsideHandler = handler;
document.addEventListener('click', handler);
},
unmounted(el: ClickOutsideElement) {
if (el._clickOutsideHandler) {
document.removeEventListener('click', el._clickOutsideHandler);
delete el._clickOutsideHandler;
}
}
};
export default clickOutside;

View File

@@ -0,0 +1,13 @@
import type { App } from 'vue';
import { clickOutside } from './clickOutside';
export { clickOutside };
/**
* Register all custom directives
*/
export function registerDirectives(app: App) {
app.directive('click-outside', clickOutside);
}
export default registerDirectives;

View File

@@ -33,13 +33,6 @@ export default {
confirmDelete: 'Click again to confirm delete', confirmDelete: 'Click again to confirm delete',
openInNewWindow: 'Open in New Window', openInNewWindow: 'Open in New Window',
alreadyOpenInNewWindow: 'Already open in another window', alreadyOpenInNewWindow: 'Already open in another window',
documentNameTooLong: 'Document name cannot exceed {max} characters',
documentNameRequired: 'Document name cannot be empty',
cannotDeleteLastDocument: 'Cannot delete the last document',
cannotDeleteDefaultDocument: 'Cannot delete the default document',
unknownTime: 'Unknown time',
invalidDate: 'Invalid date',
timeError: 'Time error',
}, },
languages: { languages: {
'zh-CN': 'Chinese', 'zh-CN': 'Chinese',
@@ -297,6 +290,10 @@ export default {
highlightTrailingWhitespace: { highlightTrailingWhitespace: {
name: 'Highlight Trailing Whitespace', name: 'Highlight Trailing Whitespace',
description: 'Highlight trailing whitespace at the end of lines' description: 'Highlight trailing whitespace at the end of lines'
},
httpClient: {
name: 'HTTP Client',
description: 'Send HTTP requests directly in the editor and view responses'
} }
}, },
monitor: { monitor: {

View File

@@ -33,13 +33,6 @@ export default {
confirmDelete: '再次点击确认删除', confirmDelete: '再次点击确认删除',
openInNewWindow: '在新窗口中打开', openInNewWindow: '在新窗口中打开',
alreadyOpenInNewWindow: '已在新窗口中打开', alreadyOpenInNewWindow: '已在新窗口中打开',
documentNameTooLong: '文档名称不能超过{max}个字符',
documentNameRequired: '文档名称不能为空',
cannotDeleteLastDocument: '无法删除最后一个文档',
cannotDeleteDefaultDocument: '无法删除默认文档',
unknownTime: '未知时间',
invalidDate: '无效日期',
timeError: '时间错误',
}, },
languages: { languages: {
'zh-CN': '简体中文', 'zh-CN': '简体中文',
@@ -299,6 +292,10 @@ export default {
highlightTrailingWhitespace: { highlightTrailingWhitespace: {
name: '高亮行尾空白', name: '高亮行尾空白',
description: '高亮显示行尾的多余空白字符' description: '高亮显示行尾的多余空白字符'
},
httpClient: {
name: 'HTTP 客户端',
description: '在编辑器中直接发送 HTTP 请求并查看响应'
} }
}, },
monitor: { monitor: {

View File

@@ -1,15 +1,18 @@
import {createApp} from 'vue'; import { createApp } from 'vue';
import App from './App.vue'; import App from './App.vue';
import '@/assets/styles/index.css'; import '@/assets/styles/index.css';
import {createPinia} from 'pinia'; import { createPinia } from 'pinia';
import i18n from './i18n'; import i18n from './i18n';
import router from './router'; import router from './router';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import { registerDirectives } from './directives';
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
const app = createApp(App); const app = createApp(App);
app.use(pinia) app.use(pinia);
app.use(i18n); app.use(i18n);
app.use(router); app.use(router);
registerDirectives(app);
app.mount('#app'); app.mount('#app');

View File

@@ -161,7 +161,7 @@ export const useConfigStore = defineStore('config', () => {
// 初始化语言设置 // 初始化语言设置
const initializeLanguage = async (): Promise<void> => { const initLanguage = async (): Promise<void> => {
try { try {
// 如果配置未加载,先加载配置 // 如果配置未加载,先加载配置
if (!state.configLoaded) { if (!state.configLoaded) {
@@ -210,7 +210,7 @@ export const useConfigStore = defineStore('config', () => {
// 语言相关方法 // 语言相关方法
setLanguage, setLanguage,
initializeLanguage, initLanguage,
// 主题相关方法 // 主题相关方法
setSystemTheme, setSystemTheme,

View File

@@ -2,12 +2,11 @@ import {defineStore} from 'pinia';
import {computed, ref} from 'vue'; import {computed, ref} from 'vue';
import {DocumentService} from '@/../bindings/voidraft/internal/services'; import {DocumentService} from '@/../bindings/voidraft/internal/services';
import {OpenDocumentWindow} from '@/../bindings/voidraft/internal/services/windowservice'; import {OpenDocumentWindow} from '@/../bindings/voidraft/internal/services/windowservice';
import {Document} from '@/../bindings/voidraft/internal/models/models'; import {Document} from '@/../bindings/voidraft/internal/models/ent/models';
import {useTabStore} from "@/stores/tabStore"; import {useTabStore} from "@/stores/tabStore";
import type {EditorViewState} from '@/stores/editorStore'; import type {EditorViewState} from '@/stores/editorStore';
export const useDocumentStore = defineStore('document', () => { export const useDocumentStore = defineStore('document', () => {
const DEFAULT_DOCUMENT_ID = ref<number>(1); // 默认草稿文档ID
// === 核心状态 === // === 核心状态 ===
const documents = ref<Record<number, Document>>({}); const documents = ref<Record<number, Document>>({});
@@ -15,7 +14,6 @@ export const useDocumentStore = defineStore('document', () => {
const currentDocument = ref<Document | null>(null); const currentDocument = ref<Document | null>(null);
// === 编辑器状态持久化 === // === 编辑器状态持久化 ===
// 修复:使用统一的 EditorViewState 类型定义
const documentStates = ref<Record<number, EditorViewState>>({}); const documentStates = ref<Record<number, EditorViewState>>({});
// === UI状态 === // === UI状态 ===
@@ -26,15 +24,18 @@ export const useDocumentStore = defineStore('document', () => {
// === 计算属性 === // === 计算属性 ===
const documentList = computed(() => const documentList = computed(() =>
Object.values(documents.value).sort((a, b) => { Object.values(documents.value).sort((a, b) => {
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(); const timeA = a.updated_at ? new Date(a.updated_at).getTime() : 0;
const timeB = b.updated_at ? new Date(b.updated_at).getTime() : 0;
return timeB - timeA;
}) })
); );
// === 私有方法 ===
const setDocuments = (docs: Document[]) => { const setDocuments = (docs: Document[]) => {
documents.value = {}; documents.value = {};
docs.forEach(doc => { docs.forEach(doc => {
documents.value[doc.id] = doc; if (doc.id !== undefined) {
documents.value[doc.id] = doc;
}
}); });
}; };
@@ -64,15 +65,7 @@ export const useDocumentStore = defineStore('document', () => {
clearError(); clearError();
}; };
const toggleDocumentSelector = () => {
if (showDocumentSelector.value) {
closeDocumentSelector();
} else {
openDocumentSelector();
}
};
// === 文档操作方法 ===
// 在新窗口中打开文档 // 在新窗口中打开文档
const openDocumentInNewWindow = async (docId: number): Promise<boolean> => { const openDocumentInNewWindow = async (docId: number): Promise<boolean> => {
@@ -94,7 +87,7 @@ export const useDocumentStore = defineStore('document', () => {
const createNewDocument = async (title: string): Promise<Document | null> => { const createNewDocument = async (title: string): Promise<Document | null> => {
try { try {
const doc = await DocumentService.CreateDocument(title); const doc = await DocumentService.CreateDocument(title);
if (doc) { if (doc && doc.id !== undefined) {
documents.value[doc.id] = doc; documents.value[doc.id] = doc;
return doc; return doc;
} }
@@ -123,8 +116,6 @@ export const useDocumentStore = defineStore('document', () => {
// 打开文档 // 打开文档
const openDocument = async (docId: number): Promise<boolean> => { const openDocument = async (docId: number): Promise<boolean> => {
try { try {
closeDocumentSelector();
// 获取完整文档数据 // 获取完整文档数据
const doc = await DocumentService.GetDocumentByID(docId); const doc = await DocumentService.GetDocumentByID(docId);
if (!doc) { if (!doc) {
@@ -150,12 +141,12 @@ export const useDocumentStore = defineStore('document', () => {
const doc = documents.value[docId]; const doc = documents.value[docId];
if (doc) { if (doc) {
doc.title = title; doc.title = title;
doc.updatedAt = new Date().toISOString(); doc.updated_at = new Date().toISOString();
} }
if (currentDocument.value?.id === docId) { if (currentDocument.value?.id === docId) {
currentDocument.value.title = title; currentDocument.value.title = title;
currentDocument.value.updatedAt = new Date().toISOString(); currentDocument.value.updated_at = new Date().toISOString();
} }
// 同步更新标签页标题 // 同步更新标签页标题
@@ -172,11 +163,6 @@ export const useDocumentStore = defineStore('document', () => {
// 删除文档 // 删除文档
const deleteDocument = async (docId: number): Promise<boolean> => { const deleteDocument = async (docId: number): Promise<boolean> => {
try { try {
// 检查是否是默认文档使用ID判断
if (docId === DEFAULT_DOCUMENT_ID.value) {
return false;
}
await DocumentService.DeleteDocument(docId); await DocumentService.DeleteDocument(docId);
// 更新本地状态 // 更新本地状态
@@ -191,7 +177,7 @@ export const useDocumentStore = defineStore('document', () => {
// 如果删除的是当前文档,切换到第一个可用文档 // 如果删除的是当前文档,切换到第一个可用文档
if (currentDocumentId.value === docId) { if (currentDocumentId.value === docId) {
const availableDocs = Object.values(documents.value); const availableDocs = Object.values(documents.value);
if (availableDocs.length > 0) { if (availableDocs.length > 0 && availableDocs[0].id !== undefined) {
await openDocument(availableDocs[0].id); await openDocument(availableDocs[0].id);
} else { } else {
currentDocumentId.value = null; currentDocumentId.value = null;
@@ -218,8 +204,10 @@ export const useDocumentStore = defineStore('document', () => {
// 如果URL中没有指定文档ID则使用持久化的文档ID // 如果URL中没有指定文档ID则使用持久化的文档ID
await openDocument(currentDocumentId.value); await openDocument(currentDocumentId.value);
} else { } else {
// 否则打开默认文档 // 否则打开第一个文档
await openDocument(DEFAULT_DOCUMENT_ID.value); if (documents.value[0].id) {
await openDocument(documents.value[0].id);
}
} }
} catch (error) { } catch (error) {
console.error('Failed to initialize document store:', error); console.error('Failed to initialize document store:', error);
@@ -227,7 +215,6 @@ export const useDocumentStore = defineStore('document', () => {
}; };
return { return {
DEFAULT_DOCUMENT_ID,
// 状态 // 状态
documents, documents,
documentList, documentList,
@@ -247,7 +234,6 @@ export const useDocumentStore = defineStore('document', () => {
deleteDocument, deleteDocument,
openDocumentSelector, openDocumentSelector,
closeDocumentSelector, closeDocumentSelector,
toggleDocumentSelector,
setError, setError,
clearError, clearError,
initialize, initialize,

View File

@@ -4,7 +4,6 @@ import {EditorView} from '@codemirror/view';
import {EditorState, Extension} from '@codemirror/state'; import {EditorState, Extension} from '@codemirror/state';
import {useConfigStore} from './configStore'; import {useConfigStore} from './configStore';
import {useDocumentStore} from './documentStore'; import {useDocumentStore} from './documentStore';
import {ExtensionID} from '@/../bindings/voidraft/internal/models/models';
import {DocumentService, ExtensionService} from '@/../bindings/voidraft/internal/services'; import {DocumentService, ExtensionService} from '@/../bindings/voidraft/internal/services';
import {ensureSyntaxTree} from "@codemirror/language"; import {ensureSyntaxTree} from "@codemirror/language";
import {createBasicSetup} from '@/views/editor/basic/basicSetup'; import {createBasicSetup} from '@/views/editor/basic/basicSetup';
@@ -28,7 +27,6 @@ import {AsyncManager} from '@/common/utils/asyncManager';
import {generateContentHash} from "@/common/utils/hashUtils"; import {generateContentHash} from "@/common/utils/hashUtils";
import {createTimerManager, type TimerManager} from '@/common/utils/timerUtils'; import {createTimerManager, type TimerManager} from '@/common/utils/timerUtils';
import {EDITOR_CONFIG} from '@/common/constant/editor'; import {EDITOR_CONFIG} from '@/common/constant/editor';
import {createHttpClientExtension} from "@/views/editor/extensions/httpclient";
import {createDebounce} from '@/common/utils/debounce'; import {createDebounce} from '@/common/utils/debounce';
export interface DocumentStats { export interface DocumentStats {
@@ -93,84 +91,6 @@ export const useEditorStore = defineStore('editor', () => {
} }
}, { delay: 500 }); // 500ms 内的多次输入只清理一次 }, { delay: 500 }); // 500ms 内的多次输入只清理一次
// === 私有方法 ===
/**
* 检查位置是否在代码块分隔符区域内
*/
const isPositionInDelimiter = (view: EditorView, pos: number): boolean => {
try {
const blocks = view.state.field(blockState, false);
if (!blocks) return false;
for (const block of blocks) {
if (pos >= block.delimiter.from && pos < block.delimiter.to) {
return true;
}
}
return false;
} catch {
return false;
}
};
/**
* 调整光标位置到有效的内容区域
* 如果位置在分隔符内,移动到该块的内容开始位置
*/
const adjustCursorPosition = (view: EditorView, pos: number): number => {
try {
const blocks = view.state.field(blockState, false);
if (!blocks || blocks.length === 0) return pos;
// 如果位置在分隔符内,移动到该块的内容开始位置
for (const block of blocks) {
if (pos >= block.delimiter.from && pos < block.delimiter.to) {
return block.content.from;
}
}
return pos;
} catch {
return pos;
}
};
/**
* 恢复编辑器的光标位置(自动滚动到光标处)
*/
const restoreEditorState = (instance: EditorInstance, documentId: number): void => {
const savedState = instance.editorState;
if (savedState) {
// 有保存的状态,恢复光标位置
let pos = Math.min(savedState.cursorPos, instance.view.state.doc.length);
// 确保位置不在分隔符上
if (isPositionInDelimiter(instance.view, pos)) {
pos = adjustCursorPosition(instance.view, pos);
}
// 修复:设置光标位置并居中滚动(更好的用户体验)
instance.view.dispatch({
selection: {anchor: pos, head: pos},
effects: EditorView.scrollIntoView(pos, {
y: "center", // 垂直居中显示
yMargin: 100 // 上下留一些边距
})
});
} else {
// 首次打开或没有记录,光标在文档末尾
const docLength = instance.view.state.doc.length;
instance.view.dispatch({
selection: {anchor: docLength, head: docLength},
effects: EditorView.scrollIntoView(docLength, {
y: "center",
yMargin: 100
})
});
}
};
// 缓存化的语法树确保方法 // 缓存化的语法树确保方法
const ensureSyntaxTreeCached = (view: EditorView, documentId: number): void => { const ensureSyntaxTreeCached = (view: EditorView, documentId: number): void => {
@@ -245,7 +165,7 @@ export const useEditorStore = defineStore('editor', () => {
increaseFontSize: () => configStore.increaseFontSizeLocal(), increaseFontSize: () => configStore.increaseFontSizeLocal(),
decreaseFontSize: () => configStore.decreaseFontSizeLocal(), decreaseFontSize: () => configStore.decreaseFontSizeLocal(),
onSave: () => configStore.saveFontSize(), onSave: () => configStore.saveFontSize(),
saveDelay: 500 saveDelay: 1000
}); });
// 统计扩展 // 统计扩展
@@ -260,9 +180,6 @@ export const useEditorStore = defineStore('editor', () => {
enableAutoDetection: true enableAutoDetection: true
}); });
const httpExtension = createHttpClientExtension();
// 再次检查操作有效性 // 再次检查操作有效性
if (!operationManager.isOperationValid(operationId, documentId)) { if (!operationManager.isOperationValid(operationId, documentId)) {
throw new Error('Operation cancelled'); throw new Error('Operation cancelled');
@@ -277,7 +194,7 @@ export const useEditorStore = defineStore('editor', () => {
} }
// 动态扩展传递文档ID以便扩展管理器可以预初始化 // 动态扩展传递文档ID以便扩展管理器可以预初始化
const dynamicExtensions = await createDynamicExtensions(documentId); const dynamicExtensions = await createDynamicExtensions();
// 最终检查操作有效性 // 最终检查操作有效性
if (!operationManager.isOperationValid(operationId, documentId)) { if (!operationManager.isOperationValid(operationId, documentId)) {
@@ -296,7 +213,6 @@ export const useEditorStore = defineStore('editor', () => {
contentChangeExtension, contentChangeExtension,
codeBlockExtension, codeBlockExtension,
...dynamicExtensions, ...dynamicExtensions,
...httpExtension,
]; ];
// 创建编辑器状态 // 创建编辑器状态
@@ -320,7 +236,6 @@ export const useEditorStore = defineStore('editor', () => {
lastModified: new Date(), lastModified: new Date(),
autoSaveTimer: createTimerManager(), autoSaveTimer: createTimerManager(),
syntaxTreeCache: null, syntaxTreeCache: null,
// 修复:创建实例时从 documentStore 读取持久化的编辑器状态
editorState: documentStore.documentStates[documentId] editorState: documentStore.documentStates[documentId]
}; };
@@ -401,9 +316,6 @@ export const useEditorStore = defineStore('editor', () => {
//使用 nextTick + requestAnimationFrame 确保 DOM 完全渲染 //使用 nextTick + requestAnimationFrame 确保 DOM 完全渲染
nextTick(() => { nextTick(() => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
// 恢复编辑器状态(光标位置和滚动位置)
restoreEditorState(instance, documentId);
// 聚焦编辑器 // 聚焦编辑器
instance.view.focus(); instance.view.focus();
@@ -433,7 +345,6 @@ export const useEditorStore = defineStore('editor', () => {
instance.isDirty = false; instance.isDirty = false;
instance.lastModified = new Date(); instance.lastModified = new Date();
} }
// 如果内容在保存期间被修改了,保持 isDirty 状态
return true; return true;
} catch (error) { } catch (error) {
@@ -462,15 +373,14 @@ export const useEditorStore = defineStore('editor', () => {
}, getAutoSaveDelay()); }, getAutoSaveDelay());
}; };
// === 公共API ===
// 设置编辑器容器 // 设置编辑器容器
const setEditorContainer = (container: HTMLElement | null) => { const setEditorContainer = (container: HTMLElement | null) => {
containerElement.value = container; containerElement.value = container;
// 如果设置容器时已有当前文档,立即加载编辑器 // 如果设置容器时已有当前文档,立即加载编辑器
if (container && documentStore.currentDocument) { if (container && documentStore.currentDocument && documentStore.currentDocument.id !== undefined) {
loadEditor(documentStore.currentDocument.id, documentStore.currentDocument.content); loadEditor(documentStore.currentDocument.id, documentStore.currentDocument.content || '');
} }
}; };
@@ -696,20 +606,20 @@ export const useEditorStore = defineStore('editor', () => {
}; };
// 更新扩展 // 更新扩展
const updateExtension = async (id: ExtensionID, enabled: boolean, config?: any) => { const updateExtension = async (key: string, enabled: boolean, config?: any) => {
// 如果只是更新启用状态 // 更新启用状态
if (config === undefined) { await ExtensionService.UpdateExtensionEnabled(key, enabled);
await ExtensionService.UpdateExtensionEnabled(id, enabled);
} else { // 如果需要更新配置
// 如果需要更新配置 if (config !== undefined) {
await ExtensionService.UpdateExtensionState(id, enabled, config); await ExtensionService.UpdateExtensionConfig(key, config);
} }
// 更新前端编辑器扩展 - 应用于所有实例 // 更新前端编辑器扩展 - 应用于所有实例
const manager = getExtensionManager(); const manager = getExtensionManager();
if (manager) { if (manager) {
// 直接更新前端扩展至所有视图 // 直接更新前端扩展至所有视图
manager.updateExtension(id, enabled, config); manager.updateExtension(key, enabled, config);
} }
// 重新加载扩展配置 // 重新加载扩展配置
@@ -723,23 +633,10 @@ export const useEditorStore = defineStore('editor', () => {
// 监听文档切换 // 监听文档切换
watch(() => documentStore.currentDocument, async (newDoc, oldDoc) => { watch(() => documentStore.currentDocument, async (newDoc, oldDoc) => {
if (newDoc && containerElement.value) { if (newDoc && newDoc.id !== undefined && containerElement.value) {
// 修复:在切换到新文档前,只保存旧文档的光标位置
if (oldDoc && oldDoc.id !== newDoc.id && currentEditor.value) {
const oldInstance = editorCache.get(oldDoc.id);
if (oldInstance) {
const currentState: EditorViewState = {
cursorPos: currentEditor.value.state.selection.main.head
};
// 同时保存到实例和 documentStore
oldInstance.editorState = currentState;
documentStore.documentStates[oldDoc.id] = currentState;
}
}
// 等待 DOM 更新完成,再加载新文档的编辑器 // 等待 DOM 更新完成,再加载新文档的编辑器
await nextTick(); await nextTick();
loadEditor(newDoc.id, newDoc.content); loadEditor(newDoc.id, newDoc.content || '');
} }
}); });

View File

@@ -1,6 +1,6 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { Extension, ExtensionID } from '@/../bindings/voidraft/internal/models/models'; import { Extension } from '@/../bindings/voidraft/internal/models/ent/models';
import { ExtensionService } from '@/../bindings/voidraft/internal/services'; import { ExtensionService } from '@/../bindings/voidraft/internal/services';
export const useExtensionStore = defineStore('extension', () => { export const useExtensionStore = defineStore('extension', () => {
@@ -12,9 +12,9 @@ export const useExtensionStore = defineStore('extension', () => {
extensions.value.filter(ext => ext.enabled) extensions.value.filter(ext => ext.enabled)
); );
// 获取启用的扩展ID列表 // 获取启用的扩展ID列表 (key)
const enabledExtensionIds = computed(() => const enabledExtensionIds = computed(() =>
enabledExtensions.value.map(ext => ext.id) enabledExtensions.value.map(ext => ext.key).filter((k): k is string => k !== undefined)
); );
/** /**
@@ -22,7 +22,8 @@ export const useExtensionStore = defineStore('extension', () => {
*/ */
const loadExtensions = async (): Promise<void> => { const loadExtensions = async (): Promise<void> => {
try { try {
extensions.value = await ExtensionService.GetAllExtensions(); const result = await ExtensionService.GetAllExtensions();
extensions.value = result.filter((ext): ext is Extension => ext !== null);
} catch (err) { } catch (err) {
console.error('[ExtensionStore] Failed to load extensions:', err); console.error('[ExtensionStore] Failed to load extensions:', err);
} }
@@ -31,8 +32,8 @@ export const useExtensionStore = defineStore('extension', () => {
/** /**
* 获取扩展配置 * 获取扩展配置
*/ */
const getExtensionConfig = (id: ExtensionID): any => { const getExtensionConfig = (key: string): any => {
const extension = extensions.value.find(ext => ext.id === id); const extension = extensions.value.find(ext => ext.key === key);
return extension?.config ?? {}; return extension?.config ?? {};
}; };

View File

@@ -1,6 +1,6 @@
import {defineStore} from 'pinia'; import {defineStore} from 'pinia';
import {computed, ref} from 'vue'; import {computed, ref} from 'vue';
import {ExtensionID, KeyBinding, KeyBindingCommand} from '@/../bindings/voidraft/internal/models/models'; import {KeyBinding} from '@/../bindings/voidraft/internal/models/ent/models';
import {GetAllKeyBindings} from '@/../bindings/voidraft/internal/services/keybindingservice'; import {GetAllKeyBindings} from '@/../bindings/voidraft/internal/services/keybindingservice';
export const useKeybindingStore = defineStore('keybinding', () => { export const useKeybindingStore = defineStore('keybinding', () => {
@@ -14,13 +14,14 @@ export const useKeybindingStore = defineStore('keybinding', () => {
// 按扩展分组的快捷键 // 按扩展分组的快捷键
const keyBindingsByExtension = computed(() => { const keyBindingsByExtension = computed(() => {
const groups = new Map<ExtensionID, KeyBinding[]>(); const groups = new Map<string, KeyBinding[]>();
for (const binding of keyBindings.value) { for (const binding of keyBindings.value) {
if (!groups.has(binding.extension)) { const ext = binding.extension || '';
groups.set(binding.extension, []); if (!groups.has(ext)) {
groups.set(ext, []);
} }
groups.get(binding.extension)!.push(binding); groups.get(ext)!.push(binding);
} }
return groups; return groups;
@@ -28,13 +29,13 @@ export const useKeybindingStore = defineStore('keybinding', () => {
// 获取指定扩展的快捷键 // 获取指定扩展的快捷键
const getKeyBindingsByExtension = computed(() => const getKeyBindingsByExtension = computed(() =>
(extension: ExtensionID) => (extension: string) =>
keyBindings.value.filter(kb => kb.extension === extension) keyBindings.value.filter(kb => kb.extension === extension)
); );
// 按命令获取快捷键 // 按命令获取快捷键
const getKeyBindingByCommand = computed(() => const getKeyBindingByCommand = computed(() =>
(command: KeyBindingCommand) => (command: string) =>
keyBindings.value.find(kb => kb.command === command) keyBindings.value.find(kb => kb.command === command)
); );
@@ -42,13 +43,14 @@ export const useKeybindingStore = defineStore('keybinding', () => {
* 从后端加载快捷键配置 * 从后端加载快捷键配置
*/ */
const loadKeyBindings = async (): Promise<void> => { const loadKeyBindings = async (): Promise<void> => {
keyBindings.value = await GetAllKeyBindings(); const result = await GetAllKeyBindings();
keyBindings.value = result.filter((kb): kb is KeyBinding => kb !== null);
}; };
/** /**
* 检查是否存在指定命令的快捷键 * 检查是否存在指定命令的快捷键
*/ */
const hasCommand = (command: KeyBindingCommand): boolean => { const hasCommand = (command: string): boolean => {
return keyBindings.value.some(kb => kb.command === command && kb.enabled); return keyBindings.value.some(kb => kb.command === command && kb.enabled);
}; };
@@ -57,9 +59,11 @@ export const useKeybindingStore = defineStore('keybinding', () => {
* 获取扩展相关的所有扩展ID * 获取扩展相关的所有扩展ID
*/ */
const getAllExtensionIds = computed(() => { const getAllExtensionIds = computed(() => {
const extensionIds = new Set<ExtensionID>(); const extensionIds = new Set<string>();
for (const binding of keyBindings.value) { for (const binding of keyBindings.value) {
extensionIds.add(binding.extension); if (binding.extension) {
extensionIds.add(binding.extension);
}
} }
return Array.from(extensionIds); return Array.from(extensionIds);
}); });

View File

@@ -38,7 +38,7 @@ export const useSystemStore = defineStore('system', () => {
}); });
// 初始化系统信息 // 初始化系统信息
const initializeSystemInfo = async (): Promise<void> => { const initSystemInfo = async (): Promise<void> => {
if (isLoading.value) return; if (isLoading.value) return;
isLoading.value = true; isLoading.value = true;
@@ -102,7 +102,7 @@ export const useSystemStore = defineStore('system', () => {
titleBarHeight, titleBarHeight,
// 方法 // 方法
initializeSystemInfo, initSystemInfo,
setWindowOnTop, setWindowOnTop,
toggleWindowOnTop, toggleWindowOnTop,
resetWindowOnTop, resetWindowOnTop,

View File

@@ -2,7 +2,7 @@ import {defineStore} from 'pinia';
import {computed, readonly, ref} from 'vue'; import {computed, readonly, ref} from 'vue';
import {useConfigStore} from './configStore'; import {useConfigStore} from './configStore';
import {useDocumentStore} from './documentStore'; import {useDocumentStore} from './documentStore';
import type {Document} from '@/../bindings/voidraft/internal/models/models'; import type {Document} from '@/../bindings/voidraft/internal/models/ent/models';
export interface Tab { export interface Tab {
documentId: number; // 直接使用文档ID作为唯一标识 documentId: number; // 直接使用文档ID作为唯一标识
@@ -55,6 +55,7 @@ export const useTabStore = defineStore('tab', () => {
*/ */
const addOrActivateTab = (document: Document) => { const addOrActivateTab = (document: Document) => {
const documentId = document.id; const documentId = document.id;
if (documentId === undefined) return;
if (hasTab(documentId)) { if (hasTab(documentId)) {
// 标签页已存在,无需重复添加 // 标签页已存在,无需重复添加
@@ -64,7 +65,7 @@ export const useTabStore = defineStore('tab', () => {
// 创建新标签页 // 创建新标签页
const newTab: Tab = { const newTab: Tab = {
documentId, documentId,
title: document.title title: document.title || ''
}; };
tabsMap.value[documentId] = newTab; tabsMap.value[documentId] = newTab;

View File

@@ -1,159 +1,161 @@
import { defineStore } from 'pinia'; import {defineStore} from 'pinia';
import { computed, ref } from 'vue'; import {computed, ref} from 'vue';
import { SystemThemeType, ThemeType, ThemeColorConfig } from '@/../bindings/voidraft/internal/models/models'; import {SystemThemeType} from '@/../bindings/voidraft/internal/models/models';
import { ThemeService } from '@/../bindings/voidraft/internal/services'; import {Type as ThemeType} from '@/../bindings/voidraft/internal/models/ent/theme/models';
import { useConfigStore } from './configStore'; import {ThemeService} from '@/../bindings/voidraft/internal/services';
import { useEditorStore } from './editorStore'; import {useConfigStore} from './configStore';
import type { ThemeColors } from '@/views/editor/theme/types'; import {useEditorStore} from './editorStore';
import { cloneThemeColors, FALLBACK_THEME_NAME, themePresetList, themePresetMap } from '@/views/editor/theme/presets'; import type {ThemeColors} from '@/views/editor/theme/types';
import {cloneThemeColors, FALLBACK_THEME_NAME, themePresetList, themePresetMap} from '@/views/editor/theme/presets';
type ThemeColorConfig = { [_: string]: any };
type ThemeOption = { name: string; type: ThemeType }; type ThemeOption = { name: string; type: ThemeType };
const resolveThemeName = (name?: string) => const resolveThemeName = (name?: string) =>
name && themePresetMap[name] ? name : FALLBACK_THEME_NAME; name && themePresetMap[name] ? name : FALLBACK_THEME_NAME;
const createThemeOptions = (type: ThemeType): ThemeOption[] => const createThemeOptions = (type: ThemeType): ThemeOption[] =>
themePresetList themePresetList
.filter(preset => preset.type === type) .filter(preset => preset.type === type)
.map(preset => ({ name: preset.name, type: preset.type })); .map(preset => ({name: preset.name, type: preset.type}));
const darkThemeOptions = createThemeOptions(ThemeType.ThemeTypeDark); const darkThemeOptions = createThemeOptions(ThemeType.TypeDark);
const lightThemeOptions = createThemeOptions(ThemeType.ThemeTypeLight); const lightThemeOptions = createThemeOptions(ThemeType.TypeLight);
const cloneColors = (colors: ThemeColorConfig): ThemeColors => const cloneColors = (colors: ThemeColorConfig): ThemeColors =>
JSON.parse(JSON.stringify(colors)) as ThemeColors; JSON.parse(JSON.stringify(colors)) as ThemeColors;
const getPresetColors = (name: string): ThemeColors => { const getPresetColors = (name: string): ThemeColors => {
const preset = themePresetMap[name] ?? themePresetMap[FALLBACK_THEME_NAME]; const preset = themePresetMap[name] ?? themePresetMap[FALLBACK_THEME_NAME];
const colors = cloneThemeColors(preset.colors); const colors = cloneThemeColors(preset.colors);
colors.themeName = name; colors.themeName = name;
return colors; return colors;
}; };
const fetchThemeColors = async (themeName: string): Promise<ThemeColors> => { const fetchThemeColors = async (themeName: string): Promise<ThemeColors> => {
const safeName = resolveThemeName(themeName); const safeName = resolveThemeName(themeName);
try { try {
const theme = await ThemeService.GetThemeByName(safeName); const theme = await ThemeService.GetThemeByKey(safeName);
if (theme?.colors) { if (theme?.colors) {
const colors = cloneColors(theme.colors); const colors = cloneColors(theme.colors);
colors.themeName = safeName; colors.themeName = safeName;
return colors; return colors;
}
} catch (error) {
console.error('Failed to load theme override:', error);
} }
} catch (error) { return getPresetColors(safeName);
console.error('Failed to load theme override:', error);
}
return getPresetColors(safeName);
}; };
export const useThemeStore = defineStore('theme', () => { export const useThemeStore = defineStore('theme', () => {
const configStore = useConfigStore(); const configStore = useConfigStore();
const currentColors = ref<ThemeColors | null>(null); const currentColors = ref<ThemeColors | null>(null);
const currentTheme = computed( const currentTheme = computed(
() => configStore.config?.appearance?.systemTheme || SystemThemeType.SystemThemeAuto () => configStore.config?.appearance?.systemTheme || SystemThemeType.SystemThemeAuto
);
const isDarkMode = computed(
() =>
currentTheme.value === SystemThemeType.SystemThemeDark ||
(currentTheme.value === SystemThemeType.SystemThemeAuto &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
);
const availableThemes = computed<ThemeOption[]>(() =>
isDarkMode.value ? darkThemeOptions : lightThemeOptions
);
const applyThemeToDOM = (theme: SystemThemeType) => {
const themeMap = {
[SystemThemeType.SystemThemeAuto]: 'auto',
[SystemThemeType.SystemThemeDark]: 'dark',
[SystemThemeType.SystemThemeLight]: 'light',
};
document.documentElement.setAttribute('data-theme', themeMap[theme]);
};
const loadThemeColors = async (themeName?: string) => {
const targetName = resolveThemeName(
themeName || configStore.config?.appearance?.currentTheme
); );
currentColors.value = await fetchThemeColors(targetName);
};
const initializeTheme = async () => { const isDarkMode = computed(
applyThemeToDOM(currentTheme.value); () =>
await loadThemeColors(); currentTheme.value === SystemThemeType.SystemThemeDark ||
}; (currentTheme.value === SystemThemeType.SystemThemeAuto &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
);
const setTheme = async (theme: SystemThemeType) => { const availableThemes = computed<ThemeOption[]>(() =>
await configStore.setSystemTheme(theme); isDarkMode.value ? darkThemeOptions : lightThemeOptions
applyThemeToDOM(theme); );
refreshEditorTheme();
};
const switchToTheme = async (themeName: string) => { const applyThemeToDOM = (theme: SystemThemeType) => {
if (!themePresetMap[themeName]) { const themeMap = {
console.error('Theme not found:', themeName); [SystemThemeType.SystemThemeAuto]: 'auto',
return false; [SystemThemeType.SystemThemeDark]: 'dark',
} [SystemThemeType.SystemThemeLight]: 'light',
};
document.documentElement.setAttribute('data-theme', themeMap[theme]);
};
await loadThemeColors(themeName); const loadThemeColors = async (themeName?: string) => {
await configStore.setCurrentTheme(themeName); const targetName = resolveThemeName(
refreshEditorTheme(); themeName || configStore.config?.appearance?.currentTheme
return true; );
}; currentColors.value = await fetchThemeColors(targetName);
};
const updateCurrentColors = (colors: Partial<ThemeColors>) => { const initTheme = async () => {
if (!currentColors.value) return; applyThemeToDOM(currentTheme.value);
Object.assign(currentColors.value, colors); await loadThemeColors();
}; };
const saveCurrentTheme = async () => { const setTheme = async (theme: SystemThemeType) => {
if (!currentColors.value) { await configStore.setSystemTheme(theme);
throw new Error('No theme selected'); applyThemeToDOM(theme);
} refreshEditorTheme();
};
const themeName = resolveThemeName(currentColors.value.themeName); const switchToTheme = async (themeName: string) => {
currentColors.value.themeName = themeName; if (!themePresetMap[themeName]) {
console.error('Theme not found:', themeName);
return false;
}
await ThemeService.UpdateTheme(themeName, currentColors.value as unknown as ThemeColorConfig); await loadThemeColors(themeName);
await configStore.setCurrentTheme(themeName);
refreshEditorTheme();
return true;
};
await loadThemeColors(themeName); const updateCurrentColors = (colors: Partial<ThemeColors>) => {
refreshEditorTheme(); if (!currentColors.value) return;
return true; Object.assign(currentColors.value, colors);
}; };
const resetCurrentTheme = async () => { const saveCurrentTheme = async () => {
if (!currentColors.value) { if (!currentColors.value) {
throw new Error('No theme selected'); throw new Error('No theme selected');
} }
const themeName = resolveThemeName(currentColors.value.themeName); const themeName = resolveThemeName(currentColors.value.themeName);
await ThemeService.ResetTheme(themeName); currentColors.value.themeName = themeName;
await loadThemeColors(themeName); await ThemeService.UpdateTheme(themeName, currentColors.value as ThemeColorConfig);
refreshEditorTheme();
return true;
};
const refreshEditorTheme = () => { await loadThemeColors(themeName);
applyThemeToDOM(currentTheme.value); refreshEditorTheme();
const editorStore = useEditorStore(); return true;
editorStore?.applyThemeSettings(); };
};
return { const resetCurrentTheme = async () => {
availableThemes, if (!currentColors.value) {
currentTheme, throw new Error('No theme selected');
currentColors, }
isDarkMode,
setTheme, const themeName = resolveThemeName(currentColors.value.themeName);
switchToTheme, await ThemeService.ResetTheme(themeName);
initializeTheme,
updateCurrentColors, await loadThemeColors(themeName);
saveCurrentTheme, refreshEditorTheme();
resetCurrentTheme, return true;
refreshEditorTheme, };
applyThemeToDOM,
}; const refreshEditorTheme = () => {
applyThemeToDOM(currentTheme.value);
const editorStore = useEditorStore();
editorStore?.applyThemeSettings();
};
return {
availableThemes,
currentTheme,
currentColors,
isDarkMode,
setTheme,
switchToTheme,
initTheme,
updateCurrentColors,
saveCurrentTheme,
resetCurrentTheme,
refreshEditorTheme,
applyThemeToDOM,
};
}); });

View File

@@ -1,7 +1,7 @@
import { EditorView } from '@codemirror/view'; import { EditorView } from '@codemirror/view';
import { Extension } from '@codemirror/state'; import { Extension } from '@codemirror/state';
import { copyCommand, cutCommand, pasteCommand } from '../codeblock/copyPaste'; import { copyCommand, cutCommand, pasteCommand } from '../codeblock/copyPaste';
import { KeyBindingCommand } from '../../../../../bindings/voidraft/internal/models/models'; import { KeyBindingKey } from '@/../bindings/voidraft/internal/models/models';
import { useKeybindingStore } from '@/stores/keybindingStore'; import { useKeybindingStore } from '@/stores/keybindingStore';
import { undo, redo } from '@codemirror/commands'; import { undo, redo } from '@codemirror/commands';
import i18n from '@/i18n'; import i18n from '@/i18n';
@@ -32,53 +32,54 @@ function formatKeyBinding(keyBinding: string): string {
.replace(/-/g, " + "); .replace(/-/g, " + ");
} }
const shortcutCache = new Map<KeyBindingCommand, string>(); const shortcutCache = new Map<KeyBindingKey, string>();
function getShortcutText(command?: KeyBindingCommand): string { function getShortcutText(keyBindingKey?: KeyBindingKey): string {
if (command === undefined) { if (keyBindingKey === undefined) {
return ""; return "";
} }
const cached = shortcutCache.get(command); const cached = shortcutCache.get(keyBindingKey);
if (cached !== undefined) { if (cached !== undefined) {
return cached; return cached;
} }
try { try {
const keybindingStore = useKeybindingStore(); const keybindingStore = useKeybindingStore();
// binding.key 是命令标识符binding.command 是快捷键组合
const binding = keybindingStore.keyBindings.find( const binding = keybindingStore.keyBindings.find(
(kb) => kb.command === command && kb.enabled (kb) => kb.key === keyBindingKey && kb.enabled
); );
if (binding?.key) { if (binding?.command) {
const formatted = formatKeyBinding(binding.key); const formatted = formatKeyBinding(binding.command);
shortcutCache.set(command, formatted); shortcutCache.set(keyBindingKey, formatted);
return formatted; return formatted;
} }
} catch (error) { } catch (error) {
console.warn("An error occurred while getting the shortcut:", error); console.warn("An error occurred while getting the shortcut:", error);
} }
shortcutCache.set(command, ""); shortcutCache.set(keyBindingKey, "");
return ""; return "";
} }
function getBuiltinMenuNodes(): MenuSchemaNode[] { function builtinMenuNodes(): MenuSchemaNode[] {
return [ return [
{ {
id: "copy", id: "copy",
labelKey: "keybindings.commands.blockCopy", labelKey: "keybindings.commands.blockCopy",
command: copyCommand, command: copyCommand,
shortcutCommand: KeyBindingCommand.BlockCopyCommand, keyBindingKey: KeyBindingKey.BlockCopyKeyBindingKey,
enabled: (context) => context.hasSelection enabled: (context) => context.hasSelection
}, },
{ {
id: "cut", id: "cut",
labelKey: "keybindings.commands.blockCut", labelKey: "keybindings.commands.blockCut",
command: cutCommand, command: cutCommand,
shortcutCommand: KeyBindingCommand.BlockCutCommand, keyBindingKey: KeyBindingKey.BlockCutKeyBindingKey,
visible: (context) => context.isEditable, visible: (context) => context.isEditable,
enabled: (context) => context.hasSelection && context.isEditable enabled: (context) => context.hasSelection && context.isEditable
}, },
@@ -86,21 +87,21 @@ function getBuiltinMenuNodes(): MenuSchemaNode[] {
id: "paste", id: "paste",
labelKey: "keybindings.commands.blockPaste", labelKey: "keybindings.commands.blockPaste",
command: pasteCommand, command: pasteCommand,
shortcutCommand: KeyBindingCommand.BlockPasteCommand, keyBindingKey: KeyBindingKey.BlockPasteKeyBindingKey,
visible: (context) => context.isEditable visible: (context) => context.isEditable
}, },
{ {
id: "undo", id: "undo",
labelKey: "keybindings.commands.historyUndo", labelKey: "keybindings.commands.historyUndo",
command: undo, command: undo,
shortcutCommand: KeyBindingCommand.HistoryUndoCommand, keyBindingKey: KeyBindingKey.HistoryUndoKeyBindingKey,
visible: (context) => context.isEditable visible: (context) => context.isEditable
}, },
{ {
id: "redo", id: "redo",
labelKey: "keybindings.commands.historyRedo", labelKey: "keybindings.commands.historyRedo",
command: redo, command: redo,
shortcutCommand: KeyBindingCommand.HistoryRedoCommand, keyBindingKey: KeyBindingKey.HistoryRedoKeyBindingKey,
visible: (context) => context.isEditable visible: (context) => context.isEditable
} }
]; ];
@@ -110,7 +111,7 @@ let builtinMenuRegistered = false;
function ensureBuiltinMenuRegistered(): void { function ensureBuiltinMenuRegistered(): void {
if (builtinMenuRegistered) return; if (builtinMenuRegistered) return;
registerMenuNodes(getBuiltinMenuNodes()); registerMenuNodes(builtinMenuNodes());
builtinMenuRegistered = true; builtinMenuRegistered = true;
} }

View File

@@ -1,6 +1,6 @@
import type { EditorView } from '@codemirror/view'; import type { EditorView } from '@codemirror/view';
import { EditorState } from '@codemirror/state'; import { EditorState } from '@codemirror/state';
import type { KeyBindingCommand } from '../../../../../bindings/voidraft/internal/models/models'; import { KeyBindingKey } from '@/../bindings/voidraft/internal/models/models';
export interface MenuContext { export interface MenuContext {
view: EditorView; view: EditorView;
@@ -16,7 +16,7 @@ export type MenuSchemaNode =
type?: "action"; type?: "action";
labelKey: string; labelKey: string;
command?: (view: EditorView) => boolean; command?: (view: EditorView) => boolean;
shortcutCommand?: KeyBindingCommand; keyBindingKey?: KeyBindingKey;
visible?: (context: MenuContext) => boolean; visible?: (context: MenuContext) => boolean;
enabled?: (context: MenuContext) => boolean; enabled?: (context: MenuContext) => boolean;
} }
@@ -37,7 +37,7 @@ export interface RenderMenuItem {
interface MenuBuildOptions { interface MenuBuildOptions {
translate: (key: string) => string; translate: (key: string) => string;
formatShortcut: (command?: KeyBindingCommand) => string; formatShortcut: (keyBindingKey?: KeyBindingKey) => string;
} }
const menuRegistry: MenuSchemaNode[] = []; const menuRegistry: MenuSchemaNode[] = [];
@@ -89,7 +89,7 @@ function convertNode(
} }
const disabled = node.enabled ? !node.enabled(context) : false; const disabled = node.enabled ? !node.enabled(context) : false;
const shortcut = options.formatShortcut(node.shortcutCommand); const shortcut = options.formatShortcut(node.keyBindingKey);
return { return {
id: node.id, id: node.id,

View File

@@ -1,7 +1,11 @@
import { Extension, StateField } from '@codemirror/state'; import { Extension, StateField } from '@codemirror/state';
import { EditorView, showTooltip, Tooltip } from '@codemirror/view'; import { EditorView, showTooltip, Tooltip } from '@codemirror/view';
import { translatorManager } from './manager'; import { translatorManager } from './manager';
import { TRANSLATION_ICON_SVG } from '@/common/constant/translation';
const TRANSLATION_ICON_SVG = `
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path d="M599.68 485.056h-8l30.592 164.672c20.352-7.04 38.72-17.344 54.912-31.104a271.36 271.36 0 0 1-40.704-64.64l32.256-4.032c8.896 17.664 19.072 33.28 30.592 46.72 23.872-27.968 42.24-65.152 55.04-111.744l-154.688 0.128z m121.92 133.76c18.368 15.36 39.36 26.56 62.848 33.472l14.784 4.416-8.64 30.336-14.72-4.352a205.696 205.696 0 0 1-76.48-41.728c-20.672 17.92-44.928 31.552-71.232 40.064l20.736 110.912H519.424l-9.984 72.512h385.152c18.112 0 32.704-14.144 32.704-31.616V295.424a32.128 32.128 0 0 0-32.704-31.552H550.528l35.2 189.696h79.424v-31.552h61.44v31.552h102.4v31.616h-42.688c-14.272 55.488-35.712 100.096-64.64 133.568zM479.36 791.68H193.472c-36.224 0-65.472-28.288-65.472-63.168V191.168C128 156.16 157.312 128 193.472 128h327.68l20.544 104.32h352.832c36.224 0 65.472 28.224 65.472 63.104v537.408c0 34.944-29.312 63.168-65.472 63.168H468.608l10.688-104.32zM337.472 548.352v-33.28H272.768v-48.896h60.16V433.28h-60.16v-41.728h64.704v-32.896h-102.4v189.632h102.4z m158.272 0V453.76c0-17.216-4.032-30.272-12.16-39.488-8.192-9.152-20.288-13.696-36.032-13.696a55.04 55.04 0 0 0-24.768 5.376 39.04 39.04 0 0 0-17.088 15.936h-1.984l-5.056-18.56h-28.352V548.48h37.12V480c0-17.088 2.304-29.376 6.912-36.736 4.608-7.424 12.16-11.072 22.528-11.072 7.616 0 13.248 2.56 16.64 7.872 3.52 5.248 5.312 13.056 5.312 23.488v84.736h36.928z" fill="currentColor"></path>
</svg>`;
function TranslationTooltips(state: any): readonly Tooltip[] { function TranslationTooltips(state: any): readonly Tooltip[] {
const selection = state.selection.main; const selection = state.selection.main;

View File

@@ -1,8 +1,4 @@
import {KeyBindingCommand} from '@/../bindings/voidraft/internal/models/models'; import {closeSearchPanel, openSearchPanel,} from '@codemirror/search';
import {
openSearchPanel,
closeSearchPanel,
} from '@codemirror/search';
import { import {
addNewBlockAfterCurrent, addNewBlockAfterCurrent,
addNewBlockAfterLast, addNewBlockAfterLast,
@@ -49,249 +45,249 @@ import {
} from '@codemirror/commands'; } from '@codemirror/commands';
import {foldAll, foldCode, unfoldAll, unfoldCode} from '@codemirror/language'; import {foldAll, foldCode, unfoldAll, unfoldCode} from '@codemirror/language';
import i18n from '@/i18n'; import i18n from '@/i18n';
import {KeyBindingKey} from '@/../bindings/voidraft/internal/models/models';
// 默认编辑器选项 // 默认代码块扩展选项
const defaultEditorOptions = { const defaultBlockExtensionOptions = {
defaultBlockToken: 'text', defaultBlockToken: 'text',
defaultBlockAutoDetect: true, defaultBlockAutoDetect: true,
}; };
/** /**
* 前端命令注册表 * 前端命令注册表
* 将后端定义的command字段映射到具体的前端方法和翻译键 * 将后端定义的key字段映射到具体的前端方法和翻译键
*/ */
export const commands = { export const commands: Record<string, { handler: any; descriptionKey: string }> = {
[KeyBindingCommand.ShowSearchCommand]: { [KeyBindingKey.ShowSearchKeyBindingKey]: {
handler: openSearchPanel, handler: openSearchPanel,
descriptionKey: 'keybindings.commands.showSearch' descriptionKey: 'keybindings.commands.showSearch'
}, },
[KeyBindingCommand.HideSearchCommand]: { [KeyBindingKey.HideSearchKeyBindingKey]: {
handler: closeSearchPanel, handler: closeSearchPanel,
descriptionKey: 'keybindings.commands.hideSearch' descriptionKey: 'keybindings.commands.hideSearch'
}, },
// 代码块操作命令 [KeyBindingKey.BlockSelectAllKeyBindingKey]: {
[KeyBindingCommand.BlockSelectAllCommand]: {
handler: selectAll, handler: selectAll,
descriptionKey: 'keybindings.commands.blockSelectAll' descriptionKey: 'keybindings.commands.blockSelectAll'
}, },
[KeyBindingCommand.BlockAddAfterCurrentCommand]: { [KeyBindingKey.BlockAddAfterCurrentKeyBindingKey]: {
handler: addNewBlockAfterCurrent(defaultEditorOptions), handler: addNewBlockAfterCurrent(defaultBlockExtensionOptions),
descriptionKey: 'keybindings.commands.blockAddAfterCurrent' descriptionKey: 'keybindings.commands.blockAddAfterCurrent'
}, },
[KeyBindingCommand.BlockAddAfterLastCommand]: { [KeyBindingKey.BlockAddAfterLastKeyBindingKey]: {
handler: addNewBlockAfterLast(defaultEditorOptions), handler: addNewBlockAfterLast(defaultBlockExtensionOptions),
descriptionKey: 'keybindings.commands.blockAddAfterLast' descriptionKey: 'keybindings.commands.blockAddAfterLast'
}, },
[KeyBindingCommand.BlockAddBeforeCurrentCommand]: { [KeyBindingKey.BlockAddBeforeCurrentKeyBindingKey]: {
handler: addNewBlockBeforeCurrent(defaultEditorOptions), handler: addNewBlockBeforeCurrent(defaultBlockExtensionOptions),
descriptionKey: 'keybindings.commands.blockAddBeforeCurrent' descriptionKey: 'keybindings.commands.blockAddBeforeCurrent'
}, },
[KeyBindingCommand.BlockGotoPreviousCommand]: { [KeyBindingKey.BlockGotoPreviousKeyBindingKey]: {
handler: gotoPreviousBlock, handler: gotoPreviousBlock,
descriptionKey: 'keybindings.commands.blockGotoPrevious' descriptionKey: 'keybindings.commands.blockGotoPrevious'
}, },
[KeyBindingCommand.BlockGotoNextCommand]: { [KeyBindingKey.BlockGotoNextKeyBindingKey]: {
handler: gotoNextBlock, handler: gotoNextBlock,
descriptionKey: 'keybindings.commands.blockGotoNext' descriptionKey: 'keybindings.commands.blockGotoNext'
}, },
[KeyBindingCommand.BlockSelectPreviousCommand]: { [KeyBindingKey.BlockSelectPreviousKeyBindingKey]: {
handler: selectPreviousBlock, handler: selectPreviousBlock,
descriptionKey: 'keybindings.commands.blockSelectPrevious' descriptionKey: 'keybindings.commands.blockSelectPrevious'
}, },
[KeyBindingCommand.BlockSelectNextCommand]: { [KeyBindingKey.BlockSelectNextKeyBindingKey]: {
handler: selectNextBlock, handler: selectNextBlock,
descriptionKey: 'keybindings.commands.blockSelectNext' descriptionKey: 'keybindings.commands.blockSelectNext'
}, },
[KeyBindingCommand.BlockDeleteCommand]: { [KeyBindingKey.BlockDeleteKeyBindingKey]: {
handler: deleteBlock(defaultEditorOptions), handler: deleteBlock(defaultBlockExtensionOptions),
descriptionKey: 'keybindings.commands.blockDelete' descriptionKey: 'keybindings.commands.blockDelete'
}, },
[KeyBindingCommand.BlockMoveUpCommand]: { [KeyBindingKey.BlockMoveUpKeyBindingKey]: {
handler: moveCurrentBlockUp, handler: moveCurrentBlockUp,
descriptionKey: 'keybindings.commands.blockMoveUp' descriptionKey: 'keybindings.commands.blockMoveUp'
}, },
[KeyBindingCommand.BlockMoveDownCommand]: { [KeyBindingKey.BlockMoveDownKeyBindingKey]: {
handler: moveCurrentBlockDown, handler: moveCurrentBlockDown,
descriptionKey: 'keybindings.commands.blockMoveDown' descriptionKey: 'keybindings.commands.blockMoveDown'
}, },
[KeyBindingCommand.BlockDeleteLineCommand]: { [KeyBindingKey.BlockDeleteLineKeyBindingKey]: {
handler: deleteLineCommand, handler: deleteLineCommand,
descriptionKey: 'keybindings.commands.blockDeleteLine' descriptionKey: 'keybindings.commands.blockDeleteLine'
}, },
[KeyBindingCommand.BlockMoveLineUpCommand]: { [KeyBindingKey.BlockMoveLineUpKeyBindingKey]: {
handler: moveLineUp, handler: moveLineUp,
descriptionKey: 'keybindings.commands.blockMoveLineUp' descriptionKey: 'keybindings.commands.blockMoveLineUp'
}, },
[KeyBindingCommand.BlockMoveLineDownCommand]: { [KeyBindingKey.BlockMoveLineDownKeyBindingKey]: {
handler: moveLineDown, handler: moveLineDown,
descriptionKey: 'keybindings.commands.blockMoveLineDown' descriptionKey: 'keybindings.commands.blockMoveLineDown'
}, },
[KeyBindingCommand.BlockTransposeCharsCommand]: { [KeyBindingKey.BlockTransposeCharsKeyBindingKey]: {
handler: transposeChars, handler: transposeChars,
descriptionKey: 'keybindings.commands.blockTransposeChars' descriptionKey: 'keybindings.commands.blockTransposeChars'
}, },
[KeyBindingCommand.BlockFormatCommand]: { [KeyBindingKey.BlockFormatKeyBindingKey]: {
handler: formatCurrentBlock, handler: formatCurrentBlock,
descriptionKey: 'keybindings.commands.blockFormat' descriptionKey: 'keybindings.commands.blockFormat'
}, },
[KeyBindingCommand.BlockCopyCommand]: { [KeyBindingKey.BlockCopyKeyBindingKey]: {
handler: copyCommand, handler: copyCommand,
descriptionKey: 'keybindings.commands.blockCopy' descriptionKey: 'keybindings.commands.blockCopy'
}, },
[KeyBindingCommand.BlockCutCommand]: { [KeyBindingKey.BlockCutKeyBindingKey]: {
handler: cutCommand, handler: cutCommand,
descriptionKey: 'keybindings.commands.blockCut' descriptionKey: 'keybindings.commands.blockCut'
}, },
[KeyBindingCommand.BlockPasteCommand]: { [KeyBindingKey.BlockPasteKeyBindingKey]: {
handler: pasteCommand, handler: pasteCommand,
descriptionKey: 'keybindings.commands.blockPaste' descriptionKey: 'keybindings.commands.blockPaste'
}, },
[KeyBindingCommand.HistoryUndoCommand]: { [KeyBindingKey.HistoryUndoKeyBindingKey]: {
handler: undo, handler: undo,
descriptionKey: 'keybindings.commands.historyUndo' descriptionKey: 'keybindings.commands.historyUndo'
}, },
[KeyBindingCommand.HistoryRedoCommand]: { [KeyBindingKey.HistoryRedoKeyBindingKey]: {
handler: redo, handler: redo,
descriptionKey: 'keybindings.commands.historyRedo' descriptionKey: 'keybindings.commands.historyRedo'
}, },
[KeyBindingCommand.HistoryUndoSelectionCommand]: { [KeyBindingKey.HistoryUndoSelectionKeyBindingKey]: {
handler: undoSelection, handler: undoSelection,
descriptionKey: 'keybindings.commands.historyUndoSelection' descriptionKey: 'keybindings.commands.historyUndoSelection'
}, },
[KeyBindingCommand.HistoryRedoSelectionCommand]: { [KeyBindingKey.HistoryRedoSelectionKeyBindingKey]: {
handler: redoSelection, handler: redoSelection,
descriptionKey: 'keybindings.commands.historyRedoSelection' descriptionKey: 'keybindings.commands.historyRedoSelection'
}, },
[KeyBindingCommand.FoldCodeCommand]: { [KeyBindingKey.FoldCodeKeyBindingKey]: {
handler: foldCode, handler: foldCode,
descriptionKey: 'keybindings.commands.foldCode' descriptionKey: 'keybindings.commands.foldCode'
}, },
[KeyBindingCommand.UnfoldCodeCommand]: { [KeyBindingKey.UnfoldCodeKeyBindingKey]: {
handler: unfoldCode, handler: unfoldCode,
descriptionKey: 'keybindings.commands.unfoldCode' descriptionKey: 'keybindings.commands.unfoldCode'
}, },
[KeyBindingCommand.FoldAllCommand]: { [KeyBindingKey.FoldAllKeyBindingKey]: {
handler: foldAll, handler: foldAll,
descriptionKey: 'keybindings.commands.foldAll' descriptionKey: 'keybindings.commands.foldAll'
}, },
[KeyBindingCommand.UnfoldAllCommand]: { [KeyBindingKey.UnfoldAllKeyBindingKey]: {
handler: unfoldAll, handler: unfoldAll,
descriptionKey: 'keybindings.commands.unfoldAll' descriptionKey: 'keybindings.commands.unfoldAll'
}, },
[KeyBindingCommand.CursorSyntaxLeftCommand]: { [KeyBindingKey.CursorSyntaxLeftKeyBindingKey]: {
handler: cursorSyntaxLeft, handler: cursorSyntaxLeft,
descriptionKey: 'keybindings.commands.cursorSyntaxLeft' descriptionKey: 'keybindings.commands.cursorSyntaxLeft'
}, },
[KeyBindingCommand.CursorSyntaxRightCommand]: { [KeyBindingKey.CursorSyntaxRightKeyBindingKey]: {
handler: cursorSyntaxRight, handler: cursorSyntaxRight,
descriptionKey: 'keybindings.commands.cursorSyntaxRight' descriptionKey: 'keybindings.commands.cursorSyntaxRight'
}, },
[KeyBindingCommand.SelectSyntaxLeftCommand]: { [KeyBindingKey.SelectSyntaxLeftKeyBindingKey]: {
handler: selectSyntaxLeft, handler: selectSyntaxLeft,
descriptionKey: 'keybindings.commands.selectSyntaxLeft' descriptionKey: 'keybindings.commands.selectSyntaxLeft'
}, },
[KeyBindingCommand.SelectSyntaxRightCommand]: { [KeyBindingKey.SelectSyntaxRightKeyBindingKey]: {
handler: selectSyntaxRight, handler: selectSyntaxRight,
descriptionKey: 'keybindings.commands.selectSyntaxRight' descriptionKey: 'keybindings.commands.selectSyntaxRight'
}, },
[KeyBindingCommand.CopyLineUpCommand]: { [KeyBindingKey.CopyLineUpKeyBindingKey]: {
handler: copyLineUp, handler: copyLineUp,
descriptionKey: 'keybindings.commands.copyLineUp' descriptionKey: 'keybindings.commands.copyLineUp'
}, },
[KeyBindingCommand.CopyLineDownCommand]: { [KeyBindingKey.CopyLineDownKeyBindingKey]: {
handler: copyLineDown, handler: copyLineDown,
descriptionKey: 'keybindings.commands.copyLineDown' descriptionKey: 'keybindings.commands.copyLineDown'
}, },
[KeyBindingCommand.InsertBlankLineCommand]: { [KeyBindingKey.InsertBlankLineKeyBindingKey]: {
handler: insertBlankLine, handler: insertBlankLine,
descriptionKey: 'keybindings.commands.insertBlankLine' descriptionKey: 'keybindings.commands.insertBlankLine'
}, },
[KeyBindingCommand.SelectLineCommand]: { [KeyBindingKey.SelectLineKeyBindingKey]: {
handler: selectLine, handler: selectLine,
descriptionKey: 'keybindings.commands.selectLine' descriptionKey: 'keybindings.commands.selectLine'
}, },
[KeyBindingCommand.SelectParentSyntaxCommand]: { [KeyBindingKey.SelectParentSyntaxKeyBindingKey]: {
handler: selectParentSyntax, handler: selectParentSyntax,
descriptionKey: 'keybindings.commands.selectParentSyntax' descriptionKey: 'keybindings.commands.selectParentSyntax'
}, },
[KeyBindingCommand.IndentLessCommand]: { [KeyBindingKey.IndentLessKeyBindingKey]: {
handler: indentLess, handler: indentLess,
descriptionKey: 'keybindings.commands.indentLess' descriptionKey: 'keybindings.commands.indentLess'
}, },
[KeyBindingCommand.IndentMoreCommand]: { [KeyBindingKey.IndentMoreKeyBindingKey]: {
handler: indentMore, handler: indentMore,
descriptionKey: 'keybindings.commands.indentMore' descriptionKey: 'keybindings.commands.indentMore'
}, },
[KeyBindingCommand.IndentSelectionCommand]: { [KeyBindingKey.IndentSelectionKeyBindingKey]: {
handler: indentSelection, handler: indentSelection,
descriptionKey: 'keybindings.commands.indentSelection' descriptionKey: 'keybindings.commands.indentSelection'
}, },
[KeyBindingCommand.CursorMatchingBracketCommand]: { [KeyBindingKey.CursorMatchingBracketKeyBindingKey]: {
handler: cursorMatchingBracket, handler: cursorMatchingBracket,
descriptionKey: 'keybindings.commands.cursorMatchingBracket' descriptionKey: 'keybindings.commands.cursorMatchingBracket'
}, },
[KeyBindingCommand.ToggleCommentCommand]: { [KeyBindingKey.ToggleCommentKeyBindingKey]: {
handler: toggleComment, handler: toggleComment,
descriptionKey: 'keybindings.commands.toggleComment' descriptionKey: 'keybindings.commands.toggleComment'
}, },
[KeyBindingCommand.ToggleBlockCommentCommand]: { [KeyBindingKey.ToggleBlockCommentKeyBindingKey]: {
handler: toggleBlockComment, handler: toggleBlockComment,
descriptionKey: 'keybindings.commands.toggleBlockComment' descriptionKey: 'keybindings.commands.toggleBlockComment'
}, },
[KeyBindingCommand.InsertNewlineAndIndentCommand]: { [KeyBindingKey.InsertNewlineAndIndentKeyBindingKey]: {
handler: insertNewlineAndIndent, handler: insertNewlineAndIndent,
descriptionKey: 'keybindings.commands.insertNewlineAndIndent' descriptionKey: 'keybindings.commands.insertNewlineAndIndent'
}, },
[KeyBindingCommand.DeleteCharBackwardCommand]: { [KeyBindingKey.DeleteCharBackwardKeyBindingKey]: {
handler: deleteCharBackward, handler: deleteCharBackward,
descriptionKey: 'keybindings.commands.deleteCharBackward' descriptionKey: 'keybindings.commands.deleteCharBackward'
}, },
[KeyBindingCommand.DeleteCharForwardCommand]: { [KeyBindingKey.DeleteCharForwardKeyBindingKey]: {
handler: deleteCharForward, handler: deleteCharForward,
descriptionKey: 'keybindings.commands.deleteCharForward' descriptionKey: 'keybindings.commands.deleteCharForward'
}, },
[KeyBindingCommand.DeleteGroupBackwardCommand]: { [KeyBindingKey.DeleteGroupBackwardKeyBindingKey]: {
handler: deleteGroupBackward, handler: deleteGroupBackward,
descriptionKey: 'keybindings.commands.deleteGroupBackward' descriptionKey: 'keybindings.commands.deleteGroupBackward'
}, },
[KeyBindingCommand.DeleteGroupForwardCommand]: { [KeyBindingKey.DeleteGroupForwardKeyBindingKey]: {
handler: deleteGroupForward, handler: deleteGroupForward,
descriptionKey: 'keybindings.commands.deleteGroupForward' descriptionKey: 'keybindings.commands.deleteGroupForward'
}, },
} as const; };
/** /**
* 获取命令处理函数 * 获取命令处理函数
* @param command 命令名称 * @param key 命令标识符
* @returns 对应的处理函数,如果不存在则返回 undefined * @returns 对应的处理函数,如果不存在则返回 undefined
*/ */
export const getCommandHandler = (command: KeyBindingCommand) => { export const getCommandHandler = (key: string) => {
return commands[command]?.handler; return commands[key]?.handler;
}; };
/** /**
* 获取命令描述 * 获取命令描述
* @param command 命令名称 * @param key 命令标识符
* @returns 对应的描述,如果不存在则返回 undefined * @returns 对应的描述,如果不存在则返回 undefined
*/ */
export const getCommandDescription = (command: KeyBindingCommand) => { export const getCommandDescription = (key: string) => {
const descriptionKey = commands[command]?.descriptionKey; const descriptionKey = commands[key]?.descriptionKey;
return descriptionKey ? i18n.global.t(descriptionKey) : undefined; return descriptionKey ? i18n.global.t(descriptionKey) : undefined;
}; };
/** /**
* 检查命令是否已注册 * 检查命令是否已注册
* @param command 命令名称 * @param key 命令标识符
* @returns 是否已注册 * @returns 是否已注册
*/ */
export const isCommandRegistered = (command: KeyBindingCommand): boolean => { export const isCommandRegistered = (key: string): boolean => {
return command in commands; return key in commands;
}; };
/** /**
* 获取所有已注册的命令 * 获取所有已注册的命令
* @returns 已注册的命令列表 * @returns 已注册的命令列表
*/ */
export const getRegisteredCommands = (): KeyBindingCommand[] => { export const getRegisteredCommands = (): string[] => {
return Object.keys(commands) as KeyBindingCommand[]; return Object.keys(commands);
}; };

View File

@@ -20,10 +20,12 @@ export const createDynamicKeymapExtension = async (): Promise<Extension> => {
await extensionStore.loadExtensions(); await extensionStore.loadExtensions();
} }
// 获取启用的扩展ID列表 // 获取启用的扩展key列表
const enabledExtensionIds = extensionStore.enabledExtensions.map(ext => ext.id); const enabledExtensionKeys = extensionStore.enabledExtensions
.map(ext => ext.key)
.filter((key): key is string => key !== undefined);
return Manager.createKeymapExtension(keybindingStore.keyBindings, enabledExtensionIds); return Manager.createKeymapExtension(keybindingStore.keyBindings, enabledExtensionKeys);
}; };
/** /**
@@ -34,10 +36,12 @@ export const updateKeymapExtension = (view: any): void => {
const keybindingStore = useKeybindingStore(); const keybindingStore = useKeybindingStore();
const extensionStore = useExtensionStore(); const extensionStore = useExtensionStore();
// 获取启用的扩展ID列表 // 获取启用的扩展key列表
const enabledExtensionIds = extensionStore.enabledExtensions.map(ext => ext.id); const enabledExtensionKeys = extensionStore.enabledExtensions
.map(ext => ext.key)
.filter((key): key is string => key !== undefined);
Manager.updateKeymap(view, keybindingStore.keyBindings, enabledExtensionIds); Manager.updateKeymap(view, keybindingStore.keyBindings, enabledExtensionKeys);
}; };
// 导出相关模块 // 导出相关模块

View File

@@ -1,6 +1,6 @@
import {keymap} from '@codemirror/view'; import {keymap} from '@codemirror/view';
import {Extension, Compartment} from '@codemirror/state'; import {Extension, Compartment} from '@codemirror/state';
import {KeyBinding as KeyBindingConfig, ExtensionID} from '@/../bindings/voidraft/internal/models/models'; import {KeyBinding as KeyBindingConfig} from '@/../bindings/voidraft/internal/models/ent/models';
import {KeyBinding, KeymapResult} from './types'; import {KeyBinding, KeymapResult} from './types';
import {getCommandHandler, isCommandRegistered} from './commands'; import {getCommandHandler, isCommandRegistered} from './commands';
@@ -14,10 +14,10 @@ export class Manager {
/** /**
* 将后端快捷键配置转换为CodeMirror快捷键绑定 * 将后端快捷键配置转换为CodeMirror快捷键绑定
* @param keyBindings 后端快捷键配置列表 * @param keyBindings 后端快捷键配置列表
* @param enabledExtensions 启用的扩展ID列表,如果不提供则使用所有启用的快捷键 * @param enabledExtensions 启用的扩展key列表,如果不提供则使用所有启用的快捷键
* @returns 转换结果 * @returns 转换结果
*/ */
static convertToKeyBindings(keyBindings: KeyBindingConfig[], enabledExtensions?: ExtensionID[]): KeymapResult { static convertToKeyBindings(keyBindings: KeyBindingConfig[], enabledExtensions?: string[]): KeymapResult {
const result: KeyBinding[] = []; const result: KeyBinding[] = [];
for (const binding of keyBindings) { for (const binding of keyBindings) {
@@ -27,24 +27,25 @@ export class Manager {
} }
// 如果提供了扩展列表,则只处理启用扩展的快捷键 // 如果提供了扩展列表,则只处理启用扩展的快捷键
if (enabledExtensions && !enabledExtensions.includes(binding.extension)) { if (enabledExtensions && binding.extension && !enabledExtensions.includes(binding.extension)) {
continue; continue;
} }
// 检查命令是否已注册 // 检查命令是否已注册(使用 key 字段作为命令标识符)
if (!isCommandRegistered(binding.command)) { if (!binding.key || !isCommandRegistered(binding.key)) {
continue; continue;
} }
// 获取命令处理函数 // 获取命令处理函数
const handler = getCommandHandler(binding.command); const handler = getCommandHandler(binding.key);
if (!handler) { if (!handler) {
continue; continue;
} }
// 转换为CodeMirror快捷键格式 // 转换为CodeMirror快捷键格式
// binding.command 是快捷键组合 (如 "Mod-f")binding.key 是命令标识符
const keyBinding: KeyBinding = { const keyBinding: KeyBinding = {
key: binding.key, key: binding.command || '',
run: handler, run: handler,
preventDefault: true preventDefault: true
}; };
@@ -58,10 +59,10 @@ export class Manager {
/** /**
* 创建CodeMirror快捷键扩展 * 创建CodeMirror快捷键扩展
* @param keyBindings 后端快捷键配置列表 * @param keyBindings 后端快捷键配置列表
* @param enabledExtensions 启用的扩展ID列表 * @param enabledExtensions 启用的扩展key列表
* @returns CodeMirror扩展 * @returns CodeMirror扩展
*/ */
static createKeymapExtension(keyBindings: KeyBindingConfig[], enabledExtensions?: ExtensionID[]): Extension { static createKeymapExtension(keyBindings: KeyBindingConfig[], enabledExtensions?: string[]): Extension {
const {keyBindings: cmKeyBindings} = const {keyBindings: cmKeyBindings} =
this.convertToKeyBindings(keyBindings, enabledExtensions); this.convertToKeyBindings(keyBindings, enabledExtensions);
@@ -72,9 +73,9 @@ export class Manager {
* 动态更新快捷键扩展 * 动态更新快捷键扩展
* @param view 编辑器视图 * @param view 编辑器视图
* @param keyBindings 后端快捷键配置列表 * @param keyBindings 后端快捷键配置列表
* @param enabledExtensions 启用的扩展ID列表 * @param enabledExtensions 启用的扩展key列表
*/ */
static updateKeymap(view: any, keyBindings: KeyBindingConfig[], enabledExtensions: ExtensionID[]): void { static updateKeymap(view: any, keyBindings: KeyBindingConfig[], enabledExtensions: string[]): void {
const {keyBindings: cmKeyBindings} = const {keyBindings: cmKeyBindings} =
this.convertToKeyBindings(keyBindings, enabledExtensions); this.convertToKeyBindings(keyBindings, enabledExtensions);

View File

@@ -1,5 +1,4 @@
import {Manager} from './manager'; import {Manager} from './manager';
import {ExtensionID} from '@/../bindings/voidraft/internal/models/models';
import i18n from '@/i18n'; import i18n from '@/i18n';
import {ExtensionDefinition} from './types'; import {ExtensionDefinition} from './types';
import {Prec} from '@codemirror/state'; import {Prec} from '@codemirror/state';
@@ -15,6 +14,8 @@ import {foldGutter} from "@codemirror/language";
import {highlightActiveLineGutter, highlightWhitespace, highlightTrailingWhitespace} from "@codemirror/view"; import {highlightActiveLineGutter, highlightWhitespace, highlightTrailingWhitespace} from "@codemirror/view";
import createEditorContextMenu from '../extensions/contextMenu'; import createEditorContextMenu from '../extensions/contextMenu';
import {blockLineNumbers} from '../extensions/codeblock'; import {blockLineNumbers} from '../extensions/codeblock';
import {createHttpClientExtension} from '../extensions/httpclient';
import {ExtensionKey} from '@/../bindings/voidraft/internal/models/models';
type ExtensionEntry = { type ExtensionEntry = {
definition: ExtensionDefinition definition: ExtensionDefinition
@@ -22,35 +23,36 @@ type ExtensionEntry = {
descriptionKey: string descriptionKey: string
}; };
type RegisteredExtensionID = Exclude<ExtensionID, ExtensionID.$zero | ExtensionID.ExtensionEditor>; // 排除 $zero 的有效扩展 Key 类型
type ValidExtensionKey = Exclude<ExtensionKey, ExtensionKey.$zero>;
const defineExtension = (create: (config: any) => any, defaultConfig: Record<string, any> = {}): ExtensionDefinition => ({ const defineExtension = (create: (config: any) => any, defaultConfig: Record<string, any> = {}): ExtensionDefinition => ({
create, create,
defaultConfig defaultConfig
}); });
const EXTENSION_REGISTRY: Record<RegisteredExtensionID, ExtensionEntry> = { const EXTENSION_REGISTRY: Record<ValidExtensionKey, ExtensionEntry> = {
[ExtensionID.ExtensionRainbowBrackets]: { [ExtensionKey.ExtensionRainbowBrackets]: {
definition: defineExtension(() => rainbowBrackets()), definition: defineExtension(() => rainbowBrackets()),
displayNameKey: 'extensions.rainbowBrackets.name', displayNameKey: 'extensions.rainbowBrackets.name',
descriptionKey: 'extensions.rainbowBrackets.description' descriptionKey: 'extensions.rainbowBrackets.description'
}, },
[ExtensionID.ExtensionHyperlink]: { [ExtensionKey.ExtensionHyperlink]: {
definition: defineExtension(() => hyperLink), definition: defineExtension(() => hyperLink),
displayNameKey: 'extensions.hyperlink.name', displayNameKey: 'extensions.hyperlink.name',
descriptionKey: 'extensions.hyperlink.description' descriptionKey: 'extensions.hyperlink.description'
}, },
[ExtensionID.ExtensionColorSelector]: { [ExtensionKey.ExtensionColorSelector]: {
definition: defineExtension(() => color), definition: defineExtension(() => color),
displayNameKey: 'extensions.colorSelector.name', displayNameKey: 'extensions.colorSelector.name',
descriptionKey: 'extensions.colorSelector.description' descriptionKey: 'extensions.colorSelector.description'
}, },
[ExtensionID.ExtensionTranslator]: { [ExtensionKey.ExtensionTranslator]: {
definition: defineExtension(() => createTranslatorExtension()), definition: defineExtension(() => createTranslatorExtension()),
displayNameKey: 'extensions.translator.name', displayNameKey: 'extensions.translator.name',
descriptionKey: 'extensions.translator.description' descriptionKey: 'extensions.translator.description'
}, },
[ExtensionID.ExtensionMinimap]: { [ExtensionKey.ExtensionMinimap]: {
definition: defineExtension((config: any) => minimap({ definition: defineExtension((config: any) => minimap({
displayText: config?.displayText ?? 'characters', displayText: config?.displayText ?? 'characters',
showOverlay: config?.showOverlay ?? 'always', showOverlay: config?.showOverlay ?? 'always',
@@ -63,85 +65,90 @@ const EXTENSION_REGISTRY: Record<RegisteredExtensionID, ExtensionEntry> = {
displayNameKey: 'extensions.minimap.name', displayNameKey: 'extensions.minimap.name',
descriptionKey: 'extensions.minimap.description' descriptionKey: 'extensions.minimap.description'
}, },
[ExtensionID.ExtensionSearch]: { [ExtensionKey.ExtensionSearch]: {
definition: defineExtension(() => vscodeSearch), definition: defineExtension(() => vscodeSearch),
displayNameKey: 'extensions.search.name', displayNameKey: 'extensions.search.name',
descriptionKey: 'extensions.search.description' descriptionKey: 'extensions.search.description'
}, },
[ExtensionID.ExtensionFold]: { [ExtensionKey.ExtensionFold]: {
definition: defineExtension(() => Prec.low(foldGutter())), definition: defineExtension(() => Prec.low(foldGutter())),
displayNameKey: 'extensions.fold.name', displayNameKey: 'extensions.fold.name',
descriptionKey: 'extensions.fold.description' descriptionKey: 'extensions.fold.description'
}, },
[ExtensionID.ExtensionMarkdown]: { [ExtensionKey.ExtensionMarkdown]: {
definition: defineExtension(() => markdownExtensions), definition: defineExtension(() => markdownExtensions),
displayNameKey: 'extensions.markdown.name', displayNameKey: 'extensions.markdown.name',
descriptionKey: 'extensions.markdown.description' descriptionKey: 'extensions.markdown.description'
}, },
[ExtensionID.ExtensionLineNumbers]: { [ExtensionKey.ExtensionLineNumbers]: {
definition: defineExtension(() => Prec.high([blockLineNumbers, highlightActiveLineGutter()])), definition: defineExtension(() => Prec.high([blockLineNumbers, highlightActiveLineGutter()])),
displayNameKey: 'extensions.lineNumbers.name', displayNameKey: 'extensions.lineNumbers.name',
descriptionKey: 'extensions.lineNumbers.description' descriptionKey: 'extensions.lineNumbers.description'
}, },
[ExtensionID.ExtensionContextMenu]: { [ExtensionKey.ExtensionContextMenu]: {
definition: defineExtension(() => createEditorContextMenu()), definition: defineExtension(() => createEditorContextMenu()),
displayNameKey: 'extensions.contextMenu.name', displayNameKey: 'extensions.contextMenu.name',
descriptionKey: 'extensions.contextMenu.description' descriptionKey: 'extensions.contextMenu.description'
}, },
[ExtensionID.ExtensionHighlightWhitespace]: { [ExtensionKey.ExtensionHighlightWhitespace]: {
definition: defineExtension(() => highlightWhitespace()), definition: defineExtension(() => highlightWhitespace()),
displayNameKey: 'extensions.highlightWhitespace.name', displayNameKey: 'extensions.highlightWhitespace.name',
descriptionKey: 'extensions.highlightWhitespace.description' descriptionKey: 'extensions.highlightWhitespace.description'
}, },
[ExtensionID.ExtensionHighlightTrailingWhitespace]: { [ExtensionKey.ExtensionHighlightTrailingWhitespace]: {
definition: defineExtension(() => highlightTrailingWhitespace()), definition: defineExtension(() => highlightTrailingWhitespace()),
displayNameKey: 'extensions.highlightTrailingWhitespace.name', displayNameKey: 'extensions.highlightTrailingWhitespace.name',
descriptionKey: 'extensions.highlightTrailingWhitespace.description' descriptionKey: 'extensions.highlightTrailingWhitespace.description'
},
[ExtensionKey.ExtensionHttpClient]: {
definition: defineExtension(() => createHttpClientExtension()),
displayNameKey: 'extensions.httpClient.name',
descriptionKey: 'extensions.httpClient.description'
} }
} as const; };
const isRegisteredExtension = (id: ExtensionID): id is RegisteredExtensionID => const isRegisteredExtension = (key: string): key is ValidExtensionKey =>
Object.prototype.hasOwnProperty.call(EXTENSION_REGISTRY, id); Object.prototype.hasOwnProperty.call(EXTENSION_REGISTRY, key);
const getRegistryEntry = (id: ExtensionID): ExtensionEntry | undefined => { const getRegistryEntry = (key: string): ExtensionEntry | undefined => {
if (!isRegisteredExtension(id)) { if (!isRegisteredExtension(key)) {
return undefined; return undefined;
} }
return EXTENSION_REGISTRY[id]; return EXTENSION_REGISTRY[key];
}; };
export function registerAllExtensions(manager: Manager): void { export function registerAllExtensions(manager: Manager): void {
(Object.entries(EXTENSION_REGISTRY) as [RegisteredExtensionID, ExtensionEntry][]).forEach(([id, entry]) => { (Object.entries(EXTENSION_REGISTRY) as [ValidExtensionKey, ExtensionEntry][]).forEach(([id, entry]) => {
manager.registerExtension(id, entry.definition); manager.registerExtension(id, entry.definition);
}); });
} }
export function getExtensionDisplayName(id: ExtensionID): string { export function getExtensionDisplayName(key: string): string {
const entry = getRegistryEntry(id); const entry = getRegistryEntry(key);
return entry?.displayNameKey ? i18n.global.t(entry.displayNameKey) : id; return entry?.displayNameKey ? i18n.global.t(entry.displayNameKey) : key;
} }
export function getExtensionDescription(id: ExtensionID): string { export function getExtensionDescription(key: string): string {
const entry = getRegistryEntry(id); const entry = getRegistryEntry(key);
return entry?.descriptionKey ? i18n.global.t(entry.descriptionKey) : ''; return entry?.descriptionKey ? i18n.global.t(entry.descriptionKey) : '';
} }
function getExtensionDefinition(id: ExtensionID): ExtensionDefinition | undefined { function getExtensionDefinition(key: string): ExtensionDefinition | undefined {
return getRegistryEntry(id)?.definition; return getRegistryEntry(key)?.definition;
} }
export function getExtensionDefaultConfig(id: ExtensionID): any { export function getExtensionDefaultConfig(key: string): any {
const definition = getExtensionDefinition(id); const definition = getExtensionDefinition(key);
if (!definition) return {}; if (!definition) return {};
return cloneConfig(definition.defaultConfig); return cloneConfig(definition.defaultConfig);
} }
export function hasExtensionConfig(id: ExtensionID): boolean { export function hasExtensionConfig(key: string): boolean {
return Object.keys(getExtensionDefaultConfig(id)).length > 0; return Object.keys(getExtensionDefaultConfig(key)).length > 0;
} }
export function getAllExtensionIds(): ExtensionID[] { export function getAllExtensionIds(): string[] {
return Object.keys(EXTENSION_REGISTRY) as RegisteredExtensionID[]; return Object.keys(EXTENSION_REGISTRY);
} }
const cloneConfig = (config: any) => { const cloneConfig = (config: any) => {

View File

@@ -12,9 +12,8 @@ const extensionManager = new Manager();
/** /**
* 异步创建动态扩展 * 异步创建动态扩展
* 确保扩展配置已加载 * 确保扩展配置已加载
* @param _documentId 可选的文档ID用于提前初始化视图
*/ */
export const createDynamicExtensions = async (_documentId?: number): Promise<Extension[]> => { export const createDynamicExtensions = async (): Promise<Extension[]> => {
const extensionStore = useExtensionStore(); const extensionStore = useExtensionStore();
// 注册所有扩展工厂 // 注册所有扩展工厂

View File

@@ -1,6 +1,6 @@
import {Compartment, Extension} from '@codemirror/state'; import {Compartment, Extension} from '@codemirror/state';
import {EditorView} from '@codemirror/view'; import {EditorView} from '@codemirror/view';
import {Extension as ExtensionConfig, ExtensionID} from '@/../bindings/voidraft/internal/models/models'; import {Extension as ExtensionConfig} from '@/../bindings/voidraft/internal/models/ent/models';
import {ExtensionDefinition, ExtensionState} from './types'; import {ExtensionDefinition, ExtensionState} from './types';
/** /**
@@ -8,10 +8,10 @@ import {ExtensionDefinition, ExtensionState} from './types';
* 负责注册、初始化与同步所有动态扩展 * 负责注册、初始化与同步所有动态扩展
*/ */
export class Manager { export class Manager {
private extensionStates = new Map<ExtensionID, ExtensionState>(); private extensionStates = new Map<string, ExtensionState>();
private views = new Map<number, EditorView>(); private views = new Map<number, EditorView>();
registerExtension(id: ExtensionID, definition: ExtensionDefinition): void { registerExtension(id: string, definition: ExtensionDefinition): void {
const existingState = this.extensionStates.get(id); const existingState = this.extensionStates.get(id);
if (existingState) { if (existingState) {
existingState.definition = definition; existingState.definition = definition;
@@ -34,10 +34,11 @@ export class Manager {
initExtensions(extensionConfigs: ExtensionConfig[]): void { initExtensions(extensionConfigs: ExtensionConfig[]): void {
for (const config of extensionConfigs) { for (const config of extensionConfigs) {
const state = this.extensionStates.get(config.id); if (!config.key) continue;
const state = this.extensionStates.get(config.key);
if (!state) continue; if (!state) continue;
const resolvedConfig = this.cloneConfig(config.config ?? state.definition.defaultConfig ?? {}); const resolvedConfig = this.cloneConfig(config.config ?? state.definition.defaultConfig ?? {});
this.commitExtensionState(state, config.enabled, resolvedConfig); this.commitExtensionState(state, config.enabled ?? false, resolvedConfig);
} }
} }
@@ -54,7 +55,7 @@ export class Manager {
this.applyAllExtensionsToView(view); this.applyAllExtensionsToView(view);
} }
updateExtension(id: ExtensionID, enabled: boolean, config?: any): void { updateExtension(id: string, enabled: boolean, config?: any): void {
const state = this.extensionStates.get(id); const state = this.extensionStates.get(id);
if (!state) return; if (!state) return;
@@ -93,7 +94,7 @@ export class Manager {
} }
} }
private applyExtensionToAllViews(id: ExtensionID): void { private applyExtensionToAllViews(id: string): void {
const state = this.extensionStates.get(id); const state = this.extensionStates.get(id);
if (!state) return; if (!state) return;

View File

@@ -1 +1,23 @@
import {Compartment, Extension} from '@codemirror/state'; import {Compartment, Extension} from '@codemirror/state';
/**
* 扩展定义
* 标准化 create 方法和默认配置
*/
export interface ExtensionDefinition {
create(config: any): Extension
defaultConfig: Record<string, any>
}
/**
* 扩展运行时状态
*/
export interface ExtensionState {
id: string // 扩展 key
definition: ExtensionDefinition
config: any
enabled: boolean
compartment: Compartment
extension: Extension
}

View File

@@ -1,5 +1,5 @@
import type {ThemeColors} from './types'; import type {ThemeColors} from './types';
import {ThemeType} from '@/../bindings/voidraft/internal/models/models'; import {Type as ThemeType} from '@/../bindings/voidraft/internal/models/ent/theme/models';
import {defaultDarkColors} from './dark/default-dark'; import {defaultDarkColors} from './dark/default-dark';
import {defaultLightColors} from './light/default-light'; import {defaultLightColors} from './light/default-light';
import {config as draculaColors} from './dark/dracula'; import {config as draculaColors} from './dark/dracula';
@@ -24,20 +24,20 @@ export interface ThemePreset {
export const FALLBACK_THEME_NAME = defaultDarkColors.themeName; export const FALLBACK_THEME_NAME = defaultDarkColors.themeName;
export const themePresetList: ThemePreset[] = [ export const themePresetList: ThemePreset[] = [
{name: defaultDarkColors.themeName, type: ThemeType.ThemeTypeDark, colors: defaultDarkColors}, {name: defaultDarkColors.themeName, type: ThemeType.TypeDark, colors: defaultDarkColors},
{name: draculaColors.themeName, type: ThemeType.ThemeTypeDark, colors: draculaColors}, {name: draculaColors.themeName, type: ThemeType.TypeDark, colors: draculaColors},
{name: auraColors.themeName, type: ThemeType.ThemeTypeDark, colors: auraColors}, {name: auraColors.themeName, type: ThemeType.TypeDark, colors: auraColors},
{name: githubDarkColors.themeName, type: ThemeType.ThemeTypeDark, colors: githubDarkColors}, {name: githubDarkColors.themeName, type: ThemeType.TypeDark, colors: githubDarkColors},
{name: materialDarkColors.themeName, type: ThemeType.ThemeTypeDark, colors: materialDarkColors}, {name: materialDarkColors.themeName, type: ThemeType.TypeDark, colors: materialDarkColors},
{name: oneDarkColors.themeName, type: ThemeType.ThemeTypeDark, colors: oneDarkColors}, {name: oneDarkColors.themeName, type: ThemeType.TypeDark, colors: oneDarkColors},
{name: solarizedDarkColors.themeName, type: ThemeType.ThemeTypeDark, colors: solarizedDarkColors}, {name: solarizedDarkColors.themeName, type: ThemeType.TypeDark, colors: solarizedDarkColors},
{name: tokyoNightColors.themeName, type: ThemeType.ThemeTypeDark, colors: tokyoNightColors}, {name: tokyoNightColors.themeName, type: ThemeType.TypeDark, colors: tokyoNightColors},
{name: tokyoNightStormColors.themeName, type: ThemeType.ThemeTypeDark, colors: tokyoNightStormColors}, {name: tokyoNightStormColors.themeName, type: ThemeType.TypeDark, colors: tokyoNightStormColors},
{name: defaultLightColors.themeName, type: ThemeType.ThemeTypeLight, colors: defaultLightColors}, {name: defaultLightColors.themeName, type: ThemeType.TypeLight, colors: defaultLightColors},
{name: githubLightColors.themeName, type: ThemeType.ThemeTypeLight, colors: githubLightColors}, {name: githubLightColors.themeName, type: ThemeType.TypeLight, colors: githubLightColors},
{name: materialLightColors.themeName, type: ThemeType.ThemeTypeLight, colors: materialLightColors}, {name: materialLightColors.themeName, type: ThemeType.TypeLight, colors: materialLightColors},
{name: solarizedLightColors.themeName, type: ThemeType.ThemeTypeLight, colors: solarizedLightColors}, {name: solarizedLightColors.themeName, type: ThemeType.TypeLight, colors: solarizedLightColors},
{name: tokyoNightDayColors.themeName, type: ThemeType.ThemeTypeLight, colors: tokyoNightDayColors}, {name: tokyoNightDayColors.themeName, type: ThemeType.TypeLight, colors: tokyoNightDayColors},
]; ];
export const themePresetMap: Record<string, ThemePreset> = themePresetList.reduce( export const themePresetMap: Record<string, ThemePreset> = themePresetList.reduce(

View File

@@ -7,7 +7,7 @@ import SettingSection from '../components/SettingSection.vue';
import SettingItem from '../components/SettingItem.vue'; import SettingItem from '../components/SettingItem.vue';
import { SystemThemeType, LanguageType } from '@/../bindings/voidraft/internal/models/models'; import { SystemThemeType, LanguageType } from '@/../bindings/voidraft/internal/models/models';
import { createDebounce } from '@/common/utils/debounce'; import { createDebounce } from '@/common/utils/debounce';
import { createTimerManager } from '@/common/utils/timerUtils'; import { useConfirm } from '@/composables/useConfirm';
import PickColors from 'vue-pick-colors'; import PickColors from 'vue-pick-colors';
import type { ThemeColors } from '@/views/editor/theme/types'; import type { ThemeColors } from '@/views/editor/theme/types';
@@ -21,31 +21,22 @@ const { debouncedFn: debouncedUpdateColor } = createDebounce(
{ delay: 100 } { delay: 100 }
); );
const { debouncedFn: debouncedResetTheme } = createDebounce(
async () => {
const success = await themeStore.resetCurrentTheme();
if (success) {
// 重新加载临时颜色
syncTempColors();
hasUnsavedChanges.value = false;
}
},
{ delay: 300 }
);
// 创建定时器管理器
const resetTimer = createTimerManager();
// 临时颜色状态(用于编辑) // 临时颜色状态(用于编辑)
const tempColors = ref<ThemeColors | null>(null); const tempColors = ref<ThemeColors | null>(null);
// 标记是否有未保存的更改 // 标记是否有未保存的更改
const hasUnsavedChanges = ref(false); const hasUnsavedChanges = ref(false);
// 重置按钮状态 // 重置主题确认
const resetButtonState = ref({ const { isConfirming: isResetConfirming, requestConfirm: requestResetConfirm } = useConfirm({
confirming: false timeout: 3000,
onConfirm: async () => {
const success = await themeStore.resetCurrentTheme();
if (success) {
syncTempColors();
hasUnsavedChanges.value = false;
}
}
}); });
// 当前选中的主题名称 // 当前选中的主题名称
@@ -125,23 +116,6 @@ const toggleSearch = async () => {
} }
}; };
// 处理重置按钮点击
const handleResetClick = () => {
if (resetButtonState.value.confirming) {
debouncedResetTheme();
resetButtonState.value.confirming = false;
resetTimer.clear();
} else {
resetButtonState.value.confirming = true;
// 设置3秒后自动恢复
resetTimer.set(() => {
resetButtonState.value.confirming = false;
}, 3000);
}
};
// 更新本地颜色配置 // 更新本地颜色配置
const updateLocalColor = (colorKey: string, value: string) => { const updateLocalColor = (colorKey: string, value: string) => {
if (!tempColors.value) return; if (!tempColors.value) return;
@@ -295,10 +269,10 @@ const handlePickerClose = () => {
</button> </button>
<button <button
v-if="!hasUnsavedChanges" v-if="!hasUnsavedChanges"
:class="['reset-button', resetButtonState.confirming ? 'reset-button-confirming' : '']" :class="['reset-button', isResetConfirming('theme') ? 'reset-button-confirming' : '']"
@click="handleResetClick" @click="requestResetConfirm('theme')"
> >
{{ resetButtonState.confirming ? t('settings.confirmReset') : t('settings.resetToDefault') }} {{ isResetConfirming('theme') ? t('settings.confirmReset') : t('settings.resetToDefault') }}
</button> </button>
<template v-else> <template v-else>
<button class="apply-button" @click="applyChanges"> <button class="apply-button" @click="applyChanges">

View File

@@ -4,7 +4,6 @@ import {useI18n} from 'vue-i18n';
import {useEditorStore} from '@/stores/editorStore'; import {useEditorStore} from '@/stores/editorStore';
import {useExtensionStore} from '@/stores/extensionStore'; import {useExtensionStore} from '@/stores/extensionStore';
import {ExtensionService} from '@/../bindings/voidraft/internal/services'; import {ExtensionService} from '@/../bindings/voidraft/internal/services';
import {ExtensionID} from '@/../bindings/voidraft/internal/models/models';
import { import {
getAllExtensionIds, getAllExtensionIds,
getExtensionDefaultConfig, getExtensionDefaultConfig,
@@ -21,59 +20,58 @@ const editorStore = useEditorStore();
const extensionStore = useExtensionStore(); const extensionStore = useExtensionStore();
// 展开状态管理 // 展开状态管理
const expandedExtensions = ref<Set<ExtensionID>>(new Set()); const expandedExtensions = ref<Set<string>>(new Set());
// 获取所有可用的扩展 // 获取所有可用的扩展
const availableExtensions = computed(() => { const availableExtensions = computed(() => {
return getAllExtensionIds().map(id => { return getAllExtensionIds().map(key => {
const extension = extensionStore.extensions.find(ext => ext.id === id); const extension = extensionStore.extensions.find(ext => ext.key === key);
return { return {
id, id: key,
displayName: getExtensionDisplayName(id), displayName: getExtensionDisplayName(key),
description: getExtensionDescription(id), description: getExtensionDescription(key),
enabled: extension?.enabled || false, enabled: extension?.enabled || false,
isDefault: extension?.isDefault || false, hasConfig: hasExtensionConfig(key),
hasConfig: hasExtensionConfig(id),
config: extension?.config || {}, config: extension?.config || {},
defaultConfig: getExtensionDefaultConfig(id) defaultConfig: getExtensionDefaultConfig(key)
}; };
}); });
}); });
// 切换展开状态 // 切换展开状态
const toggleExpanded = (extensionId: ExtensionID) => { const toggleExpanded = (extensionKey: string) => {
if (expandedExtensions.value.has(extensionId)) { if (expandedExtensions.value.has(extensionKey)) {
expandedExtensions.value.delete(extensionId); expandedExtensions.value.delete(extensionKey);
} else { } else {
expandedExtensions.value.add(extensionId); expandedExtensions.value.add(extensionKey);
} }
}; };
// 更新扩展状态 // 更新扩展状态
const updateExtension = async (extensionId: ExtensionID, enabled: boolean) => { const updateExtension = async (extensionKey: string, enabled: boolean) => {
try { try {
await editorStore.updateExtension(extensionId, enabled); await editorStore.updateExtension(extensionKey, enabled);
} catch (error) { } catch (error) {
console.error('Failed to update extension:', error); console.error('Failed to update extension:', error);
} }
}; };
// 更新扩展配置 // 更新扩展配置
const updateExtensionConfig = async (extensionId: ExtensionID, configKey: string, value: any) => { const updateExtensionConfig = async (extensionKey: string, configKey: string, value: any) => {
try { try {
// 获取当前扩展状态 // 获取当前扩展状态
const extension = extensionStore.extensions.find(ext => ext.id === extensionId); const extension = extensionStore.extensions.find(ext => ext.key === extensionKey);
if (!extension) return; if (!extension) return;
// 更新配置 // 更新配置
const updatedConfig = {...extension.config}; const updatedConfig = {...(extension.config || {})};
if (value === undefined) { if (value === undefined) {
delete updatedConfig[configKey]; delete updatedConfig[configKey];
} else { } else {
updatedConfig[configKey] = value; updatedConfig[configKey] = value;
} }
// 使用editorStore的updateExtension方法更新确保应用到所有编辑器实例 // 使用editorStore的updateExtension方法更新确保应用到所有编辑器实例
await editorStore.updateExtension(extensionId, extension.enabled, updatedConfig); await editorStore.updateExtension(extensionKey, extension.enabled ?? false, updatedConfig);
} catch (error) { } catch (error) {
console.error('Failed to update extension config:', error); console.error('Failed to update extension config:', error);
@@ -81,19 +79,19 @@ const updateExtensionConfig = async (extensionId: ExtensionID, configKey: string
}; };
// 重置扩展到默认配置 // 重置扩展到默认配置
const resetExtension = async (extensionId: ExtensionID) => { const resetExtension = async (extensionKey: string) => {
try { try {
// 重置到默认配置 // 重置到默认配置
await ExtensionService.ResetExtensionToDefault(extensionId); await ExtensionService.ResetExtensionConfig(extensionKey);
// 重新加载扩展状态以获取最新配置 // 重新加载扩展状态以获取最新配置
await extensionStore.loadExtensions(); await extensionStore.loadExtensions();
// 获取重置后的状态,立即应用到所有编辑器视图 // 获取重置后的状态,立即应用到所有编辑器视图
const extension = extensionStore.extensions.find(ext => ext.id === extensionId); const extension = extensionStore.extensions.find(ext => ext.key === extensionKey);
if (extension) { if (extension) {
// 通过editorStore更新确保所有视图都能同步 // 通过editorStore更新确保所有视图都能同步
await editorStore.updateExtension(extensionId, extension.enabled, extension.config); await editorStore.updateExtension(extensionKey, extension.enabled ?? false, extension.config);
} }
} catch (error) { } catch (error) {
console.error('Failed to reset extension:', error); console.error('Failed to reset extension:', error);
@@ -127,7 +125,7 @@ const formatConfigValue = (value: any): string => {
const handleConfigInput = async ( const handleConfigInput = async (
extensionId: ExtensionID, extensionKey: string,
configKey: string, configKey: string,
defaultValue: any, defaultValue: any,
event: Event event: Event
@@ -137,15 +135,15 @@ const handleConfigInput = async (
const rawValue = target.value; const rawValue = target.value;
const trimmedValue = rawValue.trim(); const trimmedValue = rawValue.trim();
if (!trimmedValue.length) { if (!trimmedValue.length) {
await updateExtensionConfig(extensionId, configKey, undefined); await updateExtensionConfig(extensionKey, configKey, undefined);
return; return;
} }
try { try {
const parsedValue = JSON.parse(trimmedValue); const parsedValue = JSON.parse(trimmedValue);
await updateExtensionConfig(extensionId, configKey, parsedValue); await updateExtensionConfig(extensionKey, configKey, parsedValue);
} catch (_error) { } catch (_error) {
const extension = extensionStore.extensions.find(ext => ext.id === extensionId); const extension = extensionStore.extensions.find(ext => ext.key === extensionKey);
const fallbackValue = getConfigValue(extension?.config, configKey, defaultValue); const fallbackValue = getConfigValue(extension?.config, configKey, defaultValue);
target.value = formatConfigValue(fallbackValue); target.value = formatConfigValue(fallbackValue);

View File

@@ -2,133 +2,67 @@
import {useConfigStore} from '@/stores/configStore'; import {useConfigStore} from '@/stores/configStore';
import {useTabStore} from '@/stores/tabStore'; import {useTabStore} from '@/stores/tabStore';
import {useI18n} from 'vue-i18n'; import {useI18n} from 'vue-i18n';
import {computed, onUnmounted, ref} from 'vue'; import {computed, ref} from 'vue';
import SettingSection from '../components/SettingSection.vue'; import SettingSection from '../components/SettingSection.vue';
import SettingItem from '../components/SettingItem.vue'; import SettingItem from '../components/SettingItem.vue';
import ToggleSwitch from '../components/ToggleSwitch.vue'; import ToggleSwitch from '../components/ToggleSwitch.vue';
import { import {DialogService, MigrationService} from '@/../bindings/voidraft/internal/services';
DialogService,
MigrationProgress,
MigrationService,
MigrationStatus
} from '@/../bindings/voidraft/internal/services';
import {useSystemStore} from "@/stores/systemStore"; import {useSystemStore} from "@/stores/systemStore";
import {useConfirm, usePolling} from '@/composables';
const {t} = useI18n(); const {t} = useI18n();
const configStore = useConfigStore(); const configStore = useConfigStore();
const systemStore = useSystemStore(); const systemStore = useSystemStore();
const tabStore = useTabStore(); const tabStore = useTabStore();
// 迁移进度状态
const migrationProgress = ref<MigrationProgress>(new MigrationProgress({
status: MigrationStatus.MigrationStatusCompleted,
progress: 0
}));
// 轮询相关
let pollingTimer: number | null = null;
const isPolling = ref(false);
// 进度条显示控制 // 进度条显示控制
const showProgress = ref(false); const showBar = ref(false);
const progressError = ref(''); const manualError = ref(''); // 用于捕获 MigrateDirectory 抛出的错误
let hideProgressTimer: any = null; let hideTimer = 0;
// 开始轮询迁移进度 // 轮询迁移进度
const startPolling = () => { const {data: progress, error: pollError, isActive: migrating, start, stop, reset} = usePolling(
if (isPolling.value) return; () => MigrationService.GetProgress(),
{
isPolling.value = true; interval: 300,
showProgress.value = true; shouldStop: ({progress, error}) => !!error || progress >= 100,
progressError.value = ''; onStop: () => {
const hasError = pollError.value || progress.value?.error;
// 立即重置迁移进度状态,避免从之前的失败状态渐变 hideTimer = window.setTimeout(hideAll, hasError ? 5000 : 3000);
migrationProgress.value = new MigrationProgress({
status: MigrationStatus.MigrationStatusMigrating,
progress: 0
});
pollingTimer = window.setInterval(async () => {
try {
const progress = await MigrationService.GetProgress();
migrationProgress.value = progress;
const {status, error} = progress;
const isCompleted = [MigrationStatus.MigrationStatusCompleted, MigrationStatus.MigrationStatusFailed].includes(status);
if (isCompleted) {
stopPolling();
// 设置错误信息(如果是失败状态)
progressError.value = (status === MigrationStatus.MigrationStatusFailed) ? (error || 'Migration failed') : '';
const delay = status === MigrationStatus.MigrationStatusCompleted ? 3000 : 5000;
hideProgressTimer = setTimeout(hideProgress, delay);
} }
} catch (_error) {
stopPolling();
// 使用常量简化错误处理
const errorMsg = 'Failed to get migration progress';
Object.assign(migrationProgress.value, {
status: MigrationStatus.MigrationStatusFailed,
progress: 0,
error: errorMsg
});
progressError.value = errorMsg;
hideProgressTimer = setTimeout(hideProgress, 5000);
} }
}, 200);
};
// 停止轮询
const stopPolling = () => {
if (pollingTimer) {
clearInterval(pollingTimer);
pollingTimer = null;
}
isPolling.value = false;
};
// 隐藏进度条
const hideProgress = () => {
showProgress.value = false;
progressError.value = '';
// 重置迁移状态,避免下次显示时状态不正确
migrationProgress.value = new MigrationProgress({
status: MigrationStatus.MigrationStatusCompleted,
progress: 0
});
if (hideProgressTimer) {
clearTimeout(hideProgressTimer);
hideProgressTimer = null;
}
};
// 简化的迁移状态管理
const isMigrating = computed(() => migrationProgress.value.status === MigrationStatus.MigrationStatusMigrating);
// 进度条样式 - 使用 Map 简化条件判断
const statusClassMap = new Map([
[MigrationStatus.MigrationStatusMigrating, 'migrating'],
[MigrationStatus.MigrationStatusCompleted, 'success'],
[MigrationStatus.MigrationStatusFailed, 'error']
]);
const progressBarClass = computed(() =>
showProgress.value ? statusClassMap.get(migrationProgress.value.status) ?? '' : ''
); );
const progressBarWidth = computed(() => { // 派生状态
if (!showProgress.value) return '0%'; const migrationError = computed(() => manualError.value || pollError.value || progress.value?.error || '');
return isMigrating.value ? `${migrationProgress.value.progress}%` : '100%'; const currentProgress = computed(() => progress.value?.progress ?? 0);
const barClass = computed(() => {
if (!showBar.value) return '';
return migrationError.value ? 'error' : currentProgress.value >= 100 ? 'success' : 'migrating';
}); });
// 重置确认状态 const barWidth = computed(() => {
const resetConfirmState = ref<'idle' | 'confirming'>('idle'); if (!showBar.value) return '0%';
let resetConfirmTimer: any = null; return (migrationError.value || currentProgress.value >= 100) ? '100%' : `${currentProgress.value}%`;
});
// 隐藏进度条并清除所有状态
const hideAll = () => {
clearTimeout(hideTimer);
hideTimer = 0;
showBar.value = false;
manualError.value = '';
reset(); // 清除轮询状态
};
// 重置设置确认
const {isConfirming: isResetConfirming, requestConfirm: requestResetConfirm} = useConfirm({
timeout: 3000,
onConfirm: async () => {
await configStore.resetConfig();
}
});
// 可选键列表 // 可选键列表
const keyOptions = [ const keyOptions = [
@@ -201,7 +135,7 @@ const modifierKeys = computed(() => ({
win: configStore.config.general.globalHotkey.win win: configStore.config.general.globalHotkey.win
})); }));
// 主键配置 - 只读计算属性 // 主键配置
const selectedKey = computed(() => configStore.config.general.globalHotkey.key); const selectedKey = computed(() => configStore.config.general.globalHotkey.key);
// 切换修饰键 // 切换修饰键
@@ -218,29 +152,8 @@ const updateSelectedKey = (event: Event) => {
configStore.setGlobalHotkey(newHotkey); configStore.setGlobalHotkey(newHotkey);
}; };
// 重置设置
const resetSettings = () => {
if (resetConfirmState.value === 'idle') {
// 第一次点击,进入确认状态
resetConfirmState.value = 'confirming';
// 3秒后自动返回idle状态
resetConfirmTimer = setTimeout(() => {
resetConfirmState.value = 'idle';
}, 3000);
} else if (resetConfirmState.value === 'confirming') {
// 第二次点击,执行重置
clearTimeout(resetConfirmTimer);
resetConfirmState.value = 'idle';
confirmReset();
}
};
// 确认重置 // 计算热键预览文本
const confirmReset = async () => {
await configStore.resetConfig();
};
// 计算热键预览文本 - 使用现代语法简化
const hotkeyPreview = computed(() => { const hotkeyPreview = computed(() => {
if (!enableGlobalHotkey.value) return ''; if (!enableGlobalHotkey.value) return '';
@@ -261,54 +174,30 @@ const currentDataPath = computed(() => configStore.config.general.dataPath);
// 选择数据存储目录 // 选择数据存储目录
const selectDataDirectory = async () => { const selectDataDirectory = async () => {
if (isMigrating.value) return; if (migrating.value) return;
const selectedPath = await DialogService.SelectDirectory(); const selectedPath = await DialogService.SelectDirectory();
if (!selectedPath?.trim() || selectedPath === currentDataPath.value) return;
// 检查用户是否取消了选择或路径为空 const [oldPath, newPath] = [currentDataPath.value, selectedPath.trim()];
if (!selectedPath || !selectedPath.trim() || selectedPath === currentDataPath.value) {
return;
}
const oldPath = currentDataPath.value;
const newPath = selectedPath.trim();
// 清除之前的进度状态 // 清除之前的状态并开始轮询
hideProgress(); hideAll();
showBar.value = true;
manualError.value = '';
start();
// 开始轮询迁移进度
startPolling();
// 开始迁移
try { try {
await MigrationService.MigrateDirectory(oldPath, newPath); await MigrationService.MigrateDirectory(oldPath, newPath);
await configStore.setDataPath(newPath); await configStore.setDataPath(newPath);
} catch (error) { } catch (e) {
stopPolling(); stop();
// 设置手动捕获的错误(当轮询还没获取到错误时)
// 使用解构和默认值简化错误处理 manualError.value = String(e).replace(/^Error:\s*/i, '') || 'Migration failed';
const errorMsg = error?.toString() || 'Migration failed'; showBar.value = true;
showProgress.value = true; hideTimer = window.setTimeout(hideAll, 5000);
Object.assign(migrationProgress.value, {
status: MigrationStatus.MigrationStatusFailed,
progress: 0,
error: errorMsg
});
progressError.value = errorMsg;
hideProgressTimer = setTimeout(hideProgress, 5000);
} }
}; };
// 清理定时器
onUnmounted(() => {
stopPolling();
hideProgress();
if (resetConfirmTimer) {
clearTimeout(resetConfirmTimer);
}
});
</script> </script>
<template> <template>
@@ -394,24 +283,15 @@ onUnmounted(() => {
class="path-display-input" class="path-display-input"
@click="selectDataDirectory" @click="selectDataDirectory"
:title="t('settings.clickToSelectPath')" :title="t('settings.clickToSelectPath')"
:disabled="isMigrating" :disabled="migrating"
/> />
<!-- 简洁的进度条 --> <!-- 进度条 -->
<div <div class="progress-bar" :class="[{'active': showBar}, barClass]" :style="{width: barWidth}"/>
class="progress-bar"
:class="[
{ 'active': showProgress },
progressBarClass
]"
:style="{ width: progressBarWidth }"
></div>
</div> </div>
<!-- 错误提示 --> <!-- 错误提示 -->
<Transition name="error-fade"> <Transition name="error-fade">
<div v-if="progressError" class="progress-error"> <div v-if="migrationError" class="progress-error">{{ migrationError }}</div>
{{ progressError }}
</div>
</Transition> </Transition>
</div> </div>
</div> </div>
@@ -421,15 +301,10 @@ onUnmounted(() => {
<SettingItem :title="t('settings.resetAllSettings')"> <SettingItem :title="t('settings.resetAllSettings')">
<button <button
class="reset-button" class="reset-button"
:class="{ 'confirming': resetConfirmState === 'confirming' }" :class="{ 'confirming': isResetConfirming('reset') }"
@click="resetSettings" @click="requestResetConfirm('reset')"
> >
<template v-if="resetConfirmState === 'idle'"> {{ isResetConfirming('reset') ? t('settings.confirmReset') : t('settings.reset') }}
{{ t('settings.reset') }}
</template>
<template v-else-if="resetConfirmState === 'confirming'">
{{ t('settings.confirmReset') }}
</template>
</button> </button>
</SettingItem> </SettingItem>
</SettingSection> </SettingSection>
@@ -656,11 +531,8 @@ onUnmounted(() => {
} }
.progress-error { .progress-error {
margin-top: 6px;
font-size: 12px; font-size: 12px;
color: #ef4444; color: #ef4444;
padding: 0 2px;
line-height: 1.4;
opacity: 1; opacity: 1;
transition: all 0.3s ease; transition: all 0.3s ease;
} }

View File

@@ -6,7 +6,7 @@ import { useKeybindingStore } from '@/stores/keybindingStore';
import { useExtensionStore } from '@/stores/extensionStore'; import { useExtensionStore } from '@/stores/extensionStore';
import { useSystemStore } from '@/stores/systemStore'; import { useSystemStore } from '@/stores/systemStore';
import { getCommandDescription } from '@/views/editor/keymap/commands'; import { getCommandDescription } from '@/views/editor/keymap/commands';
import {KeyBindingCommand} from "@/../bindings/voidraft/internal/models"; import { KeyBindingKey } from '@/../bindings/voidraft/internal/models/models';
const { t } = useI18n(); const { t } = useI18n();
const keybindingStore = useKeybindingStore(); const keybindingStore = useKeybindingStore();
@@ -25,21 +25,21 @@ const keyBindings = computed(() => {
const enabledExtensionIds = new Set(extensionStore.enabledExtensionIds); const enabledExtensionIds = new Set(extensionStore.enabledExtensionIds);
return keybindingStore.keyBindings return keybindingStore.keyBindings
.filter(kb => kb.enabled && enabledExtensionIds.has(kb.extension)) .filter(kb => kb.enabled && (!kb.extension || enabledExtensionIds.has(kb.extension)))
.map(kb => ({ .map(kb => ({
id: kb.command, id: kb.key,
keys: parseKeyBinding(kb.key, kb.command), keys: parseKeyBinding(kb.command || '', kb.key),
category: kb.extension, category: kb.extension || '',
description: getCommandDescription(kb.command) || kb.command description: kb.key ? (getCommandDescription(kb.key) || kb.key) : ''
})); }));
}); });
// 解析快捷键字符串为显示数组 // 解析快捷键字符串为显示数组
const parseKeyBinding = (keyStr: string, command?: string): string[] => { const parseKeyBinding = (keyStr: string, keyBindingKey?: string): string[] => {
if (!keyStr) return []; if (!keyStr) return [];
// 特殊处理重做快捷键的操作系统差异 // 特殊处理重做快捷键的操作系统差异
if (command === KeyBindingCommand.HistoryRedoCommand && keyStr === 'Mod-Shift-z') { if (keyBindingKey === KeyBindingKey.HistoryRedoKeyBindingKey && keyStr === 'Mod-Shift-z') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', '⇧', 'Z']; // macOS: Cmd+Shift+Z return ['⌘', '⇧', 'Z']; // macOS: Cmd+Shift+Z
} else { } else {
@@ -48,7 +48,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
// 特殊处理重做选择快捷键的操作系统差异 // 特殊处理重做选择快捷键的操作系统差异
if (command === KeyBindingCommand.HistoryRedoSelectionCommand && keyStr === 'Mod-Shift-u') { if (keyBindingKey === KeyBindingKey.HistoryRedoSelectionKeyBindingKey && keyStr === 'Mod-Shift-u') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', '⇧', 'U']; // macOS: Cmd+Shift+U return ['⌘', '⇧', 'U']; // macOS: Cmd+Shift+U
} else { } else {
@@ -57,7 +57,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
// 特殊处理代码折叠快捷键的操作系统差异 // 特殊处理代码折叠快捷键的操作系统差异
if (command === KeyBindingCommand.FoldCodeCommand && keyStr === 'Ctrl-Shift-[') { if (keyBindingKey === KeyBindingKey.FoldCodeKeyBindingKey && keyStr === 'Ctrl-Shift-[') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', '⌥', '[']; // macOS: Cmd+Alt+[ return ['⌘', '⌥', '[']; // macOS: Cmd+Alt+[
} else { } else {
@@ -65,7 +65,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.UnfoldCodeCommand && keyStr === 'Ctrl-Shift-]') { if (keyBindingKey === KeyBindingKey.UnfoldCodeKeyBindingKey && keyStr === 'Ctrl-Shift-]') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', '⌥', ']']; // macOS: Cmd+Alt+] return ['⌘', '⌥', ']']; // macOS: Cmd+Alt+]
} else { } else {
@@ -74,7 +74,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
// 特殊处理编辑快捷键的操作系统差异 // 特殊处理编辑快捷键的操作系统差异
if (command === KeyBindingCommand.CursorSyntaxLeftCommand && keyStr === 'Alt-ArrowLeft') { if (keyBindingKey === KeyBindingKey.CursorSyntaxLeftKeyBindingKey && keyStr === 'Alt-ArrowLeft') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['Ctrl', '←']; // macOS: Ctrl+ArrowLeft return ['Ctrl', '←']; // macOS: Ctrl+ArrowLeft
} else { } else {
@@ -82,7 +82,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.CursorSyntaxRightCommand && keyStr === 'Alt-ArrowRight') { if (keyBindingKey === KeyBindingKey.CursorSyntaxRightKeyBindingKey && keyStr === 'Alt-ArrowRight') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['Ctrl', '→']; // macOS: Ctrl+ArrowRight return ['Ctrl', '→']; // macOS: Ctrl+ArrowRight
} else { } else {
@@ -90,7 +90,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.InsertBlankLineCommand && keyStr === 'Ctrl-Enter') { if (keyBindingKey === KeyBindingKey.InsertBlankLineKeyBindingKey && keyStr === 'Ctrl-Enter') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', 'Enter']; // macOS: Cmd+Enter return ['⌘', 'Enter']; // macOS: Cmd+Enter
} else { } else {
@@ -98,7 +98,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.SelectLineCommand && keyStr === 'Alt-l') { if (keyBindingKey === KeyBindingKey.SelectLineKeyBindingKey && keyStr === 'Alt-l') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['Ctrl', 'L']; // macOS: Ctrl+l return ['Ctrl', 'L']; // macOS: Ctrl+l
} else { } else {
@@ -106,7 +106,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.SelectParentSyntaxCommand && keyStr === 'Ctrl-i') { if (keyBindingKey === KeyBindingKey.SelectParentSyntaxKeyBindingKey && keyStr === 'Ctrl-i') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', 'I']; // macOS: Cmd+i return ['⌘', 'I']; // macOS: Cmd+i
} else { } else {
@@ -114,7 +114,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.IndentLessCommand && keyStr === 'Ctrl-[') { if (keyBindingKey === KeyBindingKey.IndentLessKeyBindingKey && keyStr === 'Ctrl-[') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', '[']; // macOS: Cmd+[ return ['⌘', '[']; // macOS: Cmd+[
} else { } else {
@@ -122,7 +122,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.IndentMoreCommand && keyStr === 'Ctrl-]') { if (keyBindingKey === KeyBindingKey.IndentMoreKeyBindingKey && keyStr === 'Ctrl-]') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', ']']; // macOS: Cmd+] return ['⌘', ']']; // macOS: Cmd+]
} else { } else {
@@ -130,7 +130,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.IndentSelectionCommand && keyStr === 'Ctrl-Alt-\\') { if (keyBindingKey === KeyBindingKey.IndentSelectionKeyBindingKey && keyStr === 'Ctrl-Alt-\\') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', '⌥', '\\']; // macOS: Cmd+Alt+\ return ['⌘', '⌥', '\\']; // macOS: Cmd+Alt+\
} else { } else {
@@ -138,7 +138,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.CursorMatchingBracketCommand && keyStr === 'Shift-Ctrl-\\') { if (keyBindingKey === KeyBindingKey.CursorMatchingBracketKeyBindingKey && keyStr === 'Shift-Ctrl-\\') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⇧', '⌘', '\\']; // macOS: Shift+Cmd+\ return ['⇧', '⌘', '\\']; // macOS: Shift+Cmd+\
} else { } else {
@@ -146,7 +146,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.ToggleCommentCommand && keyStr === 'Ctrl-/') { if (keyBindingKey === KeyBindingKey.ToggleCommentKeyBindingKey && keyStr === 'Ctrl-/') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', '/']; // macOS: Cmd+/ return ['⌘', '/']; // macOS: Cmd+/
} else { } else {
@@ -155,7 +155,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
// 特殊处理删除快捷键的操作系统差异 // 特殊处理删除快捷键的操作系统差异
if (command === KeyBindingCommand.DeleteGroupBackwardCommand && keyStr === 'Ctrl-Backspace') { if (keyBindingKey === KeyBindingKey.DeleteGroupBackwardKeyBindingKey && keyStr === 'Ctrl-Backspace') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', 'Backspace']; // macOS: Cmd+Backspace return ['⌘', 'Backspace']; // macOS: Cmd+Backspace
} else { } else {
@@ -163,7 +163,7 @@ const parseKeyBinding = (keyStr: string, command?: string): string[] => {
} }
} }
if (command === KeyBindingCommand.DeleteGroupForwardCommand && keyStr === 'Ctrl-Delete') { if (keyBindingKey === KeyBindingKey.DeleteGroupForwardKeyBindingKey && keyStr === 'Ctrl-Delete') {
if (systemStore.isMacOS) { if (systemStore.isMacOS) {
return ['⌘', 'Delete']; // macOS: Cmd+Delete return ['⌘', 'Delete']; // macOS: Cmd+Delete
} else { } else {

20
go.mod
View File

@@ -3,22 +3,24 @@ module voidraft
go 1.25 go 1.25
require ( require (
entgo.io/ent v0.14.5
github.com/creativeprojects/go-selfupdate v1.5.1 github.com/creativeprojects/go-selfupdate v1.5.1
github.com/go-git/go-git/v5 v5.16.3 github.com/go-git/go-git/v5 v5.16.3
github.com/knadh/koanf/parsers/json v1.0.0 github.com/knadh/koanf/parsers/json v1.0.0
github.com/knadh/koanf/providers/file v1.2.0 github.com/knadh/koanf/providers/file v1.2.0
github.com/knadh/koanf/providers/structs v1.0.0 github.com/knadh/koanf/providers/structs v1.0.0
github.com/knadh/koanf/v2 v2.3.0 github.com/knadh/koanf/v2 v2.3.0
github.com/mattn/go-sqlite3 v1.14.32
github.com/stretchr/testify v1.11.1 github.com/stretchr/testify v1.11.1
github.com/wailsapp/wails/v3 v3.0.0-alpha.41 github.com/wailsapp/wails/v3 v3.0.0-alpha.41
golang.org/x/net v0.47.0 golang.org/x/net v0.47.0
golang.org/x/sys v0.38.0 golang.org/x/sys v0.38.0
golang.org/x/text v0.31.0 golang.org/x/text v0.31.0
modernc.org/sqlite v1.40.1
resty.dev/v3 v3.0.0-beta.3 resty.dev/v3 v3.0.0-beta.3
) )
require ( require (
ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 // indirect
code.gitea.io/sdk/gitea v0.22.1 // indirect code.gitea.io/sdk/gitea v0.22.1 // indirect
dario.cat/mergo v1.0.2 // indirect dario.cat/mergo v1.0.2 // indirect
git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 // indirect git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 // indirect
@@ -27,12 +29,14 @@ require (
github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/ProtonMail/go-crypto v1.3.0 // indirect
github.com/adrg/xdg v0.5.3 // indirect github.com/adrg/xdg v0.5.3 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/bep/debounce v1.2.1 // indirect github.com/bep/debounce v1.2.1 // indirect
github.com/bmatcuk/doublestar v1.3.4 // indirect
github.com/cloudflare/circl v1.6.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect
github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/cyphar/filepath-securejoin v0.6.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davidmz/go-pageant v1.0.2 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.9.1 // indirect github.com/ebitengine/purego v0.9.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/structs v1.1.0 // indirect github.com/fatih/structs v1.1.0 // indirect
@@ -41,15 +45,18 @@ require (
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/godbus/dbus/v5 v5.2.0 // indirect github.com/godbus/dbus/v5 v5.2.0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-github/v30 v30.1.0 // indirect github.com/google/go-github/v30 v30.1.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/hcl/v2 v2.18.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 // indirect github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 // indirect
github.com/kevinburke/ssh_config v1.4.0 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect
@@ -61,13 +68,12 @@ require (
github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/pjbgf/sha1cd v0.5.0 // indirect github.com/pjbgf/sha1cd v0.5.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/samber/lo v1.52.0 // indirect github.com/samber/lo v1.52.0 // indirect
github.com/sergi/go-diff v1.4.0 // indirect github.com/sergi/go-diff v1.4.0 // indirect
@@ -77,15 +83,15 @@ require (
github.com/wailsapp/mimetype v1.4.1 // indirect github.com/wailsapp/mimetype v1.4.1 // indirect
github.com/xanzy/go-gitlab v0.115.0 // indirect github.com/xanzy/go-gitlab v0.115.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/zclconf/go-cty v1.14.4 // indirect
github.com/zclconf/go-cty-yaml v1.1.0 // indirect
golang.org/x/crypto v0.45.0 // indirect golang.org/x/crypto v0.45.0 // indirect
golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 // indirect golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 // indirect
golang.org/x/image v0.33.0 // indirect golang.org/x/image v0.33.0 // indirect
golang.org/x/mod v0.30.0 // indirect
golang.org/x/oauth2 v0.33.0 // indirect golang.org/x/oauth2 v0.33.0 // indirect
golang.org/x/time v0.14.0 // indirect golang.org/x/time v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.67.0 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
) )

70
go.sum
View File

@@ -1,11 +1,17 @@
ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 h1:E0wvcUXTkgyN4wy4LGtNzMNGMytJN8afmIWXJVMi4cc=
ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w=
code.gitea.io/sdk/gitea v0.22.1 h1:7K05KjRORyTcTYULQ/AwvlVS6pawLcWyXZcTr7gHFyA= code.gitea.io/sdk/gitea v0.22.1 h1:7K05KjRORyTcTYULQ/AwvlVS6pawLcWyXZcTr7gHFyA=
code.gitea.io/sdk/gitea v0.22.1/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= code.gitea.io/sdk/gitea v0.22.1/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
entgo.io/ent v0.14.5 h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4=
entgo.io/ent v0.14.5/go.mod h1:zTzLmWtPvGpmSwtkaayM2cm5m819NdM7z7tYPq3vN0U=
git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 h1:N3IGoHHp9pb6mj1cbXbuaSXV/UMKwmbKLf53nQmtqMA= git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 h1:N3IGoHHp9pb6mj1cbXbuaSXV/UMKwmbKLf53nQmtqMA=
git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3/go.mod h1:QtOLZGz8olr4qH2vWK0QH0w0O4T9fEIjMuWpKUsH7nc= git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3/go.mod h1:QtOLZGz8olr4qH2vWK0QH0w0O4T9fEIjMuWpKUsH7nc=
github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs= github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM= github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
@@ -15,12 +21,18 @@ github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBi
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/creativeprojects/go-selfupdate v1.5.1 h1:fuyEGFFfqcC8SxDGolcEPYPLXGQ9Mcrc5uRyRG2Mqnk= github.com/creativeprojects/go-selfupdate v1.5.1 h1:fuyEGFFfqcC8SxDGolcEPYPLXGQ9Mcrc5uRyRG2Mqnk=
@@ -32,8 +44,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0= github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A= github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=
github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
@@ -60,6 +70,10 @@ github.com/go-git/go-git/v5 v5.16.3 h1:Z8BtvxZ09bYm/yYNgPKCzgWtaRqDTgIKRgIRHBfU6
github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8= github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8=
@@ -75,8 +89,6 @@ github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQF
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
@@ -87,8 +99,8 @@ github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVU
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 h1:njuLRcjAuMKr7kI3D85AXWkw6/+v9PwtV6M6o11sWHQ= github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 h1:njuLRcjAuMKr7kI3D85AXWkw6/+v9PwtV6M6o11sWHQ=
@@ -114,6 +126,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A= github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A=
github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU= github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M= github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M=
@@ -127,12 +141,14 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs=
github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0=
@@ -143,8 +159,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -174,6 +188,10 @@ github.com/xanzy/go-gitlab v0.115.0 h1:6DmtItNcVe+At/liXSgfE/DZNZrGfalQmBRmOcJjO
github.com/xanzy/go-gitlab v0.115.0/go.mod h1:5XCDtM7AM6WMKmfDdOiEpyRWUqui2iS9ILfvCZ2gJ5M= github.com/xanzy/go-gitlab v0.115.0/go.mod h1:5XCDtM7AM6WMKmfDdOiEpyRWUqui2iS9ILfvCZ2gJ5M=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8=
github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0=
github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
@@ -196,8 +214,6 @@ golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -222,8 +238,6 @@ golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -238,33 +252,5 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc=
modernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM=
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE=
modernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.67.0 h1:QzL4IrKab2OFmxA3/vRYl0tLXrIamwrhD6CKD4WBVjQ=
modernc.org/libc v1.67.0/go.mod h1:QvvnnJ5P7aitu0ReNpVIEyesuhmDLQ8kaEoyMjIFZJA=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.40.1 h1:VfuXcxcUWWKRBuP8+BR9L7VnmusMgBNNnBYGEe9w/iY=
modernc.org/sqlite v1.40.1/go.mod h1:9fjQZ0mB1LLP0GYrp39oOJXx/I2sxEnZtzCmEQIKvGE=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
resty.dev/v3 v3.0.0-beta.3 h1:3kEwzEgCnnS6Ob4Emlk94t+I/gClyoah7SnNi67lt+E= resty.dev/v3 v3.0.0-beta.3 h1:3kEwzEgCnnS6Ob4Emlk94t+I/gClyoah7SnNi67lt+E=
resty.dev/v3 v3.0.0-beta.3/go.mod h1:OgkqiPvTDtOuV4MGZuUDhwOpkY8enjOsjjMzeOHefy4= resty.dev/v3 v3.0.0-beta.3/go.mod h1:OgkqiPvTDtOuV4MGZuUDhwOpkY8enjOsjjMzeOHefy4=

View File

@@ -1,28 +0,0 @@
package models
// Git备份相关类型定义
type (
// AuthMethod 定义Git认证方式
AuthMethod string
)
const (
// 认证方式
Token AuthMethod = "token"
SSHKey AuthMethod = "ssh_key"
UserPass AuthMethod = "user_pass"
)
// GitBackupConfig Git备份配置
type GitBackupConfig struct {
Enabled bool `json:"enabled"`
RepoURL string `json:"repo_url"`
AuthMethod AuthMethod `json:"auth_method"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Token string `json:"token,omitempty"`
SSHKeyPath string `json:"ssh_key_path,omitempty"`
SSHKeyPass string `json:"ssh_key_passphrase,omitempty"`
BackupInterval int `json:"backup_interval"` // 分钟
AutoBackup bool `json:"auto_backup"`
}

View File

@@ -126,6 +126,33 @@ type UpdatesConfig struct {
Gitea GiteaConfig `json:"gitea"` // Gitea配置 Gitea GiteaConfig `json:"gitea"` // Gitea配置
} }
// Git备份相关类型定义
type (
// AuthMethod 定义Git认证方式
AuthMethod string
)
const (
// 认证方式
Token AuthMethod = "token"
SSHKey AuthMethod = "ssh_key"
UserPass AuthMethod = "user_pass"
)
// GitBackupConfig Git备份配置
type GitBackupConfig struct {
Enabled bool `json:"enabled"`
RepoURL string `json:"repo_url"`
AuthMethod AuthMethod `json:"auth_method"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Token string `json:"token,omitempty"`
SSHKeyPath string `json:"ssh_key_path,omitempty"`
SSHKeyPass string `json:"ssh_key_passphrase,omitempty"`
BackupInterval int `json:"backup_interval"` // 分钟
AutoBackup bool `json:"auto_backup"`
}
// AppConfig 应用配置 - 按照前端设置页面分类组织 // AppConfig 应用配置 - 按照前端设置页面分类组织
type AppConfig struct { type AppConfig struct {
General GeneralConfig `json:"general"` // 通用设置 General GeneralConfig `json:"general"` // 通用设置

View File

@@ -1,34 +0,0 @@
package models
import (
"time"
)
// Document represents a document in the system
type Document struct {
ID int64 `json:"id" db:"id"`
Title string `json:"title" db:"title"`
Content string `json:"content" db:"content"`
CreatedAt string `json:"createdAt" db:"created_at"`
UpdatedAt string `json:"updatedAt" db:"updated_at"`
IsDeleted bool `json:"is_deleted" db:"is_deleted"`
IsLocked bool `json:"is_locked" db:"is_locked"` // 锁定标志,锁定的文档无法被删除
}
// NewDocument 创建新文档
func NewDocument(title, content string) *Document {
now := time.Now()
return &Document{
Title: title,
Content: content,
CreatedAt: now.String(),
UpdatedAt: now.String(),
IsDeleted: false,
IsLocked: false, // 默认不锁定
}
}
// NewDefaultDocument 创建默认文档
func NewDefaultDocument() *Document {
return NewDocument("default", "\n∞∞∞text-a\n")
}

View File

@@ -0,0 +1,804 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"log"
"reflect"
"voidraft/internal/models/ent/migrate"
"voidraft/internal/models/ent/document"
"voidraft/internal/models/ent/extension"
"voidraft/internal/models/ent/keybinding"
"voidraft/internal/models/ent/theme"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
stdsql "database/sql"
)
// Client is the client that holds all ent builders.
type Client struct {
config
// Schema is the client for creating, migrating and dropping schema.
Schema *migrate.Schema
// Document is the client for interacting with the Document builders.
Document *DocumentClient
// Extension is the client for interacting with the Extension builders.
Extension *ExtensionClient
// KeyBinding is the client for interacting with the KeyBinding builders.
KeyBinding *KeyBindingClient
// Theme is the client for interacting with the Theme builders.
Theme *ThemeClient
}
// NewClient creates a new client configured with the given options.
func NewClient(opts ...Option) *Client {
client := &Client{config: newConfig(opts...)}
client.init()
return client
}
func (c *Client) init() {
c.Schema = migrate.NewSchema(c.driver)
c.Document = NewDocumentClient(c.config)
c.Extension = NewExtensionClient(c.config)
c.KeyBinding = NewKeyBindingClient(c.config)
c.Theme = NewThemeClient(c.config)
}
type (
// config is the configuration for the client and its builder.
config struct {
// driver used for executing database requests.
driver dialect.Driver
// debug enable a debug logging.
debug bool
// log used for logging on debug mode.
log func(...any)
// hooks to execute on mutations.
hooks *hooks
// interceptors to execute on queries.
inters *inters
}
// Option function to configure the client.
Option func(*config)
)
// newConfig creates a new config for the client.
func newConfig(opts ...Option) config {
cfg := config{log: log.Println, hooks: &hooks{}, inters: &inters{}}
cfg.options(opts...)
return cfg
}
// options applies the options on the config object.
func (c *config) options(opts ...Option) {
for _, opt := range opts {
opt(c)
}
if c.debug {
c.driver = dialect.Debug(c.driver, c.log)
}
}
// Debug enables debug logging on the ent.Driver.
func Debug() Option {
return func(c *config) {
c.debug = true
}
}
// Log sets the logging function for debug mode.
func Log(fn func(...any)) Option {
return func(c *config) {
c.log = fn
}
}
// Driver configures the client driver.
func Driver(driver dialect.Driver) Option {
return func(c *config) {
c.driver = driver
}
}
// Open opens a database/sql.DB specified by the driver name and
// the data source name, and returns a new client attached to it.
// Optional parameters can be added for configuring the client.
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite:
drv, err := sql.Open(driverName, dataSourceName)
if err != nil {
return nil, err
}
return NewClient(append(options, Driver(drv))...), nil
default:
return nil, fmt.Errorf("unsupported driver: %q", driverName)
}
}
// ErrTxStarted is returned when trying to start a new transaction from a transactional client.
var ErrTxStarted = errors.New("ent: cannot start a transaction within a transaction")
// Tx returns a new transactional client. The provided context
// is used until the transaction is committed or rolled back.
func (c *Client) Tx(ctx context.Context) (*Tx, error) {
if _, ok := c.driver.(*txDriver); ok {
return nil, ErrTxStarted
}
tx, err := newTx(ctx, c.driver)
if err != nil {
return nil, fmt.Errorf("ent: starting a transaction: %w", err)
}
cfg := c.config
cfg.driver = tx
return &Tx{
ctx: ctx,
config: cfg,
Document: NewDocumentClient(cfg),
Extension: NewExtensionClient(cfg),
KeyBinding: NewKeyBindingClient(cfg),
Theme: NewThemeClient(cfg),
}, nil
}
// BeginTx returns a transactional client with specified options.
func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
if _, ok := c.driver.(*txDriver); ok {
return nil, errors.New("ent: cannot start a transaction within a transaction")
}
tx, err := c.driver.(interface {
BeginTx(context.Context, *sql.TxOptions) (dialect.Tx, error)
}).BeginTx(ctx, opts)
if err != nil {
return nil, fmt.Errorf("ent: starting a transaction: %w", err)
}
cfg := c.config
cfg.driver = &txDriver{tx: tx, drv: c.driver}
return &Tx{
ctx: ctx,
config: cfg,
Document: NewDocumentClient(cfg),
Extension: NewExtensionClient(cfg),
KeyBinding: NewKeyBindingClient(cfg),
Theme: NewThemeClient(cfg),
}, nil
}
// Debug returns a new debug-client. It's used to get verbose logging on specific operations.
//
// client.Debug().
// Document.
// Query().
// Count(ctx)
func (c *Client) Debug() *Client {
if c.debug {
return c
}
cfg := c.config
cfg.driver = dialect.Debug(c.driver, c.log)
client := &Client{config: cfg}
client.init()
return client
}
// Close closes the database connection and prevents new queries from starting.
func (c *Client) Close() error {
return c.driver.Close()
}
// Use adds the mutation hooks to all the entity clients.
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
func (c *Client) Use(hooks ...Hook) {
c.Document.Use(hooks...)
c.Extension.Use(hooks...)
c.KeyBinding.Use(hooks...)
c.Theme.Use(hooks...)
}
// Intercept adds the query interceptors to all the entity clients.
// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
func (c *Client) Intercept(interceptors ...Interceptor) {
c.Document.Intercept(interceptors...)
c.Extension.Intercept(interceptors...)
c.KeyBinding.Intercept(interceptors...)
c.Theme.Intercept(interceptors...)
}
// Mutate implements the ent.Mutator interface.
func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
switch m := m.(type) {
case *DocumentMutation:
return c.Document.mutate(ctx, m)
case *ExtensionMutation:
return c.Extension.mutate(ctx, m)
case *KeyBindingMutation:
return c.KeyBinding.mutate(ctx, m)
case *ThemeMutation:
return c.Theme.mutate(ctx, m)
default:
return nil, fmt.Errorf("ent: unknown mutation type %T", m)
}
}
// DocumentClient is a client for the Document schema.
type DocumentClient struct {
config
}
// NewDocumentClient returns a client for the Document from the given config.
func NewDocumentClient(c config) *DocumentClient {
return &DocumentClient{config: c}
}
// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `document.Hooks(f(g(h())))`.
func (c *DocumentClient) Use(hooks ...Hook) {
c.hooks.Document = append(c.hooks.Document, hooks...)
}
// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `document.Intercept(f(g(h())))`.
func (c *DocumentClient) Intercept(interceptors ...Interceptor) {
c.inters.Document = append(c.inters.Document, interceptors...)
}
// Create returns a builder for creating a Document entity.
func (c *DocumentClient) Create() *DocumentCreate {
mutation := newDocumentMutation(c.config, OpCreate)
return &DocumentCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// CreateBulk returns a builder for creating a bulk of Document entities.
func (c *DocumentClient) CreateBulk(builders ...*DocumentCreate) *DocumentCreateBulk {
return &DocumentCreateBulk{config: c.config, builders: builders}
}
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *DocumentClient) MapCreateBulk(slice any, setFunc func(*DocumentCreate, int)) *DocumentCreateBulk {
rv := reflect.ValueOf(slice)
if rv.Kind() != reflect.Slice {
return &DocumentCreateBulk{err: fmt.Errorf("calling to DocumentClient.MapCreateBulk with wrong type %T, need slice", slice)}
}
builders := make([]*DocumentCreate, rv.Len())
for i := 0; i < rv.Len(); i++ {
builders[i] = c.Create()
setFunc(builders[i], i)
}
return &DocumentCreateBulk{config: c.config, builders: builders}
}
// Update returns an update builder for Document.
func (c *DocumentClient) Update() *DocumentUpdate {
mutation := newDocumentMutation(c.config, OpUpdate)
return &DocumentUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOne returns an update builder for the given entity.
func (c *DocumentClient) UpdateOne(_m *Document) *DocumentUpdateOne {
mutation := newDocumentMutation(c.config, OpUpdateOne, withDocument(_m))
return &DocumentUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *DocumentClient) UpdateOneID(id int) *DocumentUpdateOne {
mutation := newDocumentMutation(c.config, OpUpdateOne, withDocumentID(id))
return &DocumentUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for Document.
func (c *DocumentClient) Delete() *DocumentDelete {
mutation := newDocumentMutation(c.config, OpDelete)
return &DocumentDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// DeleteOne returns a builder for deleting the given entity.
func (c *DocumentClient) DeleteOne(_m *Document) *DocumentDeleteOne {
return c.DeleteOneID(_m.ID)
}
// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *DocumentClient) DeleteOneID(id int) *DocumentDeleteOne {
builder := c.Delete().Where(document.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &DocumentDeleteOne{builder}
}
// Query returns a query builder for Document.
func (c *DocumentClient) Query() *DocumentQuery {
return &DocumentQuery{
config: c.config,
ctx: &QueryContext{Type: TypeDocument},
inters: c.Interceptors(),
}
}
// Get returns a Document entity by its id.
func (c *DocumentClient) Get(ctx context.Context, id int) (*Document, error) {
return c.Query().Where(document.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *DocumentClient) GetX(ctx context.Context, id int) *Document {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// Hooks returns the client hooks.
func (c *DocumentClient) Hooks() []Hook {
hooks := c.hooks.Document
return append(hooks[:len(hooks):len(hooks)], document.Hooks[:]...)
}
// Interceptors returns the client interceptors.
func (c *DocumentClient) Interceptors() []Interceptor {
inters := c.inters.Document
return append(inters[:len(inters):len(inters)], document.Interceptors[:]...)
}
func (c *DocumentClient) mutate(ctx context.Context, m *DocumentMutation) (Value, error) {
switch m.Op() {
case OpCreate:
return (&DocumentCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdate:
return (&DocumentUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdateOne:
return (&DocumentUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpDelete, OpDeleteOne:
return (&DocumentDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
default:
return nil, fmt.Errorf("ent: unknown Document mutation op: %q", m.Op())
}
}
// ExtensionClient is a client for the Extension schema.
type ExtensionClient struct {
config
}
// NewExtensionClient returns a client for the Extension from the given config.
func NewExtensionClient(c config) *ExtensionClient {
return &ExtensionClient{config: c}
}
// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `extension.Hooks(f(g(h())))`.
func (c *ExtensionClient) Use(hooks ...Hook) {
c.hooks.Extension = append(c.hooks.Extension, hooks...)
}
// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `extension.Intercept(f(g(h())))`.
func (c *ExtensionClient) Intercept(interceptors ...Interceptor) {
c.inters.Extension = append(c.inters.Extension, interceptors...)
}
// Create returns a builder for creating a Extension entity.
func (c *ExtensionClient) Create() *ExtensionCreate {
mutation := newExtensionMutation(c.config, OpCreate)
return &ExtensionCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// CreateBulk returns a builder for creating a bulk of Extension entities.
func (c *ExtensionClient) CreateBulk(builders ...*ExtensionCreate) *ExtensionCreateBulk {
return &ExtensionCreateBulk{config: c.config, builders: builders}
}
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *ExtensionClient) MapCreateBulk(slice any, setFunc func(*ExtensionCreate, int)) *ExtensionCreateBulk {
rv := reflect.ValueOf(slice)
if rv.Kind() != reflect.Slice {
return &ExtensionCreateBulk{err: fmt.Errorf("calling to ExtensionClient.MapCreateBulk with wrong type %T, need slice", slice)}
}
builders := make([]*ExtensionCreate, rv.Len())
for i := 0; i < rv.Len(); i++ {
builders[i] = c.Create()
setFunc(builders[i], i)
}
return &ExtensionCreateBulk{config: c.config, builders: builders}
}
// Update returns an update builder for Extension.
func (c *ExtensionClient) Update() *ExtensionUpdate {
mutation := newExtensionMutation(c.config, OpUpdate)
return &ExtensionUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOne returns an update builder for the given entity.
func (c *ExtensionClient) UpdateOne(_m *Extension) *ExtensionUpdateOne {
mutation := newExtensionMutation(c.config, OpUpdateOne, withExtension(_m))
return &ExtensionUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *ExtensionClient) UpdateOneID(id int) *ExtensionUpdateOne {
mutation := newExtensionMutation(c.config, OpUpdateOne, withExtensionID(id))
return &ExtensionUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for Extension.
func (c *ExtensionClient) Delete() *ExtensionDelete {
mutation := newExtensionMutation(c.config, OpDelete)
return &ExtensionDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// DeleteOne returns a builder for deleting the given entity.
func (c *ExtensionClient) DeleteOne(_m *Extension) *ExtensionDeleteOne {
return c.DeleteOneID(_m.ID)
}
// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *ExtensionClient) DeleteOneID(id int) *ExtensionDeleteOne {
builder := c.Delete().Where(extension.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &ExtensionDeleteOne{builder}
}
// Query returns a query builder for Extension.
func (c *ExtensionClient) Query() *ExtensionQuery {
return &ExtensionQuery{
config: c.config,
ctx: &QueryContext{Type: TypeExtension},
inters: c.Interceptors(),
}
}
// Get returns a Extension entity by its id.
func (c *ExtensionClient) Get(ctx context.Context, id int) (*Extension, error) {
return c.Query().Where(extension.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *ExtensionClient) GetX(ctx context.Context, id int) *Extension {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// Hooks returns the client hooks.
func (c *ExtensionClient) Hooks() []Hook {
hooks := c.hooks.Extension
return append(hooks[:len(hooks):len(hooks)], extension.Hooks[:]...)
}
// Interceptors returns the client interceptors.
func (c *ExtensionClient) Interceptors() []Interceptor {
inters := c.inters.Extension
return append(inters[:len(inters):len(inters)], extension.Interceptors[:]...)
}
func (c *ExtensionClient) mutate(ctx context.Context, m *ExtensionMutation) (Value, error) {
switch m.Op() {
case OpCreate:
return (&ExtensionCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdate:
return (&ExtensionUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdateOne:
return (&ExtensionUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpDelete, OpDeleteOne:
return (&ExtensionDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
default:
return nil, fmt.Errorf("ent: unknown Extension mutation op: %q", m.Op())
}
}
// KeyBindingClient is a client for the KeyBinding schema.
type KeyBindingClient struct {
config
}
// NewKeyBindingClient returns a client for the KeyBinding from the given config.
func NewKeyBindingClient(c config) *KeyBindingClient {
return &KeyBindingClient{config: c}
}
// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `keybinding.Hooks(f(g(h())))`.
func (c *KeyBindingClient) Use(hooks ...Hook) {
c.hooks.KeyBinding = append(c.hooks.KeyBinding, hooks...)
}
// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `keybinding.Intercept(f(g(h())))`.
func (c *KeyBindingClient) Intercept(interceptors ...Interceptor) {
c.inters.KeyBinding = append(c.inters.KeyBinding, interceptors...)
}
// Create returns a builder for creating a KeyBinding entity.
func (c *KeyBindingClient) Create() *KeyBindingCreate {
mutation := newKeyBindingMutation(c.config, OpCreate)
return &KeyBindingCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// CreateBulk returns a builder for creating a bulk of KeyBinding entities.
func (c *KeyBindingClient) CreateBulk(builders ...*KeyBindingCreate) *KeyBindingCreateBulk {
return &KeyBindingCreateBulk{config: c.config, builders: builders}
}
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *KeyBindingClient) MapCreateBulk(slice any, setFunc func(*KeyBindingCreate, int)) *KeyBindingCreateBulk {
rv := reflect.ValueOf(slice)
if rv.Kind() != reflect.Slice {
return &KeyBindingCreateBulk{err: fmt.Errorf("calling to KeyBindingClient.MapCreateBulk with wrong type %T, need slice", slice)}
}
builders := make([]*KeyBindingCreate, rv.Len())
for i := 0; i < rv.Len(); i++ {
builders[i] = c.Create()
setFunc(builders[i], i)
}
return &KeyBindingCreateBulk{config: c.config, builders: builders}
}
// Update returns an update builder for KeyBinding.
func (c *KeyBindingClient) Update() *KeyBindingUpdate {
mutation := newKeyBindingMutation(c.config, OpUpdate)
return &KeyBindingUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOne returns an update builder for the given entity.
func (c *KeyBindingClient) UpdateOne(_m *KeyBinding) *KeyBindingUpdateOne {
mutation := newKeyBindingMutation(c.config, OpUpdateOne, withKeyBinding(_m))
return &KeyBindingUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *KeyBindingClient) UpdateOneID(id int) *KeyBindingUpdateOne {
mutation := newKeyBindingMutation(c.config, OpUpdateOne, withKeyBindingID(id))
return &KeyBindingUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for KeyBinding.
func (c *KeyBindingClient) Delete() *KeyBindingDelete {
mutation := newKeyBindingMutation(c.config, OpDelete)
return &KeyBindingDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// DeleteOne returns a builder for deleting the given entity.
func (c *KeyBindingClient) DeleteOne(_m *KeyBinding) *KeyBindingDeleteOne {
return c.DeleteOneID(_m.ID)
}
// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *KeyBindingClient) DeleteOneID(id int) *KeyBindingDeleteOne {
builder := c.Delete().Where(keybinding.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &KeyBindingDeleteOne{builder}
}
// Query returns a query builder for KeyBinding.
func (c *KeyBindingClient) Query() *KeyBindingQuery {
return &KeyBindingQuery{
config: c.config,
ctx: &QueryContext{Type: TypeKeyBinding},
inters: c.Interceptors(),
}
}
// Get returns a KeyBinding entity by its id.
func (c *KeyBindingClient) Get(ctx context.Context, id int) (*KeyBinding, error) {
return c.Query().Where(keybinding.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *KeyBindingClient) GetX(ctx context.Context, id int) *KeyBinding {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// Hooks returns the client hooks.
func (c *KeyBindingClient) Hooks() []Hook {
hooks := c.hooks.KeyBinding
return append(hooks[:len(hooks):len(hooks)], keybinding.Hooks[:]...)
}
// Interceptors returns the client interceptors.
func (c *KeyBindingClient) Interceptors() []Interceptor {
inters := c.inters.KeyBinding
return append(inters[:len(inters):len(inters)], keybinding.Interceptors[:]...)
}
func (c *KeyBindingClient) mutate(ctx context.Context, m *KeyBindingMutation) (Value, error) {
switch m.Op() {
case OpCreate:
return (&KeyBindingCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdate:
return (&KeyBindingUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdateOne:
return (&KeyBindingUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpDelete, OpDeleteOne:
return (&KeyBindingDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
default:
return nil, fmt.Errorf("ent: unknown KeyBinding mutation op: %q", m.Op())
}
}
// ThemeClient is a client for the Theme schema.
type ThemeClient struct {
config
}
// NewThemeClient returns a client for the Theme from the given config.
func NewThemeClient(c config) *ThemeClient {
return &ThemeClient{config: c}
}
// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `theme.Hooks(f(g(h())))`.
func (c *ThemeClient) Use(hooks ...Hook) {
c.hooks.Theme = append(c.hooks.Theme, hooks...)
}
// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `theme.Intercept(f(g(h())))`.
func (c *ThemeClient) Intercept(interceptors ...Interceptor) {
c.inters.Theme = append(c.inters.Theme, interceptors...)
}
// Create returns a builder for creating a Theme entity.
func (c *ThemeClient) Create() *ThemeCreate {
mutation := newThemeMutation(c.config, OpCreate)
return &ThemeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// CreateBulk returns a builder for creating a bulk of Theme entities.
func (c *ThemeClient) CreateBulk(builders ...*ThemeCreate) *ThemeCreateBulk {
return &ThemeCreateBulk{config: c.config, builders: builders}
}
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *ThemeClient) MapCreateBulk(slice any, setFunc func(*ThemeCreate, int)) *ThemeCreateBulk {
rv := reflect.ValueOf(slice)
if rv.Kind() != reflect.Slice {
return &ThemeCreateBulk{err: fmt.Errorf("calling to ThemeClient.MapCreateBulk with wrong type %T, need slice", slice)}
}
builders := make([]*ThemeCreate, rv.Len())
for i := 0; i < rv.Len(); i++ {
builders[i] = c.Create()
setFunc(builders[i], i)
}
return &ThemeCreateBulk{config: c.config, builders: builders}
}
// Update returns an update builder for Theme.
func (c *ThemeClient) Update() *ThemeUpdate {
mutation := newThemeMutation(c.config, OpUpdate)
return &ThemeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOne returns an update builder for the given entity.
func (c *ThemeClient) UpdateOne(_m *Theme) *ThemeUpdateOne {
mutation := newThemeMutation(c.config, OpUpdateOne, withTheme(_m))
return &ThemeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *ThemeClient) UpdateOneID(id int) *ThemeUpdateOne {
mutation := newThemeMutation(c.config, OpUpdateOne, withThemeID(id))
return &ThemeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for Theme.
func (c *ThemeClient) Delete() *ThemeDelete {
mutation := newThemeMutation(c.config, OpDelete)
return &ThemeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// DeleteOne returns a builder for deleting the given entity.
func (c *ThemeClient) DeleteOne(_m *Theme) *ThemeDeleteOne {
return c.DeleteOneID(_m.ID)
}
// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *ThemeClient) DeleteOneID(id int) *ThemeDeleteOne {
builder := c.Delete().Where(theme.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &ThemeDeleteOne{builder}
}
// Query returns a query builder for Theme.
func (c *ThemeClient) Query() *ThemeQuery {
return &ThemeQuery{
config: c.config,
ctx: &QueryContext{Type: TypeTheme},
inters: c.Interceptors(),
}
}
// Get returns a Theme entity by its id.
func (c *ThemeClient) Get(ctx context.Context, id int) (*Theme, error) {
return c.Query().Where(theme.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *ThemeClient) GetX(ctx context.Context, id int) *Theme {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// Hooks returns the client hooks.
func (c *ThemeClient) Hooks() []Hook {
hooks := c.hooks.Theme
return append(hooks[:len(hooks):len(hooks)], theme.Hooks[:]...)
}
// Interceptors returns the client interceptors.
func (c *ThemeClient) Interceptors() []Interceptor {
inters := c.inters.Theme
return append(inters[:len(inters):len(inters)], theme.Interceptors[:]...)
}
func (c *ThemeClient) mutate(ctx context.Context, m *ThemeMutation) (Value, error) {
switch m.Op() {
case OpCreate:
return (&ThemeCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdate:
return (&ThemeUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpUpdateOne:
return (&ThemeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
case OpDelete, OpDeleteOne:
return (&ThemeDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
default:
return nil, fmt.Errorf("ent: unknown Theme mutation op: %q", m.Op())
}
}
// hooks and interceptors per client, for fast access.
type (
hooks struct {
Document, Extension, KeyBinding, Theme []ent.Hook
}
inters struct {
Document, Extension, KeyBinding, Theme []ent.Interceptor
}
)
// ExecContext allows calling the underlying ExecContext method of the driver if it is supported by it.
// See, database/sql#DB.ExecContext for more information.
func (c *config) ExecContext(ctx context.Context, query string, args ...any) (stdsql.Result, error) {
ex, ok := c.driver.(interface {
ExecContext(context.Context, string, ...any) (stdsql.Result, error)
})
if !ok {
return nil, fmt.Errorf("Driver.ExecContext is not supported")
}
return ex.ExecContext(ctx, query, args...)
}
// QueryContext allows calling the underlying QueryContext method of the driver if it is supported by it.
// See, database/sql#DB.QueryContext for more information.
func (c *config) QueryContext(ctx context.Context, query string, args ...any) (*stdsql.Rows, error) {
q, ok := c.driver.(interface {
QueryContext(context.Context, string, ...any) (*stdsql.Rows, error)
})
if !ok {
return nil, fmt.Errorf("Driver.QueryContext is not supported")
}
return q.QueryContext(ctx, query, args...)
}

View File

@@ -0,0 +1,163 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"voidraft/internal/models/ent/document"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
)
// Document is the model entity for the Document schema.
type Document struct {
config `json:"-"`
// ID of the ent.
ID int `json:"id,omitempty"`
// 创建时间
CreatedAt string `json:"created_at"`
// 最后更新时间
UpdatedAt string `json:"updated_at"`
// 删除时间NULL表示未删除
DeletedAt *string `json:"deleted_at,omitempty"`
// 文档标题
Title string `json:"title"`
// 文档内容
Content string `json:"content"`
// 是否锁定
Locked bool `json:"locked"`
selectValues sql.SelectValues
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Document) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case document.FieldLocked:
values[i] = new(sql.NullBool)
case document.FieldID:
values[i] = new(sql.NullInt64)
case document.FieldCreatedAt, document.FieldUpdatedAt, document.FieldDeletedAt, document.FieldTitle, document.FieldContent:
values[i] = new(sql.NullString)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Document fields.
func (_m *Document) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case document.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
_m.ID = int(value.Int64)
case document.FieldCreatedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
_m.CreatedAt = value.String
}
case document.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
_m.UpdatedAt = value.String
}
case document.FieldDeletedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
} else if value.Valid {
_m.DeletedAt = new(string)
*_m.DeletedAt = value.String
}
case document.FieldTitle:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field title", values[i])
} else if value.Valid {
_m.Title = value.String
}
case document.FieldContent:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field content", values[i])
} else if value.Valid {
_m.Content = value.String
}
case document.FieldLocked:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field locked", values[i])
} else if value.Valid {
_m.Locked = value.Bool
}
default:
_m.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the Document.
// This includes values selected through modifiers, order, etc.
func (_m *Document) Value(name string) (ent.Value, error) {
return _m.selectValues.Get(name)
}
// Update returns a builder for updating this Document.
// Note that you need to call Document.Unwrap() before calling this method if this Document
// was returned from a transaction, and the transaction was committed or rolled back.
func (_m *Document) Update() *DocumentUpdateOne {
return NewDocumentClient(_m.config).UpdateOne(_m)
}
// Unwrap unwraps the Document entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (_m *Document) Unwrap() *Document {
_tx, ok := _m.config.driver.(*txDriver)
if !ok {
panic("ent: Document is not a transactional entity")
}
_m.config.driver = _tx.drv
return _m
}
// String implements the fmt.Stringer.
func (_m *Document) String() string {
var builder strings.Builder
builder.WriteString("Document(")
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
builder.WriteString("created_at=")
builder.WriteString(_m.CreatedAt)
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(_m.UpdatedAt)
builder.WriteString(", ")
if v := _m.DeletedAt; v != nil {
builder.WriteString("deleted_at=")
builder.WriteString(*v)
}
builder.WriteString(", ")
builder.WriteString("title=")
builder.WriteString(_m.Title)
builder.WriteString(", ")
builder.WriteString("content=")
builder.WriteString(_m.Content)
builder.WriteString(", ")
builder.WriteString("locked=")
builder.WriteString(fmt.Sprintf("%v", _m.Locked))
builder.WriteByte(')')
return builder.String()
}
// Documents is a parsable slice of Document.
type Documents []*Document

View File

@@ -0,0 +1,108 @@
// Code generated by ent, DO NOT EDIT.
package document
import (
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
)
const (
// Label holds the string label denoting the document type in the database.
Label = "document"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
FieldDeletedAt = "deleted_at"
// FieldTitle holds the string denoting the title field in the database.
FieldTitle = "title"
// FieldContent holds the string denoting the content field in the database.
FieldContent = "content"
// FieldLocked holds the string denoting the locked field in the database.
FieldLocked = "locked"
// Table holds the table name of the document in the database.
Table = "documents"
)
// Columns holds all SQL columns for document fields.
var Columns = []string{
FieldID,
FieldCreatedAt,
FieldUpdatedAt,
FieldDeletedAt,
FieldTitle,
FieldContent,
FieldLocked,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
// Note that the variables below are initialized by the runtime
// package on the initialization of the application. Therefore,
// it should be imported in the main as follows:
//
// import _ "voidraft/internal/models/ent/runtime"
var (
Hooks [2]ent.Hook
Interceptors [1]ent.Interceptor
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() string
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() string
// TitleValidator is a validator for the "title" field. It is called by the builders before save.
TitleValidator func(string) error
// DefaultContent holds the default value on creation for the "content" field.
DefaultContent string
// DefaultLocked holds the default value on creation for the "locked" field.
DefaultLocked bool
)
// OrderOption defines the ordering options for the Document queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// ByDeletedAt orders the results by the deleted_at field.
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
}
// ByTitle orders the results by the title field.
func ByTitle(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldTitle, opts...).ToFunc()
}
// ByContent orders the results by the content field.
func ByContent(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldContent, opts...).ToFunc()
}
// ByLocked orders the results by the locked field.
func ByLocked(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldLocked, opts...).ToFunc()
}

View File

@@ -0,0 +1,454 @@
// Code generated by ent, DO NOT EDIT.
package document
import (
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
)
// ID filters vertices based on their ID field.
func ID(id int) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int) predicate.Document {
return predicate.Document(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int) predicate.Document {
return predicate.Document(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int) predicate.Document {
return predicate.Document(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int) predicate.Document {
return predicate.Document(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int) predicate.Document {
return predicate.Document(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int) predicate.Document {
return predicate.Document(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int) predicate.Document {
return predicate.Document(sql.FieldLTE(FieldID, id))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldCreatedAt, v))
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldUpdatedAt, v))
}
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
func DeletedAt(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldDeletedAt, v))
}
// Title applies equality check predicate on the "title" field. It's identical to TitleEQ.
func Title(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldTitle, v))
}
// Content applies equality check predicate on the "content" field. It's identical to ContentEQ.
func Content(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldContent, v))
}
// Locked applies equality check predicate on the "locked" field. It's identical to LockedEQ.
func Locked(v bool) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldLocked, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v string) predicate.Document {
return predicate.Document(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v string) predicate.Document {
return predicate.Document(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v string) predicate.Document {
return predicate.Document(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v string) predicate.Document {
return predicate.Document(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v string) predicate.Document {
return predicate.Document(sql.FieldLTE(FieldCreatedAt, v))
}
// CreatedAtContains applies the Contains predicate on the "created_at" field.
func CreatedAtContains(v string) predicate.Document {
return predicate.Document(sql.FieldContains(FieldCreatedAt, v))
}
// CreatedAtHasPrefix applies the HasPrefix predicate on the "created_at" field.
func CreatedAtHasPrefix(v string) predicate.Document {
return predicate.Document(sql.FieldHasPrefix(FieldCreatedAt, v))
}
// CreatedAtHasSuffix applies the HasSuffix predicate on the "created_at" field.
func CreatedAtHasSuffix(v string) predicate.Document {
return predicate.Document(sql.FieldHasSuffix(FieldCreatedAt, v))
}
// CreatedAtEqualFold applies the EqualFold predicate on the "created_at" field.
func CreatedAtEqualFold(v string) predicate.Document {
return predicate.Document(sql.FieldEqualFold(FieldCreatedAt, v))
}
// CreatedAtContainsFold applies the ContainsFold predicate on the "created_at" field.
func CreatedAtContainsFold(v string) predicate.Document {
return predicate.Document(sql.FieldContainsFold(FieldCreatedAt, v))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldUpdatedAt, v))
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v string) predicate.Document {
return predicate.Document(sql.FieldNEQ(FieldUpdatedAt, v))
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldIn(FieldUpdatedAt, vs...))
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldNotIn(FieldUpdatedAt, vs...))
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v string) predicate.Document {
return predicate.Document(sql.FieldGT(FieldUpdatedAt, v))
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v string) predicate.Document {
return predicate.Document(sql.FieldGTE(FieldUpdatedAt, v))
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v string) predicate.Document {
return predicate.Document(sql.FieldLT(FieldUpdatedAt, v))
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v string) predicate.Document {
return predicate.Document(sql.FieldLTE(FieldUpdatedAt, v))
}
// UpdatedAtContains applies the Contains predicate on the "updated_at" field.
func UpdatedAtContains(v string) predicate.Document {
return predicate.Document(sql.FieldContains(FieldUpdatedAt, v))
}
// UpdatedAtHasPrefix applies the HasPrefix predicate on the "updated_at" field.
func UpdatedAtHasPrefix(v string) predicate.Document {
return predicate.Document(sql.FieldHasPrefix(FieldUpdatedAt, v))
}
// UpdatedAtHasSuffix applies the HasSuffix predicate on the "updated_at" field.
func UpdatedAtHasSuffix(v string) predicate.Document {
return predicate.Document(sql.FieldHasSuffix(FieldUpdatedAt, v))
}
// UpdatedAtEqualFold applies the EqualFold predicate on the "updated_at" field.
func UpdatedAtEqualFold(v string) predicate.Document {
return predicate.Document(sql.FieldEqualFold(FieldUpdatedAt, v))
}
// UpdatedAtContainsFold applies the ContainsFold predicate on the "updated_at" field.
func UpdatedAtContainsFold(v string) predicate.Document {
return predicate.Document(sql.FieldContainsFold(FieldUpdatedAt, v))
}
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
func DeletedAtEQ(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldDeletedAt, v))
}
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
func DeletedAtNEQ(v string) predicate.Document {
return predicate.Document(sql.FieldNEQ(FieldDeletedAt, v))
}
// DeletedAtIn applies the In predicate on the "deleted_at" field.
func DeletedAtIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldIn(FieldDeletedAt, vs...))
}
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
func DeletedAtNotIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldNotIn(FieldDeletedAt, vs...))
}
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
func DeletedAtGT(v string) predicate.Document {
return predicate.Document(sql.FieldGT(FieldDeletedAt, v))
}
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
func DeletedAtGTE(v string) predicate.Document {
return predicate.Document(sql.FieldGTE(FieldDeletedAt, v))
}
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
func DeletedAtLT(v string) predicate.Document {
return predicate.Document(sql.FieldLT(FieldDeletedAt, v))
}
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
func DeletedAtLTE(v string) predicate.Document {
return predicate.Document(sql.FieldLTE(FieldDeletedAt, v))
}
// DeletedAtContains applies the Contains predicate on the "deleted_at" field.
func DeletedAtContains(v string) predicate.Document {
return predicate.Document(sql.FieldContains(FieldDeletedAt, v))
}
// DeletedAtHasPrefix applies the HasPrefix predicate on the "deleted_at" field.
func DeletedAtHasPrefix(v string) predicate.Document {
return predicate.Document(sql.FieldHasPrefix(FieldDeletedAt, v))
}
// DeletedAtHasSuffix applies the HasSuffix predicate on the "deleted_at" field.
func DeletedAtHasSuffix(v string) predicate.Document {
return predicate.Document(sql.FieldHasSuffix(FieldDeletedAt, v))
}
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
func DeletedAtIsNil() predicate.Document {
return predicate.Document(sql.FieldIsNull(FieldDeletedAt))
}
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
func DeletedAtNotNil() predicate.Document {
return predicate.Document(sql.FieldNotNull(FieldDeletedAt))
}
// DeletedAtEqualFold applies the EqualFold predicate on the "deleted_at" field.
func DeletedAtEqualFold(v string) predicate.Document {
return predicate.Document(sql.FieldEqualFold(FieldDeletedAt, v))
}
// DeletedAtContainsFold applies the ContainsFold predicate on the "deleted_at" field.
func DeletedAtContainsFold(v string) predicate.Document {
return predicate.Document(sql.FieldContainsFold(FieldDeletedAt, v))
}
// TitleEQ applies the EQ predicate on the "title" field.
func TitleEQ(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldTitle, v))
}
// TitleNEQ applies the NEQ predicate on the "title" field.
func TitleNEQ(v string) predicate.Document {
return predicate.Document(sql.FieldNEQ(FieldTitle, v))
}
// TitleIn applies the In predicate on the "title" field.
func TitleIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldIn(FieldTitle, vs...))
}
// TitleNotIn applies the NotIn predicate on the "title" field.
func TitleNotIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldNotIn(FieldTitle, vs...))
}
// TitleGT applies the GT predicate on the "title" field.
func TitleGT(v string) predicate.Document {
return predicate.Document(sql.FieldGT(FieldTitle, v))
}
// TitleGTE applies the GTE predicate on the "title" field.
func TitleGTE(v string) predicate.Document {
return predicate.Document(sql.FieldGTE(FieldTitle, v))
}
// TitleLT applies the LT predicate on the "title" field.
func TitleLT(v string) predicate.Document {
return predicate.Document(sql.FieldLT(FieldTitle, v))
}
// TitleLTE applies the LTE predicate on the "title" field.
func TitleLTE(v string) predicate.Document {
return predicate.Document(sql.FieldLTE(FieldTitle, v))
}
// TitleContains applies the Contains predicate on the "title" field.
func TitleContains(v string) predicate.Document {
return predicate.Document(sql.FieldContains(FieldTitle, v))
}
// TitleHasPrefix applies the HasPrefix predicate on the "title" field.
func TitleHasPrefix(v string) predicate.Document {
return predicate.Document(sql.FieldHasPrefix(FieldTitle, v))
}
// TitleHasSuffix applies the HasSuffix predicate on the "title" field.
func TitleHasSuffix(v string) predicate.Document {
return predicate.Document(sql.FieldHasSuffix(FieldTitle, v))
}
// TitleEqualFold applies the EqualFold predicate on the "title" field.
func TitleEqualFold(v string) predicate.Document {
return predicate.Document(sql.FieldEqualFold(FieldTitle, v))
}
// TitleContainsFold applies the ContainsFold predicate on the "title" field.
func TitleContainsFold(v string) predicate.Document {
return predicate.Document(sql.FieldContainsFold(FieldTitle, v))
}
// ContentEQ applies the EQ predicate on the "content" field.
func ContentEQ(v string) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldContent, v))
}
// ContentNEQ applies the NEQ predicate on the "content" field.
func ContentNEQ(v string) predicate.Document {
return predicate.Document(sql.FieldNEQ(FieldContent, v))
}
// ContentIn applies the In predicate on the "content" field.
func ContentIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldIn(FieldContent, vs...))
}
// ContentNotIn applies the NotIn predicate on the "content" field.
func ContentNotIn(vs ...string) predicate.Document {
return predicate.Document(sql.FieldNotIn(FieldContent, vs...))
}
// ContentGT applies the GT predicate on the "content" field.
func ContentGT(v string) predicate.Document {
return predicate.Document(sql.FieldGT(FieldContent, v))
}
// ContentGTE applies the GTE predicate on the "content" field.
func ContentGTE(v string) predicate.Document {
return predicate.Document(sql.FieldGTE(FieldContent, v))
}
// ContentLT applies the LT predicate on the "content" field.
func ContentLT(v string) predicate.Document {
return predicate.Document(sql.FieldLT(FieldContent, v))
}
// ContentLTE applies the LTE predicate on the "content" field.
func ContentLTE(v string) predicate.Document {
return predicate.Document(sql.FieldLTE(FieldContent, v))
}
// ContentContains applies the Contains predicate on the "content" field.
func ContentContains(v string) predicate.Document {
return predicate.Document(sql.FieldContains(FieldContent, v))
}
// ContentHasPrefix applies the HasPrefix predicate on the "content" field.
func ContentHasPrefix(v string) predicate.Document {
return predicate.Document(sql.FieldHasPrefix(FieldContent, v))
}
// ContentHasSuffix applies the HasSuffix predicate on the "content" field.
func ContentHasSuffix(v string) predicate.Document {
return predicate.Document(sql.FieldHasSuffix(FieldContent, v))
}
// ContentIsNil applies the IsNil predicate on the "content" field.
func ContentIsNil() predicate.Document {
return predicate.Document(sql.FieldIsNull(FieldContent))
}
// ContentNotNil applies the NotNil predicate on the "content" field.
func ContentNotNil() predicate.Document {
return predicate.Document(sql.FieldNotNull(FieldContent))
}
// ContentEqualFold applies the EqualFold predicate on the "content" field.
func ContentEqualFold(v string) predicate.Document {
return predicate.Document(sql.FieldEqualFold(FieldContent, v))
}
// ContentContainsFold applies the ContainsFold predicate on the "content" field.
func ContentContainsFold(v string) predicate.Document {
return predicate.Document(sql.FieldContainsFold(FieldContent, v))
}
// LockedEQ applies the EQ predicate on the "locked" field.
func LockedEQ(v bool) predicate.Document {
return predicate.Document(sql.FieldEQ(FieldLocked, v))
}
// LockedNEQ applies the NEQ predicate on the "locked" field.
func LockedNEQ(v bool) predicate.Document {
return predicate.Document(sql.FieldNEQ(FieldLocked, v))
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Document) predicate.Document {
return predicate.Document(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.Document) predicate.Document {
return predicate.Document(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.Document) predicate.Document {
return predicate.Document(sql.NotPredicates(p))
}

View File

@@ -0,0 +1,318 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"voidraft/internal/models/ent/document"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// DocumentCreate is the builder for creating a Document entity.
type DocumentCreate struct {
config
mutation *DocumentMutation
hooks []Hook
}
// SetCreatedAt sets the "created_at" field.
func (_c *DocumentCreate) SetCreatedAt(v string) *DocumentCreate {
_c.mutation.SetCreatedAt(v)
return _c
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (_c *DocumentCreate) SetNillableCreatedAt(v *string) *DocumentCreate {
if v != nil {
_c.SetCreatedAt(*v)
}
return _c
}
// SetUpdatedAt sets the "updated_at" field.
func (_c *DocumentCreate) SetUpdatedAt(v string) *DocumentCreate {
_c.mutation.SetUpdatedAt(v)
return _c
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_c *DocumentCreate) SetNillableUpdatedAt(v *string) *DocumentCreate {
if v != nil {
_c.SetUpdatedAt(*v)
}
return _c
}
// SetDeletedAt sets the "deleted_at" field.
func (_c *DocumentCreate) SetDeletedAt(v string) *DocumentCreate {
_c.mutation.SetDeletedAt(v)
return _c
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_c *DocumentCreate) SetNillableDeletedAt(v *string) *DocumentCreate {
if v != nil {
_c.SetDeletedAt(*v)
}
return _c
}
// SetTitle sets the "title" field.
func (_c *DocumentCreate) SetTitle(v string) *DocumentCreate {
_c.mutation.SetTitle(v)
return _c
}
// SetContent sets the "content" field.
func (_c *DocumentCreate) SetContent(v string) *DocumentCreate {
_c.mutation.SetContent(v)
return _c
}
// SetNillableContent sets the "content" field if the given value is not nil.
func (_c *DocumentCreate) SetNillableContent(v *string) *DocumentCreate {
if v != nil {
_c.SetContent(*v)
}
return _c
}
// SetLocked sets the "locked" field.
func (_c *DocumentCreate) SetLocked(v bool) *DocumentCreate {
_c.mutation.SetLocked(v)
return _c
}
// SetNillableLocked sets the "locked" field if the given value is not nil.
func (_c *DocumentCreate) SetNillableLocked(v *bool) *DocumentCreate {
if v != nil {
_c.SetLocked(*v)
}
return _c
}
// Mutation returns the DocumentMutation object of the builder.
func (_c *DocumentCreate) Mutation() *DocumentMutation {
return _c.mutation
}
// Save creates the Document in the database.
func (_c *DocumentCreate) Save(ctx context.Context) (*Document, error) {
if err := _c.defaults(); err != nil {
return nil, err
}
return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks)
}
// SaveX calls Save and panics if Save returns an error.
func (_c *DocumentCreate) SaveX(ctx context.Context) *Document {
v, err := _c.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (_c *DocumentCreate) Exec(ctx context.Context) error {
_, err := _c.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_c *DocumentCreate) ExecX(ctx context.Context) {
if err := _c.Exec(ctx); err != nil {
panic(err)
}
}
// defaults sets the default values of the builder before save.
func (_c *DocumentCreate) defaults() error {
if _, ok := _c.mutation.CreatedAt(); !ok {
if document.DefaultCreatedAt == nil {
return fmt.Errorf("ent: uninitialized document.DefaultCreatedAt (forgotten import ent/runtime?)")
}
v := document.DefaultCreatedAt()
_c.mutation.SetCreatedAt(v)
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
if document.DefaultUpdatedAt == nil {
return fmt.Errorf("ent: uninitialized document.DefaultUpdatedAt (forgotten import ent/runtime?)")
}
v := document.DefaultUpdatedAt()
_c.mutation.SetUpdatedAt(v)
}
if _, ok := _c.mutation.Content(); !ok {
v := document.DefaultContent
_c.mutation.SetContent(v)
}
if _, ok := _c.mutation.Locked(); !ok {
v := document.DefaultLocked
_c.mutation.SetLocked(v)
}
return nil
}
// check runs all checks and user-defined validators on the builder.
func (_c *DocumentCreate) check() error {
if _, ok := _c.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "Document.created_at"`)}
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "Document.updated_at"`)}
}
if _, ok := _c.mutation.Title(); !ok {
return &ValidationError{Name: "title", err: errors.New(`ent: missing required field "Document.title"`)}
}
if v, ok := _c.mutation.Title(); ok {
if err := document.TitleValidator(v); err != nil {
return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Document.title": %w`, err)}
}
}
if _, ok := _c.mutation.Locked(); !ok {
return &ValidationError{Name: "locked", err: errors.New(`ent: missing required field "Document.locked"`)}
}
return nil
}
func (_c *DocumentCreate) sqlSave(ctx context.Context) (*Document, error) {
if err := _c.check(); err != nil {
return nil, err
}
_node, _spec := _c.createSpec()
if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
id := _spec.ID.Value.(int64)
_node.ID = int(id)
_c.mutation.id = &_node.ID
_c.mutation.done = true
return _node, nil
}
func (_c *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) {
var (
_node = &Document{config: _c.config}
_spec = sqlgraph.NewCreateSpec(document.Table, sqlgraph.NewFieldSpec(document.FieldID, field.TypeInt))
)
if value, ok := _c.mutation.CreatedAt(); ok {
_spec.SetField(document.FieldCreatedAt, field.TypeString, value)
_node.CreatedAt = value
}
if value, ok := _c.mutation.UpdatedAt(); ok {
_spec.SetField(document.FieldUpdatedAt, field.TypeString, value)
_node.UpdatedAt = value
}
if value, ok := _c.mutation.DeletedAt(); ok {
_spec.SetField(document.FieldDeletedAt, field.TypeString, value)
_node.DeletedAt = &value
}
if value, ok := _c.mutation.Title(); ok {
_spec.SetField(document.FieldTitle, field.TypeString, value)
_node.Title = value
}
if value, ok := _c.mutation.Content(); ok {
_spec.SetField(document.FieldContent, field.TypeString, value)
_node.Content = value
}
if value, ok := _c.mutation.Locked(); ok {
_spec.SetField(document.FieldLocked, field.TypeBool, value)
_node.Locked = value
}
return _node, _spec
}
// DocumentCreateBulk is the builder for creating many Document entities in bulk.
type DocumentCreateBulk struct {
config
err error
builders []*DocumentCreate
}
// Save creates the Document entities in the database.
func (_c *DocumentCreateBulk) Save(ctx context.Context) ([]*Document, error) {
if _c.err != nil {
return nil, _c.err
}
specs := make([]*sqlgraph.CreateSpec, len(_c.builders))
nodes := make([]*Document, len(_c.builders))
mutators := make([]Mutator, len(_c.builders))
for i := range _c.builders {
func(i int, root context.Context) {
builder := _c.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*DocumentMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
var err error
nodes[i], specs[i] = builder.createSpec()
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation)
} else {
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
}
}
if err != nil {
return nil, err
}
mutation.id = &nodes[i].ID
if specs[i].ID.Value != nil {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int(id)
}
mutation.done = true
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (_c *DocumentCreateBulk) SaveX(ctx context.Context) []*Document {
v, err := _c.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (_c *DocumentCreateBulk) Exec(ctx context.Context) error {
_, err := _c.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_c *DocumentCreateBulk) ExecX(ctx context.Context) {
if err := _c.Exec(ctx); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,88 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"voidraft/internal/models/ent/document"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// DocumentDelete is the builder for deleting a Document entity.
type DocumentDelete struct {
config
hooks []Hook
mutation *DocumentMutation
}
// Where appends a list predicates to the DocumentDelete builder.
func (_d *DocumentDelete) Where(ps ...predicate.Document) *DocumentDelete {
_d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (_d *DocumentDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *DocumentDelete) ExecX(ctx context.Context) int {
n, err := _d.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (_d *DocumentDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(document.Table, sqlgraph.NewFieldSpec(document.FieldID, field.TypeInt))
if ps := _d.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
_d.mutation.done = true
return affected, err
}
// DocumentDeleteOne is the builder for deleting a single Document entity.
type DocumentDeleteOne struct {
_d *DocumentDelete
}
// Where appends a list predicates to the DocumentDelete builder.
func (_d *DocumentDeleteOne) Where(ps ...predicate.Document) *DocumentDeleteOne {
_d._d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query.
func (_d *DocumentDeleteOne) Exec(ctx context.Context) error {
n, err := _d._d.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{document.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *DocumentDeleteOne) ExecX(ctx context.Context) {
if err := _d.Exec(ctx); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,577 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"math"
"voidraft/internal/models/ent/document"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// DocumentQuery is the builder for querying Document entities.
type DocumentQuery struct {
config
ctx *QueryContext
order []document.OrderOption
inters []Interceptor
predicates []predicate.Document
modifiers []func(*sql.Selector)
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the DocumentQuery builder.
func (_q *DocumentQuery) Where(ps ...predicate.Document) *DocumentQuery {
_q.predicates = append(_q.predicates, ps...)
return _q
}
// Limit the number of records to be returned by this query.
func (_q *DocumentQuery) Limit(limit int) *DocumentQuery {
_q.ctx.Limit = &limit
return _q
}
// Offset to start from.
func (_q *DocumentQuery) Offset(offset int) *DocumentQuery {
_q.ctx.Offset = &offset
return _q
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func (_q *DocumentQuery) Unique(unique bool) *DocumentQuery {
_q.ctx.Unique = &unique
return _q
}
// Order specifies how the records should be ordered.
func (_q *DocumentQuery) Order(o ...document.OrderOption) *DocumentQuery {
_q.order = append(_q.order, o...)
return _q
}
// First returns the first Document entity from the query.
// Returns a *NotFoundError when no Document was found.
func (_q *DocumentQuery) First(ctx context.Context) (*Document, error) {
nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{document.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (_q *DocumentQuery) FirstX(ctx context.Context) *Document {
node, err := _q.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first Document ID from the query.
// Returns a *NotFoundError when no Document ID was found.
func (_q *DocumentQuery) FirstID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{document.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (_q *DocumentQuery) FirstIDX(ctx context.Context) int {
id, err := _q.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single Document entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one Document entity is found.
// Returns a *NotFoundError when no Document entities are found.
func (_q *DocumentQuery) Only(ctx context.Context) (*Document, error) {
nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{document.Label}
default:
return nil, &NotSingularError{document.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (_q *DocumentQuery) OnlyX(ctx context.Context) *Document {
node, err := _q.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only Document ID in the query.
// Returns a *NotSingularError when more than one Document ID is found.
// Returns a *NotFoundError when no entities are found.
func (_q *DocumentQuery) OnlyID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{document.Label}
default:
err = &NotSingularError{document.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (_q *DocumentQuery) OnlyIDX(ctx context.Context) int {
id, err := _q.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of Documents.
func (_q *DocumentQuery) All(ctx context.Context) ([]*Document, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll)
if err := _q.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*Document, *DocumentQuery]()
return withInterceptors[[]*Document](ctx, _q, qr, _q.inters)
}
// AllX is like All, but panics if an error occurs.
func (_q *DocumentQuery) AllX(ctx context.Context) []*Document {
nodes, err := _q.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of Document IDs.
func (_q *DocumentQuery) IDs(ctx context.Context) (ids []int, err error) {
if _q.ctx.Unique == nil && _q.path != nil {
_q.Unique(true)
}
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs)
if err = _q.Select(document.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (_q *DocumentQuery) IDsX(ctx context.Context) []int {
ids, err := _q.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (_q *DocumentQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount)
if err := _q.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, _q, querierCount[*DocumentQuery](), _q.inters)
}
// CountX is like Count, but panics if an error occurs.
func (_q *DocumentQuery) CountX(ctx context.Context) int {
count, err := _q.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (_q *DocumentQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist)
switch _, err := _q.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (_q *DocumentQuery) ExistX(ctx context.Context) bool {
exist, err := _q.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the DocumentQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (_q *DocumentQuery) Clone() *DocumentQuery {
if _q == nil {
return nil
}
return &DocumentQuery{
config: _q.config,
ctx: _q.ctx.Clone(),
order: append([]document.OrderOption{}, _q.order...),
inters: append([]Interceptor{}, _q.inters...),
predicates: append([]predicate.Document{}, _q.predicates...),
// clone intermediate query.
sql: _q.sql.Clone(),
path: _q.path,
modifiers: append([]func(*sql.Selector){}, _q.modifiers...),
}
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// CreatedAt string `json:"created_at"`
// Count int `json:"count,omitempty"`
// }
//
// client.Document.Query().
// GroupBy(document.FieldCreatedAt).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func (_q *DocumentQuery) GroupBy(field string, fields ...string) *DocumentGroupBy {
_q.ctx.Fields = append([]string{field}, fields...)
grbuild := &DocumentGroupBy{build: _q}
grbuild.flds = &_q.ctx.Fields
grbuild.label = document.Label
grbuild.scan = grbuild.Scan
return grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// CreatedAt string `json:"created_at"`
// }
//
// client.Document.Query().
// Select(document.FieldCreatedAt).
// Scan(ctx, &v)
func (_q *DocumentQuery) Select(fields ...string) *DocumentSelect {
_q.ctx.Fields = append(_q.ctx.Fields, fields...)
sbuild := &DocumentSelect{DocumentQuery: _q}
sbuild.label = document.Label
sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a DocumentSelect configured with the given aggregations.
func (_q *DocumentQuery) Aggregate(fns ...AggregateFunc) *DocumentSelect {
return _q.Select().Aggregate(fns...)
}
func (_q *DocumentQuery) prepareQuery(ctx context.Context) error {
for _, inter := range _q.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, _q); err != nil {
return err
}
}
}
for _, f := range _q.ctx.Fields {
if !document.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if _q.path != nil {
prev, err := _q.path(ctx)
if err != nil {
return err
}
_q.sql = prev
}
return nil
}
func (_q *DocumentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Document, error) {
var (
nodes = []*Document{}
_spec = _q.querySpec()
)
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*Document).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &Document{config: _q.config}
nodes = append(nodes, node)
return node.assignValues(columns, values)
}
if len(_q.modifiers) > 0 {
_spec.Modifiers = _q.modifiers
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
return nodes, nil
}
func (_q *DocumentQuery) sqlCount(ctx context.Context) (int, error) {
_spec := _q.querySpec()
if len(_q.modifiers) > 0 {
_spec.Modifiers = _q.modifiers
}
_spec.Node.Columns = _q.ctx.Fields
if len(_q.ctx.Fields) > 0 {
_spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique
}
return sqlgraph.CountNodes(ctx, _q.driver, _spec)
}
func (_q *DocumentQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(document.Table, document.Columns, sqlgraph.NewFieldSpec(document.FieldID, field.TypeInt))
_spec.From = _q.sql
if unique := _q.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if _q.path != nil {
_spec.Unique = true
}
if fields := _q.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, document.FieldID)
for i := range fields {
if fields[i] != document.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := _q.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := _q.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := _q.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := _q.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (_q *DocumentQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(_q.driver.Dialect())
t1 := builder.Table(document.Table)
columns := _q.ctx.Fields
if len(columns) == 0 {
columns = document.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if _q.sql != nil {
selector = _q.sql
selector.Select(selector.Columns(columns...)...)
}
if _q.ctx.Unique != nil && *_q.ctx.Unique {
selector.Distinct()
}
for _, m := range _q.modifiers {
m(selector)
}
for _, p := range _q.predicates {
p(selector)
}
for _, p := range _q.order {
p(selector)
}
if offset := _q.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := _q.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
// either committed or rolled-back.
func (_q *DocumentQuery) ForUpdate(opts ...sql.LockOption) *DocumentQuery {
if _q.driver.Dialect() == dialect.Postgres {
_q.Unique(false)
}
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
s.ForUpdate(opts...)
})
return _q
}
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
// on any rows that are read. Other sessions can read the rows, but cannot modify them
// until your transaction commits.
func (_q *DocumentQuery) ForShare(opts ...sql.LockOption) *DocumentQuery {
if _q.driver.Dialect() == dialect.Postgres {
_q.Unique(false)
}
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
s.ForShare(opts...)
})
return _q
}
// Modify adds a query modifier for attaching custom logic to queries.
func (_q *DocumentQuery) Modify(modifiers ...func(s *sql.Selector)) *DocumentSelect {
_q.modifiers = append(_q.modifiers, modifiers...)
return _q.Select()
}
// DocumentGroupBy is the group-by builder for Document entities.
type DocumentGroupBy struct {
selector
build *DocumentQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (_g *DocumentGroupBy) Aggregate(fns ...AggregateFunc) *DocumentGroupBy {
_g.fns = append(_g.fns, fns...)
return _g
}
// Scan applies the selector query and scans the result into the given value.
func (_g *DocumentGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy)
if err := _g.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*DocumentQuery, *DocumentGroupBy](ctx, _g.build, _g, _g.build.inters, v)
}
func (_g *DocumentGroupBy) sqlScan(ctx context.Context, root *DocumentQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(_g.fns))
for _, fn := range _g.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*_g.flds)+len(_g.fns))
for _, f := range *_g.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*_g.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := _g.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// DocumentSelect is the builder for selecting fields of Document entities.
type DocumentSelect struct {
*DocumentQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (_s *DocumentSelect) Aggregate(fns ...AggregateFunc) *DocumentSelect {
_s.fns = append(_s.fns, fns...)
return _s
}
// Scan applies the selector query and scans the result into the given value.
func (_s *DocumentSelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect)
if err := _s.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*DocumentQuery, *DocumentSelect](ctx, _s.DocumentQuery, _s, _s.inters, v)
}
func (_s *DocumentSelect) sqlScan(ctx context.Context, root *DocumentQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(_s.fns))
for _, fn := range _s.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*_s.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := _s.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// Modify adds a query modifier for attaching custom logic to queries.
func (_s *DocumentSelect) Modify(modifiers ...func(s *sql.Selector)) *DocumentSelect {
_s.modifiers = append(_s.modifiers, modifiers...)
return _s
}

View File

@@ -0,0 +1,423 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"voidraft/internal/models/ent/document"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// DocumentUpdate is the builder for updating Document entities.
type DocumentUpdate struct {
config
hooks []Hook
mutation *DocumentMutation
modifiers []func(*sql.UpdateBuilder)
}
// Where appends a list predicates to the DocumentUpdate builder.
func (_u *DocumentUpdate) Where(ps ...predicate.Document) *DocumentUpdate {
_u.mutation.Where(ps...)
return _u
}
// SetUpdatedAt sets the "updated_at" field.
func (_u *DocumentUpdate) SetUpdatedAt(v string) *DocumentUpdate {
_u.mutation.SetUpdatedAt(v)
return _u
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_u *DocumentUpdate) SetNillableUpdatedAt(v *string) *DocumentUpdate {
if v != nil {
_u.SetUpdatedAt(*v)
}
return _u
}
// SetDeletedAt sets the "deleted_at" field.
func (_u *DocumentUpdate) SetDeletedAt(v string) *DocumentUpdate {
_u.mutation.SetDeletedAt(v)
return _u
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_u *DocumentUpdate) SetNillableDeletedAt(v *string) *DocumentUpdate {
if v != nil {
_u.SetDeletedAt(*v)
}
return _u
}
// ClearDeletedAt clears the value of the "deleted_at" field.
func (_u *DocumentUpdate) ClearDeletedAt() *DocumentUpdate {
_u.mutation.ClearDeletedAt()
return _u
}
// SetTitle sets the "title" field.
func (_u *DocumentUpdate) SetTitle(v string) *DocumentUpdate {
_u.mutation.SetTitle(v)
return _u
}
// SetNillableTitle sets the "title" field if the given value is not nil.
func (_u *DocumentUpdate) SetNillableTitle(v *string) *DocumentUpdate {
if v != nil {
_u.SetTitle(*v)
}
return _u
}
// SetContent sets the "content" field.
func (_u *DocumentUpdate) SetContent(v string) *DocumentUpdate {
_u.mutation.SetContent(v)
return _u
}
// SetNillableContent sets the "content" field if the given value is not nil.
func (_u *DocumentUpdate) SetNillableContent(v *string) *DocumentUpdate {
if v != nil {
_u.SetContent(*v)
}
return _u
}
// ClearContent clears the value of the "content" field.
func (_u *DocumentUpdate) ClearContent() *DocumentUpdate {
_u.mutation.ClearContent()
return _u
}
// SetLocked sets the "locked" field.
func (_u *DocumentUpdate) SetLocked(v bool) *DocumentUpdate {
_u.mutation.SetLocked(v)
return _u
}
// SetNillableLocked sets the "locked" field if the given value is not nil.
func (_u *DocumentUpdate) SetNillableLocked(v *bool) *DocumentUpdate {
if v != nil {
_u.SetLocked(*v)
}
return _u
}
// Mutation returns the DocumentMutation object of the builder.
func (_u *DocumentUpdate) Mutation() *DocumentMutation {
return _u.mutation
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (_u *DocumentUpdate) Save(ctx context.Context) (int, error) {
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (_u *DocumentUpdate) SaveX(ctx context.Context) int {
affected, err := _u.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (_u *DocumentUpdate) Exec(ctx context.Context) error {
_, err := _u.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_u *DocumentUpdate) ExecX(ctx context.Context) {
if err := _u.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (_u *DocumentUpdate) check() error {
if v, ok := _u.mutation.Title(); ok {
if err := document.TitleValidator(v); err != nil {
return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Document.title": %w`, err)}
}
}
return nil
}
// Modify adds a statement modifier for attaching custom logic to the UPDATE statement.
func (_u *DocumentUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *DocumentUpdate {
_u.modifiers = append(_u.modifiers, modifiers...)
return _u
}
func (_u *DocumentUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if err := _u.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(document.Table, document.Columns, sqlgraph.NewFieldSpec(document.FieldID, field.TypeInt))
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := _u.mutation.UpdatedAt(); ok {
_spec.SetField(document.FieldUpdatedAt, field.TypeString, value)
}
if value, ok := _u.mutation.DeletedAt(); ok {
_spec.SetField(document.FieldDeletedAt, field.TypeString, value)
}
if _u.mutation.DeletedAtCleared() {
_spec.ClearField(document.FieldDeletedAt, field.TypeString)
}
if value, ok := _u.mutation.Title(); ok {
_spec.SetField(document.FieldTitle, field.TypeString, value)
}
if value, ok := _u.mutation.Content(); ok {
_spec.SetField(document.FieldContent, field.TypeString, value)
}
if _u.mutation.ContentCleared() {
_spec.ClearField(document.FieldContent, field.TypeString)
}
if value, ok := _u.mutation.Locked(); ok {
_spec.SetField(document.FieldLocked, field.TypeBool, value)
}
_spec.AddModifiers(_u.modifiers...)
if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{document.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return 0, err
}
_u.mutation.done = true
return _node, nil
}
// DocumentUpdateOne is the builder for updating a single Document entity.
type DocumentUpdateOne struct {
config
fields []string
hooks []Hook
mutation *DocumentMutation
modifiers []func(*sql.UpdateBuilder)
}
// SetUpdatedAt sets the "updated_at" field.
func (_u *DocumentUpdateOne) SetUpdatedAt(v string) *DocumentUpdateOne {
_u.mutation.SetUpdatedAt(v)
return _u
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_u *DocumentUpdateOne) SetNillableUpdatedAt(v *string) *DocumentUpdateOne {
if v != nil {
_u.SetUpdatedAt(*v)
}
return _u
}
// SetDeletedAt sets the "deleted_at" field.
func (_u *DocumentUpdateOne) SetDeletedAt(v string) *DocumentUpdateOne {
_u.mutation.SetDeletedAt(v)
return _u
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_u *DocumentUpdateOne) SetNillableDeletedAt(v *string) *DocumentUpdateOne {
if v != nil {
_u.SetDeletedAt(*v)
}
return _u
}
// ClearDeletedAt clears the value of the "deleted_at" field.
func (_u *DocumentUpdateOne) ClearDeletedAt() *DocumentUpdateOne {
_u.mutation.ClearDeletedAt()
return _u
}
// SetTitle sets the "title" field.
func (_u *DocumentUpdateOne) SetTitle(v string) *DocumentUpdateOne {
_u.mutation.SetTitle(v)
return _u
}
// SetNillableTitle sets the "title" field if the given value is not nil.
func (_u *DocumentUpdateOne) SetNillableTitle(v *string) *DocumentUpdateOne {
if v != nil {
_u.SetTitle(*v)
}
return _u
}
// SetContent sets the "content" field.
func (_u *DocumentUpdateOne) SetContent(v string) *DocumentUpdateOne {
_u.mutation.SetContent(v)
return _u
}
// SetNillableContent sets the "content" field if the given value is not nil.
func (_u *DocumentUpdateOne) SetNillableContent(v *string) *DocumentUpdateOne {
if v != nil {
_u.SetContent(*v)
}
return _u
}
// ClearContent clears the value of the "content" field.
func (_u *DocumentUpdateOne) ClearContent() *DocumentUpdateOne {
_u.mutation.ClearContent()
return _u
}
// SetLocked sets the "locked" field.
func (_u *DocumentUpdateOne) SetLocked(v bool) *DocumentUpdateOne {
_u.mutation.SetLocked(v)
return _u
}
// SetNillableLocked sets the "locked" field if the given value is not nil.
func (_u *DocumentUpdateOne) SetNillableLocked(v *bool) *DocumentUpdateOne {
if v != nil {
_u.SetLocked(*v)
}
return _u
}
// Mutation returns the DocumentMutation object of the builder.
func (_u *DocumentUpdateOne) Mutation() *DocumentMutation {
return _u.mutation
}
// Where appends a list predicates to the DocumentUpdate builder.
func (_u *DocumentUpdateOne) Where(ps ...predicate.Document) *DocumentUpdateOne {
_u.mutation.Where(ps...)
return _u
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func (_u *DocumentUpdateOne) Select(field string, fields ...string) *DocumentUpdateOne {
_u.fields = append([]string{field}, fields...)
return _u
}
// Save executes the query and returns the updated Document entity.
func (_u *DocumentUpdateOne) Save(ctx context.Context) (*Document, error) {
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (_u *DocumentUpdateOne) SaveX(ctx context.Context) *Document {
node, err := _u.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (_u *DocumentUpdateOne) Exec(ctx context.Context) error {
_, err := _u.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_u *DocumentUpdateOne) ExecX(ctx context.Context) {
if err := _u.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (_u *DocumentUpdateOne) check() error {
if v, ok := _u.mutation.Title(); ok {
if err := document.TitleValidator(v); err != nil {
return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Document.title": %w`, err)}
}
}
return nil
}
// Modify adds a statement modifier for attaching custom logic to the UPDATE statement.
func (_u *DocumentUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *DocumentUpdateOne {
_u.modifiers = append(_u.modifiers, modifiers...)
return _u
}
func (_u *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err error) {
if err := _u.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(document.Table, document.Columns, sqlgraph.NewFieldSpec(document.FieldID, field.TypeInt))
id, ok := _u.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Document.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := _u.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, document.FieldID)
for _, f := range fields {
if !document.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
if f != document.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := _u.mutation.UpdatedAt(); ok {
_spec.SetField(document.FieldUpdatedAt, field.TypeString, value)
}
if value, ok := _u.mutation.DeletedAt(); ok {
_spec.SetField(document.FieldDeletedAt, field.TypeString, value)
}
if _u.mutation.DeletedAtCleared() {
_spec.ClearField(document.FieldDeletedAt, field.TypeString)
}
if value, ok := _u.mutation.Title(); ok {
_spec.SetField(document.FieldTitle, field.TypeString, value)
}
if value, ok := _u.mutation.Content(); ok {
_spec.SetField(document.FieldContent, field.TypeString, value)
}
if _u.mutation.ContentCleared() {
_spec.ClearField(document.FieldContent, field.TypeString)
}
if value, ok := _u.mutation.Locked(); ok {
_spec.SetField(document.FieldLocked, field.TypeBool, value)
}
_spec.AddModifiers(_u.modifiers...)
_node = &Document{config: _u.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{document.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
_u.mutation.done = true
return _node, nil
}

614
internal/models/ent/ent.go Normal file
View File

@@ -0,0 +1,614 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"reflect"
"sync"
"voidraft/internal/models/ent/document"
"voidraft/internal/models/ent/extension"
"voidraft/internal/models/ent/keybinding"
"voidraft/internal/models/ent/theme"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
)
// ent aliases to avoid import conflicts in user's code.
type (
Op = ent.Op
Hook = ent.Hook
Value = ent.Value
Query = ent.Query
QueryContext = ent.QueryContext
Querier = ent.Querier
QuerierFunc = ent.QuerierFunc
Interceptor = ent.Interceptor
InterceptFunc = ent.InterceptFunc
Traverser = ent.Traverser
TraverseFunc = ent.TraverseFunc
Policy = ent.Policy
Mutator = ent.Mutator
Mutation = ent.Mutation
MutateFunc = ent.MutateFunc
)
type clientCtxKey struct{}
// FromContext returns a Client stored inside a context, or nil if there isn't one.
func FromContext(ctx context.Context) *Client {
c, _ := ctx.Value(clientCtxKey{}).(*Client)
return c
}
// NewContext returns a new context with the given Client attached.
func NewContext(parent context.Context, c *Client) context.Context {
return context.WithValue(parent, clientCtxKey{}, c)
}
type txCtxKey struct{}
// TxFromContext returns a Tx stored inside a context, or nil if there isn't one.
func TxFromContext(ctx context.Context) *Tx {
tx, _ := ctx.Value(txCtxKey{}).(*Tx)
return tx
}
// NewTxContext returns a new context with the given Tx attached.
func NewTxContext(parent context.Context, tx *Tx) context.Context {
return context.WithValue(parent, txCtxKey{}, tx)
}
// OrderFunc applies an ordering on the sql selector.
// Deprecated: Use Asc/Desc functions or the package builders instead.
type OrderFunc func(*sql.Selector)
var (
initCheck sync.Once
columnCheck sql.ColumnCheck
)
// checkColumn checks if the column exists in the given table.
func checkColumn(t, c string) error {
initCheck.Do(func() {
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
document.Table: document.ValidColumn,
extension.Table: extension.ValidColumn,
keybinding.Table: keybinding.ValidColumn,
theme.Table: theme.ValidColumn,
})
})
return columnCheck(t, c)
}
// Asc applies the given fields in ASC order.
func Asc(fields ...string) func(*sql.Selector) {
return func(s *sql.Selector) {
for _, f := range fields {
if err := checkColumn(s.TableName(), f); err != nil {
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)})
}
s.OrderBy(sql.Asc(s.C(f)))
}
}
}
// Desc applies the given fields in DESC order.
func Desc(fields ...string) func(*sql.Selector) {
return func(s *sql.Selector) {
for _, f := range fields {
if err := checkColumn(s.TableName(), f); err != nil {
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)})
}
s.OrderBy(sql.Desc(s.C(f)))
}
}
}
// AggregateFunc applies an aggregation step on the group-by traversal/selector.
type AggregateFunc func(*sql.Selector) string
// As is a pseudo aggregation function for renaming another other functions with custom names. For example:
//
// GroupBy(field1, field2).
// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")).
// Scan(ctx, &v)
func As(fn AggregateFunc, end string) AggregateFunc {
return func(s *sql.Selector) string {
return sql.As(fn(s), end)
}
}
// Count applies the "count" aggregation function on each group.
func Count() AggregateFunc {
return func(s *sql.Selector) string {
return sql.Count("*")
}
}
// Max applies the "max" aggregation function on the given field of each group.
func Max(field string) AggregateFunc {
return func(s *sql.Selector) string {
if err := checkColumn(s.TableName(), field); err != nil {
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
return ""
}
return sql.Max(s.C(field))
}
}
// Mean applies the "mean" aggregation function on the given field of each group.
func Mean(field string) AggregateFunc {
return func(s *sql.Selector) string {
if err := checkColumn(s.TableName(), field); err != nil {
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
return ""
}
return sql.Avg(s.C(field))
}
}
// Min applies the "min" aggregation function on the given field of each group.
func Min(field string) AggregateFunc {
return func(s *sql.Selector) string {
if err := checkColumn(s.TableName(), field); err != nil {
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
return ""
}
return sql.Min(s.C(field))
}
}
// Sum applies the "sum" aggregation function on the given field of each group.
func Sum(field string) AggregateFunc {
return func(s *sql.Selector) string {
if err := checkColumn(s.TableName(), field); err != nil {
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
return ""
}
return sql.Sum(s.C(field))
}
}
// ValidationError returns when validating a field or edge fails.
type ValidationError struct {
Name string // Field or edge name.
err error
}
// Error implements the error interface.
func (e *ValidationError) Error() string {
return e.err.Error()
}
// Unwrap implements the errors.Wrapper interface.
func (e *ValidationError) Unwrap() error {
return e.err
}
// IsValidationError returns a boolean indicating whether the error is a validation error.
func IsValidationError(err error) bool {
if err == nil {
return false
}
var e *ValidationError
return errors.As(err, &e)
}
// NotFoundError returns when trying to fetch a specific entity and it was not found in the database.
type NotFoundError struct {
label string
}
// Error implements the error interface.
func (e *NotFoundError) Error() string {
return "ent: " + e.label + " not found"
}
// IsNotFound returns a boolean indicating whether the error is a not found error.
func IsNotFound(err error) bool {
if err == nil {
return false
}
var e *NotFoundError
return errors.As(err, &e)
}
// MaskNotFound masks not found error.
func MaskNotFound(err error) error {
if IsNotFound(err) {
return nil
}
return err
}
// NotSingularError returns when trying to fetch a singular entity and more then one was found in the database.
type NotSingularError struct {
label string
}
// Error implements the error interface.
func (e *NotSingularError) Error() string {
return "ent: " + e.label + " not singular"
}
// IsNotSingular returns a boolean indicating whether the error is a not singular error.
func IsNotSingular(err error) bool {
if err == nil {
return false
}
var e *NotSingularError
return errors.As(err, &e)
}
// NotLoadedError returns when trying to get a node that was not loaded by the query.
type NotLoadedError struct {
edge string
}
// Error implements the error interface.
func (e *NotLoadedError) Error() string {
return "ent: " + e.edge + " edge was not loaded"
}
// IsNotLoaded returns a boolean indicating whether the error is a not loaded error.
func IsNotLoaded(err error) bool {
if err == nil {
return false
}
var e *NotLoadedError
return errors.As(err, &e)
}
// ConstraintError returns when trying to create/update one or more entities and
// one or more of their constraints failed. For example, violation of edge or
// field uniqueness.
type ConstraintError struct {
msg string
wrap error
}
// Error implements the error interface.
func (e ConstraintError) Error() string {
return "ent: constraint failed: " + e.msg
}
// Unwrap implements the errors.Wrapper interface.
func (e *ConstraintError) Unwrap() error {
return e.wrap
}
// IsConstraintError returns a boolean indicating whether the error is a constraint failure.
func IsConstraintError(err error) bool {
if err == nil {
return false
}
var e *ConstraintError
return errors.As(err, &e)
}
// selector embedded by the different Select/GroupBy builders.
type selector struct {
label string
flds *[]string
fns []AggregateFunc
scan func(context.Context, any) error
}
// ScanX is like Scan, but panics if an error occurs.
func (s *selector) ScanX(ctx context.Context, v any) {
if err := s.scan(ctx, v); err != nil {
panic(err)
}
}
// Strings returns list of strings from a selector. It is only allowed when selecting one field.
func (s *selector) Strings(ctx context.Context) ([]string, error) {
if len(*s.flds) > 1 {
return nil, errors.New("ent: Strings is not achievable when selecting more than 1 field")
}
var v []string
if err := s.scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// StringsX is like Strings, but panics if an error occurs.
func (s *selector) StringsX(ctx context.Context) []string {
v, err := s.Strings(ctx)
if err != nil {
panic(err)
}
return v
}
// String returns a single string from a selector. It is only allowed when selecting one field.
func (s *selector) String(ctx context.Context) (_ string, err error) {
var v []string
if v, err = s.Strings(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{s.label}
default:
err = fmt.Errorf("ent: Strings returned %d results when one was expected", len(v))
}
return
}
// StringX is like String, but panics if an error occurs.
func (s *selector) StringX(ctx context.Context) string {
v, err := s.String(ctx)
if err != nil {
panic(err)
}
return v
}
// Ints returns list of ints from a selector. It is only allowed when selecting one field.
func (s *selector) Ints(ctx context.Context) ([]int, error) {
if len(*s.flds) > 1 {
return nil, errors.New("ent: Ints is not achievable when selecting more than 1 field")
}
var v []int
if err := s.scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// IntsX is like Ints, but panics if an error occurs.
func (s *selector) IntsX(ctx context.Context) []int {
v, err := s.Ints(ctx)
if err != nil {
panic(err)
}
return v
}
// Int returns a single int from a selector. It is only allowed when selecting one field.
func (s *selector) Int(ctx context.Context) (_ int, err error) {
var v []int
if v, err = s.Ints(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{s.label}
default:
err = fmt.Errorf("ent: Ints returned %d results when one was expected", len(v))
}
return
}
// IntX is like Int, but panics if an error occurs.
func (s *selector) IntX(ctx context.Context) int {
v, err := s.Int(ctx)
if err != nil {
panic(err)
}
return v
}
// Float64s returns list of float64s from a selector. It is only allowed when selecting one field.
func (s *selector) Float64s(ctx context.Context) ([]float64, error) {
if len(*s.flds) > 1 {
return nil, errors.New("ent: Float64s is not achievable when selecting more than 1 field")
}
var v []float64
if err := s.scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// Float64sX is like Float64s, but panics if an error occurs.
func (s *selector) Float64sX(ctx context.Context) []float64 {
v, err := s.Float64s(ctx)
if err != nil {
panic(err)
}
return v
}
// Float64 returns a single float64 from a selector. It is only allowed when selecting one field.
func (s *selector) Float64(ctx context.Context) (_ float64, err error) {
var v []float64
if v, err = s.Float64s(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{s.label}
default:
err = fmt.Errorf("ent: Float64s returned %d results when one was expected", len(v))
}
return
}
// Float64X is like Float64, but panics if an error occurs.
func (s *selector) Float64X(ctx context.Context) float64 {
v, err := s.Float64(ctx)
if err != nil {
panic(err)
}
return v
}
// Bools returns list of bools from a selector. It is only allowed when selecting one field.
func (s *selector) Bools(ctx context.Context) ([]bool, error) {
if len(*s.flds) > 1 {
return nil, errors.New("ent: Bools is not achievable when selecting more than 1 field")
}
var v []bool
if err := s.scan(ctx, &v); err != nil {
return nil, err
}
return v, nil
}
// BoolsX is like Bools, but panics if an error occurs.
func (s *selector) BoolsX(ctx context.Context) []bool {
v, err := s.Bools(ctx)
if err != nil {
panic(err)
}
return v
}
// Bool returns a single bool from a selector. It is only allowed when selecting one field.
func (s *selector) Bool(ctx context.Context) (_ bool, err error) {
var v []bool
if v, err = s.Bools(ctx); err != nil {
return
}
switch len(v) {
case 1:
return v[0], nil
case 0:
err = &NotFoundError{s.label}
default:
err = fmt.Errorf("ent: Bools returned %d results when one was expected", len(v))
}
return
}
// BoolX is like Bool, but panics if an error occurs.
func (s *selector) BoolX(ctx context.Context) bool {
v, err := s.Bool(ctx)
if err != nil {
panic(err)
}
return v
}
// withHooks invokes the builder operation with the given hooks, if any.
func withHooks[V Value, M any, PM interface {
*M
Mutation
}](ctx context.Context, exec func(context.Context) (V, error), mutation PM, hooks []Hook) (value V, err error) {
if len(hooks) == 0 {
return exec(ctx)
}
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutationT, ok := any(m).(PM)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
// Set the mutation to the builder.
*mutation = *mutationT
return exec(ctx)
})
for i := len(hooks) - 1; i >= 0; i-- {
if hooks[i] == nil {
return value, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
}
mut = hooks[i](mut)
}
v, err := mut.Mutate(ctx, mutation)
if err != nil {
return value, err
}
nv, ok := v.(V)
if !ok {
return value, fmt.Errorf("unexpected node type %T returned from %T", v, mutation)
}
return nv, nil
}
// setContextOp returns a new context with the given QueryContext attached (including its op) in case it does not exist.
func setContextOp(ctx context.Context, qc *QueryContext, op string) context.Context {
if ent.QueryFromContext(ctx) == nil {
qc.Op = op
ctx = ent.NewQueryContext(ctx, qc)
}
return ctx
}
func querierAll[V Value, Q interface {
sqlAll(context.Context, ...queryHook) (V, error)
}]() Querier {
return QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
query, ok := q.(Q)
if !ok {
return nil, fmt.Errorf("unexpected query type %T", q)
}
return query.sqlAll(ctx)
})
}
func querierCount[Q interface {
sqlCount(context.Context) (int, error)
}]() Querier {
return QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
query, ok := q.(Q)
if !ok {
return nil, fmt.Errorf("unexpected query type %T", q)
}
return query.sqlCount(ctx)
})
}
func withInterceptors[V Value](ctx context.Context, q Query, qr Querier, inters []Interceptor) (v V, err error) {
for i := len(inters) - 1; i >= 0; i-- {
qr = inters[i].Intercept(qr)
}
rv, err := qr.Query(ctx, q)
if err != nil {
return v, err
}
vt, ok := rv.(V)
if !ok {
return v, fmt.Errorf("unexpected type %T returned from %T. expected type: %T", vt, q, v)
}
return vt, nil
}
func scanWithInterceptors[Q1 ent.Query, Q2 interface {
sqlScan(context.Context, Q1, any) error
}](ctx context.Context, rootQuery Q1, selectOrGroup Q2, inters []Interceptor, v any) error {
rv := reflect.ValueOf(v)
var qr Querier = QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
query, ok := q.(Q1)
if !ok {
return nil, fmt.Errorf("unexpected query type %T", q)
}
if err := selectOrGroup.sqlScan(ctx, query, v); err != nil {
return nil, err
}
if k := rv.Kind(); k == reflect.Pointer && rv.Elem().CanInterface() {
return rv.Elem().Interface(), nil
}
return v, nil
})
for i := len(inters) - 1; i >= 0; i-- {
qr = inters[i].Intercept(qr)
}
vv, err := qr.Query(ctx, rootQuery)
if err != nil {
return err
}
switch rv2 := reflect.ValueOf(vv); {
case rv.IsNil(), rv2.IsNil(), rv.Kind() != reflect.Pointer:
case rv.Type() == rv2.Type():
rv.Elem().Set(rv2.Elem())
case rv.Elem().Type() == rv2.Type():
rv.Elem().Set(rv2)
}
return nil
}
// queryHook describes an internal hook for the different sqlAll methods.
type queryHook func(context.Context, *sqlgraph.QuerySpec)

View File

@@ -0,0 +1,389 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"voidraft/internal/models/ent/document"
"voidraft/internal/models/ent/extension"
"voidraft/internal/models/ent/keybinding"
"voidraft/internal/models/ent/theme"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/entql"
"entgo.io/ent/schema/field"
)
// schemaGraph holds a representation of ent/schema at runtime.
var schemaGraph = func() *sqlgraph.Schema {
graph := &sqlgraph.Schema{Nodes: make([]*sqlgraph.Node, 4)}
graph.Nodes[0] = &sqlgraph.Node{
NodeSpec: sqlgraph.NodeSpec{
Table: document.Table,
Columns: document.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: document.FieldID,
},
},
Type: "Document",
Fields: map[string]*sqlgraph.FieldSpec{
document.FieldCreatedAt: {Type: field.TypeString, Column: document.FieldCreatedAt},
document.FieldUpdatedAt: {Type: field.TypeString, Column: document.FieldUpdatedAt},
document.FieldDeletedAt: {Type: field.TypeString, Column: document.FieldDeletedAt},
document.FieldTitle: {Type: field.TypeString, Column: document.FieldTitle},
document.FieldContent: {Type: field.TypeString, Column: document.FieldContent},
document.FieldLocked: {Type: field.TypeBool, Column: document.FieldLocked},
},
}
graph.Nodes[1] = &sqlgraph.Node{
NodeSpec: sqlgraph.NodeSpec{
Table: extension.Table,
Columns: extension.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: extension.FieldID,
},
},
Type: "Extension",
Fields: map[string]*sqlgraph.FieldSpec{
extension.FieldCreatedAt: {Type: field.TypeString, Column: extension.FieldCreatedAt},
extension.FieldUpdatedAt: {Type: field.TypeString, Column: extension.FieldUpdatedAt},
extension.FieldDeletedAt: {Type: field.TypeString, Column: extension.FieldDeletedAt},
extension.FieldKey: {Type: field.TypeString, Column: extension.FieldKey},
extension.FieldEnabled: {Type: field.TypeBool, Column: extension.FieldEnabled},
extension.FieldConfig: {Type: field.TypeJSON, Column: extension.FieldConfig},
},
}
graph.Nodes[2] = &sqlgraph.Node{
NodeSpec: sqlgraph.NodeSpec{
Table: keybinding.Table,
Columns: keybinding.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: keybinding.FieldID,
},
},
Type: "KeyBinding",
Fields: map[string]*sqlgraph.FieldSpec{
keybinding.FieldCreatedAt: {Type: field.TypeString, Column: keybinding.FieldCreatedAt},
keybinding.FieldUpdatedAt: {Type: field.TypeString, Column: keybinding.FieldUpdatedAt},
keybinding.FieldDeletedAt: {Type: field.TypeString, Column: keybinding.FieldDeletedAt},
keybinding.FieldKey: {Type: field.TypeString, Column: keybinding.FieldKey},
keybinding.FieldCommand: {Type: field.TypeString, Column: keybinding.FieldCommand},
keybinding.FieldExtension: {Type: field.TypeString, Column: keybinding.FieldExtension},
keybinding.FieldEnabled: {Type: field.TypeBool, Column: keybinding.FieldEnabled},
},
}
graph.Nodes[3] = &sqlgraph.Node{
NodeSpec: sqlgraph.NodeSpec{
Table: theme.Table,
Columns: theme.Columns,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: theme.FieldID,
},
},
Type: "Theme",
Fields: map[string]*sqlgraph.FieldSpec{
theme.FieldCreatedAt: {Type: field.TypeString, Column: theme.FieldCreatedAt},
theme.FieldUpdatedAt: {Type: field.TypeString, Column: theme.FieldUpdatedAt},
theme.FieldDeletedAt: {Type: field.TypeString, Column: theme.FieldDeletedAt},
theme.FieldKey: {Type: field.TypeString, Column: theme.FieldKey},
theme.FieldType: {Type: field.TypeEnum, Column: theme.FieldType},
theme.FieldColors: {Type: field.TypeJSON, Column: theme.FieldColors},
},
}
return graph
}()
// predicateAdder wraps the addPredicate method.
// All update, update-one and query builders implement this interface.
type predicateAdder interface {
addPredicate(func(s *sql.Selector))
}
// addPredicate implements the predicateAdder interface.
func (_q *DocumentQuery) addPredicate(pred func(s *sql.Selector)) {
_q.predicates = append(_q.predicates, pred)
}
// Filter returns a Filter implementation to apply filters on the DocumentQuery builder.
func (_q *DocumentQuery) Filter() *DocumentFilter {
return &DocumentFilter{config: _q.config, predicateAdder: _q}
}
// addPredicate implements the predicateAdder interface.
func (m *DocumentMutation) addPredicate(pred func(s *sql.Selector)) {
m.predicates = append(m.predicates, pred)
}
// Filter returns an entql.Where implementation to apply filters on the DocumentMutation builder.
func (m *DocumentMutation) Filter() *DocumentFilter {
return &DocumentFilter{config: m.config, predicateAdder: m}
}
// DocumentFilter provides a generic filtering capability at runtime for DocumentQuery.
type DocumentFilter struct {
predicateAdder
config
}
// Where applies the entql predicate on the query filter.
func (f *DocumentFilter) Where(p entql.P) {
f.addPredicate(func(s *sql.Selector) {
if err := schemaGraph.EvalP(schemaGraph.Nodes[0].Type, p, s); err != nil {
s.AddError(err)
}
})
}
// WhereID applies the entql int predicate on the id field.
func (f *DocumentFilter) WhereID(p entql.IntP) {
f.Where(p.Field(document.FieldID))
}
// WhereCreatedAt applies the entql string predicate on the created_at field.
func (f *DocumentFilter) WhereCreatedAt(p entql.StringP) {
f.Where(p.Field(document.FieldCreatedAt))
}
// WhereUpdatedAt applies the entql string predicate on the updated_at field.
func (f *DocumentFilter) WhereUpdatedAt(p entql.StringP) {
f.Where(p.Field(document.FieldUpdatedAt))
}
// WhereDeletedAt applies the entql string predicate on the deleted_at field.
func (f *DocumentFilter) WhereDeletedAt(p entql.StringP) {
f.Where(p.Field(document.FieldDeletedAt))
}
// WhereTitle applies the entql string predicate on the title field.
func (f *DocumentFilter) WhereTitle(p entql.StringP) {
f.Where(p.Field(document.FieldTitle))
}
// WhereContent applies the entql string predicate on the content field.
func (f *DocumentFilter) WhereContent(p entql.StringP) {
f.Where(p.Field(document.FieldContent))
}
// WhereLocked applies the entql bool predicate on the locked field.
func (f *DocumentFilter) WhereLocked(p entql.BoolP) {
f.Where(p.Field(document.FieldLocked))
}
// addPredicate implements the predicateAdder interface.
func (_q *ExtensionQuery) addPredicate(pred func(s *sql.Selector)) {
_q.predicates = append(_q.predicates, pred)
}
// Filter returns a Filter implementation to apply filters on the ExtensionQuery builder.
func (_q *ExtensionQuery) Filter() *ExtensionFilter {
return &ExtensionFilter{config: _q.config, predicateAdder: _q}
}
// addPredicate implements the predicateAdder interface.
func (m *ExtensionMutation) addPredicate(pred func(s *sql.Selector)) {
m.predicates = append(m.predicates, pred)
}
// Filter returns an entql.Where implementation to apply filters on the ExtensionMutation builder.
func (m *ExtensionMutation) Filter() *ExtensionFilter {
return &ExtensionFilter{config: m.config, predicateAdder: m}
}
// ExtensionFilter provides a generic filtering capability at runtime for ExtensionQuery.
type ExtensionFilter struct {
predicateAdder
config
}
// Where applies the entql predicate on the query filter.
func (f *ExtensionFilter) Where(p entql.P) {
f.addPredicate(func(s *sql.Selector) {
if err := schemaGraph.EvalP(schemaGraph.Nodes[1].Type, p, s); err != nil {
s.AddError(err)
}
})
}
// WhereID applies the entql int predicate on the id field.
func (f *ExtensionFilter) WhereID(p entql.IntP) {
f.Where(p.Field(extension.FieldID))
}
// WhereCreatedAt applies the entql string predicate on the created_at field.
func (f *ExtensionFilter) WhereCreatedAt(p entql.StringP) {
f.Where(p.Field(extension.FieldCreatedAt))
}
// WhereUpdatedAt applies the entql string predicate on the updated_at field.
func (f *ExtensionFilter) WhereUpdatedAt(p entql.StringP) {
f.Where(p.Field(extension.FieldUpdatedAt))
}
// WhereDeletedAt applies the entql string predicate on the deleted_at field.
func (f *ExtensionFilter) WhereDeletedAt(p entql.StringP) {
f.Where(p.Field(extension.FieldDeletedAt))
}
// WhereKey applies the entql string predicate on the key field.
func (f *ExtensionFilter) WhereKey(p entql.StringP) {
f.Where(p.Field(extension.FieldKey))
}
// WhereEnabled applies the entql bool predicate on the enabled field.
func (f *ExtensionFilter) WhereEnabled(p entql.BoolP) {
f.Where(p.Field(extension.FieldEnabled))
}
// WhereConfig applies the entql json.RawMessage predicate on the config field.
func (f *ExtensionFilter) WhereConfig(p entql.BytesP) {
f.Where(p.Field(extension.FieldConfig))
}
// addPredicate implements the predicateAdder interface.
func (_q *KeyBindingQuery) addPredicate(pred func(s *sql.Selector)) {
_q.predicates = append(_q.predicates, pred)
}
// Filter returns a Filter implementation to apply filters on the KeyBindingQuery builder.
func (_q *KeyBindingQuery) Filter() *KeyBindingFilter {
return &KeyBindingFilter{config: _q.config, predicateAdder: _q}
}
// addPredicate implements the predicateAdder interface.
func (m *KeyBindingMutation) addPredicate(pred func(s *sql.Selector)) {
m.predicates = append(m.predicates, pred)
}
// Filter returns an entql.Where implementation to apply filters on the KeyBindingMutation builder.
func (m *KeyBindingMutation) Filter() *KeyBindingFilter {
return &KeyBindingFilter{config: m.config, predicateAdder: m}
}
// KeyBindingFilter provides a generic filtering capability at runtime for KeyBindingQuery.
type KeyBindingFilter struct {
predicateAdder
config
}
// Where applies the entql predicate on the query filter.
func (f *KeyBindingFilter) Where(p entql.P) {
f.addPredicate(func(s *sql.Selector) {
if err := schemaGraph.EvalP(schemaGraph.Nodes[2].Type, p, s); err != nil {
s.AddError(err)
}
})
}
// WhereID applies the entql int predicate on the id field.
func (f *KeyBindingFilter) WhereID(p entql.IntP) {
f.Where(p.Field(keybinding.FieldID))
}
// WhereCreatedAt applies the entql string predicate on the created_at field.
func (f *KeyBindingFilter) WhereCreatedAt(p entql.StringP) {
f.Where(p.Field(keybinding.FieldCreatedAt))
}
// WhereUpdatedAt applies the entql string predicate on the updated_at field.
func (f *KeyBindingFilter) WhereUpdatedAt(p entql.StringP) {
f.Where(p.Field(keybinding.FieldUpdatedAt))
}
// WhereDeletedAt applies the entql string predicate on the deleted_at field.
func (f *KeyBindingFilter) WhereDeletedAt(p entql.StringP) {
f.Where(p.Field(keybinding.FieldDeletedAt))
}
// WhereKey applies the entql string predicate on the key field.
func (f *KeyBindingFilter) WhereKey(p entql.StringP) {
f.Where(p.Field(keybinding.FieldKey))
}
// WhereCommand applies the entql string predicate on the command field.
func (f *KeyBindingFilter) WhereCommand(p entql.StringP) {
f.Where(p.Field(keybinding.FieldCommand))
}
// WhereExtension applies the entql string predicate on the extension field.
func (f *KeyBindingFilter) WhereExtension(p entql.StringP) {
f.Where(p.Field(keybinding.FieldExtension))
}
// WhereEnabled applies the entql bool predicate on the enabled field.
func (f *KeyBindingFilter) WhereEnabled(p entql.BoolP) {
f.Where(p.Field(keybinding.FieldEnabled))
}
// addPredicate implements the predicateAdder interface.
func (_q *ThemeQuery) addPredicate(pred func(s *sql.Selector)) {
_q.predicates = append(_q.predicates, pred)
}
// Filter returns a Filter implementation to apply filters on the ThemeQuery builder.
func (_q *ThemeQuery) Filter() *ThemeFilter {
return &ThemeFilter{config: _q.config, predicateAdder: _q}
}
// addPredicate implements the predicateAdder interface.
func (m *ThemeMutation) addPredicate(pred func(s *sql.Selector)) {
m.predicates = append(m.predicates, pred)
}
// Filter returns an entql.Where implementation to apply filters on the ThemeMutation builder.
func (m *ThemeMutation) Filter() *ThemeFilter {
return &ThemeFilter{config: m.config, predicateAdder: m}
}
// ThemeFilter provides a generic filtering capability at runtime for ThemeQuery.
type ThemeFilter struct {
predicateAdder
config
}
// Where applies the entql predicate on the query filter.
func (f *ThemeFilter) Where(p entql.P) {
f.addPredicate(func(s *sql.Selector) {
if err := schemaGraph.EvalP(schemaGraph.Nodes[3].Type, p, s); err != nil {
s.AddError(err)
}
})
}
// WhereID applies the entql int predicate on the id field.
func (f *ThemeFilter) WhereID(p entql.IntP) {
f.Where(p.Field(theme.FieldID))
}
// WhereCreatedAt applies the entql string predicate on the created_at field.
func (f *ThemeFilter) WhereCreatedAt(p entql.StringP) {
f.Where(p.Field(theme.FieldCreatedAt))
}
// WhereUpdatedAt applies the entql string predicate on the updated_at field.
func (f *ThemeFilter) WhereUpdatedAt(p entql.StringP) {
f.Where(p.Field(theme.FieldUpdatedAt))
}
// WhereDeletedAt applies the entql string predicate on the deleted_at field.
func (f *ThemeFilter) WhereDeletedAt(p entql.StringP) {
f.Where(p.Field(theme.FieldDeletedAt))
}
// WhereKey applies the entql string predicate on the key field.
func (f *ThemeFilter) WhereKey(p entql.StringP) {
f.Where(p.Field(theme.FieldKey))
}
// WhereType applies the entql string predicate on the type field.
func (f *ThemeFilter) WhereType(p entql.StringP) {
f.Where(p.Field(theme.FieldType))
}
// WhereColors applies the entql json.RawMessage predicate on the colors field.
func (f *ThemeFilter) WhereColors(p entql.BytesP) {
f.Where(p.Field(theme.FieldColors))
}

View File

@@ -0,0 +1,85 @@
// Code generated by ent, DO NOT EDIT.
package enttest
import (
"context"
"voidraft/internal/models/ent"
// required by schema hooks.
_ "voidraft/internal/models/ent/runtime"
"voidraft/internal/models/ent/migrate"
"entgo.io/ent/dialect/sql/schema"
)
type (
// TestingT is the interface that is shared between
// testing.T and testing.B and used by enttest.
TestingT interface {
FailNow()
Error(...any)
}
// Option configures client creation.
Option func(*options)
options struct {
opts []ent.Option
migrateOpts []schema.MigrateOption
}
)
// WithOptions forwards options to client creation.
func WithOptions(opts ...ent.Option) Option {
return func(o *options) {
o.opts = append(o.opts, opts...)
}
}
// WithMigrateOptions forwards options to auto migration.
func WithMigrateOptions(opts ...schema.MigrateOption) Option {
return func(o *options) {
o.migrateOpts = append(o.migrateOpts, opts...)
}
}
func newOptions(opts []Option) *options {
o := &options{}
for _, opt := range opts {
opt(o)
}
return o
}
// Open calls ent.Open and auto-run migration.
func Open(t TestingT, driverName, dataSourceName string, opts ...Option) *ent.Client {
o := newOptions(opts)
c, err := ent.Open(driverName, dataSourceName, o.opts...)
if err != nil {
t.Error(err)
t.FailNow()
}
migrateSchema(t, c, o)
return c
}
// NewClient calls ent.NewClient and auto-run migration.
func NewClient(t TestingT, opts ...Option) *ent.Client {
o := newOptions(opts)
c := ent.NewClient(o.opts...)
migrateSchema(t, c, o)
return c
}
func migrateSchema(t TestingT, c *ent.Client, o *options) {
tables, err := schema.CopyTables(migrate.Tables)
if err != nil {
t.Error(err)
t.FailNow()
}
if err := migrate.Create(context.Background(), c.Schema, tables, o.migrateOpts...); err != nil {
t.Error(err)
t.FailNow()
}
}

View File

@@ -0,0 +1,168 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"encoding/json"
"fmt"
"strings"
"voidraft/internal/models/ent/extension"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
)
// Extension is the model entity for the Extension schema.
type Extension struct {
config `json:"-"`
// ID of the ent.
ID int `json:"id,omitempty"`
// 创建时间
CreatedAt string `json:"created_at"`
// 最后更新时间
UpdatedAt string `json:"updated_at"`
// 删除时间NULL表示未删除
DeletedAt *string `json:"deleted_at,omitempty"`
// 扩展标识符
Key string `json:"key"`
// 是否启用
Enabled bool `json:"enabled"`
// 扩展配置
Config map[string]interface{} `json:"config"`
selectValues sql.SelectValues
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Extension) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case extension.FieldConfig:
values[i] = new([]byte)
case extension.FieldEnabled:
values[i] = new(sql.NullBool)
case extension.FieldID:
values[i] = new(sql.NullInt64)
case extension.FieldCreatedAt, extension.FieldUpdatedAt, extension.FieldDeletedAt, extension.FieldKey:
values[i] = new(sql.NullString)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Extension fields.
func (_m *Extension) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case extension.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
_m.ID = int(value.Int64)
case extension.FieldCreatedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
_m.CreatedAt = value.String
}
case extension.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
_m.UpdatedAt = value.String
}
case extension.FieldDeletedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
} else if value.Valid {
_m.DeletedAt = new(string)
*_m.DeletedAt = value.String
}
case extension.FieldKey:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field key", values[i])
} else if value.Valid {
_m.Key = value.String
}
case extension.FieldEnabled:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field enabled", values[i])
} else if value.Valid {
_m.Enabled = value.Bool
}
case extension.FieldConfig:
if value, ok := values[i].(*[]byte); !ok {
return fmt.Errorf("unexpected type %T for field config", values[i])
} else if value != nil && len(*value) > 0 {
if err := json.Unmarshal(*value, &_m.Config); err != nil {
return fmt.Errorf("unmarshal field config: %w", err)
}
}
default:
_m.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the Extension.
// This includes values selected through modifiers, order, etc.
func (_m *Extension) Value(name string) (ent.Value, error) {
return _m.selectValues.Get(name)
}
// Update returns a builder for updating this Extension.
// Note that you need to call Extension.Unwrap() before calling this method if this Extension
// was returned from a transaction, and the transaction was committed or rolled back.
func (_m *Extension) Update() *ExtensionUpdateOne {
return NewExtensionClient(_m.config).UpdateOne(_m)
}
// Unwrap unwraps the Extension entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (_m *Extension) Unwrap() *Extension {
_tx, ok := _m.config.driver.(*txDriver)
if !ok {
panic("ent: Extension is not a transactional entity")
}
_m.config.driver = _tx.drv
return _m
}
// String implements the fmt.Stringer.
func (_m *Extension) String() string {
var builder strings.Builder
builder.WriteString("Extension(")
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
builder.WriteString("created_at=")
builder.WriteString(_m.CreatedAt)
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(_m.UpdatedAt)
builder.WriteString(", ")
if v := _m.DeletedAt; v != nil {
builder.WriteString("deleted_at=")
builder.WriteString(*v)
}
builder.WriteString(", ")
builder.WriteString("key=")
builder.WriteString(_m.Key)
builder.WriteString(", ")
builder.WriteString("enabled=")
builder.WriteString(fmt.Sprintf("%v", _m.Enabled))
builder.WriteString(", ")
builder.WriteString("config=")
builder.WriteString(fmt.Sprintf("%v", _m.Config))
builder.WriteByte(')')
return builder.String()
}
// Extensions is a parsable slice of Extension.
type Extensions []*Extension

View File

@@ -0,0 +1,101 @@
// Code generated by ent, DO NOT EDIT.
package extension
import (
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
)
const (
// Label holds the string label denoting the extension type in the database.
Label = "extension"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
FieldDeletedAt = "deleted_at"
// FieldKey holds the string denoting the key field in the database.
FieldKey = "key"
// FieldEnabled holds the string denoting the enabled field in the database.
FieldEnabled = "enabled"
// FieldConfig holds the string denoting the config field in the database.
FieldConfig = "config"
// Table holds the table name of the extension in the database.
Table = "extensions"
)
// Columns holds all SQL columns for extension fields.
var Columns = []string{
FieldID,
FieldCreatedAt,
FieldUpdatedAt,
FieldDeletedAt,
FieldKey,
FieldEnabled,
FieldConfig,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
// Note that the variables below are initialized by the runtime
// package on the initialization of the application. Therefore,
// it should be imported in the main as follows:
//
// import _ "voidraft/internal/models/ent/runtime"
var (
Hooks [2]ent.Hook
Interceptors [1]ent.Interceptor
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() string
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() string
// KeyValidator is a validator for the "key" field. It is called by the builders before save.
KeyValidator func(string) error
// DefaultEnabled holds the default value on creation for the "enabled" field.
DefaultEnabled bool
)
// OrderOption defines the ordering options for the Extension queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// ByDeletedAt orders the results by the deleted_at field.
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
}
// ByKey orders the results by the key field.
func ByKey(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldKey, opts...).ToFunc()
}
// ByEnabled orders the results by the enabled field.
func ByEnabled(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldEnabled, opts...).ToFunc()
}

View File

@@ -0,0 +1,384 @@
// Code generated by ent, DO NOT EDIT.
package extension
import (
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
)
// ID filters vertices based on their ID field.
func ID(id int) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int) predicate.Extension {
return predicate.Extension(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int) predicate.Extension {
return predicate.Extension(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int) predicate.Extension {
return predicate.Extension(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int) predicate.Extension {
return predicate.Extension(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int) predicate.Extension {
return predicate.Extension(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int) predicate.Extension {
return predicate.Extension(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int) predicate.Extension {
return predicate.Extension(sql.FieldLTE(FieldID, id))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v string) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldCreatedAt, v))
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v string) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldUpdatedAt, v))
}
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
func DeletedAt(v string) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldDeletedAt, v))
}
// Key applies equality check predicate on the "key" field. It's identical to KeyEQ.
func Key(v string) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldKey, v))
}
// Enabled applies equality check predicate on the "enabled" field. It's identical to EnabledEQ.
func Enabled(v bool) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldEnabled, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v string) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v string) predicate.Extension {
return predicate.Extension(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...string) predicate.Extension {
return predicate.Extension(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...string) predicate.Extension {
return predicate.Extension(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v string) predicate.Extension {
return predicate.Extension(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v string) predicate.Extension {
return predicate.Extension(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v string) predicate.Extension {
return predicate.Extension(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v string) predicate.Extension {
return predicate.Extension(sql.FieldLTE(FieldCreatedAt, v))
}
// CreatedAtContains applies the Contains predicate on the "created_at" field.
func CreatedAtContains(v string) predicate.Extension {
return predicate.Extension(sql.FieldContains(FieldCreatedAt, v))
}
// CreatedAtHasPrefix applies the HasPrefix predicate on the "created_at" field.
func CreatedAtHasPrefix(v string) predicate.Extension {
return predicate.Extension(sql.FieldHasPrefix(FieldCreatedAt, v))
}
// CreatedAtHasSuffix applies the HasSuffix predicate on the "created_at" field.
func CreatedAtHasSuffix(v string) predicate.Extension {
return predicate.Extension(sql.FieldHasSuffix(FieldCreatedAt, v))
}
// CreatedAtEqualFold applies the EqualFold predicate on the "created_at" field.
func CreatedAtEqualFold(v string) predicate.Extension {
return predicate.Extension(sql.FieldEqualFold(FieldCreatedAt, v))
}
// CreatedAtContainsFold applies the ContainsFold predicate on the "created_at" field.
func CreatedAtContainsFold(v string) predicate.Extension {
return predicate.Extension(sql.FieldContainsFold(FieldCreatedAt, v))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v string) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldUpdatedAt, v))
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v string) predicate.Extension {
return predicate.Extension(sql.FieldNEQ(FieldUpdatedAt, v))
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...string) predicate.Extension {
return predicate.Extension(sql.FieldIn(FieldUpdatedAt, vs...))
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...string) predicate.Extension {
return predicate.Extension(sql.FieldNotIn(FieldUpdatedAt, vs...))
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v string) predicate.Extension {
return predicate.Extension(sql.FieldGT(FieldUpdatedAt, v))
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v string) predicate.Extension {
return predicate.Extension(sql.FieldGTE(FieldUpdatedAt, v))
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v string) predicate.Extension {
return predicate.Extension(sql.FieldLT(FieldUpdatedAt, v))
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v string) predicate.Extension {
return predicate.Extension(sql.FieldLTE(FieldUpdatedAt, v))
}
// UpdatedAtContains applies the Contains predicate on the "updated_at" field.
func UpdatedAtContains(v string) predicate.Extension {
return predicate.Extension(sql.FieldContains(FieldUpdatedAt, v))
}
// UpdatedAtHasPrefix applies the HasPrefix predicate on the "updated_at" field.
func UpdatedAtHasPrefix(v string) predicate.Extension {
return predicate.Extension(sql.FieldHasPrefix(FieldUpdatedAt, v))
}
// UpdatedAtHasSuffix applies the HasSuffix predicate on the "updated_at" field.
func UpdatedAtHasSuffix(v string) predicate.Extension {
return predicate.Extension(sql.FieldHasSuffix(FieldUpdatedAt, v))
}
// UpdatedAtEqualFold applies the EqualFold predicate on the "updated_at" field.
func UpdatedAtEqualFold(v string) predicate.Extension {
return predicate.Extension(sql.FieldEqualFold(FieldUpdatedAt, v))
}
// UpdatedAtContainsFold applies the ContainsFold predicate on the "updated_at" field.
func UpdatedAtContainsFold(v string) predicate.Extension {
return predicate.Extension(sql.FieldContainsFold(FieldUpdatedAt, v))
}
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
func DeletedAtEQ(v string) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldDeletedAt, v))
}
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
func DeletedAtNEQ(v string) predicate.Extension {
return predicate.Extension(sql.FieldNEQ(FieldDeletedAt, v))
}
// DeletedAtIn applies the In predicate on the "deleted_at" field.
func DeletedAtIn(vs ...string) predicate.Extension {
return predicate.Extension(sql.FieldIn(FieldDeletedAt, vs...))
}
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
func DeletedAtNotIn(vs ...string) predicate.Extension {
return predicate.Extension(sql.FieldNotIn(FieldDeletedAt, vs...))
}
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
func DeletedAtGT(v string) predicate.Extension {
return predicate.Extension(sql.FieldGT(FieldDeletedAt, v))
}
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
func DeletedAtGTE(v string) predicate.Extension {
return predicate.Extension(sql.FieldGTE(FieldDeletedAt, v))
}
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
func DeletedAtLT(v string) predicate.Extension {
return predicate.Extension(sql.FieldLT(FieldDeletedAt, v))
}
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
func DeletedAtLTE(v string) predicate.Extension {
return predicate.Extension(sql.FieldLTE(FieldDeletedAt, v))
}
// DeletedAtContains applies the Contains predicate on the "deleted_at" field.
func DeletedAtContains(v string) predicate.Extension {
return predicate.Extension(sql.FieldContains(FieldDeletedAt, v))
}
// DeletedAtHasPrefix applies the HasPrefix predicate on the "deleted_at" field.
func DeletedAtHasPrefix(v string) predicate.Extension {
return predicate.Extension(sql.FieldHasPrefix(FieldDeletedAt, v))
}
// DeletedAtHasSuffix applies the HasSuffix predicate on the "deleted_at" field.
func DeletedAtHasSuffix(v string) predicate.Extension {
return predicate.Extension(sql.FieldHasSuffix(FieldDeletedAt, v))
}
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
func DeletedAtIsNil() predicate.Extension {
return predicate.Extension(sql.FieldIsNull(FieldDeletedAt))
}
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
func DeletedAtNotNil() predicate.Extension {
return predicate.Extension(sql.FieldNotNull(FieldDeletedAt))
}
// DeletedAtEqualFold applies the EqualFold predicate on the "deleted_at" field.
func DeletedAtEqualFold(v string) predicate.Extension {
return predicate.Extension(sql.FieldEqualFold(FieldDeletedAt, v))
}
// DeletedAtContainsFold applies the ContainsFold predicate on the "deleted_at" field.
func DeletedAtContainsFold(v string) predicate.Extension {
return predicate.Extension(sql.FieldContainsFold(FieldDeletedAt, v))
}
// KeyEQ applies the EQ predicate on the "key" field.
func KeyEQ(v string) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldKey, v))
}
// KeyNEQ applies the NEQ predicate on the "key" field.
func KeyNEQ(v string) predicate.Extension {
return predicate.Extension(sql.FieldNEQ(FieldKey, v))
}
// KeyIn applies the In predicate on the "key" field.
func KeyIn(vs ...string) predicate.Extension {
return predicate.Extension(sql.FieldIn(FieldKey, vs...))
}
// KeyNotIn applies the NotIn predicate on the "key" field.
func KeyNotIn(vs ...string) predicate.Extension {
return predicate.Extension(sql.FieldNotIn(FieldKey, vs...))
}
// KeyGT applies the GT predicate on the "key" field.
func KeyGT(v string) predicate.Extension {
return predicate.Extension(sql.FieldGT(FieldKey, v))
}
// KeyGTE applies the GTE predicate on the "key" field.
func KeyGTE(v string) predicate.Extension {
return predicate.Extension(sql.FieldGTE(FieldKey, v))
}
// KeyLT applies the LT predicate on the "key" field.
func KeyLT(v string) predicate.Extension {
return predicate.Extension(sql.FieldLT(FieldKey, v))
}
// KeyLTE applies the LTE predicate on the "key" field.
func KeyLTE(v string) predicate.Extension {
return predicate.Extension(sql.FieldLTE(FieldKey, v))
}
// KeyContains applies the Contains predicate on the "key" field.
func KeyContains(v string) predicate.Extension {
return predicate.Extension(sql.FieldContains(FieldKey, v))
}
// KeyHasPrefix applies the HasPrefix predicate on the "key" field.
func KeyHasPrefix(v string) predicate.Extension {
return predicate.Extension(sql.FieldHasPrefix(FieldKey, v))
}
// KeyHasSuffix applies the HasSuffix predicate on the "key" field.
func KeyHasSuffix(v string) predicate.Extension {
return predicate.Extension(sql.FieldHasSuffix(FieldKey, v))
}
// KeyEqualFold applies the EqualFold predicate on the "key" field.
func KeyEqualFold(v string) predicate.Extension {
return predicate.Extension(sql.FieldEqualFold(FieldKey, v))
}
// KeyContainsFold applies the ContainsFold predicate on the "key" field.
func KeyContainsFold(v string) predicate.Extension {
return predicate.Extension(sql.FieldContainsFold(FieldKey, v))
}
// EnabledEQ applies the EQ predicate on the "enabled" field.
func EnabledEQ(v bool) predicate.Extension {
return predicate.Extension(sql.FieldEQ(FieldEnabled, v))
}
// EnabledNEQ applies the NEQ predicate on the "enabled" field.
func EnabledNEQ(v bool) predicate.Extension {
return predicate.Extension(sql.FieldNEQ(FieldEnabled, v))
}
// ConfigIsNil applies the IsNil predicate on the "config" field.
func ConfigIsNil() predicate.Extension {
return predicate.Extension(sql.FieldIsNull(FieldConfig))
}
// ConfigNotNil applies the NotNil predicate on the "config" field.
func ConfigNotNil() predicate.Extension {
return predicate.Extension(sql.FieldNotNull(FieldConfig))
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Extension) predicate.Extension {
return predicate.Extension(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.Extension) predicate.Extension {
return predicate.Extension(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.Extension) predicate.Extension {
return predicate.Extension(sql.NotPredicates(p))
}

View File

@@ -0,0 +1,306 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"voidraft/internal/models/ent/extension"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// ExtensionCreate is the builder for creating a Extension entity.
type ExtensionCreate struct {
config
mutation *ExtensionMutation
hooks []Hook
}
// SetCreatedAt sets the "created_at" field.
func (_c *ExtensionCreate) SetCreatedAt(v string) *ExtensionCreate {
_c.mutation.SetCreatedAt(v)
return _c
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (_c *ExtensionCreate) SetNillableCreatedAt(v *string) *ExtensionCreate {
if v != nil {
_c.SetCreatedAt(*v)
}
return _c
}
// SetUpdatedAt sets the "updated_at" field.
func (_c *ExtensionCreate) SetUpdatedAt(v string) *ExtensionCreate {
_c.mutation.SetUpdatedAt(v)
return _c
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_c *ExtensionCreate) SetNillableUpdatedAt(v *string) *ExtensionCreate {
if v != nil {
_c.SetUpdatedAt(*v)
}
return _c
}
// SetDeletedAt sets the "deleted_at" field.
func (_c *ExtensionCreate) SetDeletedAt(v string) *ExtensionCreate {
_c.mutation.SetDeletedAt(v)
return _c
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_c *ExtensionCreate) SetNillableDeletedAt(v *string) *ExtensionCreate {
if v != nil {
_c.SetDeletedAt(*v)
}
return _c
}
// SetKey sets the "key" field.
func (_c *ExtensionCreate) SetKey(v string) *ExtensionCreate {
_c.mutation.SetKey(v)
return _c
}
// SetEnabled sets the "enabled" field.
func (_c *ExtensionCreate) SetEnabled(v bool) *ExtensionCreate {
_c.mutation.SetEnabled(v)
return _c
}
// SetNillableEnabled sets the "enabled" field if the given value is not nil.
func (_c *ExtensionCreate) SetNillableEnabled(v *bool) *ExtensionCreate {
if v != nil {
_c.SetEnabled(*v)
}
return _c
}
// SetConfig sets the "config" field.
func (_c *ExtensionCreate) SetConfig(v map[string]interface{}) *ExtensionCreate {
_c.mutation.SetConfig(v)
return _c
}
// Mutation returns the ExtensionMutation object of the builder.
func (_c *ExtensionCreate) Mutation() *ExtensionMutation {
return _c.mutation
}
// Save creates the Extension in the database.
func (_c *ExtensionCreate) Save(ctx context.Context) (*Extension, error) {
if err := _c.defaults(); err != nil {
return nil, err
}
return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks)
}
// SaveX calls Save and panics if Save returns an error.
func (_c *ExtensionCreate) SaveX(ctx context.Context) *Extension {
v, err := _c.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (_c *ExtensionCreate) Exec(ctx context.Context) error {
_, err := _c.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_c *ExtensionCreate) ExecX(ctx context.Context) {
if err := _c.Exec(ctx); err != nil {
panic(err)
}
}
// defaults sets the default values of the builder before save.
func (_c *ExtensionCreate) defaults() error {
if _, ok := _c.mutation.CreatedAt(); !ok {
if extension.DefaultCreatedAt == nil {
return fmt.Errorf("ent: uninitialized extension.DefaultCreatedAt (forgotten import ent/runtime?)")
}
v := extension.DefaultCreatedAt()
_c.mutation.SetCreatedAt(v)
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
if extension.DefaultUpdatedAt == nil {
return fmt.Errorf("ent: uninitialized extension.DefaultUpdatedAt (forgotten import ent/runtime?)")
}
v := extension.DefaultUpdatedAt()
_c.mutation.SetUpdatedAt(v)
}
if _, ok := _c.mutation.Enabled(); !ok {
v := extension.DefaultEnabled
_c.mutation.SetEnabled(v)
}
return nil
}
// check runs all checks and user-defined validators on the builder.
func (_c *ExtensionCreate) check() error {
if _, ok := _c.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "Extension.created_at"`)}
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "Extension.updated_at"`)}
}
if _, ok := _c.mutation.Key(); !ok {
return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "Extension.key"`)}
}
if v, ok := _c.mutation.Key(); ok {
if err := extension.KeyValidator(v); err != nil {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Extension.key": %w`, err)}
}
}
if _, ok := _c.mutation.Enabled(); !ok {
return &ValidationError{Name: "enabled", err: errors.New(`ent: missing required field "Extension.enabled"`)}
}
return nil
}
func (_c *ExtensionCreate) sqlSave(ctx context.Context) (*Extension, error) {
if err := _c.check(); err != nil {
return nil, err
}
_node, _spec := _c.createSpec()
if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
id := _spec.ID.Value.(int64)
_node.ID = int(id)
_c.mutation.id = &_node.ID
_c.mutation.done = true
return _node, nil
}
func (_c *ExtensionCreate) createSpec() (*Extension, *sqlgraph.CreateSpec) {
var (
_node = &Extension{config: _c.config}
_spec = sqlgraph.NewCreateSpec(extension.Table, sqlgraph.NewFieldSpec(extension.FieldID, field.TypeInt))
)
if value, ok := _c.mutation.CreatedAt(); ok {
_spec.SetField(extension.FieldCreatedAt, field.TypeString, value)
_node.CreatedAt = value
}
if value, ok := _c.mutation.UpdatedAt(); ok {
_spec.SetField(extension.FieldUpdatedAt, field.TypeString, value)
_node.UpdatedAt = value
}
if value, ok := _c.mutation.DeletedAt(); ok {
_spec.SetField(extension.FieldDeletedAt, field.TypeString, value)
_node.DeletedAt = &value
}
if value, ok := _c.mutation.Key(); ok {
_spec.SetField(extension.FieldKey, field.TypeString, value)
_node.Key = value
}
if value, ok := _c.mutation.Enabled(); ok {
_spec.SetField(extension.FieldEnabled, field.TypeBool, value)
_node.Enabled = value
}
if value, ok := _c.mutation.Config(); ok {
_spec.SetField(extension.FieldConfig, field.TypeJSON, value)
_node.Config = value
}
return _node, _spec
}
// ExtensionCreateBulk is the builder for creating many Extension entities in bulk.
type ExtensionCreateBulk struct {
config
err error
builders []*ExtensionCreate
}
// Save creates the Extension entities in the database.
func (_c *ExtensionCreateBulk) Save(ctx context.Context) ([]*Extension, error) {
if _c.err != nil {
return nil, _c.err
}
specs := make([]*sqlgraph.CreateSpec, len(_c.builders))
nodes := make([]*Extension, len(_c.builders))
mutators := make([]Mutator, len(_c.builders))
for i := range _c.builders {
func(i int, root context.Context) {
builder := _c.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ExtensionMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
var err error
nodes[i], specs[i] = builder.createSpec()
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation)
} else {
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
}
}
if err != nil {
return nil, err
}
mutation.id = &nodes[i].ID
if specs[i].ID.Value != nil {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int(id)
}
mutation.done = true
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (_c *ExtensionCreateBulk) SaveX(ctx context.Context) []*Extension {
v, err := _c.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (_c *ExtensionCreateBulk) Exec(ctx context.Context) error {
_, err := _c.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_c *ExtensionCreateBulk) ExecX(ctx context.Context) {
if err := _c.Exec(ctx); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,88 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"voidraft/internal/models/ent/extension"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// ExtensionDelete is the builder for deleting a Extension entity.
type ExtensionDelete struct {
config
hooks []Hook
mutation *ExtensionMutation
}
// Where appends a list predicates to the ExtensionDelete builder.
func (_d *ExtensionDelete) Where(ps ...predicate.Extension) *ExtensionDelete {
_d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (_d *ExtensionDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *ExtensionDelete) ExecX(ctx context.Context) int {
n, err := _d.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (_d *ExtensionDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(extension.Table, sqlgraph.NewFieldSpec(extension.FieldID, field.TypeInt))
if ps := _d.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
_d.mutation.done = true
return affected, err
}
// ExtensionDeleteOne is the builder for deleting a single Extension entity.
type ExtensionDeleteOne struct {
_d *ExtensionDelete
}
// Where appends a list predicates to the ExtensionDelete builder.
func (_d *ExtensionDeleteOne) Where(ps ...predicate.Extension) *ExtensionDeleteOne {
_d._d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query.
func (_d *ExtensionDeleteOne) Exec(ctx context.Context) error {
n, err := _d._d.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{extension.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *ExtensionDeleteOne) ExecX(ctx context.Context) {
if err := _d.Exec(ctx); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,577 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"math"
"voidraft/internal/models/ent/extension"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// ExtensionQuery is the builder for querying Extension entities.
type ExtensionQuery struct {
config
ctx *QueryContext
order []extension.OrderOption
inters []Interceptor
predicates []predicate.Extension
modifiers []func(*sql.Selector)
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the ExtensionQuery builder.
func (_q *ExtensionQuery) Where(ps ...predicate.Extension) *ExtensionQuery {
_q.predicates = append(_q.predicates, ps...)
return _q
}
// Limit the number of records to be returned by this query.
func (_q *ExtensionQuery) Limit(limit int) *ExtensionQuery {
_q.ctx.Limit = &limit
return _q
}
// Offset to start from.
func (_q *ExtensionQuery) Offset(offset int) *ExtensionQuery {
_q.ctx.Offset = &offset
return _q
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func (_q *ExtensionQuery) Unique(unique bool) *ExtensionQuery {
_q.ctx.Unique = &unique
return _q
}
// Order specifies how the records should be ordered.
func (_q *ExtensionQuery) Order(o ...extension.OrderOption) *ExtensionQuery {
_q.order = append(_q.order, o...)
return _q
}
// First returns the first Extension entity from the query.
// Returns a *NotFoundError when no Extension was found.
func (_q *ExtensionQuery) First(ctx context.Context) (*Extension, error) {
nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{extension.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (_q *ExtensionQuery) FirstX(ctx context.Context) *Extension {
node, err := _q.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first Extension ID from the query.
// Returns a *NotFoundError when no Extension ID was found.
func (_q *ExtensionQuery) FirstID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{extension.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (_q *ExtensionQuery) FirstIDX(ctx context.Context) int {
id, err := _q.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single Extension entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one Extension entity is found.
// Returns a *NotFoundError when no Extension entities are found.
func (_q *ExtensionQuery) Only(ctx context.Context) (*Extension, error) {
nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{extension.Label}
default:
return nil, &NotSingularError{extension.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (_q *ExtensionQuery) OnlyX(ctx context.Context) *Extension {
node, err := _q.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only Extension ID in the query.
// Returns a *NotSingularError when more than one Extension ID is found.
// Returns a *NotFoundError when no entities are found.
func (_q *ExtensionQuery) OnlyID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{extension.Label}
default:
err = &NotSingularError{extension.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (_q *ExtensionQuery) OnlyIDX(ctx context.Context) int {
id, err := _q.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of Extensions.
func (_q *ExtensionQuery) All(ctx context.Context) ([]*Extension, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll)
if err := _q.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*Extension, *ExtensionQuery]()
return withInterceptors[[]*Extension](ctx, _q, qr, _q.inters)
}
// AllX is like All, but panics if an error occurs.
func (_q *ExtensionQuery) AllX(ctx context.Context) []*Extension {
nodes, err := _q.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of Extension IDs.
func (_q *ExtensionQuery) IDs(ctx context.Context) (ids []int, err error) {
if _q.ctx.Unique == nil && _q.path != nil {
_q.Unique(true)
}
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs)
if err = _q.Select(extension.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (_q *ExtensionQuery) IDsX(ctx context.Context) []int {
ids, err := _q.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (_q *ExtensionQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount)
if err := _q.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, _q, querierCount[*ExtensionQuery](), _q.inters)
}
// CountX is like Count, but panics if an error occurs.
func (_q *ExtensionQuery) CountX(ctx context.Context) int {
count, err := _q.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (_q *ExtensionQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist)
switch _, err := _q.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (_q *ExtensionQuery) ExistX(ctx context.Context) bool {
exist, err := _q.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the ExtensionQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (_q *ExtensionQuery) Clone() *ExtensionQuery {
if _q == nil {
return nil
}
return &ExtensionQuery{
config: _q.config,
ctx: _q.ctx.Clone(),
order: append([]extension.OrderOption{}, _q.order...),
inters: append([]Interceptor{}, _q.inters...),
predicates: append([]predicate.Extension{}, _q.predicates...),
// clone intermediate query.
sql: _q.sql.Clone(),
path: _q.path,
modifiers: append([]func(*sql.Selector){}, _q.modifiers...),
}
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// CreatedAt string `json:"created_at"`
// Count int `json:"count,omitempty"`
// }
//
// client.Extension.Query().
// GroupBy(extension.FieldCreatedAt).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func (_q *ExtensionQuery) GroupBy(field string, fields ...string) *ExtensionGroupBy {
_q.ctx.Fields = append([]string{field}, fields...)
grbuild := &ExtensionGroupBy{build: _q}
grbuild.flds = &_q.ctx.Fields
grbuild.label = extension.Label
grbuild.scan = grbuild.Scan
return grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// CreatedAt string `json:"created_at"`
// }
//
// client.Extension.Query().
// Select(extension.FieldCreatedAt).
// Scan(ctx, &v)
func (_q *ExtensionQuery) Select(fields ...string) *ExtensionSelect {
_q.ctx.Fields = append(_q.ctx.Fields, fields...)
sbuild := &ExtensionSelect{ExtensionQuery: _q}
sbuild.label = extension.Label
sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a ExtensionSelect configured with the given aggregations.
func (_q *ExtensionQuery) Aggregate(fns ...AggregateFunc) *ExtensionSelect {
return _q.Select().Aggregate(fns...)
}
func (_q *ExtensionQuery) prepareQuery(ctx context.Context) error {
for _, inter := range _q.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, _q); err != nil {
return err
}
}
}
for _, f := range _q.ctx.Fields {
if !extension.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if _q.path != nil {
prev, err := _q.path(ctx)
if err != nil {
return err
}
_q.sql = prev
}
return nil
}
func (_q *ExtensionQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Extension, error) {
var (
nodes = []*Extension{}
_spec = _q.querySpec()
)
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*Extension).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &Extension{config: _q.config}
nodes = append(nodes, node)
return node.assignValues(columns, values)
}
if len(_q.modifiers) > 0 {
_spec.Modifiers = _q.modifiers
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
return nodes, nil
}
func (_q *ExtensionQuery) sqlCount(ctx context.Context) (int, error) {
_spec := _q.querySpec()
if len(_q.modifiers) > 0 {
_spec.Modifiers = _q.modifiers
}
_spec.Node.Columns = _q.ctx.Fields
if len(_q.ctx.Fields) > 0 {
_spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique
}
return sqlgraph.CountNodes(ctx, _q.driver, _spec)
}
func (_q *ExtensionQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(extension.Table, extension.Columns, sqlgraph.NewFieldSpec(extension.FieldID, field.TypeInt))
_spec.From = _q.sql
if unique := _q.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if _q.path != nil {
_spec.Unique = true
}
if fields := _q.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, extension.FieldID)
for i := range fields {
if fields[i] != extension.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := _q.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := _q.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := _q.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := _q.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (_q *ExtensionQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(_q.driver.Dialect())
t1 := builder.Table(extension.Table)
columns := _q.ctx.Fields
if len(columns) == 0 {
columns = extension.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if _q.sql != nil {
selector = _q.sql
selector.Select(selector.Columns(columns...)...)
}
if _q.ctx.Unique != nil && *_q.ctx.Unique {
selector.Distinct()
}
for _, m := range _q.modifiers {
m(selector)
}
for _, p := range _q.predicates {
p(selector)
}
for _, p := range _q.order {
p(selector)
}
if offset := _q.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := _q.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
// either committed or rolled-back.
func (_q *ExtensionQuery) ForUpdate(opts ...sql.LockOption) *ExtensionQuery {
if _q.driver.Dialect() == dialect.Postgres {
_q.Unique(false)
}
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
s.ForUpdate(opts...)
})
return _q
}
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
// on any rows that are read. Other sessions can read the rows, but cannot modify them
// until your transaction commits.
func (_q *ExtensionQuery) ForShare(opts ...sql.LockOption) *ExtensionQuery {
if _q.driver.Dialect() == dialect.Postgres {
_q.Unique(false)
}
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
s.ForShare(opts...)
})
return _q
}
// Modify adds a query modifier for attaching custom logic to queries.
func (_q *ExtensionQuery) Modify(modifiers ...func(s *sql.Selector)) *ExtensionSelect {
_q.modifiers = append(_q.modifiers, modifiers...)
return _q.Select()
}
// ExtensionGroupBy is the group-by builder for Extension entities.
type ExtensionGroupBy struct {
selector
build *ExtensionQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (_g *ExtensionGroupBy) Aggregate(fns ...AggregateFunc) *ExtensionGroupBy {
_g.fns = append(_g.fns, fns...)
return _g
}
// Scan applies the selector query and scans the result into the given value.
func (_g *ExtensionGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy)
if err := _g.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*ExtensionQuery, *ExtensionGroupBy](ctx, _g.build, _g, _g.build.inters, v)
}
func (_g *ExtensionGroupBy) sqlScan(ctx context.Context, root *ExtensionQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(_g.fns))
for _, fn := range _g.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*_g.flds)+len(_g.fns))
for _, f := range *_g.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*_g.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := _g.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// ExtensionSelect is the builder for selecting fields of Extension entities.
type ExtensionSelect struct {
*ExtensionQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (_s *ExtensionSelect) Aggregate(fns ...AggregateFunc) *ExtensionSelect {
_s.fns = append(_s.fns, fns...)
return _s
}
// Scan applies the selector query and scans the result into the given value.
func (_s *ExtensionSelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect)
if err := _s.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*ExtensionQuery, *ExtensionSelect](ctx, _s.ExtensionQuery, _s, _s.inters, v)
}
func (_s *ExtensionSelect) sqlScan(ctx context.Context, root *ExtensionQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(_s.fns))
for _, fn := range _s.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*_s.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := _s.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// Modify adds a query modifier for attaching custom logic to queries.
func (_s *ExtensionSelect) Modify(modifiers ...func(s *sql.Selector)) *ExtensionSelect {
_s.modifiers = append(_s.modifiers, modifiers...)
return _s
}

View File

@@ -0,0 +1,407 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"voidraft/internal/models/ent/extension"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// ExtensionUpdate is the builder for updating Extension entities.
type ExtensionUpdate struct {
config
hooks []Hook
mutation *ExtensionMutation
modifiers []func(*sql.UpdateBuilder)
}
// Where appends a list predicates to the ExtensionUpdate builder.
func (_u *ExtensionUpdate) Where(ps ...predicate.Extension) *ExtensionUpdate {
_u.mutation.Where(ps...)
return _u
}
// SetUpdatedAt sets the "updated_at" field.
func (_u *ExtensionUpdate) SetUpdatedAt(v string) *ExtensionUpdate {
_u.mutation.SetUpdatedAt(v)
return _u
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_u *ExtensionUpdate) SetNillableUpdatedAt(v *string) *ExtensionUpdate {
if v != nil {
_u.SetUpdatedAt(*v)
}
return _u
}
// SetDeletedAt sets the "deleted_at" field.
func (_u *ExtensionUpdate) SetDeletedAt(v string) *ExtensionUpdate {
_u.mutation.SetDeletedAt(v)
return _u
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_u *ExtensionUpdate) SetNillableDeletedAt(v *string) *ExtensionUpdate {
if v != nil {
_u.SetDeletedAt(*v)
}
return _u
}
// ClearDeletedAt clears the value of the "deleted_at" field.
func (_u *ExtensionUpdate) ClearDeletedAt() *ExtensionUpdate {
_u.mutation.ClearDeletedAt()
return _u
}
// SetKey sets the "key" field.
func (_u *ExtensionUpdate) SetKey(v string) *ExtensionUpdate {
_u.mutation.SetKey(v)
return _u
}
// SetNillableKey sets the "key" field if the given value is not nil.
func (_u *ExtensionUpdate) SetNillableKey(v *string) *ExtensionUpdate {
if v != nil {
_u.SetKey(*v)
}
return _u
}
// SetEnabled sets the "enabled" field.
func (_u *ExtensionUpdate) SetEnabled(v bool) *ExtensionUpdate {
_u.mutation.SetEnabled(v)
return _u
}
// SetNillableEnabled sets the "enabled" field if the given value is not nil.
func (_u *ExtensionUpdate) SetNillableEnabled(v *bool) *ExtensionUpdate {
if v != nil {
_u.SetEnabled(*v)
}
return _u
}
// SetConfig sets the "config" field.
func (_u *ExtensionUpdate) SetConfig(v map[string]interface{}) *ExtensionUpdate {
_u.mutation.SetConfig(v)
return _u
}
// ClearConfig clears the value of the "config" field.
func (_u *ExtensionUpdate) ClearConfig() *ExtensionUpdate {
_u.mutation.ClearConfig()
return _u
}
// Mutation returns the ExtensionMutation object of the builder.
func (_u *ExtensionUpdate) Mutation() *ExtensionMutation {
return _u.mutation
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (_u *ExtensionUpdate) Save(ctx context.Context) (int, error) {
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (_u *ExtensionUpdate) SaveX(ctx context.Context) int {
affected, err := _u.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (_u *ExtensionUpdate) Exec(ctx context.Context) error {
_, err := _u.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_u *ExtensionUpdate) ExecX(ctx context.Context) {
if err := _u.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (_u *ExtensionUpdate) check() error {
if v, ok := _u.mutation.Key(); ok {
if err := extension.KeyValidator(v); err != nil {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Extension.key": %w`, err)}
}
}
return nil
}
// Modify adds a statement modifier for attaching custom logic to the UPDATE statement.
func (_u *ExtensionUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *ExtensionUpdate {
_u.modifiers = append(_u.modifiers, modifiers...)
return _u
}
func (_u *ExtensionUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if err := _u.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(extension.Table, extension.Columns, sqlgraph.NewFieldSpec(extension.FieldID, field.TypeInt))
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := _u.mutation.UpdatedAt(); ok {
_spec.SetField(extension.FieldUpdatedAt, field.TypeString, value)
}
if value, ok := _u.mutation.DeletedAt(); ok {
_spec.SetField(extension.FieldDeletedAt, field.TypeString, value)
}
if _u.mutation.DeletedAtCleared() {
_spec.ClearField(extension.FieldDeletedAt, field.TypeString)
}
if value, ok := _u.mutation.Key(); ok {
_spec.SetField(extension.FieldKey, field.TypeString, value)
}
if value, ok := _u.mutation.Enabled(); ok {
_spec.SetField(extension.FieldEnabled, field.TypeBool, value)
}
if value, ok := _u.mutation.Config(); ok {
_spec.SetField(extension.FieldConfig, field.TypeJSON, value)
}
if _u.mutation.ConfigCleared() {
_spec.ClearField(extension.FieldConfig, field.TypeJSON)
}
_spec.AddModifiers(_u.modifiers...)
if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{extension.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return 0, err
}
_u.mutation.done = true
return _node, nil
}
// ExtensionUpdateOne is the builder for updating a single Extension entity.
type ExtensionUpdateOne struct {
config
fields []string
hooks []Hook
mutation *ExtensionMutation
modifiers []func(*sql.UpdateBuilder)
}
// SetUpdatedAt sets the "updated_at" field.
func (_u *ExtensionUpdateOne) SetUpdatedAt(v string) *ExtensionUpdateOne {
_u.mutation.SetUpdatedAt(v)
return _u
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_u *ExtensionUpdateOne) SetNillableUpdatedAt(v *string) *ExtensionUpdateOne {
if v != nil {
_u.SetUpdatedAt(*v)
}
return _u
}
// SetDeletedAt sets the "deleted_at" field.
func (_u *ExtensionUpdateOne) SetDeletedAt(v string) *ExtensionUpdateOne {
_u.mutation.SetDeletedAt(v)
return _u
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_u *ExtensionUpdateOne) SetNillableDeletedAt(v *string) *ExtensionUpdateOne {
if v != nil {
_u.SetDeletedAt(*v)
}
return _u
}
// ClearDeletedAt clears the value of the "deleted_at" field.
func (_u *ExtensionUpdateOne) ClearDeletedAt() *ExtensionUpdateOne {
_u.mutation.ClearDeletedAt()
return _u
}
// SetKey sets the "key" field.
func (_u *ExtensionUpdateOne) SetKey(v string) *ExtensionUpdateOne {
_u.mutation.SetKey(v)
return _u
}
// SetNillableKey sets the "key" field if the given value is not nil.
func (_u *ExtensionUpdateOne) SetNillableKey(v *string) *ExtensionUpdateOne {
if v != nil {
_u.SetKey(*v)
}
return _u
}
// SetEnabled sets the "enabled" field.
func (_u *ExtensionUpdateOne) SetEnabled(v bool) *ExtensionUpdateOne {
_u.mutation.SetEnabled(v)
return _u
}
// SetNillableEnabled sets the "enabled" field if the given value is not nil.
func (_u *ExtensionUpdateOne) SetNillableEnabled(v *bool) *ExtensionUpdateOne {
if v != nil {
_u.SetEnabled(*v)
}
return _u
}
// SetConfig sets the "config" field.
func (_u *ExtensionUpdateOne) SetConfig(v map[string]interface{}) *ExtensionUpdateOne {
_u.mutation.SetConfig(v)
return _u
}
// ClearConfig clears the value of the "config" field.
func (_u *ExtensionUpdateOne) ClearConfig() *ExtensionUpdateOne {
_u.mutation.ClearConfig()
return _u
}
// Mutation returns the ExtensionMutation object of the builder.
func (_u *ExtensionUpdateOne) Mutation() *ExtensionMutation {
return _u.mutation
}
// Where appends a list predicates to the ExtensionUpdate builder.
func (_u *ExtensionUpdateOne) Where(ps ...predicate.Extension) *ExtensionUpdateOne {
_u.mutation.Where(ps...)
return _u
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func (_u *ExtensionUpdateOne) Select(field string, fields ...string) *ExtensionUpdateOne {
_u.fields = append([]string{field}, fields...)
return _u
}
// Save executes the query and returns the updated Extension entity.
func (_u *ExtensionUpdateOne) Save(ctx context.Context) (*Extension, error) {
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (_u *ExtensionUpdateOne) SaveX(ctx context.Context) *Extension {
node, err := _u.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (_u *ExtensionUpdateOne) Exec(ctx context.Context) error {
_, err := _u.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_u *ExtensionUpdateOne) ExecX(ctx context.Context) {
if err := _u.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (_u *ExtensionUpdateOne) check() error {
if v, ok := _u.mutation.Key(); ok {
if err := extension.KeyValidator(v); err != nil {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Extension.key": %w`, err)}
}
}
return nil
}
// Modify adds a statement modifier for attaching custom logic to the UPDATE statement.
func (_u *ExtensionUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *ExtensionUpdateOne {
_u.modifiers = append(_u.modifiers, modifiers...)
return _u
}
func (_u *ExtensionUpdateOne) sqlSave(ctx context.Context) (_node *Extension, err error) {
if err := _u.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(extension.Table, extension.Columns, sqlgraph.NewFieldSpec(extension.FieldID, field.TypeInt))
id, ok := _u.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Extension.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := _u.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, extension.FieldID)
for _, f := range fields {
if !extension.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
if f != extension.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := _u.mutation.UpdatedAt(); ok {
_spec.SetField(extension.FieldUpdatedAt, field.TypeString, value)
}
if value, ok := _u.mutation.DeletedAt(); ok {
_spec.SetField(extension.FieldDeletedAt, field.TypeString, value)
}
if _u.mutation.DeletedAtCleared() {
_spec.ClearField(extension.FieldDeletedAt, field.TypeString)
}
if value, ok := _u.mutation.Key(); ok {
_spec.SetField(extension.FieldKey, field.TypeString, value)
}
if value, ok := _u.mutation.Enabled(); ok {
_spec.SetField(extension.FieldEnabled, field.TypeBool, value)
}
if value, ok := _u.mutation.Config(); ok {
_spec.SetField(extension.FieldConfig, field.TypeJSON, value)
}
if _u.mutation.ConfigCleared() {
_spec.ClearField(extension.FieldConfig, field.TypeJSON)
}
_spec.AddModifiers(_u.modifiers...)
_node = &Extension{config: _u.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{extension.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
_u.mutation.done = true
return _node, nil
}

View File

@@ -0,0 +1 @@
package ent

View File

@@ -0,0 +1,234 @@
// Code generated by ent, DO NOT EDIT.
package hook
import (
"context"
"fmt"
"voidraft/internal/models/ent"
)
// The DocumentFunc type is an adapter to allow the use of ordinary
// function as Document mutator.
type DocumentFunc func(context.Context, *ent.DocumentMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f DocumentFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.DocumentMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.DocumentMutation", m)
}
// The ExtensionFunc type is an adapter to allow the use of ordinary
// function as Extension mutator.
type ExtensionFunc func(context.Context, *ent.ExtensionMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ExtensionFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ExtensionMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ExtensionMutation", m)
}
// The KeyBindingFunc type is an adapter to allow the use of ordinary
// function as KeyBinding mutator.
type KeyBindingFunc func(context.Context, *ent.KeyBindingMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f KeyBindingFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.KeyBindingMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.KeyBindingMutation", m)
}
// The ThemeFunc type is an adapter to allow the use of ordinary
// function as Theme mutator.
type ThemeFunc func(context.Context, *ent.ThemeMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ThemeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ThemeMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ThemeMutation", m)
}
// Condition is a hook condition function.
type Condition func(context.Context, ent.Mutation) bool
// And groups conditions with the AND operator.
func And(first, second Condition, rest ...Condition) Condition {
return func(ctx context.Context, m ent.Mutation) bool {
if !first(ctx, m) || !second(ctx, m) {
return false
}
for _, cond := range rest {
if !cond(ctx, m) {
return false
}
}
return true
}
}
// Or groups conditions with the OR operator.
func Or(first, second Condition, rest ...Condition) Condition {
return func(ctx context.Context, m ent.Mutation) bool {
if first(ctx, m) || second(ctx, m) {
return true
}
for _, cond := range rest {
if cond(ctx, m) {
return true
}
}
return false
}
}
// Not negates a given condition.
func Not(cond Condition) Condition {
return func(ctx context.Context, m ent.Mutation) bool {
return !cond(ctx, m)
}
}
// HasOp is a condition testing mutation operation.
func HasOp(op ent.Op) Condition {
return func(_ context.Context, m ent.Mutation) bool {
return m.Op().Is(op)
}
}
// HasAddedFields is a condition validating `.AddedField` on fields.
func HasAddedFields(field string, fields ...string) Condition {
return func(_ context.Context, m ent.Mutation) bool {
if _, exists := m.AddedField(field); !exists {
return false
}
for _, field := range fields {
if _, exists := m.AddedField(field); !exists {
return false
}
}
return true
}
}
// HasClearedFields is a condition validating `.FieldCleared` on fields.
func HasClearedFields(field string, fields ...string) Condition {
return func(_ context.Context, m ent.Mutation) bool {
if exists := m.FieldCleared(field); !exists {
return false
}
for _, field := range fields {
if exists := m.FieldCleared(field); !exists {
return false
}
}
return true
}
}
// HasFields is a condition validating `.Field` on fields.
func HasFields(field string, fields ...string) Condition {
return func(_ context.Context, m ent.Mutation) bool {
if _, exists := m.Field(field); !exists {
return false
}
for _, field := range fields {
if _, exists := m.Field(field); !exists {
return false
}
}
return true
}
}
// If executes the given hook under condition.
//
// hook.If(ComputeAverage, And(HasFields(...), HasAddedFields(...)))
func If(hk ent.Hook, cond Condition) ent.Hook {
return func(next ent.Mutator) ent.Mutator {
return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if cond(ctx, m) {
return hk(next).Mutate(ctx, m)
}
return next.Mutate(ctx, m)
})
}
}
// On executes the given hook only for the given operation.
//
// hook.On(Log, ent.Delete|ent.Create)
func On(hk ent.Hook, op ent.Op) ent.Hook {
return If(hk, HasOp(op))
}
// Unless skips the given hook only for the given operation.
//
// hook.Unless(Log, ent.Update|ent.UpdateOne)
func Unless(hk ent.Hook, op ent.Op) ent.Hook {
return If(hk, Not(HasOp(op)))
}
// FixedError is a hook returning a fixed error.
func FixedError(err error) ent.Hook {
return func(ent.Mutator) ent.Mutator {
return ent.MutateFunc(func(context.Context, ent.Mutation) (ent.Value, error) {
return nil, err
})
}
}
// Reject returns a hook that rejects all operations that match op.
//
// func (T) Hooks() []ent.Hook {
// return []ent.Hook{
// Reject(ent.Delete|ent.Update),
// }
// }
func Reject(op ent.Op) ent.Hook {
hk := FixedError(fmt.Errorf("%s operation is not allowed", op))
return On(hk, op)
}
// Chain acts as a list of hooks and is effectively immutable.
// Once created, it will always hold the same set of hooks in the same order.
type Chain struct {
hooks []ent.Hook
}
// NewChain creates a new chain of hooks.
func NewChain(hooks ...ent.Hook) Chain {
return Chain{append([]ent.Hook(nil), hooks...)}
}
// Hook chains the list of hooks and returns the final hook.
func (c Chain) Hook() ent.Hook {
return func(mutator ent.Mutator) ent.Mutator {
for i := len(c.hooks) - 1; i >= 0; i-- {
mutator = c.hooks[i](mutator)
}
return mutator
}
}
// Append extends a chain, adding the specified hook
// as the last ones in the mutation flow.
func (c Chain) Append(hooks ...ent.Hook) Chain {
newHooks := make([]ent.Hook, 0, len(c.hooks)+len(hooks))
newHooks = append(newHooks, c.hooks...)
newHooks = append(newHooks, hooks...)
return Chain{newHooks}
}
// Extend extends a chain, adding the specified chain
// as the last ones in the mutation flow.
func (c Chain) Extend(chain Chain) Chain {
return c.Append(chain.hooks...)
}

View File

@@ -0,0 +1,240 @@
// Code generated by ent, DO NOT EDIT.
package intercept
import (
"context"
"fmt"
"voidraft/internal/models/ent"
"voidraft/internal/models/ent/document"
"voidraft/internal/models/ent/extension"
"voidraft/internal/models/ent/keybinding"
"voidraft/internal/models/ent/predicate"
"voidraft/internal/models/ent/theme"
"entgo.io/ent/dialect/sql"
)
// The Query interface represents an operation that queries a graph.
// By using this interface, users can write generic code that manipulates
// query builders of different types.
type Query interface {
// Type returns the string representation of the query type.
Type() string
// Limit the number of records to be returned by this query.
Limit(int)
// Offset to start from.
Offset(int)
// Unique configures the query builder to filter duplicate records.
Unique(bool)
// Order specifies how the records should be ordered.
Order(...func(*sql.Selector))
// WhereP appends storage-level predicates to the query builder. Using this method, users
// can use type-assertion to append predicates that do not depend on any generated package.
WhereP(...func(*sql.Selector))
}
// The Func type is an adapter that allows ordinary functions to be used as interceptors.
// Unlike traversal functions, interceptors are skipped during graph traversals. Note that the
// implementation of Func is different from the one defined in entgo.io/ent.InterceptFunc.
type Func func(context.Context, Query) error
// Intercept calls f(ctx, q) and then applied the next Querier.
func (f Func) Intercept(next ent.Querier) ent.Querier {
return ent.QuerierFunc(func(ctx context.Context, q ent.Query) (ent.Value, error) {
query, err := NewQuery(q)
if err != nil {
return nil, err
}
if err := f(ctx, query); err != nil {
return nil, err
}
return next.Query(ctx, q)
})
}
// The TraverseFunc type is an adapter to allow the use of ordinary function as Traverser.
// If f is a function with the appropriate signature, TraverseFunc(f) is a Traverser that calls f.
type TraverseFunc func(context.Context, Query) error
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
func (f TraverseFunc) Intercept(next ent.Querier) ent.Querier {
return next
}
// Traverse calls f(ctx, q).
func (f TraverseFunc) Traverse(ctx context.Context, q ent.Query) error {
query, err := NewQuery(q)
if err != nil {
return err
}
return f(ctx, query)
}
// The DocumentFunc type is an adapter to allow the use of ordinary function as a Querier.
type DocumentFunc func(context.Context, *ent.DocumentQuery) (ent.Value, error)
// Query calls f(ctx, q).
func (f DocumentFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
if q, ok := q.(*ent.DocumentQuery); ok {
return f(ctx, q)
}
return nil, fmt.Errorf("unexpected query type %T. expect *ent.DocumentQuery", q)
}
// The TraverseDocument type is an adapter to allow the use of ordinary function as Traverser.
type TraverseDocument func(context.Context, *ent.DocumentQuery) error
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
func (f TraverseDocument) Intercept(next ent.Querier) ent.Querier {
return next
}
// Traverse calls f(ctx, q).
func (f TraverseDocument) Traverse(ctx context.Context, q ent.Query) error {
if q, ok := q.(*ent.DocumentQuery); ok {
return f(ctx, q)
}
return fmt.Errorf("unexpected query type %T. expect *ent.DocumentQuery", q)
}
// The ExtensionFunc type is an adapter to allow the use of ordinary function as a Querier.
type ExtensionFunc func(context.Context, *ent.ExtensionQuery) (ent.Value, error)
// Query calls f(ctx, q).
func (f ExtensionFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
if q, ok := q.(*ent.ExtensionQuery); ok {
return f(ctx, q)
}
return nil, fmt.Errorf("unexpected query type %T. expect *ent.ExtensionQuery", q)
}
// The TraverseExtension type is an adapter to allow the use of ordinary function as Traverser.
type TraverseExtension func(context.Context, *ent.ExtensionQuery) error
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
func (f TraverseExtension) Intercept(next ent.Querier) ent.Querier {
return next
}
// Traverse calls f(ctx, q).
func (f TraverseExtension) Traverse(ctx context.Context, q ent.Query) error {
if q, ok := q.(*ent.ExtensionQuery); ok {
return f(ctx, q)
}
return fmt.Errorf("unexpected query type %T. expect *ent.ExtensionQuery", q)
}
// The KeyBindingFunc type is an adapter to allow the use of ordinary function as a Querier.
type KeyBindingFunc func(context.Context, *ent.KeyBindingQuery) (ent.Value, error)
// Query calls f(ctx, q).
func (f KeyBindingFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
if q, ok := q.(*ent.KeyBindingQuery); ok {
return f(ctx, q)
}
return nil, fmt.Errorf("unexpected query type %T. expect *ent.KeyBindingQuery", q)
}
// The TraverseKeyBinding type is an adapter to allow the use of ordinary function as Traverser.
type TraverseKeyBinding func(context.Context, *ent.KeyBindingQuery) error
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
func (f TraverseKeyBinding) Intercept(next ent.Querier) ent.Querier {
return next
}
// Traverse calls f(ctx, q).
func (f TraverseKeyBinding) Traverse(ctx context.Context, q ent.Query) error {
if q, ok := q.(*ent.KeyBindingQuery); ok {
return f(ctx, q)
}
return fmt.Errorf("unexpected query type %T. expect *ent.KeyBindingQuery", q)
}
// The ThemeFunc type is an adapter to allow the use of ordinary function as a Querier.
type ThemeFunc func(context.Context, *ent.ThemeQuery) (ent.Value, error)
// Query calls f(ctx, q).
func (f ThemeFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
if q, ok := q.(*ent.ThemeQuery); ok {
return f(ctx, q)
}
return nil, fmt.Errorf("unexpected query type %T. expect *ent.ThemeQuery", q)
}
// The TraverseTheme type is an adapter to allow the use of ordinary function as Traverser.
type TraverseTheme func(context.Context, *ent.ThemeQuery) error
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
func (f TraverseTheme) Intercept(next ent.Querier) ent.Querier {
return next
}
// Traverse calls f(ctx, q).
func (f TraverseTheme) Traverse(ctx context.Context, q ent.Query) error {
if q, ok := q.(*ent.ThemeQuery); ok {
return f(ctx, q)
}
return fmt.Errorf("unexpected query type %T. expect *ent.ThemeQuery", q)
}
// NewQuery returns the generic Query interface for the given typed query.
func NewQuery(q ent.Query) (Query, error) {
switch q := q.(type) {
case *ent.DocumentQuery:
return &query[*ent.DocumentQuery, predicate.Document, document.OrderOption]{typ: ent.TypeDocument, tq: q}, nil
case *ent.ExtensionQuery:
return &query[*ent.ExtensionQuery, predicate.Extension, extension.OrderOption]{typ: ent.TypeExtension, tq: q}, nil
case *ent.KeyBindingQuery:
return &query[*ent.KeyBindingQuery, predicate.KeyBinding, keybinding.OrderOption]{typ: ent.TypeKeyBinding, tq: q}, nil
case *ent.ThemeQuery:
return &query[*ent.ThemeQuery, predicate.Theme, theme.OrderOption]{typ: ent.TypeTheme, tq: q}, nil
default:
return nil, fmt.Errorf("unknown query type %T", q)
}
}
type query[T any, P ~func(*sql.Selector), R ~func(*sql.Selector)] struct {
typ string
tq interface {
Limit(int) T
Offset(int) T
Unique(bool) T
Order(...R) T
Where(...P) T
}
}
func (q query[T, P, R]) Type() string {
return q.typ
}
func (q query[T, P, R]) Limit(limit int) {
q.tq.Limit(limit)
}
func (q query[T, P, R]) Offset(offset int) {
q.tq.Offset(offset)
}
func (q query[T, P, R]) Unique(unique bool) {
q.tq.Unique(unique)
}
func (q query[T, P, R]) Order(orders ...func(*sql.Selector)) {
rs := make([]R, len(orders))
for i := range orders {
rs[i] = orders[i]
}
q.tq.Order(rs...)
}
func (q query[T, P, R]) WhereP(ps ...func(*sql.Selector)) {
p := make([]P, len(ps))
for i := range ps {
p[i] = ps[i]
}
q.tq.Where(p...)
}

View File

@@ -0,0 +1,174 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"voidraft/internal/models/ent/keybinding"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
)
// KeyBinding is the model entity for the KeyBinding schema.
type KeyBinding struct {
config `json:"-"`
// ID of the ent.
ID int `json:"id,omitempty"`
// 创建时间
CreatedAt string `json:"created_at"`
// 最后更新时间
UpdatedAt string `json:"updated_at"`
// 删除时间NULL表示未删除
DeletedAt *string `json:"deleted_at,omitempty"`
// 快捷键标识符
Key string `json:"key"`
// 快捷键命令
Command string `json:"command"`
// 所属扩展标识符
Extension string `json:"extension,omitempty"`
// 是否启用
Enabled bool `json:"enabled"`
selectValues sql.SelectValues
}
// scanValues returns the types for scanning values from sql.Rows.
func (*KeyBinding) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case keybinding.FieldEnabled:
values[i] = new(sql.NullBool)
case keybinding.FieldID:
values[i] = new(sql.NullInt64)
case keybinding.FieldCreatedAt, keybinding.FieldUpdatedAt, keybinding.FieldDeletedAt, keybinding.FieldKey, keybinding.FieldCommand, keybinding.FieldExtension:
values[i] = new(sql.NullString)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the KeyBinding fields.
func (_m *KeyBinding) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case keybinding.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
_m.ID = int(value.Int64)
case keybinding.FieldCreatedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
_m.CreatedAt = value.String
}
case keybinding.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
_m.UpdatedAt = value.String
}
case keybinding.FieldDeletedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
} else if value.Valid {
_m.DeletedAt = new(string)
*_m.DeletedAt = value.String
}
case keybinding.FieldKey:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field key", values[i])
} else if value.Valid {
_m.Key = value.String
}
case keybinding.FieldCommand:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field command", values[i])
} else if value.Valid {
_m.Command = value.String
}
case keybinding.FieldExtension:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field extension", values[i])
} else if value.Valid {
_m.Extension = value.String
}
case keybinding.FieldEnabled:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field enabled", values[i])
} else if value.Valid {
_m.Enabled = value.Bool
}
default:
_m.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the KeyBinding.
// This includes values selected through modifiers, order, etc.
func (_m *KeyBinding) Value(name string) (ent.Value, error) {
return _m.selectValues.Get(name)
}
// Update returns a builder for updating this KeyBinding.
// Note that you need to call KeyBinding.Unwrap() before calling this method if this KeyBinding
// was returned from a transaction, and the transaction was committed or rolled back.
func (_m *KeyBinding) Update() *KeyBindingUpdateOne {
return NewKeyBindingClient(_m.config).UpdateOne(_m)
}
// Unwrap unwraps the KeyBinding entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (_m *KeyBinding) Unwrap() *KeyBinding {
_tx, ok := _m.config.driver.(*txDriver)
if !ok {
panic("ent: KeyBinding is not a transactional entity")
}
_m.config.driver = _tx.drv
return _m
}
// String implements the fmt.Stringer.
func (_m *KeyBinding) String() string {
var builder strings.Builder
builder.WriteString("KeyBinding(")
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
builder.WriteString("created_at=")
builder.WriteString(_m.CreatedAt)
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(_m.UpdatedAt)
builder.WriteString(", ")
if v := _m.DeletedAt; v != nil {
builder.WriteString("deleted_at=")
builder.WriteString(*v)
}
builder.WriteString(", ")
builder.WriteString("key=")
builder.WriteString(_m.Key)
builder.WriteString(", ")
builder.WriteString("command=")
builder.WriteString(_m.Command)
builder.WriteString(", ")
builder.WriteString("extension=")
builder.WriteString(_m.Extension)
builder.WriteString(", ")
builder.WriteString("enabled=")
builder.WriteString(fmt.Sprintf("%v", _m.Enabled))
builder.WriteByte(')')
return builder.String()
}
// KeyBindings is a parsable slice of KeyBinding.
type KeyBindings []*KeyBinding

View File

@@ -0,0 +1,118 @@
// Code generated by ent, DO NOT EDIT.
package keybinding
import (
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
)
const (
// Label holds the string label denoting the keybinding type in the database.
Label = "key_binding"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
FieldDeletedAt = "deleted_at"
// FieldKey holds the string denoting the key field in the database.
FieldKey = "key"
// FieldCommand holds the string denoting the command field in the database.
FieldCommand = "command"
// FieldExtension holds the string denoting the extension field in the database.
FieldExtension = "extension"
// FieldEnabled holds the string denoting the enabled field in the database.
FieldEnabled = "enabled"
// Table holds the table name of the keybinding in the database.
Table = "key_bindings"
)
// Columns holds all SQL columns for keybinding fields.
var Columns = []string{
FieldID,
FieldCreatedAt,
FieldUpdatedAt,
FieldDeletedAt,
FieldKey,
FieldCommand,
FieldExtension,
FieldEnabled,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
// Note that the variables below are initialized by the runtime
// package on the initialization of the application. Therefore,
// it should be imported in the main as follows:
//
// import _ "voidraft/internal/models/ent/runtime"
var (
Hooks [2]ent.Hook
Interceptors [1]ent.Interceptor
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() string
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() string
// KeyValidator is a validator for the "key" field. It is called by the builders before save.
KeyValidator func(string) error
// CommandValidator is a validator for the "command" field. It is called by the builders before save.
CommandValidator func(string) error
// ExtensionValidator is a validator for the "extension" field. It is called by the builders before save.
ExtensionValidator func(string) error
// DefaultEnabled holds the default value on creation for the "enabled" field.
DefaultEnabled bool
)
// OrderOption defines the ordering options for the KeyBinding queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// ByDeletedAt orders the results by the deleted_at field.
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
}
// ByKey orders the results by the key field.
func ByKey(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldKey, opts...).ToFunc()
}
// ByCommand orders the results by the command field.
func ByCommand(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCommand, opts...).ToFunc()
}
// ByExtension orders the results by the extension field.
func ByExtension(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldExtension, opts...).ToFunc()
}
// ByEnabled orders the results by the enabled field.
func ByEnabled(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldEnabled, opts...).ToFunc()
}

View File

@@ -0,0 +1,524 @@
// Code generated by ent, DO NOT EDIT.
package keybinding
import (
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
)
// ID filters vertices based on their ID field.
func ID(id int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLTE(FieldID, id))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldCreatedAt, v))
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldUpdatedAt, v))
}
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
func DeletedAt(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldDeletedAt, v))
}
// Key applies equality check predicate on the "key" field. It's identical to KeyEQ.
func Key(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldKey, v))
}
// Command applies equality check predicate on the "command" field. It's identical to CommandEQ.
func Command(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldCommand, v))
}
// Extension applies equality check predicate on the "extension" field. It's identical to ExtensionEQ.
func Extension(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldExtension, v))
}
// Enabled applies equality check predicate on the "enabled" field. It's identical to EnabledEQ.
func Enabled(v bool) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldEnabled, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLTE(FieldCreatedAt, v))
}
// CreatedAtContains applies the Contains predicate on the "created_at" field.
func CreatedAtContains(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContains(FieldCreatedAt, v))
}
// CreatedAtHasPrefix applies the HasPrefix predicate on the "created_at" field.
func CreatedAtHasPrefix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasPrefix(FieldCreatedAt, v))
}
// CreatedAtHasSuffix applies the HasSuffix predicate on the "created_at" field.
func CreatedAtHasSuffix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasSuffix(FieldCreatedAt, v))
}
// CreatedAtEqualFold applies the EqualFold predicate on the "created_at" field.
func CreatedAtEqualFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEqualFold(FieldCreatedAt, v))
}
// CreatedAtContainsFold applies the ContainsFold predicate on the "created_at" field.
func CreatedAtContainsFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContainsFold(FieldCreatedAt, v))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldUpdatedAt, v))
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNEQ(FieldUpdatedAt, v))
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIn(FieldUpdatedAt, vs...))
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotIn(FieldUpdatedAt, vs...))
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGT(FieldUpdatedAt, v))
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGTE(FieldUpdatedAt, v))
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLT(FieldUpdatedAt, v))
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLTE(FieldUpdatedAt, v))
}
// UpdatedAtContains applies the Contains predicate on the "updated_at" field.
func UpdatedAtContains(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContains(FieldUpdatedAt, v))
}
// UpdatedAtHasPrefix applies the HasPrefix predicate on the "updated_at" field.
func UpdatedAtHasPrefix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasPrefix(FieldUpdatedAt, v))
}
// UpdatedAtHasSuffix applies the HasSuffix predicate on the "updated_at" field.
func UpdatedAtHasSuffix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasSuffix(FieldUpdatedAt, v))
}
// UpdatedAtEqualFold applies the EqualFold predicate on the "updated_at" field.
func UpdatedAtEqualFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEqualFold(FieldUpdatedAt, v))
}
// UpdatedAtContainsFold applies the ContainsFold predicate on the "updated_at" field.
func UpdatedAtContainsFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContainsFold(FieldUpdatedAt, v))
}
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
func DeletedAtEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldDeletedAt, v))
}
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
func DeletedAtNEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNEQ(FieldDeletedAt, v))
}
// DeletedAtIn applies the In predicate on the "deleted_at" field.
func DeletedAtIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIn(FieldDeletedAt, vs...))
}
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
func DeletedAtNotIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotIn(FieldDeletedAt, vs...))
}
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
func DeletedAtGT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGT(FieldDeletedAt, v))
}
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
func DeletedAtGTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGTE(FieldDeletedAt, v))
}
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
func DeletedAtLT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLT(FieldDeletedAt, v))
}
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
func DeletedAtLTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLTE(FieldDeletedAt, v))
}
// DeletedAtContains applies the Contains predicate on the "deleted_at" field.
func DeletedAtContains(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContains(FieldDeletedAt, v))
}
// DeletedAtHasPrefix applies the HasPrefix predicate on the "deleted_at" field.
func DeletedAtHasPrefix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasPrefix(FieldDeletedAt, v))
}
// DeletedAtHasSuffix applies the HasSuffix predicate on the "deleted_at" field.
func DeletedAtHasSuffix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasSuffix(FieldDeletedAt, v))
}
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
func DeletedAtIsNil() predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIsNull(FieldDeletedAt))
}
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
func DeletedAtNotNil() predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotNull(FieldDeletedAt))
}
// DeletedAtEqualFold applies the EqualFold predicate on the "deleted_at" field.
func DeletedAtEqualFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEqualFold(FieldDeletedAt, v))
}
// DeletedAtContainsFold applies the ContainsFold predicate on the "deleted_at" field.
func DeletedAtContainsFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContainsFold(FieldDeletedAt, v))
}
// KeyEQ applies the EQ predicate on the "key" field.
func KeyEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldKey, v))
}
// KeyNEQ applies the NEQ predicate on the "key" field.
func KeyNEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNEQ(FieldKey, v))
}
// KeyIn applies the In predicate on the "key" field.
func KeyIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIn(FieldKey, vs...))
}
// KeyNotIn applies the NotIn predicate on the "key" field.
func KeyNotIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotIn(FieldKey, vs...))
}
// KeyGT applies the GT predicate on the "key" field.
func KeyGT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGT(FieldKey, v))
}
// KeyGTE applies the GTE predicate on the "key" field.
func KeyGTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGTE(FieldKey, v))
}
// KeyLT applies the LT predicate on the "key" field.
func KeyLT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLT(FieldKey, v))
}
// KeyLTE applies the LTE predicate on the "key" field.
func KeyLTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLTE(FieldKey, v))
}
// KeyContains applies the Contains predicate on the "key" field.
func KeyContains(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContains(FieldKey, v))
}
// KeyHasPrefix applies the HasPrefix predicate on the "key" field.
func KeyHasPrefix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasPrefix(FieldKey, v))
}
// KeyHasSuffix applies the HasSuffix predicate on the "key" field.
func KeyHasSuffix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasSuffix(FieldKey, v))
}
// KeyEqualFold applies the EqualFold predicate on the "key" field.
func KeyEqualFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEqualFold(FieldKey, v))
}
// KeyContainsFold applies the ContainsFold predicate on the "key" field.
func KeyContainsFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContainsFold(FieldKey, v))
}
// CommandEQ applies the EQ predicate on the "command" field.
func CommandEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldCommand, v))
}
// CommandNEQ applies the NEQ predicate on the "command" field.
func CommandNEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNEQ(FieldCommand, v))
}
// CommandIn applies the In predicate on the "command" field.
func CommandIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIn(FieldCommand, vs...))
}
// CommandNotIn applies the NotIn predicate on the "command" field.
func CommandNotIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotIn(FieldCommand, vs...))
}
// CommandGT applies the GT predicate on the "command" field.
func CommandGT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGT(FieldCommand, v))
}
// CommandGTE applies the GTE predicate on the "command" field.
func CommandGTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGTE(FieldCommand, v))
}
// CommandLT applies the LT predicate on the "command" field.
func CommandLT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLT(FieldCommand, v))
}
// CommandLTE applies the LTE predicate on the "command" field.
func CommandLTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLTE(FieldCommand, v))
}
// CommandContains applies the Contains predicate on the "command" field.
func CommandContains(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContains(FieldCommand, v))
}
// CommandHasPrefix applies the HasPrefix predicate on the "command" field.
func CommandHasPrefix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasPrefix(FieldCommand, v))
}
// CommandHasSuffix applies the HasSuffix predicate on the "command" field.
func CommandHasSuffix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasSuffix(FieldCommand, v))
}
// CommandEqualFold applies the EqualFold predicate on the "command" field.
func CommandEqualFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEqualFold(FieldCommand, v))
}
// CommandContainsFold applies the ContainsFold predicate on the "command" field.
func CommandContainsFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContainsFold(FieldCommand, v))
}
// ExtensionEQ applies the EQ predicate on the "extension" field.
func ExtensionEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldExtension, v))
}
// ExtensionNEQ applies the NEQ predicate on the "extension" field.
func ExtensionNEQ(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNEQ(FieldExtension, v))
}
// ExtensionIn applies the In predicate on the "extension" field.
func ExtensionIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIn(FieldExtension, vs...))
}
// ExtensionNotIn applies the NotIn predicate on the "extension" field.
func ExtensionNotIn(vs ...string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotIn(FieldExtension, vs...))
}
// ExtensionGT applies the GT predicate on the "extension" field.
func ExtensionGT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGT(FieldExtension, v))
}
// ExtensionGTE applies the GTE predicate on the "extension" field.
func ExtensionGTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldGTE(FieldExtension, v))
}
// ExtensionLT applies the LT predicate on the "extension" field.
func ExtensionLT(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLT(FieldExtension, v))
}
// ExtensionLTE applies the LTE predicate on the "extension" field.
func ExtensionLTE(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldLTE(FieldExtension, v))
}
// ExtensionContains applies the Contains predicate on the "extension" field.
func ExtensionContains(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContains(FieldExtension, v))
}
// ExtensionHasPrefix applies the HasPrefix predicate on the "extension" field.
func ExtensionHasPrefix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasPrefix(FieldExtension, v))
}
// ExtensionHasSuffix applies the HasSuffix predicate on the "extension" field.
func ExtensionHasSuffix(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldHasSuffix(FieldExtension, v))
}
// ExtensionIsNil applies the IsNil predicate on the "extension" field.
func ExtensionIsNil() predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldIsNull(FieldExtension))
}
// ExtensionNotNil applies the NotNil predicate on the "extension" field.
func ExtensionNotNil() predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNotNull(FieldExtension))
}
// ExtensionEqualFold applies the EqualFold predicate on the "extension" field.
func ExtensionEqualFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEqualFold(FieldExtension, v))
}
// ExtensionContainsFold applies the ContainsFold predicate on the "extension" field.
func ExtensionContainsFold(v string) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldContainsFold(FieldExtension, v))
}
// EnabledEQ applies the EQ predicate on the "enabled" field.
func EnabledEQ(v bool) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldEQ(FieldEnabled, v))
}
// EnabledNEQ applies the NEQ predicate on the "enabled" field.
func EnabledNEQ(v bool) predicate.KeyBinding {
return predicate.KeyBinding(sql.FieldNEQ(FieldEnabled, v))
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.KeyBinding) predicate.KeyBinding {
return predicate.KeyBinding(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.KeyBinding) predicate.KeyBinding {
return predicate.KeyBinding(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.KeyBinding) predicate.KeyBinding {
return predicate.KeyBinding(sql.NotPredicates(p))
}

View File

@@ -0,0 +1,337 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"voidraft/internal/models/ent/keybinding"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// KeyBindingCreate is the builder for creating a KeyBinding entity.
type KeyBindingCreate struct {
config
mutation *KeyBindingMutation
hooks []Hook
}
// SetCreatedAt sets the "created_at" field.
func (_c *KeyBindingCreate) SetCreatedAt(v string) *KeyBindingCreate {
_c.mutation.SetCreatedAt(v)
return _c
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (_c *KeyBindingCreate) SetNillableCreatedAt(v *string) *KeyBindingCreate {
if v != nil {
_c.SetCreatedAt(*v)
}
return _c
}
// SetUpdatedAt sets the "updated_at" field.
func (_c *KeyBindingCreate) SetUpdatedAt(v string) *KeyBindingCreate {
_c.mutation.SetUpdatedAt(v)
return _c
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_c *KeyBindingCreate) SetNillableUpdatedAt(v *string) *KeyBindingCreate {
if v != nil {
_c.SetUpdatedAt(*v)
}
return _c
}
// SetDeletedAt sets the "deleted_at" field.
func (_c *KeyBindingCreate) SetDeletedAt(v string) *KeyBindingCreate {
_c.mutation.SetDeletedAt(v)
return _c
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_c *KeyBindingCreate) SetNillableDeletedAt(v *string) *KeyBindingCreate {
if v != nil {
_c.SetDeletedAt(*v)
}
return _c
}
// SetKey sets the "key" field.
func (_c *KeyBindingCreate) SetKey(v string) *KeyBindingCreate {
_c.mutation.SetKey(v)
return _c
}
// SetCommand sets the "command" field.
func (_c *KeyBindingCreate) SetCommand(v string) *KeyBindingCreate {
_c.mutation.SetCommand(v)
return _c
}
// SetExtension sets the "extension" field.
func (_c *KeyBindingCreate) SetExtension(v string) *KeyBindingCreate {
_c.mutation.SetExtension(v)
return _c
}
// SetNillableExtension sets the "extension" field if the given value is not nil.
func (_c *KeyBindingCreate) SetNillableExtension(v *string) *KeyBindingCreate {
if v != nil {
_c.SetExtension(*v)
}
return _c
}
// SetEnabled sets the "enabled" field.
func (_c *KeyBindingCreate) SetEnabled(v bool) *KeyBindingCreate {
_c.mutation.SetEnabled(v)
return _c
}
// SetNillableEnabled sets the "enabled" field if the given value is not nil.
func (_c *KeyBindingCreate) SetNillableEnabled(v *bool) *KeyBindingCreate {
if v != nil {
_c.SetEnabled(*v)
}
return _c
}
// Mutation returns the KeyBindingMutation object of the builder.
func (_c *KeyBindingCreate) Mutation() *KeyBindingMutation {
return _c.mutation
}
// Save creates the KeyBinding in the database.
func (_c *KeyBindingCreate) Save(ctx context.Context) (*KeyBinding, error) {
if err := _c.defaults(); err != nil {
return nil, err
}
return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks)
}
// SaveX calls Save and panics if Save returns an error.
func (_c *KeyBindingCreate) SaveX(ctx context.Context) *KeyBinding {
v, err := _c.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (_c *KeyBindingCreate) Exec(ctx context.Context) error {
_, err := _c.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_c *KeyBindingCreate) ExecX(ctx context.Context) {
if err := _c.Exec(ctx); err != nil {
panic(err)
}
}
// defaults sets the default values of the builder before save.
func (_c *KeyBindingCreate) defaults() error {
if _, ok := _c.mutation.CreatedAt(); !ok {
if keybinding.DefaultCreatedAt == nil {
return fmt.Errorf("ent: uninitialized keybinding.DefaultCreatedAt (forgotten import ent/runtime?)")
}
v := keybinding.DefaultCreatedAt()
_c.mutation.SetCreatedAt(v)
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
if keybinding.DefaultUpdatedAt == nil {
return fmt.Errorf("ent: uninitialized keybinding.DefaultUpdatedAt (forgotten import ent/runtime?)")
}
v := keybinding.DefaultUpdatedAt()
_c.mutation.SetUpdatedAt(v)
}
if _, ok := _c.mutation.Enabled(); !ok {
v := keybinding.DefaultEnabled
_c.mutation.SetEnabled(v)
}
return nil
}
// check runs all checks and user-defined validators on the builder.
func (_c *KeyBindingCreate) check() error {
if _, ok := _c.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "KeyBinding.created_at"`)}
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "KeyBinding.updated_at"`)}
}
if _, ok := _c.mutation.Key(); !ok {
return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "KeyBinding.key"`)}
}
if v, ok := _c.mutation.Key(); ok {
if err := keybinding.KeyValidator(v); err != nil {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.key": %w`, err)}
}
}
if _, ok := _c.mutation.Command(); !ok {
return &ValidationError{Name: "command", err: errors.New(`ent: missing required field "KeyBinding.command"`)}
}
if v, ok := _c.mutation.Command(); ok {
if err := keybinding.CommandValidator(v); err != nil {
return &ValidationError{Name: "command", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.command": %w`, err)}
}
}
if v, ok := _c.mutation.Extension(); ok {
if err := keybinding.ExtensionValidator(v); err != nil {
return &ValidationError{Name: "extension", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.extension": %w`, err)}
}
}
if _, ok := _c.mutation.Enabled(); !ok {
return &ValidationError{Name: "enabled", err: errors.New(`ent: missing required field "KeyBinding.enabled"`)}
}
return nil
}
func (_c *KeyBindingCreate) sqlSave(ctx context.Context) (*KeyBinding, error) {
if err := _c.check(); err != nil {
return nil, err
}
_node, _spec := _c.createSpec()
if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
id := _spec.ID.Value.(int64)
_node.ID = int(id)
_c.mutation.id = &_node.ID
_c.mutation.done = true
return _node, nil
}
func (_c *KeyBindingCreate) createSpec() (*KeyBinding, *sqlgraph.CreateSpec) {
var (
_node = &KeyBinding{config: _c.config}
_spec = sqlgraph.NewCreateSpec(keybinding.Table, sqlgraph.NewFieldSpec(keybinding.FieldID, field.TypeInt))
)
if value, ok := _c.mutation.CreatedAt(); ok {
_spec.SetField(keybinding.FieldCreatedAt, field.TypeString, value)
_node.CreatedAt = value
}
if value, ok := _c.mutation.UpdatedAt(); ok {
_spec.SetField(keybinding.FieldUpdatedAt, field.TypeString, value)
_node.UpdatedAt = value
}
if value, ok := _c.mutation.DeletedAt(); ok {
_spec.SetField(keybinding.FieldDeletedAt, field.TypeString, value)
_node.DeletedAt = &value
}
if value, ok := _c.mutation.Key(); ok {
_spec.SetField(keybinding.FieldKey, field.TypeString, value)
_node.Key = value
}
if value, ok := _c.mutation.Command(); ok {
_spec.SetField(keybinding.FieldCommand, field.TypeString, value)
_node.Command = value
}
if value, ok := _c.mutation.Extension(); ok {
_spec.SetField(keybinding.FieldExtension, field.TypeString, value)
_node.Extension = value
}
if value, ok := _c.mutation.Enabled(); ok {
_spec.SetField(keybinding.FieldEnabled, field.TypeBool, value)
_node.Enabled = value
}
return _node, _spec
}
// KeyBindingCreateBulk is the builder for creating many KeyBinding entities in bulk.
type KeyBindingCreateBulk struct {
config
err error
builders []*KeyBindingCreate
}
// Save creates the KeyBinding entities in the database.
func (_c *KeyBindingCreateBulk) Save(ctx context.Context) ([]*KeyBinding, error) {
if _c.err != nil {
return nil, _c.err
}
specs := make([]*sqlgraph.CreateSpec, len(_c.builders))
nodes := make([]*KeyBinding, len(_c.builders))
mutators := make([]Mutator, len(_c.builders))
for i := range _c.builders {
func(i int, root context.Context) {
builder := _c.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*KeyBindingMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
var err error
nodes[i], specs[i] = builder.createSpec()
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation)
} else {
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
}
}
if err != nil {
return nil, err
}
mutation.id = &nodes[i].ID
if specs[i].ID.Value != nil {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int(id)
}
mutation.done = true
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (_c *KeyBindingCreateBulk) SaveX(ctx context.Context) []*KeyBinding {
v, err := _c.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (_c *KeyBindingCreateBulk) Exec(ctx context.Context) error {
_, err := _c.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_c *KeyBindingCreateBulk) ExecX(ctx context.Context) {
if err := _c.Exec(ctx); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,88 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"voidraft/internal/models/ent/keybinding"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// KeyBindingDelete is the builder for deleting a KeyBinding entity.
type KeyBindingDelete struct {
config
hooks []Hook
mutation *KeyBindingMutation
}
// Where appends a list predicates to the KeyBindingDelete builder.
func (_d *KeyBindingDelete) Where(ps ...predicate.KeyBinding) *KeyBindingDelete {
_d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (_d *KeyBindingDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *KeyBindingDelete) ExecX(ctx context.Context) int {
n, err := _d.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (_d *KeyBindingDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(keybinding.Table, sqlgraph.NewFieldSpec(keybinding.FieldID, field.TypeInt))
if ps := _d.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
_d.mutation.done = true
return affected, err
}
// KeyBindingDeleteOne is the builder for deleting a single KeyBinding entity.
type KeyBindingDeleteOne struct {
_d *KeyBindingDelete
}
// Where appends a list predicates to the KeyBindingDelete builder.
func (_d *KeyBindingDeleteOne) Where(ps ...predicate.KeyBinding) *KeyBindingDeleteOne {
_d._d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query.
func (_d *KeyBindingDeleteOne) Exec(ctx context.Context) error {
n, err := _d._d.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{keybinding.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *KeyBindingDeleteOne) ExecX(ctx context.Context) {
if err := _d.Exec(ctx); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,577 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"math"
"voidraft/internal/models/ent/keybinding"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// KeyBindingQuery is the builder for querying KeyBinding entities.
type KeyBindingQuery struct {
config
ctx *QueryContext
order []keybinding.OrderOption
inters []Interceptor
predicates []predicate.KeyBinding
modifiers []func(*sql.Selector)
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the KeyBindingQuery builder.
func (_q *KeyBindingQuery) Where(ps ...predicate.KeyBinding) *KeyBindingQuery {
_q.predicates = append(_q.predicates, ps...)
return _q
}
// Limit the number of records to be returned by this query.
func (_q *KeyBindingQuery) Limit(limit int) *KeyBindingQuery {
_q.ctx.Limit = &limit
return _q
}
// Offset to start from.
func (_q *KeyBindingQuery) Offset(offset int) *KeyBindingQuery {
_q.ctx.Offset = &offset
return _q
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func (_q *KeyBindingQuery) Unique(unique bool) *KeyBindingQuery {
_q.ctx.Unique = &unique
return _q
}
// Order specifies how the records should be ordered.
func (_q *KeyBindingQuery) Order(o ...keybinding.OrderOption) *KeyBindingQuery {
_q.order = append(_q.order, o...)
return _q
}
// First returns the first KeyBinding entity from the query.
// Returns a *NotFoundError when no KeyBinding was found.
func (_q *KeyBindingQuery) First(ctx context.Context) (*KeyBinding, error) {
nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{keybinding.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (_q *KeyBindingQuery) FirstX(ctx context.Context) *KeyBinding {
node, err := _q.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first KeyBinding ID from the query.
// Returns a *NotFoundError when no KeyBinding ID was found.
func (_q *KeyBindingQuery) FirstID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{keybinding.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (_q *KeyBindingQuery) FirstIDX(ctx context.Context) int {
id, err := _q.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single KeyBinding entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one KeyBinding entity is found.
// Returns a *NotFoundError when no KeyBinding entities are found.
func (_q *KeyBindingQuery) Only(ctx context.Context) (*KeyBinding, error) {
nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{keybinding.Label}
default:
return nil, &NotSingularError{keybinding.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (_q *KeyBindingQuery) OnlyX(ctx context.Context) *KeyBinding {
node, err := _q.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only KeyBinding ID in the query.
// Returns a *NotSingularError when more than one KeyBinding ID is found.
// Returns a *NotFoundError when no entities are found.
func (_q *KeyBindingQuery) OnlyID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{keybinding.Label}
default:
err = &NotSingularError{keybinding.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (_q *KeyBindingQuery) OnlyIDX(ctx context.Context) int {
id, err := _q.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of KeyBindings.
func (_q *KeyBindingQuery) All(ctx context.Context) ([]*KeyBinding, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll)
if err := _q.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*KeyBinding, *KeyBindingQuery]()
return withInterceptors[[]*KeyBinding](ctx, _q, qr, _q.inters)
}
// AllX is like All, but panics if an error occurs.
func (_q *KeyBindingQuery) AllX(ctx context.Context) []*KeyBinding {
nodes, err := _q.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of KeyBinding IDs.
func (_q *KeyBindingQuery) IDs(ctx context.Context) (ids []int, err error) {
if _q.ctx.Unique == nil && _q.path != nil {
_q.Unique(true)
}
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs)
if err = _q.Select(keybinding.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (_q *KeyBindingQuery) IDsX(ctx context.Context) []int {
ids, err := _q.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (_q *KeyBindingQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount)
if err := _q.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, _q, querierCount[*KeyBindingQuery](), _q.inters)
}
// CountX is like Count, but panics if an error occurs.
func (_q *KeyBindingQuery) CountX(ctx context.Context) int {
count, err := _q.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (_q *KeyBindingQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist)
switch _, err := _q.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (_q *KeyBindingQuery) ExistX(ctx context.Context) bool {
exist, err := _q.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the KeyBindingQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (_q *KeyBindingQuery) Clone() *KeyBindingQuery {
if _q == nil {
return nil
}
return &KeyBindingQuery{
config: _q.config,
ctx: _q.ctx.Clone(),
order: append([]keybinding.OrderOption{}, _q.order...),
inters: append([]Interceptor{}, _q.inters...),
predicates: append([]predicate.KeyBinding{}, _q.predicates...),
// clone intermediate query.
sql: _q.sql.Clone(),
path: _q.path,
modifiers: append([]func(*sql.Selector){}, _q.modifiers...),
}
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// CreatedAt string `json:"created_at"`
// Count int `json:"count,omitempty"`
// }
//
// client.KeyBinding.Query().
// GroupBy(keybinding.FieldCreatedAt).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func (_q *KeyBindingQuery) GroupBy(field string, fields ...string) *KeyBindingGroupBy {
_q.ctx.Fields = append([]string{field}, fields...)
grbuild := &KeyBindingGroupBy{build: _q}
grbuild.flds = &_q.ctx.Fields
grbuild.label = keybinding.Label
grbuild.scan = grbuild.Scan
return grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// CreatedAt string `json:"created_at"`
// }
//
// client.KeyBinding.Query().
// Select(keybinding.FieldCreatedAt).
// Scan(ctx, &v)
func (_q *KeyBindingQuery) Select(fields ...string) *KeyBindingSelect {
_q.ctx.Fields = append(_q.ctx.Fields, fields...)
sbuild := &KeyBindingSelect{KeyBindingQuery: _q}
sbuild.label = keybinding.Label
sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a KeyBindingSelect configured with the given aggregations.
func (_q *KeyBindingQuery) Aggregate(fns ...AggregateFunc) *KeyBindingSelect {
return _q.Select().Aggregate(fns...)
}
func (_q *KeyBindingQuery) prepareQuery(ctx context.Context) error {
for _, inter := range _q.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, _q); err != nil {
return err
}
}
}
for _, f := range _q.ctx.Fields {
if !keybinding.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if _q.path != nil {
prev, err := _q.path(ctx)
if err != nil {
return err
}
_q.sql = prev
}
return nil
}
func (_q *KeyBindingQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*KeyBinding, error) {
var (
nodes = []*KeyBinding{}
_spec = _q.querySpec()
)
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*KeyBinding).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &KeyBinding{config: _q.config}
nodes = append(nodes, node)
return node.assignValues(columns, values)
}
if len(_q.modifiers) > 0 {
_spec.Modifiers = _q.modifiers
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
return nodes, nil
}
func (_q *KeyBindingQuery) sqlCount(ctx context.Context) (int, error) {
_spec := _q.querySpec()
if len(_q.modifiers) > 0 {
_spec.Modifiers = _q.modifiers
}
_spec.Node.Columns = _q.ctx.Fields
if len(_q.ctx.Fields) > 0 {
_spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique
}
return sqlgraph.CountNodes(ctx, _q.driver, _spec)
}
func (_q *KeyBindingQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(keybinding.Table, keybinding.Columns, sqlgraph.NewFieldSpec(keybinding.FieldID, field.TypeInt))
_spec.From = _q.sql
if unique := _q.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if _q.path != nil {
_spec.Unique = true
}
if fields := _q.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, keybinding.FieldID)
for i := range fields {
if fields[i] != keybinding.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := _q.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := _q.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := _q.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := _q.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (_q *KeyBindingQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(_q.driver.Dialect())
t1 := builder.Table(keybinding.Table)
columns := _q.ctx.Fields
if len(columns) == 0 {
columns = keybinding.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if _q.sql != nil {
selector = _q.sql
selector.Select(selector.Columns(columns...)...)
}
if _q.ctx.Unique != nil && *_q.ctx.Unique {
selector.Distinct()
}
for _, m := range _q.modifiers {
m(selector)
}
for _, p := range _q.predicates {
p(selector)
}
for _, p := range _q.order {
p(selector)
}
if offset := _q.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := _q.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
// either committed or rolled-back.
func (_q *KeyBindingQuery) ForUpdate(opts ...sql.LockOption) *KeyBindingQuery {
if _q.driver.Dialect() == dialect.Postgres {
_q.Unique(false)
}
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
s.ForUpdate(opts...)
})
return _q
}
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
// on any rows that are read. Other sessions can read the rows, but cannot modify them
// until your transaction commits.
func (_q *KeyBindingQuery) ForShare(opts ...sql.LockOption) *KeyBindingQuery {
if _q.driver.Dialect() == dialect.Postgres {
_q.Unique(false)
}
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
s.ForShare(opts...)
})
return _q
}
// Modify adds a query modifier for attaching custom logic to queries.
func (_q *KeyBindingQuery) Modify(modifiers ...func(s *sql.Selector)) *KeyBindingSelect {
_q.modifiers = append(_q.modifiers, modifiers...)
return _q.Select()
}
// KeyBindingGroupBy is the group-by builder for KeyBinding entities.
type KeyBindingGroupBy struct {
selector
build *KeyBindingQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (_g *KeyBindingGroupBy) Aggregate(fns ...AggregateFunc) *KeyBindingGroupBy {
_g.fns = append(_g.fns, fns...)
return _g
}
// Scan applies the selector query and scans the result into the given value.
func (_g *KeyBindingGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy)
if err := _g.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*KeyBindingQuery, *KeyBindingGroupBy](ctx, _g.build, _g, _g.build.inters, v)
}
func (_g *KeyBindingGroupBy) sqlScan(ctx context.Context, root *KeyBindingQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(_g.fns))
for _, fn := range _g.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*_g.flds)+len(_g.fns))
for _, f := range *_g.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*_g.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := _g.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// KeyBindingSelect is the builder for selecting fields of KeyBinding entities.
type KeyBindingSelect struct {
*KeyBindingQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (_s *KeyBindingSelect) Aggregate(fns ...AggregateFunc) *KeyBindingSelect {
_s.fns = append(_s.fns, fns...)
return _s
}
// Scan applies the selector query and scans the result into the given value.
func (_s *KeyBindingSelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect)
if err := _s.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*KeyBindingQuery, *KeyBindingSelect](ctx, _s.KeyBindingQuery, _s, _s.inters, v)
}
func (_s *KeyBindingSelect) sqlScan(ctx context.Context, root *KeyBindingQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(_s.fns))
for _, fn := range _s.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*_s.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := _s.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// Modify adds a query modifier for attaching custom logic to queries.
func (_s *KeyBindingSelect) Modify(modifiers ...func(s *sql.Selector)) *KeyBindingSelect {
_s.modifiers = append(_s.modifiers, modifiers...)
return _s
}

View File

@@ -0,0 +1,477 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"voidraft/internal/models/ent/keybinding"
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// KeyBindingUpdate is the builder for updating KeyBinding entities.
type KeyBindingUpdate struct {
config
hooks []Hook
mutation *KeyBindingMutation
modifiers []func(*sql.UpdateBuilder)
}
// Where appends a list predicates to the KeyBindingUpdate builder.
func (_u *KeyBindingUpdate) Where(ps ...predicate.KeyBinding) *KeyBindingUpdate {
_u.mutation.Where(ps...)
return _u
}
// SetUpdatedAt sets the "updated_at" field.
func (_u *KeyBindingUpdate) SetUpdatedAt(v string) *KeyBindingUpdate {
_u.mutation.SetUpdatedAt(v)
return _u
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_u *KeyBindingUpdate) SetNillableUpdatedAt(v *string) *KeyBindingUpdate {
if v != nil {
_u.SetUpdatedAt(*v)
}
return _u
}
// SetDeletedAt sets the "deleted_at" field.
func (_u *KeyBindingUpdate) SetDeletedAt(v string) *KeyBindingUpdate {
_u.mutation.SetDeletedAt(v)
return _u
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_u *KeyBindingUpdate) SetNillableDeletedAt(v *string) *KeyBindingUpdate {
if v != nil {
_u.SetDeletedAt(*v)
}
return _u
}
// ClearDeletedAt clears the value of the "deleted_at" field.
func (_u *KeyBindingUpdate) ClearDeletedAt() *KeyBindingUpdate {
_u.mutation.ClearDeletedAt()
return _u
}
// SetKey sets the "key" field.
func (_u *KeyBindingUpdate) SetKey(v string) *KeyBindingUpdate {
_u.mutation.SetKey(v)
return _u
}
// SetNillableKey sets the "key" field if the given value is not nil.
func (_u *KeyBindingUpdate) SetNillableKey(v *string) *KeyBindingUpdate {
if v != nil {
_u.SetKey(*v)
}
return _u
}
// SetCommand sets the "command" field.
func (_u *KeyBindingUpdate) SetCommand(v string) *KeyBindingUpdate {
_u.mutation.SetCommand(v)
return _u
}
// SetNillableCommand sets the "command" field if the given value is not nil.
func (_u *KeyBindingUpdate) SetNillableCommand(v *string) *KeyBindingUpdate {
if v != nil {
_u.SetCommand(*v)
}
return _u
}
// SetExtension sets the "extension" field.
func (_u *KeyBindingUpdate) SetExtension(v string) *KeyBindingUpdate {
_u.mutation.SetExtension(v)
return _u
}
// SetNillableExtension sets the "extension" field if the given value is not nil.
func (_u *KeyBindingUpdate) SetNillableExtension(v *string) *KeyBindingUpdate {
if v != nil {
_u.SetExtension(*v)
}
return _u
}
// ClearExtension clears the value of the "extension" field.
func (_u *KeyBindingUpdate) ClearExtension() *KeyBindingUpdate {
_u.mutation.ClearExtension()
return _u
}
// SetEnabled sets the "enabled" field.
func (_u *KeyBindingUpdate) SetEnabled(v bool) *KeyBindingUpdate {
_u.mutation.SetEnabled(v)
return _u
}
// SetNillableEnabled sets the "enabled" field if the given value is not nil.
func (_u *KeyBindingUpdate) SetNillableEnabled(v *bool) *KeyBindingUpdate {
if v != nil {
_u.SetEnabled(*v)
}
return _u
}
// Mutation returns the KeyBindingMutation object of the builder.
func (_u *KeyBindingUpdate) Mutation() *KeyBindingMutation {
return _u.mutation
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (_u *KeyBindingUpdate) Save(ctx context.Context) (int, error) {
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (_u *KeyBindingUpdate) SaveX(ctx context.Context) int {
affected, err := _u.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (_u *KeyBindingUpdate) Exec(ctx context.Context) error {
_, err := _u.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_u *KeyBindingUpdate) ExecX(ctx context.Context) {
if err := _u.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (_u *KeyBindingUpdate) check() error {
if v, ok := _u.mutation.Key(); ok {
if err := keybinding.KeyValidator(v); err != nil {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.key": %w`, err)}
}
}
if v, ok := _u.mutation.Command(); ok {
if err := keybinding.CommandValidator(v); err != nil {
return &ValidationError{Name: "command", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.command": %w`, err)}
}
}
if v, ok := _u.mutation.Extension(); ok {
if err := keybinding.ExtensionValidator(v); err != nil {
return &ValidationError{Name: "extension", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.extension": %w`, err)}
}
}
return nil
}
// Modify adds a statement modifier for attaching custom logic to the UPDATE statement.
func (_u *KeyBindingUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *KeyBindingUpdate {
_u.modifiers = append(_u.modifiers, modifiers...)
return _u
}
func (_u *KeyBindingUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if err := _u.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(keybinding.Table, keybinding.Columns, sqlgraph.NewFieldSpec(keybinding.FieldID, field.TypeInt))
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := _u.mutation.UpdatedAt(); ok {
_spec.SetField(keybinding.FieldUpdatedAt, field.TypeString, value)
}
if value, ok := _u.mutation.DeletedAt(); ok {
_spec.SetField(keybinding.FieldDeletedAt, field.TypeString, value)
}
if _u.mutation.DeletedAtCleared() {
_spec.ClearField(keybinding.FieldDeletedAt, field.TypeString)
}
if value, ok := _u.mutation.Key(); ok {
_spec.SetField(keybinding.FieldKey, field.TypeString, value)
}
if value, ok := _u.mutation.Command(); ok {
_spec.SetField(keybinding.FieldCommand, field.TypeString, value)
}
if value, ok := _u.mutation.Extension(); ok {
_spec.SetField(keybinding.FieldExtension, field.TypeString, value)
}
if _u.mutation.ExtensionCleared() {
_spec.ClearField(keybinding.FieldExtension, field.TypeString)
}
if value, ok := _u.mutation.Enabled(); ok {
_spec.SetField(keybinding.FieldEnabled, field.TypeBool, value)
}
_spec.AddModifiers(_u.modifiers...)
if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{keybinding.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return 0, err
}
_u.mutation.done = true
return _node, nil
}
// KeyBindingUpdateOne is the builder for updating a single KeyBinding entity.
type KeyBindingUpdateOne struct {
config
fields []string
hooks []Hook
mutation *KeyBindingMutation
modifiers []func(*sql.UpdateBuilder)
}
// SetUpdatedAt sets the "updated_at" field.
func (_u *KeyBindingUpdateOne) SetUpdatedAt(v string) *KeyBindingUpdateOne {
_u.mutation.SetUpdatedAt(v)
return _u
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_u *KeyBindingUpdateOne) SetNillableUpdatedAt(v *string) *KeyBindingUpdateOne {
if v != nil {
_u.SetUpdatedAt(*v)
}
return _u
}
// SetDeletedAt sets the "deleted_at" field.
func (_u *KeyBindingUpdateOne) SetDeletedAt(v string) *KeyBindingUpdateOne {
_u.mutation.SetDeletedAt(v)
return _u
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_u *KeyBindingUpdateOne) SetNillableDeletedAt(v *string) *KeyBindingUpdateOne {
if v != nil {
_u.SetDeletedAt(*v)
}
return _u
}
// ClearDeletedAt clears the value of the "deleted_at" field.
func (_u *KeyBindingUpdateOne) ClearDeletedAt() *KeyBindingUpdateOne {
_u.mutation.ClearDeletedAt()
return _u
}
// SetKey sets the "key" field.
func (_u *KeyBindingUpdateOne) SetKey(v string) *KeyBindingUpdateOne {
_u.mutation.SetKey(v)
return _u
}
// SetNillableKey sets the "key" field if the given value is not nil.
func (_u *KeyBindingUpdateOne) SetNillableKey(v *string) *KeyBindingUpdateOne {
if v != nil {
_u.SetKey(*v)
}
return _u
}
// SetCommand sets the "command" field.
func (_u *KeyBindingUpdateOne) SetCommand(v string) *KeyBindingUpdateOne {
_u.mutation.SetCommand(v)
return _u
}
// SetNillableCommand sets the "command" field if the given value is not nil.
func (_u *KeyBindingUpdateOne) SetNillableCommand(v *string) *KeyBindingUpdateOne {
if v != nil {
_u.SetCommand(*v)
}
return _u
}
// SetExtension sets the "extension" field.
func (_u *KeyBindingUpdateOne) SetExtension(v string) *KeyBindingUpdateOne {
_u.mutation.SetExtension(v)
return _u
}
// SetNillableExtension sets the "extension" field if the given value is not nil.
func (_u *KeyBindingUpdateOne) SetNillableExtension(v *string) *KeyBindingUpdateOne {
if v != nil {
_u.SetExtension(*v)
}
return _u
}
// ClearExtension clears the value of the "extension" field.
func (_u *KeyBindingUpdateOne) ClearExtension() *KeyBindingUpdateOne {
_u.mutation.ClearExtension()
return _u
}
// SetEnabled sets the "enabled" field.
func (_u *KeyBindingUpdateOne) SetEnabled(v bool) *KeyBindingUpdateOne {
_u.mutation.SetEnabled(v)
return _u
}
// SetNillableEnabled sets the "enabled" field if the given value is not nil.
func (_u *KeyBindingUpdateOne) SetNillableEnabled(v *bool) *KeyBindingUpdateOne {
if v != nil {
_u.SetEnabled(*v)
}
return _u
}
// Mutation returns the KeyBindingMutation object of the builder.
func (_u *KeyBindingUpdateOne) Mutation() *KeyBindingMutation {
return _u.mutation
}
// Where appends a list predicates to the KeyBindingUpdate builder.
func (_u *KeyBindingUpdateOne) Where(ps ...predicate.KeyBinding) *KeyBindingUpdateOne {
_u.mutation.Where(ps...)
return _u
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func (_u *KeyBindingUpdateOne) Select(field string, fields ...string) *KeyBindingUpdateOne {
_u.fields = append([]string{field}, fields...)
return _u
}
// Save executes the query and returns the updated KeyBinding entity.
func (_u *KeyBindingUpdateOne) Save(ctx context.Context) (*KeyBinding, error) {
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (_u *KeyBindingUpdateOne) SaveX(ctx context.Context) *KeyBinding {
node, err := _u.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (_u *KeyBindingUpdateOne) Exec(ctx context.Context) error {
_, err := _u.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_u *KeyBindingUpdateOne) ExecX(ctx context.Context) {
if err := _u.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (_u *KeyBindingUpdateOne) check() error {
if v, ok := _u.mutation.Key(); ok {
if err := keybinding.KeyValidator(v); err != nil {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.key": %w`, err)}
}
}
if v, ok := _u.mutation.Command(); ok {
if err := keybinding.CommandValidator(v); err != nil {
return &ValidationError{Name: "command", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.command": %w`, err)}
}
}
if v, ok := _u.mutation.Extension(); ok {
if err := keybinding.ExtensionValidator(v); err != nil {
return &ValidationError{Name: "extension", err: fmt.Errorf(`ent: validator failed for field "KeyBinding.extension": %w`, err)}
}
}
return nil
}
// Modify adds a statement modifier for attaching custom logic to the UPDATE statement.
func (_u *KeyBindingUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *KeyBindingUpdateOne {
_u.modifiers = append(_u.modifiers, modifiers...)
return _u
}
func (_u *KeyBindingUpdateOne) sqlSave(ctx context.Context) (_node *KeyBinding, err error) {
if err := _u.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(keybinding.Table, keybinding.Columns, sqlgraph.NewFieldSpec(keybinding.FieldID, field.TypeInt))
id, ok := _u.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "KeyBinding.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := _u.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, keybinding.FieldID)
for _, f := range fields {
if !keybinding.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
if f != keybinding.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := _u.mutation.UpdatedAt(); ok {
_spec.SetField(keybinding.FieldUpdatedAt, field.TypeString, value)
}
if value, ok := _u.mutation.DeletedAt(); ok {
_spec.SetField(keybinding.FieldDeletedAt, field.TypeString, value)
}
if _u.mutation.DeletedAtCleared() {
_spec.ClearField(keybinding.FieldDeletedAt, field.TypeString)
}
if value, ok := _u.mutation.Key(); ok {
_spec.SetField(keybinding.FieldKey, field.TypeString, value)
}
if value, ok := _u.mutation.Command(); ok {
_spec.SetField(keybinding.FieldCommand, field.TypeString, value)
}
if value, ok := _u.mutation.Extension(); ok {
_spec.SetField(keybinding.FieldExtension, field.TypeString, value)
}
if _u.mutation.ExtensionCleared() {
_spec.ClearField(keybinding.FieldExtension, field.TypeString)
}
if value, ok := _u.mutation.Enabled(); ok {
_spec.SetField(keybinding.FieldEnabled, field.TypeBool, value)
}
_spec.AddModifiers(_u.modifiers...)
_node = &KeyBinding{config: _u.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{keybinding.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
_u.mutation.done = true
return _node, nil
}

View File

@@ -0,0 +1,64 @@
// Code generated by ent, DO NOT EDIT.
package migrate
import (
"context"
"fmt"
"io"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql/schema"
)
var (
// WithGlobalUniqueID sets the universal ids options to the migration.
// If this option is enabled, ent migration will allocate a 1<<32 range
// for the ids of each entity (table).
// Note that this option cannot be applied on tables that already exist.
WithGlobalUniqueID = schema.WithGlobalUniqueID
// WithDropColumn sets the drop column option to the migration.
// If this option is enabled, ent migration will drop old columns
// that were used for both fields and edges. This defaults to false.
WithDropColumn = schema.WithDropColumn
// WithDropIndex sets the drop index option to the migration.
// If this option is enabled, ent migration will drop old indexes
// that were defined in the schema. This defaults to false.
// Note that unique constraints are defined using `UNIQUE INDEX`,
// and therefore, it's recommended to enable this option to get more
// flexibility in the schema changes.
WithDropIndex = schema.WithDropIndex
// WithForeignKeys enables creating foreign-key in schema DDL. This defaults to true.
WithForeignKeys = schema.WithForeignKeys
)
// Schema is the API for creating, migrating and dropping a schema.
type Schema struct {
drv dialect.Driver
}
// NewSchema creates a new schema client.
func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} }
// Create creates all schema resources.
func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error {
return Create(ctx, s, Tables, opts...)
}
// Create creates all table resources using the given schema driver.
func Create(ctx context.Context, s *Schema, tables []*schema.Table, opts ...schema.MigrateOption) error {
migrate, err := schema.NewMigrate(s.drv, opts...)
if err != nil {
return fmt.Errorf("ent/migrate: %w", err)
}
return migrate.Create(ctx, tables...)
}
// WriteTo writes the schema changes to w instead of running them against the database.
//
// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil {
// log.Fatal(err)
// }
func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error {
return Create(ctx, &Schema{drv: &schema.WriteDriver{Writer: w, Driver: s.drv}}, Tables, opts...)
}

View File

@@ -0,0 +1,157 @@
// Code generated by ent, DO NOT EDIT.
package migrate
import (
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/dialect/sql/schema"
"entgo.io/ent/schema/field"
)
var (
// DocumentsColumns holds the columns for the "documents" table.
DocumentsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "created_at", Type: field.TypeString},
{Name: "updated_at", Type: field.TypeString},
{Name: "deleted_at", Type: field.TypeString, Nullable: true},
{Name: "title", Type: field.TypeString, Size: 255},
{Name: "content", Type: field.TypeString, Nullable: true, Size: 2147483647, Default: "\n∞∞∞text-a\n"},
{Name: "locked", Type: field.TypeBool, Default: false},
}
// DocumentsTable holds the schema information for the "documents" table.
DocumentsTable = &schema.Table{
Name: "documents",
Columns: DocumentsColumns,
PrimaryKey: []*schema.Column{DocumentsColumns[0]},
Indexes: []*schema.Index{
{
Name: "document_deleted_at",
Unique: false,
Columns: []*schema.Column{DocumentsColumns[3]},
},
{
Name: "document_title",
Unique: false,
Columns: []*schema.Column{DocumentsColumns[4]},
},
{
Name: "document_created_at",
Unique: false,
Columns: []*schema.Column{DocumentsColumns[1]},
},
{
Name: "document_updated_at",
Unique: false,
Columns: []*schema.Column{DocumentsColumns[2]},
},
},
}
// ExtensionsColumns holds the columns for the "extensions" table.
ExtensionsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "created_at", Type: field.TypeString},
{Name: "updated_at", Type: field.TypeString},
{Name: "deleted_at", Type: field.TypeString, Nullable: true},
{Name: "key", Type: field.TypeString, Unique: true, Size: 100},
{Name: "enabled", Type: field.TypeBool, Default: true},
{Name: "config", Type: field.TypeJSON, Nullable: true},
}
// ExtensionsTable holds the schema information for the "extensions" table.
ExtensionsTable = &schema.Table{
Name: "extensions",
Columns: ExtensionsColumns,
PrimaryKey: []*schema.Column{ExtensionsColumns[0]},
Indexes: []*schema.Index{
{
Name: "extension_deleted_at",
Unique: false,
Columns: []*schema.Column{ExtensionsColumns[3]},
},
{
Name: "extension_enabled",
Unique: false,
Columns: []*schema.Column{ExtensionsColumns[5]},
},
},
}
// KeyBindingsColumns holds the columns for the "key_bindings" table.
KeyBindingsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "created_at", Type: field.TypeString},
{Name: "updated_at", Type: field.TypeString},
{Name: "deleted_at", Type: field.TypeString, Nullable: true},
{Name: "key", Type: field.TypeString, Unique: true, Size: 100},
{Name: "command", Type: field.TypeString, Size: 100},
{Name: "extension", Type: field.TypeString, Nullable: true, Size: 100},
{Name: "enabled", Type: field.TypeBool, Default: true},
}
// KeyBindingsTable holds the schema information for the "key_bindings" table.
KeyBindingsTable = &schema.Table{
Name: "key_bindings",
Columns: KeyBindingsColumns,
PrimaryKey: []*schema.Column{KeyBindingsColumns[0]},
Indexes: []*schema.Index{
{
Name: "keybinding_deleted_at",
Unique: false,
Columns: []*schema.Column{KeyBindingsColumns[3]},
},
{
Name: "keybinding_extension",
Unique: false,
Columns: []*schema.Column{KeyBindingsColumns[6]},
},
{
Name: "keybinding_enabled",
Unique: false,
Columns: []*schema.Column{KeyBindingsColumns[7]},
},
},
}
// ThemesColumns holds the columns for the "themes" table.
ThemesColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "created_at", Type: field.TypeString},
{Name: "updated_at", Type: field.TypeString},
{Name: "deleted_at", Type: field.TypeString, Nullable: true},
{Name: "key", Type: field.TypeString, Unique: true, Size: 100},
{Name: "type", Type: field.TypeEnum, Enums: []string{"dark", "light"}},
{Name: "colors", Type: field.TypeJSON, Nullable: true},
}
// ThemesTable holds the schema information for the "themes" table.
ThemesTable = &schema.Table{
Name: "themes",
Columns: ThemesColumns,
PrimaryKey: []*schema.Column{ThemesColumns[0]},
Indexes: []*schema.Index{
{
Name: "theme_deleted_at",
Unique: false,
Columns: []*schema.Column{ThemesColumns[3]},
},
},
}
// Tables holds all the tables in the schema.
Tables = []*schema.Table{
DocumentsTable,
ExtensionsTable,
KeyBindingsTable,
ThemesTable,
}
)
func init() {
DocumentsTable.Annotation = &entsql.Annotation{
Table: "documents",
}
ExtensionsTable.Annotation = &entsql.Annotation{
Table: "extensions",
}
KeyBindingsTable.Annotation = &entsql.Annotation{
Table: "key_bindings",
}
ThemesTable.Annotation = &entsql.Annotation{
Table: "themes",
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
// Code generated by ent, DO NOT EDIT.
package predicate
import (
"entgo.io/ent/dialect/sql"
)
// Document is the predicate function for document builders.
type Document func(*sql.Selector)
// Extension is the predicate function for extension builders.
type Extension func(*sql.Selector)
// KeyBinding is the predicate function for keybinding builders.
type KeyBinding func(*sql.Selector)
// Theme is the predicate function for theme builders.
type Theme func(*sql.Selector)

View File

@@ -0,0 +1,271 @@
// Code generated by ent, DO NOT EDIT.
package privacy
import (
"context"
"voidraft/internal/models/ent"
"entgo.io/ent/entql"
"entgo.io/ent/privacy"
)
var (
// Allow may be returned by rules to indicate that the policy
// evaluation should terminate with allow decision.
Allow = privacy.Allow
// Deny may be returned by rules to indicate that the policy
// evaluation should terminate with deny decision.
Deny = privacy.Deny
// Skip may be returned by rules to indicate that the policy
// evaluation should continue to the next rule.
Skip = privacy.Skip
)
// Allowf returns a formatted wrapped Allow decision.
func Allowf(format string, a ...any) error {
return privacy.Allowf(format, a...)
}
// Denyf returns a formatted wrapped Deny decision.
func Denyf(format string, a ...any) error {
return privacy.Denyf(format, a...)
}
// Skipf returns a formatted wrapped Skip decision.
func Skipf(format string, a ...any) error {
return privacy.Skipf(format, a...)
}
// DecisionContext creates a new context from the given parent context with
// a policy decision attach to it.
func DecisionContext(parent context.Context, decision error) context.Context {
return privacy.DecisionContext(parent, decision)
}
// DecisionFromContext retrieves the policy decision from the context.
func DecisionFromContext(ctx context.Context) (error, bool) {
return privacy.DecisionFromContext(ctx)
}
type (
// Policy groups query and mutation policies.
Policy = privacy.Policy
// QueryRule defines the interface deciding whether a
// query is allowed and optionally modify it.
QueryRule = privacy.QueryRule
// QueryPolicy combines multiple query rules into a single policy.
QueryPolicy = privacy.QueryPolicy
// MutationRule defines the interface which decides whether a
// mutation is allowed and optionally modifies it.
MutationRule = privacy.MutationRule
// MutationPolicy combines multiple mutation rules into a single policy.
MutationPolicy = privacy.MutationPolicy
// MutationRuleFunc type is an adapter which allows the use of
// ordinary functions as mutation rules.
MutationRuleFunc = privacy.MutationRuleFunc
// QueryMutationRule is an interface which groups query and mutation rules.
QueryMutationRule = privacy.QueryMutationRule
)
// QueryRuleFunc type is an adapter to allow the use of
// ordinary functions as query rules.
type QueryRuleFunc func(context.Context, ent.Query) error
// Eval returns f(ctx, q).
func (f QueryRuleFunc) EvalQuery(ctx context.Context, q ent.Query) error {
return f(ctx, q)
}
// AlwaysAllowRule returns a rule that returns an allow decision.
func AlwaysAllowRule() QueryMutationRule {
return privacy.AlwaysAllowRule()
}
// AlwaysDenyRule returns a rule that returns a deny decision.
func AlwaysDenyRule() QueryMutationRule {
return privacy.AlwaysDenyRule()
}
// ContextQueryMutationRule creates a query/mutation rule from a context eval func.
func ContextQueryMutationRule(eval func(context.Context) error) QueryMutationRule {
return privacy.ContextQueryMutationRule(eval)
}
// OnMutationOperation evaluates the given rule only on a given mutation operation.
func OnMutationOperation(rule MutationRule, op ent.Op) MutationRule {
return privacy.OnMutationOperation(rule, op)
}
// DenyMutationOperationRule returns a rule denying specified mutation operation.
func DenyMutationOperationRule(op ent.Op) MutationRule {
rule := MutationRuleFunc(func(_ context.Context, m ent.Mutation) error {
return Denyf("ent/privacy: operation %s is not allowed", m.Op())
})
return OnMutationOperation(rule, op)
}
// The DocumentQueryRuleFunc type is an adapter to allow the use of ordinary
// functions as a query rule.
type DocumentQueryRuleFunc func(context.Context, *ent.DocumentQuery) error
// EvalQuery return f(ctx, q).
func (f DocumentQueryRuleFunc) EvalQuery(ctx context.Context, q ent.Query) error {
if q, ok := q.(*ent.DocumentQuery); ok {
return f(ctx, q)
}
return Denyf("ent/privacy: unexpected query type %T, expect *ent.DocumentQuery", q)
}
// The DocumentMutationRuleFunc type is an adapter to allow the use of ordinary
// functions as a mutation rule.
type DocumentMutationRuleFunc func(context.Context, *ent.DocumentMutation) error
// EvalMutation calls f(ctx, m).
func (f DocumentMutationRuleFunc) EvalMutation(ctx context.Context, m ent.Mutation) error {
if m, ok := m.(*ent.DocumentMutation); ok {
return f(ctx, m)
}
return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.DocumentMutation", m)
}
// The ExtensionQueryRuleFunc type is an adapter to allow the use of ordinary
// functions as a query rule.
type ExtensionQueryRuleFunc func(context.Context, *ent.ExtensionQuery) error
// EvalQuery return f(ctx, q).
func (f ExtensionQueryRuleFunc) EvalQuery(ctx context.Context, q ent.Query) error {
if q, ok := q.(*ent.ExtensionQuery); ok {
return f(ctx, q)
}
return Denyf("ent/privacy: unexpected query type %T, expect *ent.ExtensionQuery", q)
}
// The ExtensionMutationRuleFunc type is an adapter to allow the use of ordinary
// functions as a mutation rule.
type ExtensionMutationRuleFunc func(context.Context, *ent.ExtensionMutation) error
// EvalMutation calls f(ctx, m).
func (f ExtensionMutationRuleFunc) EvalMutation(ctx context.Context, m ent.Mutation) error {
if m, ok := m.(*ent.ExtensionMutation); ok {
return f(ctx, m)
}
return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.ExtensionMutation", m)
}
// The KeyBindingQueryRuleFunc type is an adapter to allow the use of ordinary
// functions as a query rule.
type KeyBindingQueryRuleFunc func(context.Context, *ent.KeyBindingQuery) error
// EvalQuery return f(ctx, q).
func (f KeyBindingQueryRuleFunc) EvalQuery(ctx context.Context, q ent.Query) error {
if q, ok := q.(*ent.KeyBindingQuery); ok {
return f(ctx, q)
}
return Denyf("ent/privacy: unexpected query type %T, expect *ent.KeyBindingQuery", q)
}
// The KeyBindingMutationRuleFunc type is an adapter to allow the use of ordinary
// functions as a mutation rule.
type KeyBindingMutationRuleFunc func(context.Context, *ent.KeyBindingMutation) error
// EvalMutation calls f(ctx, m).
func (f KeyBindingMutationRuleFunc) EvalMutation(ctx context.Context, m ent.Mutation) error {
if m, ok := m.(*ent.KeyBindingMutation); ok {
return f(ctx, m)
}
return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.KeyBindingMutation", m)
}
// The ThemeQueryRuleFunc type is an adapter to allow the use of ordinary
// functions as a query rule.
type ThemeQueryRuleFunc func(context.Context, *ent.ThemeQuery) error
// EvalQuery return f(ctx, q).
func (f ThemeQueryRuleFunc) EvalQuery(ctx context.Context, q ent.Query) error {
if q, ok := q.(*ent.ThemeQuery); ok {
return f(ctx, q)
}
return Denyf("ent/privacy: unexpected query type %T, expect *ent.ThemeQuery", q)
}
// The ThemeMutationRuleFunc type is an adapter to allow the use of ordinary
// functions as a mutation rule.
type ThemeMutationRuleFunc func(context.Context, *ent.ThemeMutation) error
// EvalMutation calls f(ctx, m).
func (f ThemeMutationRuleFunc) EvalMutation(ctx context.Context, m ent.Mutation) error {
if m, ok := m.(*ent.ThemeMutation); ok {
return f(ctx, m)
}
return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.ThemeMutation", m)
}
type (
// Filter is the interface that wraps the Where function
// for filtering nodes in queries and mutations.
Filter interface {
// Where applies a filter on the executed query/mutation.
Where(entql.P)
}
// The FilterFunc type is an adapter that allows the use of ordinary
// functions as filters for query and mutation types.
FilterFunc func(context.Context, Filter) error
)
// EvalQuery calls f(ctx, q) if the query implements the Filter interface, otherwise it is denied.
func (f FilterFunc) EvalQuery(ctx context.Context, q ent.Query) error {
fr, err := queryFilter(q)
if err != nil {
return err
}
return f(ctx, fr)
}
// EvalMutation calls f(ctx, q) if the mutation implements the Filter interface, otherwise it is denied.
func (f FilterFunc) EvalMutation(ctx context.Context, m ent.Mutation) error {
fr, err := mutationFilter(m)
if err != nil {
return err
}
return f(ctx, fr)
}
var _ QueryMutationRule = FilterFunc(nil)
func queryFilter(q ent.Query) (Filter, error) {
switch q := q.(type) {
case *ent.DocumentQuery:
return q.Filter(), nil
case *ent.ExtensionQuery:
return q.Filter(), nil
case *ent.KeyBindingQuery:
return q.Filter(), nil
case *ent.ThemeQuery:
return q.Filter(), nil
default:
return nil, Denyf("ent/privacy: unexpected query type %T for query filter", q)
}
}
func mutationFilter(m ent.Mutation) (Filter, error) {
switch m := m.(type) {
case *ent.DocumentMutation:
return m.Filter(), nil
case *ent.ExtensionMutation:
return m.Filter(), nil
case *ent.KeyBindingMutation:
return m.Filter(), nil
case *ent.ThemeMutation:
return m.Filter(), nil
default:
return nil, Denyf("ent/privacy: unexpected mutation type %T for mutation filter", m)
}
}

View File

@@ -0,0 +1,5 @@
// Code generated by ent, DO NOT EDIT.
package ent
// The schema-stitching logic is generated in voidraft/internal/models/ent/runtime/runtime.go

View File

@@ -0,0 +1,208 @@
// Code generated by ent, DO NOT EDIT.
package runtime
import (
"voidraft/internal/models/ent/document"
"voidraft/internal/models/ent/extension"
"voidraft/internal/models/ent/keybinding"
"voidraft/internal/models/ent/theme"
"voidraft/internal/models/schema"
)
// The init function reads all schema descriptors with runtime code
// (default values, validators, hooks and policies) and stitches it
// to their package variables.
func init() {
documentMixin := schema.Document{}.Mixin()
documentMixinHooks0 := documentMixin[0].Hooks()
documentMixinHooks1 := documentMixin[1].Hooks()
document.Hooks[0] = documentMixinHooks0[0]
document.Hooks[1] = documentMixinHooks1[0]
documentMixinInters1 := documentMixin[1].Interceptors()
document.Interceptors[0] = documentMixinInters1[0]
documentMixinFields0 := documentMixin[0].Fields()
_ = documentMixinFields0
documentFields := schema.Document{}.Fields()
_ = documentFields
// documentDescCreatedAt is the schema descriptor for created_at field.
documentDescCreatedAt := documentMixinFields0[0].Descriptor()
// document.DefaultCreatedAt holds the default value on creation for the created_at field.
document.DefaultCreatedAt = documentDescCreatedAt.Default.(func() string)
// documentDescUpdatedAt is the schema descriptor for updated_at field.
documentDescUpdatedAt := documentMixinFields0[1].Descriptor()
// document.DefaultUpdatedAt holds the default value on creation for the updated_at field.
document.DefaultUpdatedAt = documentDescUpdatedAt.Default.(func() string)
// documentDescTitle is the schema descriptor for title field.
documentDescTitle := documentFields[0].Descriptor()
// document.TitleValidator is a validator for the "title" field. It is called by the builders before save.
document.TitleValidator = func() func(string) error {
validators := documentDescTitle.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(title string) error {
for _, fn := range fns {
if err := fn(title); err != nil {
return err
}
}
return nil
}
}()
// documentDescContent is the schema descriptor for content field.
documentDescContent := documentFields[1].Descriptor()
// document.DefaultContent holds the default value on creation for the content field.
document.DefaultContent = documentDescContent.Default.(string)
// documentDescLocked is the schema descriptor for locked field.
documentDescLocked := documentFields[2].Descriptor()
// document.DefaultLocked holds the default value on creation for the locked field.
document.DefaultLocked = documentDescLocked.Default.(bool)
extensionMixin := schema.Extension{}.Mixin()
extensionMixinHooks0 := extensionMixin[0].Hooks()
extensionMixinHooks1 := extensionMixin[1].Hooks()
extension.Hooks[0] = extensionMixinHooks0[0]
extension.Hooks[1] = extensionMixinHooks1[0]
extensionMixinInters1 := extensionMixin[1].Interceptors()
extension.Interceptors[0] = extensionMixinInters1[0]
extensionMixinFields0 := extensionMixin[0].Fields()
_ = extensionMixinFields0
extensionFields := schema.Extension{}.Fields()
_ = extensionFields
// extensionDescCreatedAt is the schema descriptor for created_at field.
extensionDescCreatedAt := extensionMixinFields0[0].Descriptor()
// extension.DefaultCreatedAt holds the default value on creation for the created_at field.
extension.DefaultCreatedAt = extensionDescCreatedAt.Default.(func() string)
// extensionDescUpdatedAt is the schema descriptor for updated_at field.
extensionDescUpdatedAt := extensionMixinFields0[1].Descriptor()
// extension.DefaultUpdatedAt holds the default value on creation for the updated_at field.
extension.DefaultUpdatedAt = extensionDescUpdatedAt.Default.(func() string)
// extensionDescKey is the schema descriptor for key field.
extensionDescKey := extensionFields[0].Descriptor()
// extension.KeyValidator is a validator for the "key" field. It is called by the builders before save.
extension.KeyValidator = func() func(string) error {
validators := extensionDescKey.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(key string) error {
for _, fn := range fns {
if err := fn(key); err != nil {
return err
}
}
return nil
}
}()
// extensionDescEnabled is the schema descriptor for enabled field.
extensionDescEnabled := extensionFields[1].Descriptor()
// extension.DefaultEnabled holds the default value on creation for the enabled field.
extension.DefaultEnabled = extensionDescEnabled.Default.(bool)
keybindingMixin := schema.KeyBinding{}.Mixin()
keybindingMixinHooks0 := keybindingMixin[0].Hooks()
keybindingMixinHooks1 := keybindingMixin[1].Hooks()
keybinding.Hooks[0] = keybindingMixinHooks0[0]
keybinding.Hooks[1] = keybindingMixinHooks1[0]
keybindingMixinInters1 := keybindingMixin[1].Interceptors()
keybinding.Interceptors[0] = keybindingMixinInters1[0]
keybindingMixinFields0 := keybindingMixin[0].Fields()
_ = keybindingMixinFields0
keybindingFields := schema.KeyBinding{}.Fields()
_ = keybindingFields
// keybindingDescCreatedAt is the schema descriptor for created_at field.
keybindingDescCreatedAt := keybindingMixinFields0[0].Descriptor()
// keybinding.DefaultCreatedAt holds the default value on creation for the created_at field.
keybinding.DefaultCreatedAt = keybindingDescCreatedAt.Default.(func() string)
// keybindingDescUpdatedAt is the schema descriptor for updated_at field.
keybindingDescUpdatedAt := keybindingMixinFields0[1].Descriptor()
// keybinding.DefaultUpdatedAt holds the default value on creation for the updated_at field.
keybinding.DefaultUpdatedAt = keybindingDescUpdatedAt.Default.(func() string)
// keybindingDescKey is the schema descriptor for key field.
keybindingDescKey := keybindingFields[0].Descriptor()
// keybinding.KeyValidator is a validator for the "key" field. It is called by the builders before save.
keybinding.KeyValidator = func() func(string) error {
validators := keybindingDescKey.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(key string) error {
for _, fn := range fns {
if err := fn(key); err != nil {
return err
}
}
return nil
}
}()
// keybindingDescCommand is the schema descriptor for command field.
keybindingDescCommand := keybindingFields[1].Descriptor()
// keybinding.CommandValidator is a validator for the "command" field. It is called by the builders before save.
keybinding.CommandValidator = func() func(string) error {
validators := keybindingDescCommand.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(command string) error {
for _, fn := range fns {
if err := fn(command); err != nil {
return err
}
}
return nil
}
}()
// keybindingDescExtension is the schema descriptor for extension field.
keybindingDescExtension := keybindingFields[2].Descriptor()
// keybinding.ExtensionValidator is a validator for the "extension" field. It is called by the builders before save.
keybinding.ExtensionValidator = keybindingDescExtension.Validators[0].(func(string) error)
// keybindingDescEnabled is the schema descriptor for enabled field.
keybindingDescEnabled := keybindingFields[3].Descriptor()
// keybinding.DefaultEnabled holds the default value on creation for the enabled field.
keybinding.DefaultEnabled = keybindingDescEnabled.Default.(bool)
themeMixin := schema.Theme{}.Mixin()
themeMixinHooks0 := themeMixin[0].Hooks()
themeMixinHooks1 := themeMixin[1].Hooks()
theme.Hooks[0] = themeMixinHooks0[0]
theme.Hooks[1] = themeMixinHooks1[0]
themeMixinInters1 := themeMixin[1].Interceptors()
theme.Interceptors[0] = themeMixinInters1[0]
themeMixinFields0 := themeMixin[0].Fields()
_ = themeMixinFields0
themeFields := schema.Theme{}.Fields()
_ = themeFields
// themeDescCreatedAt is the schema descriptor for created_at field.
themeDescCreatedAt := themeMixinFields0[0].Descriptor()
// theme.DefaultCreatedAt holds the default value on creation for the created_at field.
theme.DefaultCreatedAt = themeDescCreatedAt.Default.(func() string)
// themeDescUpdatedAt is the schema descriptor for updated_at field.
themeDescUpdatedAt := themeMixinFields0[1].Descriptor()
// theme.DefaultUpdatedAt holds the default value on creation for the updated_at field.
theme.DefaultUpdatedAt = themeDescUpdatedAt.Default.(func() string)
// themeDescKey is the schema descriptor for key field.
themeDescKey := themeFields[0].Descriptor()
// theme.KeyValidator is a validator for the "key" field. It is called by the builders before save.
theme.KeyValidator = func() func(string) error {
validators := themeDescKey.Validators
fns := [...]func(string) error{
validators[0].(func(string) error),
validators[1].(func(string) error),
}
return func(key string) error {
for _, fn := range fns {
if err := fn(key); err != nil {
return err
}
}
return nil
}
}()
}
const (
Version = "v0.14.5" // Version of ent codegen.
Sum = "h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4=" // Sum of ent codegen.
)

View File

@@ -0,0 +1,54 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/mixin"
)
// Theme holds the schema definition for the Theme entity.
type Theme struct {
ent.Schema
}
// Annotations of the Theme.
func (Theme) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "themes"},
}
}
// Mixin of the Theme.
func (Theme) Mixin() []ent.Mixin {
return []ent.Mixin{
mixin.Time{},
}
}
// Fields of the Theme.
func (Theme) Fields() []ent.Field {
return []ent.Field{
field.String("key").
MaxLen(100).
NotEmpty().
Unique().
Comment("主题标识符"),
field.Enum("type").
Values("dark", "light").
Comment("主题类型"),
field.JSON("colors", map[string]interface{}{}).
Optional().
Comment("主题颜色配置"),
field.Time("deleted_at").
Optional().
Nillable().
Comment("软删除时间"),
}
}
// Edges of the Theme.
func (Theme) Edges() []ent.Edge {
return nil
}

View File

@@ -0,0 +1,166 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"encoding/json"
"fmt"
"strings"
"voidraft/internal/models/ent/theme"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
)
// Theme is the model entity for the Theme schema.
type Theme struct {
config `json:"-"`
// ID of the ent.
ID int `json:"id,omitempty"`
// 创建时间
CreatedAt string `json:"created_at"`
// 最后更新时间
UpdatedAt string `json:"updated_at"`
// 删除时间NULL表示未删除
DeletedAt *string `json:"deleted_at,omitempty"`
// 主题标识符
Key string `json:"key"`
// 主题类型
Type theme.Type `json:"type"`
// 主题颜色配置
Colors map[string]interface{} `json:"colors"`
selectValues sql.SelectValues
}
// scanValues returns the types for scanning values from sql.Rows.
func (*Theme) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case theme.FieldColors:
values[i] = new([]byte)
case theme.FieldID:
values[i] = new(sql.NullInt64)
case theme.FieldCreatedAt, theme.FieldUpdatedAt, theme.FieldDeletedAt, theme.FieldKey, theme.FieldType:
values[i] = new(sql.NullString)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Theme fields.
func (_m *Theme) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case theme.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
_m.ID = int(value.Int64)
case theme.FieldCreatedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
_m.CreatedAt = value.String
}
case theme.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
_m.UpdatedAt = value.String
}
case theme.FieldDeletedAt:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
} else if value.Valid {
_m.DeletedAt = new(string)
*_m.DeletedAt = value.String
}
case theme.FieldKey:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field key", values[i])
} else if value.Valid {
_m.Key = value.String
}
case theme.FieldType:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field type", values[i])
} else if value.Valid {
_m.Type = theme.Type(value.String)
}
case theme.FieldColors:
if value, ok := values[i].(*[]byte); !ok {
return fmt.Errorf("unexpected type %T for field colors", values[i])
} else if value != nil && len(*value) > 0 {
if err := json.Unmarshal(*value, &_m.Colors); err != nil {
return fmt.Errorf("unmarshal field colors: %w", err)
}
}
default:
_m.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the Theme.
// This includes values selected through modifiers, order, etc.
func (_m *Theme) Value(name string) (ent.Value, error) {
return _m.selectValues.Get(name)
}
// Update returns a builder for updating this Theme.
// Note that you need to call Theme.Unwrap() before calling this method if this Theme
// was returned from a transaction, and the transaction was committed or rolled back.
func (_m *Theme) Update() *ThemeUpdateOne {
return NewThemeClient(_m.config).UpdateOne(_m)
}
// Unwrap unwraps the Theme entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (_m *Theme) Unwrap() *Theme {
_tx, ok := _m.config.driver.(*txDriver)
if !ok {
panic("ent: Theme is not a transactional entity")
}
_m.config.driver = _tx.drv
return _m
}
// String implements the fmt.Stringer.
func (_m *Theme) String() string {
var builder strings.Builder
builder.WriteString("Theme(")
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
builder.WriteString("created_at=")
builder.WriteString(_m.CreatedAt)
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(_m.UpdatedAt)
builder.WriteString(", ")
if v := _m.DeletedAt; v != nil {
builder.WriteString("deleted_at=")
builder.WriteString(*v)
}
builder.WriteString(", ")
builder.WriteString("key=")
builder.WriteString(_m.Key)
builder.WriteString(", ")
builder.WriteString("type=")
builder.WriteString(fmt.Sprintf("%v", _m.Type))
builder.WriteString(", ")
builder.WriteString("colors=")
builder.WriteString(fmt.Sprintf("%v", _m.Colors))
builder.WriteByte(')')
return builder.String()
}
// Themes is a parsable slice of Theme.
type Themes []*Theme

View File

@@ -0,0 +1,124 @@
// Code generated by ent, DO NOT EDIT.
package theme
import (
"fmt"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
)
const (
// Label holds the string label denoting the theme type in the database.
Label = "theme"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
FieldDeletedAt = "deleted_at"
// FieldKey holds the string denoting the key field in the database.
FieldKey = "key"
// FieldType holds the string denoting the type field in the database.
FieldType = "type"
// FieldColors holds the string denoting the colors field in the database.
FieldColors = "colors"
// Table holds the table name of the theme in the database.
Table = "themes"
)
// Columns holds all SQL columns for theme fields.
var Columns = []string{
FieldID,
FieldCreatedAt,
FieldUpdatedAt,
FieldDeletedAt,
FieldKey,
FieldType,
FieldColors,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
// Note that the variables below are initialized by the runtime
// package on the initialization of the application. Therefore,
// it should be imported in the main as follows:
//
// import _ "voidraft/internal/models/ent/runtime"
var (
Hooks [2]ent.Hook
Interceptors [1]ent.Interceptor
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() string
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
DefaultUpdatedAt func() string
// KeyValidator is a validator for the "key" field. It is called by the builders before save.
KeyValidator func(string) error
)
// Type defines the type for the "type" enum field.
type Type string
// Type values.
const (
TypeDark Type = "dark"
TypeLight Type = "light"
)
func (_type Type) String() string {
return string(_type)
}
// TypeValidator is a validator for the "type" field enum values. It is called by the builders before save.
func TypeValidator(_type Type) error {
switch _type {
case TypeDark, TypeLight:
return nil
default:
return fmt.Errorf("theme: invalid enum value for type field: %q", _type)
}
}
// OrderOption defines the ordering options for the Theme queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// ByDeletedAt orders the results by the deleted_at field.
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
}
// ByKey orders the results by the key field.
func ByKey(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldKey, opts...).ToFunc()
}
// ByType orders the results by the type field.
func ByType(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldType, opts...).ToFunc()
}

View File

@@ -0,0 +1,389 @@
// Code generated by ent, DO NOT EDIT.
package theme
import (
"voidraft/internal/models/ent/predicate"
"entgo.io/ent/dialect/sql"
)
// ID filters vertices based on their ID field.
func ID(id int) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int) predicate.Theme {
return predicate.Theme(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int) predicate.Theme {
return predicate.Theme(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int) predicate.Theme {
return predicate.Theme(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int) predicate.Theme {
return predicate.Theme(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int) predicate.Theme {
return predicate.Theme(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int) predicate.Theme {
return predicate.Theme(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int) predicate.Theme {
return predicate.Theme(sql.FieldLTE(FieldID, id))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v string) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldCreatedAt, v))
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v string) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldUpdatedAt, v))
}
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
func DeletedAt(v string) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldDeletedAt, v))
}
// Key applies equality check predicate on the "key" field. It's identical to KeyEQ.
func Key(v string) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldKey, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v string) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v string) predicate.Theme {
return predicate.Theme(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...string) predicate.Theme {
return predicate.Theme(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...string) predicate.Theme {
return predicate.Theme(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v string) predicate.Theme {
return predicate.Theme(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v string) predicate.Theme {
return predicate.Theme(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v string) predicate.Theme {
return predicate.Theme(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v string) predicate.Theme {
return predicate.Theme(sql.FieldLTE(FieldCreatedAt, v))
}
// CreatedAtContains applies the Contains predicate on the "created_at" field.
func CreatedAtContains(v string) predicate.Theme {
return predicate.Theme(sql.FieldContains(FieldCreatedAt, v))
}
// CreatedAtHasPrefix applies the HasPrefix predicate on the "created_at" field.
func CreatedAtHasPrefix(v string) predicate.Theme {
return predicate.Theme(sql.FieldHasPrefix(FieldCreatedAt, v))
}
// CreatedAtHasSuffix applies the HasSuffix predicate on the "created_at" field.
func CreatedAtHasSuffix(v string) predicate.Theme {
return predicate.Theme(sql.FieldHasSuffix(FieldCreatedAt, v))
}
// CreatedAtEqualFold applies the EqualFold predicate on the "created_at" field.
func CreatedAtEqualFold(v string) predicate.Theme {
return predicate.Theme(sql.FieldEqualFold(FieldCreatedAt, v))
}
// CreatedAtContainsFold applies the ContainsFold predicate on the "created_at" field.
func CreatedAtContainsFold(v string) predicate.Theme {
return predicate.Theme(sql.FieldContainsFold(FieldCreatedAt, v))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v string) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldUpdatedAt, v))
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v string) predicate.Theme {
return predicate.Theme(sql.FieldNEQ(FieldUpdatedAt, v))
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...string) predicate.Theme {
return predicate.Theme(sql.FieldIn(FieldUpdatedAt, vs...))
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...string) predicate.Theme {
return predicate.Theme(sql.FieldNotIn(FieldUpdatedAt, vs...))
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v string) predicate.Theme {
return predicate.Theme(sql.FieldGT(FieldUpdatedAt, v))
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v string) predicate.Theme {
return predicate.Theme(sql.FieldGTE(FieldUpdatedAt, v))
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v string) predicate.Theme {
return predicate.Theme(sql.FieldLT(FieldUpdatedAt, v))
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v string) predicate.Theme {
return predicate.Theme(sql.FieldLTE(FieldUpdatedAt, v))
}
// UpdatedAtContains applies the Contains predicate on the "updated_at" field.
func UpdatedAtContains(v string) predicate.Theme {
return predicate.Theme(sql.FieldContains(FieldUpdatedAt, v))
}
// UpdatedAtHasPrefix applies the HasPrefix predicate on the "updated_at" field.
func UpdatedAtHasPrefix(v string) predicate.Theme {
return predicate.Theme(sql.FieldHasPrefix(FieldUpdatedAt, v))
}
// UpdatedAtHasSuffix applies the HasSuffix predicate on the "updated_at" field.
func UpdatedAtHasSuffix(v string) predicate.Theme {
return predicate.Theme(sql.FieldHasSuffix(FieldUpdatedAt, v))
}
// UpdatedAtEqualFold applies the EqualFold predicate on the "updated_at" field.
func UpdatedAtEqualFold(v string) predicate.Theme {
return predicate.Theme(sql.FieldEqualFold(FieldUpdatedAt, v))
}
// UpdatedAtContainsFold applies the ContainsFold predicate on the "updated_at" field.
func UpdatedAtContainsFold(v string) predicate.Theme {
return predicate.Theme(sql.FieldContainsFold(FieldUpdatedAt, v))
}
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
func DeletedAtEQ(v string) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldDeletedAt, v))
}
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
func DeletedAtNEQ(v string) predicate.Theme {
return predicate.Theme(sql.FieldNEQ(FieldDeletedAt, v))
}
// DeletedAtIn applies the In predicate on the "deleted_at" field.
func DeletedAtIn(vs ...string) predicate.Theme {
return predicate.Theme(sql.FieldIn(FieldDeletedAt, vs...))
}
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
func DeletedAtNotIn(vs ...string) predicate.Theme {
return predicate.Theme(sql.FieldNotIn(FieldDeletedAt, vs...))
}
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
func DeletedAtGT(v string) predicate.Theme {
return predicate.Theme(sql.FieldGT(FieldDeletedAt, v))
}
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
func DeletedAtGTE(v string) predicate.Theme {
return predicate.Theme(sql.FieldGTE(FieldDeletedAt, v))
}
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
func DeletedAtLT(v string) predicate.Theme {
return predicate.Theme(sql.FieldLT(FieldDeletedAt, v))
}
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
func DeletedAtLTE(v string) predicate.Theme {
return predicate.Theme(sql.FieldLTE(FieldDeletedAt, v))
}
// DeletedAtContains applies the Contains predicate on the "deleted_at" field.
func DeletedAtContains(v string) predicate.Theme {
return predicate.Theme(sql.FieldContains(FieldDeletedAt, v))
}
// DeletedAtHasPrefix applies the HasPrefix predicate on the "deleted_at" field.
func DeletedAtHasPrefix(v string) predicate.Theme {
return predicate.Theme(sql.FieldHasPrefix(FieldDeletedAt, v))
}
// DeletedAtHasSuffix applies the HasSuffix predicate on the "deleted_at" field.
func DeletedAtHasSuffix(v string) predicate.Theme {
return predicate.Theme(sql.FieldHasSuffix(FieldDeletedAt, v))
}
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
func DeletedAtIsNil() predicate.Theme {
return predicate.Theme(sql.FieldIsNull(FieldDeletedAt))
}
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
func DeletedAtNotNil() predicate.Theme {
return predicate.Theme(sql.FieldNotNull(FieldDeletedAt))
}
// DeletedAtEqualFold applies the EqualFold predicate on the "deleted_at" field.
func DeletedAtEqualFold(v string) predicate.Theme {
return predicate.Theme(sql.FieldEqualFold(FieldDeletedAt, v))
}
// DeletedAtContainsFold applies the ContainsFold predicate on the "deleted_at" field.
func DeletedAtContainsFold(v string) predicate.Theme {
return predicate.Theme(sql.FieldContainsFold(FieldDeletedAt, v))
}
// KeyEQ applies the EQ predicate on the "key" field.
func KeyEQ(v string) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldKey, v))
}
// KeyNEQ applies the NEQ predicate on the "key" field.
func KeyNEQ(v string) predicate.Theme {
return predicate.Theme(sql.FieldNEQ(FieldKey, v))
}
// KeyIn applies the In predicate on the "key" field.
func KeyIn(vs ...string) predicate.Theme {
return predicate.Theme(sql.FieldIn(FieldKey, vs...))
}
// KeyNotIn applies the NotIn predicate on the "key" field.
func KeyNotIn(vs ...string) predicate.Theme {
return predicate.Theme(sql.FieldNotIn(FieldKey, vs...))
}
// KeyGT applies the GT predicate on the "key" field.
func KeyGT(v string) predicate.Theme {
return predicate.Theme(sql.FieldGT(FieldKey, v))
}
// KeyGTE applies the GTE predicate on the "key" field.
func KeyGTE(v string) predicate.Theme {
return predicate.Theme(sql.FieldGTE(FieldKey, v))
}
// KeyLT applies the LT predicate on the "key" field.
func KeyLT(v string) predicate.Theme {
return predicate.Theme(sql.FieldLT(FieldKey, v))
}
// KeyLTE applies the LTE predicate on the "key" field.
func KeyLTE(v string) predicate.Theme {
return predicate.Theme(sql.FieldLTE(FieldKey, v))
}
// KeyContains applies the Contains predicate on the "key" field.
func KeyContains(v string) predicate.Theme {
return predicate.Theme(sql.FieldContains(FieldKey, v))
}
// KeyHasPrefix applies the HasPrefix predicate on the "key" field.
func KeyHasPrefix(v string) predicate.Theme {
return predicate.Theme(sql.FieldHasPrefix(FieldKey, v))
}
// KeyHasSuffix applies the HasSuffix predicate on the "key" field.
func KeyHasSuffix(v string) predicate.Theme {
return predicate.Theme(sql.FieldHasSuffix(FieldKey, v))
}
// KeyEqualFold applies the EqualFold predicate on the "key" field.
func KeyEqualFold(v string) predicate.Theme {
return predicate.Theme(sql.FieldEqualFold(FieldKey, v))
}
// KeyContainsFold applies the ContainsFold predicate on the "key" field.
func KeyContainsFold(v string) predicate.Theme {
return predicate.Theme(sql.FieldContainsFold(FieldKey, v))
}
// TypeEQ applies the EQ predicate on the "type" field.
func TypeEQ(v Type) predicate.Theme {
return predicate.Theme(sql.FieldEQ(FieldType, v))
}
// TypeNEQ applies the NEQ predicate on the "type" field.
func TypeNEQ(v Type) predicate.Theme {
return predicate.Theme(sql.FieldNEQ(FieldType, v))
}
// TypeIn applies the In predicate on the "type" field.
func TypeIn(vs ...Type) predicate.Theme {
return predicate.Theme(sql.FieldIn(FieldType, vs...))
}
// TypeNotIn applies the NotIn predicate on the "type" field.
func TypeNotIn(vs ...Type) predicate.Theme {
return predicate.Theme(sql.FieldNotIn(FieldType, vs...))
}
// ColorsIsNil applies the IsNil predicate on the "colors" field.
func ColorsIsNil() predicate.Theme {
return predicate.Theme(sql.FieldIsNull(FieldColors))
}
// ColorsNotNil applies the NotNil predicate on the "colors" field.
func ColorsNotNil() predicate.Theme {
return predicate.Theme(sql.FieldNotNull(FieldColors))
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.Theme) predicate.Theme {
return predicate.Theme(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.Theme) predicate.Theme {
return predicate.Theme(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.Theme) predicate.Theme {
return predicate.Theme(sql.NotPredicates(p))
}

View File

@@ -0,0 +1,299 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"voidraft/internal/models/ent/theme"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// ThemeCreate is the builder for creating a Theme entity.
type ThemeCreate struct {
config
mutation *ThemeMutation
hooks []Hook
}
// SetCreatedAt sets the "created_at" field.
func (_c *ThemeCreate) SetCreatedAt(v string) *ThemeCreate {
_c.mutation.SetCreatedAt(v)
return _c
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (_c *ThemeCreate) SetNillableCreatedAt(v *string) *ThemeCreate {
if v != nil {
_c.SetCreatedAt(*v)
}
return _c
}
// SetUpdatedAt sets the "updated_at" field.
func (_c *ThemeCreate) SetUpdatedAt(v string) *ThemeCreate {
_c.mutation.SetUpdatedAt(v)
return _c
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (_c *ThemeCreate) SetNillableUpdatedAt(v *string) *ThemeCreate {
if v != nil {
_c.SetUpdatedAt(*v)
}
return _c
}
// SetDeletedAt sets the "deleted_at" field.
func (_c *ThemeCreate) SetDeletedAt(v string) *ThemeCreate {
_c.mutation.SetDeletedAt(v)
return _c
}
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
func (_c *ThemeCreate) SetNillableDeletedAt(v *string) *ThemeCreate {
if v != nil {
_c.SetDeletedAt(*v)
}
return _c
}
// SetKey sets the "key" field.
func (_c *ThemeCreate) SetKey(v string) *ThemeCreate {
_c.mutation.SetKey(v)
return _c
}
// SetType sets the "type" field.
func (_c *ThemeCreate) SetType(v theme.Type) *ThemeCreate {
_c.mutation.SetType(v)
return _c
}
// SetColors sets the "colors" field.
func (_c *ThemeCreate) SetColors(v map[string]interface{}) *ThemeCreate {
_c.mutation.SetColors(v)
return _c
}
// Mutation returns the ThemeMutation object of the builder.
func (_c *ThemeCreate) Mutation() *ThemeMutation {
return _c.mutation
}
// Save creates the Theme in the database.
func (_c *ThemeCreate) Save(ctx context.Context) (*Theme, error) {
if err := _c.defaults(); err != nil {
return nil, err
}
return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks)
}
// SaveX calls Save and panics if Save returns an error.
func (_c *ThemeCreate) SaveX(ctx context.Context) *Theme {
v, err := _c.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (_c *ThemeCreate) Exec(ctx context.Context) error {
_, err := _c.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_c *ThemeCreate) ExecX(ctx context.Context) {
if err := _c.Exec(ctx); err != nil {
panic(err)
}
}
// defaults sets the default values of the builder before save.
func (_c *ThemeCreate) defaults() error {
if _, ok := _c.mutation.CreatedAt(); !ok {
if theme.DefaultCreatedAt == nil {
return fmt.Errorf("ent: uninitialized theme.DefaultCreatedAt (forgotten import ent/runtime?)")
}
v := theme.DefaultCreatedAt()
_c.mutation.SetCreatedAt(v)
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
if theme.DefaultUpdatedAt == nil {
return fmt.Errorf("ent: uninitialized theme.DefaultUpdatedAt (forgotten import ent/runtime?)")
}
v := theme.DefaultUpdatedAt()
_c.mutation.SetUpdatedAt(v)
}
return nil
}
// check runs all checks and user-defined validators on the builder.
func (_c *ThemeCreate) check() error {
if _, ok := _c.mutation.CreatedAt(); !ok {
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "Theme.created_at"`)}
}
if _, ok := _c.mutation.UpdatedAt(); !ok {
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "Theme.updated_at"`)}
}
if _, ok := _c.mutation.Key(); !ok {
return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "Theme.key"`)}
}
if v, ok := _c.mutation.Key(); ok {
if err := theme.KeyValidator(v); err != nil {
return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Theme.key": %w`, err)}
}
}
if _, ok := _c.mutation.GetType(); !ok {
return &ValidationError{Name: "type", err: errors.New(`ent: missing required field "Theme.type"`)}
}
if v, ok := _c.mutation.GetType(); ok {
if err := theme.TypeValidator(v); err != nil {
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Theme.type": %w`, err)}
}
}
return nil
}
func (_c *ThemeCreate) sqlSave(ctx context.Context) (*Theme, error) {
if err := _c.check(); err != nil {
return nil, err
}
_node, _spec := _c.createSpec()
if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
id := _spec.ID.Value.(int64)
_node.ID = int(id)
_c.mutation.id = &_node.ID
_c.mutation.done = true
return _node, nil
}
func (_c *ThemeCreate) createSpec() (*Theme, *sqlgraph.CreateSpec) {
var (
_node = &Theme{config: _c.config}
_spec = sqlgraph.NewCreateSpec(theme.Table, sqlgraph.NewFieldSpec(theme.FieldID, field.TypeInt))
)
if value, ok := _c.mutation.CreatedAt(); ok {
_spec.SetField(theme.FieldCreatedAt, field.TypeString, value)
_node.CreatedAt = value
}
if value, ok := _c.mutation.UpdatedAt(); ok {
_spec.SetField(theme.FieldUpdatedAt, field.TypeString, value)
_node.UpdatedAt = value
}
if value, ok := _c.mutation.DeletedAt(); ok {
_spec.SetField(theme.FieldDeletedAt, field.TypeString, value)
_node.DeletedAt = &value
}
if value, ok := _c.mutation.Key(); ok {
_spec.SetField(theme.FieldKey, field.TypeString, value)
_node.Key = value
}
if value, ok := _c.mutation.GetType(); ok {
_spec.SetField(theme.FieldType, field.TypeEnum, value)
_node.Type = value
}
if value, ok := _c.mutation.Colors(); ok {
_spec.SetField(theme.FieldColors, field.TypeJSON, value)
_node.Colors = value
}
return _node, _spec
}
// ThemeCreateBulk is the builder for creating many Theme entities in bulk.
type ThemeCreateBulk struct {
config
err error
builders []*ThemeCreate
}
// Save creates the Theme entities in the database.
func (_c *ThemeCreateBulk) Save(ctx context.Context) ([]*Theme, error) {
if _c.err != nil {
return nil, _c.err
}
specs := make([]*sqlgraph.CreateSpec, len(_c.builders))
nodes := make([]*Theme, len(_c.builders))
mutators := make([]Mutator, len(_c.builders))
for i := range _c.builders {
func(i int, root context.Context) {
builder := _c.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ThemeMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
var err error
nodes[i], specs[i] = builder.createSpec()
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation)
} else {
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
}
}
if err != nil {
return nil, err
}
mutation.id = &nodes[i].ID
if specs[i].ID.Value != nil {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int(id)
}
mutation.done = true
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (_c *ThemeCreateBulk) SaveX(ctx context.Context) []*Theme {
v, err := _c.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (_c *ThemeCreateBulk) Exec(ctx context.Context) error {
_, err := _c.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (_c *ThemeCreateBulk) ExecX(ctx context.Context) {
if err := _c.Exec(ctx); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,88 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"voidraft/internal/models/ent/predicate"
"voidraft/internal/models/ent/theme"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// ThemeDelete is the builder for deleting a Theme entity.
type ThemeDelete struct {
config
hooks []Hook
mutation *ThemeMutation
}
// Where appends a list predicates to the ThemeDelete builder.
func (_d *ThemeDelete) Where(ps ...predicate.Theme) *ThemeDelete {
_d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (_d *ThemeDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *ThemeDelete) ExecX(ctx context.Context) int {
n, err := _d.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (_d *ThemeDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(theme.Table, sqlgraph.NewFieldSpec(theme.FieldID, field.TypeInt))
if ps := _d.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
_d.mutation.done = true
return affected, err
}
// ThemeDeleteOne is the builder for deleting a single Theme entity.
type ThemeDeleteOne struct {
_d *ThemeDelete
}
// Where appends a list predicates to the ThemeDelete builder.
func (_d *ThemeDeleteOne) Where(ps ...predicate.Theme) *ThemeDeleteOne {
_d._d.mutation.Where(ps...)
return _d
}
// Exec executes the deletion query.
func (_d *ThemeDeleteOne) Exec(ctx context.Context) error {
n, err := _d._d.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{theme.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (_d *ThemeDeleteOne) ExecX(ctx context.Context) {
if err := _d.Exec(ctx); err != nil {
panic(err)
}
}

Some files were not shown because too many files have changed in this diff Show More