Merge branch 'main' into refactor/libs-versions

pull/7449/head
Ryan Wang 2025-05-20 10:07:25 +08:00 committed by GitHub
commit d382b45236
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 764 additions and 345 deletions

View File

@ -15,7 +15,7 @@ inputs:
java-version:
description: Java version.
required: false
default: "17"
default: "21"
runs:
using: "composite"

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
"openapi": "3.0.1",
"info": {
"title": "Halo",
"version": "2.20.11-SNAPSHOT"
"version": "2.21.0-SNAPSHOT"
},
"servers": [
{
@ -3628,7 +3628,8 @@
"spec": {
"$ref": "#/components/schemas/AuthProviderSpec"
}
}
},
"description": "Auth provider extension."
},
"AuthProviderSpec": {
"required": [
@ -3640,6 +3641,7 @@
"properties": {
"authType": {
"type": "string",
"description": "Auth type: form or oauth2.",
"enum": [
"FORM",
"OAUTH2"
@ -3704,17 +3706,21 @@
"type": "object",
"properties": {
"filename": {
"type": "string"
"type": "string",
"description": "Filename of backup file."
},
"lastModifiedTime": {
"type": "string",
"description": "Last modified time of backup file.",
"format": "date-time"
},
"size": {
"type": "integer",
"description": "Size of backup file.",
"format": "int64"
}
}
},
"description": "Backup file."
},
"Category": {
"required": [
@ -3767,14 +3773,17 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "\u003cp\u003eWhether to hide the category from the category list.\u003c/p\u003e\n \u003cp\u003eWhen set to true, the category including its subcategories and related posts will\n not be displayed in the category list, but it can still be accessed by permalink.\u003c/p\u003e\n \u003cp\u003eLimitation: It only takes effect on the theme-side categorized list and it only\n allows to be set to true on the first level(root node) of categories.\u003c/p\u003e"
},
"postTemplate": {
"maxLength": 255,
"type": "string"
"type": "string",
"description": "\u003cp\u003eUsed to specify the template for the posts associated with the category.\u003c/p\u003e\n \u003cp\u003eThe priority is not as high as that of the post.\u003c/p\u003e\n \u003cp\u003eIf the post also specifies a template, the post\u0027s template will prevail.\u003c/p\u003e"
},
"preventParentPostCascadeQuery": {
"type": "boolean"
"type": "boolean",
"description": "\u003cp\u003eif a category is queried for related posts, the default behavior is to\n query all posts under the category including its subcategories, but if this field is\n set to true, cascade query behavior will be terminated here.\u003c/p\u003e\n \u003cp\u003eFor example, if a category has subcategories A and B, and A has subcategories C and\n D and C marked this field as true, when querying posts under A category,all posts under A\n and B will be queried, but C and D will not be queried.\u003c/p\u003e"
},
"priority": {
"type": "integer",
@ -3799,10 +3808,12 @@
},
"postCount": {
"type": "integer",
"description": "包括当前和其下所有层级的文章数量 (depth\u003dmax).",
"format": "int32"
},
"visiblePostCount": {
"type": "integer",
"description": "包括当前和其下所有层级的已发布且公开的文章数量 (depth\u003dmax).",
"format": "int32"
}
}
@ -3868,18 +3879,23 @@
"type": "object",
"properties": {
"avatar": {
"type": "string"
"type": "string",
"description": "avatar for comment owner"
},
"displayName": {
"type": "string"
"type": "string",
"description": "display name for comment owner"
},
"email": {
"type": "string"
"type": "string",
"description": "email for comment owner"
},
"website": {
"type": "string"
"type": "string",
"description": "website for comment owner"
}
}
},
"description": "\u003cp\u003eThe creator info of the comment.\u003c/p\u003e\n This {@link CommentEmailOwner CommentEmailOwner} is only applicable to the user who is allowed to comment\n without logging in."
},
"CommentOwner": {
"required": [
@ -3933,7 +3949,8 @@
"subjectRef": {
"$ref": "#/components/schemas/Ref"
}
}
},
"description": "Request parameter object for {@link Comment Comment}."
},
"CommentSpec": {
"required": [
@ -3967,6 +3984,7 @@
},
"creationTime": {
"type": "string",
"description": "The user-defined creation time default is \u003ccode\u003emetadata.creationTimestamp\u003c/code\u003e.",
"format": "date-time"
},
"hidden": {
@ -4011,7 +4029,8 @@
"type": "integer",
"format": "int32"
}
}
},
"description": "comment stats value object."
},
"CommentStatus": {
"type": "object",
@ -4051,19 +4070,23 @@
"properties": {
"lastTransitionTime": {
"type": "string",
"description": "Last time the condition transitioned from one status to another.",
"format": "date-time"
},
"message": {
"maxLength": 32768,
"type": "string"
"type": "string",
"description": "Human-readable message indicating details about last transition.\n This may be an empty string."
},
"reason": {
"maxLength": 1024,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
"type": "string",
"description": "Unique, one-word, CamelCase reason for the condition\u0027s last transition."
},
"status": {
"type": "string",
"description": "Status is the status of the condition. Can be True, False, Unknown.",
"enum": [
"TRUE",
"FALSE",
@ -4073,9 +4096,11 @@
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
"type": "string",
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.\n example: Ready, Initialized.\n maxLength: 316."
}
}
},
"description": "EqualsAndHashCode 排除了lastTransitionTime否则失败时lastTransitionTime 会被更新\n 导致 equals 为 false一直被加入队列."
},
"ConfigMap": {
"required": [
@ -4100,7 +4125,8 @@
"metadata": {
"$ref": "#/components/schemas/Metadata"
}
}
},
"description": "\u003cp\u003eConfigMap holds configuration data to consume.\u003c/p\u003e"
},
"ConfigMapRef": {
"required": [
@ -4175,7 +4201,8 @@
"name": {
"type": "string"
}
}
},
"description": "Contributor from user."
},
"CopyOperation": {
"required": [
@ -4322,7 +4349,8 @@
"type": "object",
"properties": {
"displayName": {
"type": "string"
"type": "string",
"description": "Gets email display name."
},
"enable": {
"type": "boolean"
@ -4341,7 +4369,8 @@
"format": "int32"
},
"sender": {
"type": "string"
"type": "string",
"description": "Gets email sender address."
},
"username": {
"type": "string"
@ -4391,7 +4420,8 @@
"metadata": {
"$ref": "#/components/schemas/Metadata"
}
}
},
"description": "Extension is an interface which represents an Extension. It contains setters and getters of\n GroupVersionKind and Metadata."
},
"GrantRequest": {
"type": "object",
@ -4487,7 +4517,8 @@
"url": {
"type": "string"
}
}
},
"description": "Common data objects for license."
},
"ListedAuthProvider": {
"required": [
@ -4546,7 +4577,8 @@
"website": {
"type": "string"
}
}
},
"description": "A listed value object for {@link run.halo.app.core.extension.AuthProvider run.halo.app.core.extension.AuthProvider}."
},
"ListedComment": {
"required": [
@ -4981,15 +5013,18 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Annotations are like key-value format."
},
"creationTimestamp": {
"type": "string",
"description": "Creation timestamp of the Extension.",
"format": "date-time",
"nullable": true
},
"deletionTimestamp": {
"type": "string",
"description": "Deletion timestamp of the Extension.",
"format": "date-time",
"nullable": true
},
@ -5010,7 +5045,8 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Labels are like key-value format."
},
"name": {
"type": "string",
@ -5018,10 +5054,12 @@
},
"version": {
"type": "integer",
"description": "Current version of the Extension. It will be bumped up every update.",
"format": "int64",
"nullable": true
}
}
},
"description": "Metadata of Extension."
},
"MoveOperation": {
"required": [
@ -5069,7 +5107,8 @@
"name": {
"type": "string"
}
}
},
"description": "Comment owner info."
},
"Plugin": {
"required": [
@ -5095,7 +5134,8 @@
"status": {
"$ref": "#/components/schemas/PluginStatus"
}
}
},
"description": "A custom resource for Plugin."
},
"PluginAuthor": {
"required": [
@ -5254,14 +5294,16 @@
"type": "string"
},
"requires": {
"type": "string"
"type": "string",
"description": "SemVer format."
},
"settingName": {
"type": "string"
},
"version": {
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
"type": "string"
"type": "string",
"description": "plugin version."
}
}
},
@ -5331,35 +5373,41 @@
"properties": {
"apiGroups": {
"type": "array",
"description": "APIGroups is the name of the APIGroup that contains the resources.\n If multiple API groups are specified, any action requested against one of the enumerated\n resources in any API group will be allowed.",
"items": {
"type": "string"
}
},
"nonResourceURLs": {
"type": "array",
"description": "NonResourceURLs is a set of partial urls that a user should have access to.\n *s are allowed, but only as the full, final step in the path\n If an action is not a resource API request, then the URL is split on \u0027/\u0027 and is checked\n against the NonResourceURLs to look for a match.\n Since non-resource URLs are not namespaced, this field is only applicable for\n ClusterRoles referenced from a ClusterRoleBinding.\n Rules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource\n URL paths (such as \"/api\"), but not both.",
"items": {
"type": "string"
}
},
"resourceNames": {
"type": "array",
"description": "ResourceNames is an optional white list of names that the rule applies to. An empty set\n means that everything is allowed.",
"items": {
"type": "string"
}
},
"resources": {
"type": "array",
"description": "Resources is a list of resources this rule applies to. \u0027*\u0027 represents all resources in\n the specified apiGroups.\n \u0027*\u0026#47;foo\u0027 represents the subresource \u0027foo\u0027 for all resources in the specified\n apiGroups.",
"items": {
"type": "string"
}
},
"verbs": {
"type": "array",
"description": "about who the rule applies to or which namespace the rule applies to.",
"items": {
"type": "string"
}
}
}
},
"description": "PolicyRule holds information that describes a policy rule, but does not contain information\n about whom the rule applies to or which namespace the rule applies to."
},
"Post": {
"required": [
@ -5385,7 +5433,8 @@
"status": {
"$ref": "#/components/schemas/PostStatus"
}
}
},
"description": "\u003cp\u003ePost extension.\u003c/p\u003e"
},
"PostRequest": {
"required": [
@ -5399,7 +5448,8 @@
"post": {
"$ref": "#/components/schemas/Post"
}
}
},
"description": "Post and content data for creating and updating post."
},
"PostSpec": {
"required": [
@ -5471,7 +5521,8 @@
"format": "date-time"
},
"releaseSnapshot": {
"type": "string"
"type": "string",
"description": "文章引用到的已发布的内容,用于主题端显示."
},
"slug": {
"minLength": 1,
@ -5529,7 +5580,8 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "see {@link Category.CategorySpec#isHideFromList Category.CategorySpec#isHideFromList()}."
},
"inProgress": {
"type": "boolean"
@ -5673,7 +5725,8 @@
"minLength": 1,
"type": "string"
}
}
},
"description": "A request parameter object for {@link Reply Reply}."
},
"ReplySpec": {
"required": [
@ -5711,6 +5764,7 @@
},
"creationTime": {
"type": "string",
"description": "The user-defined creation time default is \u003ccode\u003emetadata.creationTimestamp\u003c/code\u003e.",
"format": "date-time"
},
"hidden": {
@ -5845,7 +5899,8 @@
"spec": {
"$ref": "#/components/schemas/SettingSpec"
}
}
},
"description": "{@link Setting Setting} is a custom extension to generate forms based on configuration."
},
"SettingForm": {
"minLength": 1,
@ -5925,7 +5980,8 @@
"status": {
"$ref": "#/components/schemas/SinglePageStatus"
}
}
},
"description": "\u003cp\u003eSingle page extension.\u003c/p\u003e"
},
"SinglePageRequest": {
"required": [
@ -5940,7 +5996,8 @@
"page": {
"$ref": "#/components/schemas/SinglePage"
}
}
},
"description": "A request parameter for {@link SinglePage SinglePage}."
},
"SinglePageSpec": {
"required": [
@ -6006,7 +6063,8 @@
"format": "date-time"
},
"releaseSnapshot": {
"type": "string"
"type": "string",
"description": "引用到的已发布的内容,用于主题端显示."
},
"slug": {
"minLength": 1,
@ -6058,7 +6116,8 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "see {@link Category.CategorySpec#isHideFromList Category.CategorySpec#isHideFromList()}."
},
"inProgress": {
"type": "boolean"
@ -6098,7 +6157,8 @@
"type": "integer",
"format": "int32"
}
}
},
"description": "Stats value object."
},
"Tag": {
"required": [
@ -6195,7 +6255,8 @@
"properties": {
"color": {
"pattern": "^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$",
"type": "string"
"type": "string",
"description": "Color regex explanation.\n \u003cpre\u003e\n ^ # start of the line\n # # start with a number sign `#`\n ( # start of (group 1)\n [a-fA-F0-9]{6} # support z-f, A-F and 0-9, with a length of 6\n | # or\n [a-fA-F0-9]{3} # support z-f, A-F and 0-9, with a length of 3\n ) # end of (group 1)\n $ # end of the line\n \u003c/pre\u003e"
},
"cover": {
"type": "string"
@ -6251,7 +6312,8 @@
"screenshot": {
"type": "string"
}
}
},
"description": "Type used to describe custom template page."
},
"TestOperation": {
"required": [
@ -6302,7 +6364,8 @@
"status": {
"$ref": "#/components/schemas/ThemeStatus"
}
}
},
"description": "\u003cp\u003eTheme extension.\u003c/p\u003e"
},
"ThemeInstallRequest": {
"type": "object"
@ -6391,7 +6454,8 @@
"type": "string"
},
"homepage": {
"type": "string"
"type": "string",
"description": "Compatible with {@link run.halo.app.core.extension.Theme$ThemeSpec#website #website} property."
},
"issues": {
"type": "string"
@ -6414,7 +6478,8 @@
"deprecated": true
},
"requires": {
"type": "string"
"type": "string",
"description": "if requires is not empty, then return requires, else return require or \u003ccode\u003eWILDCARD\u003c/code\u003e."
},
"settingName": {
"type": "string"
@ -6525,7 +6590,8 @@
"status": {
"$ref": "#/components/schemas/UserStatus"
}
}
},
"description": "The extension represents user details of Halo."
},
"UserEndpoint.ListedUserList": {
"required": [

View File

@ -2,7 +2,7 @@
"openapi": "3.0.1",
"info": {
"title": "Halo",
"version": "2.20.11-SNAPSHOT"
"version": "2.21.0-SNAPSHOT"
},
"servers": [
{
@ -10025,7 +10025,8 @@
"spec": {
"$ref": "#/components/schemas/AuthProviderSpec"
}
}
},
"description": "Auth provider extension."
},
"AuthProviderList": {
"required": [
@ -10096,6 +10097,7 @@
"properties": {
"authType": {
"type": "string",
"description": "Auth type: form or oauth2.",
"enum": [
"FORM",
"OAUTH2"
@ -10267,7 +10269,8 @@
"type": "string"
},
"filename": {
"type": "string"
"type": "string",
"description": "Name of backup file."
},
"phase": {
"type": "string",
@ -10280,6 +10283,7 @@
},
"size": {
"type": "integer",
"description": "Size of backup file. Data unit: byte",
"format": "int64"
},
"startTimestamp": {
@ -10398,14 +10402,17 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "\u003cp\u003eWhether to hide the category from the category list.\u003c/p\u003e\n \u003cp\u003eWhen set to true, the category including its subcategories and related posts will\n not be displayed in the category list, but it can still be accessed by permalink.\u003c/p\u003e\n \u003cp\u003eLimitation: It only takes effect on the theme-side categorized list and it only\n allows to be set to true on the first level(root node) of categories.\u003c/p\u003e"
},
"postTemplate": {
"maxLength": 255,
"type": "string"
"type": "string",
"description": "\u003cp\u003eUsed to specify the template for the posts associated with the category.\u003c/p\u003e\n \u003cp\u003eThe priority is not as high as that of the post.\u003c/p\u003e\n \u003cp\u003eIf the post also specifies a template, the post\u0027s template will prevail.\u003c/p\u003e"
},
"preventParentPostCascadeQuery": {
"type": "boolean"
"type": "boolean",
"description": "\u003cp\u003eif a category is queried for related posts, the default behavior is to\n query all posts under the category including its subcategories, but if this field is\n set to true, cascade query behavior will be terminated here.\u003c/p\u003e\n \u003cp\u003eFor example, if a category has subcategories A and B, and A has subcategories C and\n D and C marked this field as true, when querying posts under A category,all posts under A\n and B will be queried, but C and D will not be queried.\u003c/p\u003e"
},
"priority": {
"type": "integer",
@ -10430,10 +10437,12 @@
},
"postCount": {
"type": "integer",
"description": "包括当前和其下所有层级的文章数量 (depth\u003dmax).",
"format": "int32"
},
"visiblePostCount": {
"type": "integer",
"description": "包括当前和其下所有层级的已发布且公开的文章数量 (depth\u003dmax).",
"format": "int32"
}
}
@ -10581,6 +10590,7 @@
},
"creationTime": {
"type": "string",
"description": "The user-defined creation time default is \u003ccode\u003emetadata.creationTimestamp\u003c/code\u003e.",
"format": "date-time"
},
"hidden": {
@ -10656,19 +10666,23 @@
"properties": {
"lastTransitionTime": {
"type": "string",
"description": "Last time the condition transitioned from one status to another.",
"format": "date-time"
},
"message": {
"maxLength": 32768,
"type": "string"
"type": "string",
"description": "Human-readable message indicating details about last transition.\n This may be an empty string."
},
"reason": {
"maxLength": 1024,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
"type": "string",
"description": "Unique, one-word, CamelCase reason for the condition\u0027s last transition."
},
"status": {
"type": "string",
"description": "Status is the status of the condition. Can be True, False, Unknown.",
"enum": [
"TRUE",
"FALSE",
@ -10678,9 +10692,11 @@
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
"type": "string",
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.\n example: Ready, Initialized.\n maxLength: 316."
}
}
},
"description": "EqualsAndHashCode 排除了lastTransitionTime否则失败时lastTransitionTime 会被更新\n 导致 equals 为 false一直被加入队列."
},
"ConfigMap": {
"required": [
@ -10705,7 +10721,8 @@
"metadata": {
"$ref": "#/components/schemas/Metadata"
}
}
},
"description": "\u003cp\u003eConfigMap holds configuration data to consume.\u003c/p\u003e"
},
"ConfigMapList": {
"required": [
@ -10843,7 +10860,8 @@
"type": "integer",
"format": "int32"
}
}
},
"description": "A counter for number of requests by extension resource name."
},
"CounterList": {
"required": [
@ -11097,7 +11115,8 @@
"spec": {
"$ref": "#/components/schemas/ExtensionSpec"
}
}
},
"description": "Extension definition.\n An {@link ExtensionDefinition ExtensionDefinition} is a type of metadata that provides additional information about\n an extension. An extension is a way to add new functionality to an existing class, structure,\n enumeration, or protocol type without needing to subclass it."
},
"ExtensionDefinitionList": {
"required": [
@ -11179,7 +11198,8 @@
"spec": {
"$ref": "#/components/schemas/ExtensionPointSpec"
}
}
},
"description": "Extension point definition.\n An {@link ExtensionPointDefinition ExtensionPointDefinition} is a concept used in \u003ccode\u003eHalo\u003c/code\u003e to allow for the\n dynamic extension of system. It defines a location within \u003ccode\u003eHalo\u003c/code\u003e where\n additional functionality can be added through the use of plugins or extensions."
},
"ExtensionPointDefinitionList": {
"required": [
@ -11335,12 +11355,15 @@
"type": "object",
"properties": {
"group": {
"type": "string"
"type": "string",
"description": "is group name of Extension."
},
"kind": {
"type": "string"
"type": "string",
"description": "is kind name of Extension."
}
}
},
"description": "GroupKind contains group and kind data only."
},
"GroupList": {
"required": [
@ -11509,7 +11532,8 @@
"url": {
"type": "string"
}
}
},
"description": "Common data objects for license."
},
"LocalThumbnail": {
"required": [
@ -11608,11 +11632,13 @@
"type": "object",
"properties": {
"filePath": {
"type": "string"
"type": "string",
"description": "Consider the compatibility of the system and migration, use unix-style relative paths\n here."
},
"imageSignature": {
"minLength": 1,
"type": "string"
"type": "string",
"description": "A hash signature for the image uri."
},
"imageUri": {
"minLength": 1,
@ -11629,7 +11655,8 @@
},
"thumbSignature": {
"minLength": 1,
"type": "string"
"type": "string",
"description": "A hash signature for the thumbnail uri."
},
"thumbnailUri": {
"minLength": 1,
@ -11931,15 +11958,18 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Annotations are like key-value format."
},
"creationTimestamp": {
"type": "string",
"description": "Creation timestamp of the Extension.",
"format": "date-time",
"nullable": true
},
"deletionTimestamp": {
"type": "string",
"description": "Deletion timestamp of the Extension.",
"format": "date-time",
"nullable": true
},
@ -11960,7 +11990,8 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Labels are like key-value format."
},
"name": {
"type": "string",
@ -11968,10 +11999,12 @@
},
"version": {
"type": "integer",
"description": "Current version of the Extension. It will be bumped up every update.",
"format": "int64",
"nullable": true
}
}
},
"description": "Metadata of Extension."
},
"MoveOperation": {
"required": [
@ -12021,7 +12054,8 @@
"spec": {
"$ref": "#/components/schemas/NotificationSpec"
}
}
},
"description": "\u003cp\u003e{@link Notification Notification} is a custom extension that used to store notification information for\n inner use, it\u0027s on-site notification.\u003c/p\u003e\n\n \u003cp\u003eSupports the following operations:\u003c/p\u003e\n \u003cul\u003e\n \u003cli\u003eMarked as read: {@link NotificationSpec#setUnread(boolean) NotificationSpec#setUnread(boolean)}\u003c/li\u003e\n \u003cli\u003eGet the last read time: {@link NotificationSpec#getLastReadAt NotificationSpec#getLastReadAt()}\u003c/li\u003e\n \u003cli\u003eFilter by recipient: {@link NotificationSpec#getRecipient NotificationSpec#getRecipient()}\u003c/li\u003e\n \u003c/ul\u003e"
},
"NotificationList": {
"required": [
@ -12141,7 +12175,8 @@
"spec": {
"$ref": "#/components/schemas/NotificationTemplateSpec"
}
}
},
"description": "\u003cp\u003e{@link NotificationTemplate NotificationTemplate} is a custom extension that defines a notification template.\u003c/p\u003e\n \u003cp\u003eIt describes the notification template\u0027s name, description, and the template content.\u003c/p\u003e\n \u003cp\u003e{@link Spec#getReasonSelector Spec#getReasonSelector()} is used to select the template by reasonType and language,\n if multiple templates are matched, the best match will be selected. This is useful when you\n want to override the default template.\u003c/p\u003e"
},
"NotificationTemplateList": {
"required": [
@ -12233,7 +12268,8 @@
"spec": {
"$ref": "#/components/schemas/NotifierDescriptorSpec"
}
}
},
"description": "\u003cp\u003e{@link NotifierDescriptor NotifierDescriptor} is a custom extension that defines a notifier.\u003c/p\u003e\n \u003cp\u003eIt describes the notifier\u0027s name, description, and the extension name of the notifier to\n let the user know what the notifier is and what it can do in the UI and also let the\n \u003ccode\u003eNotificationCenter\u003c/code\u003e know how to load the notifier and prepare the notifier\u0027s settings.\u003c/p\u003e"
},
"NotifierDescriptorList": {
"required": [
@ -12489,7 +12525,8 @@
"status": {
"$ref": "#/components/schemas/PluginStatus"
}
}
},
"description": "A custom resource for Plugin."
},
"PluginAuthor": {
"required": [
@ -12615,14 +12652,16 @@
"type": "string"
},
"requires": {
"type": "string"
"type": "string",
"description": "SemVer format."
},
"settingName": {
"type": "string"
},
"version": {
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
"type": "string"
"type": "string",
"description": "plugin version."
}
}
},
@ -12774,35 +12813,41 @@
"properties": {
"apiGroups": {
"type": "array",
"description": "APIGroups is the name of the APIGroup that contains the resources.\n If multiple API groups are specified, any action requested against one of the enumerated\n resources in any API group will be allowed.",
"items": {
"type": "string"
}
},
"nonResourceURLs": {
"type": "array",
"description": "NonResourceURLs is a set of partial urls that a user should have access to.\n *s are allowed, but only as the full, final step in the path\n If an action is not a resource API request, then the URL is split on \u0027/\u0027 and is checked\n against the NonResourceURLs to look for a match.\n Since non-resource URLs are not namespaced, this field is only applicable for\n ClusterRoles referenced from a ClusterRoleBinding.\n Rules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource\n URL paths (such as \"/api\"), but not both.",
"items": {
"type": "string"
}
},
"resourceNames": {
"type": "array",
"description": "ResourceNames is an optional white list of names that the rule applies to. An empty set\n means that everything is allowed.",
"items": {
"type": "string"
}
},
"resources": {
"type": "array",
"description": "Resources is a list of resources this rule applies to. \u0027*\u0027 represents all resources in\n the specified apiGroups.\n \u0027*\u0026#47;foo\u0027 represents the subresource \u0027foo\u0027 for all resources in the specified\n apiGroups.",
"items": {
"type": "string"
}
},
"verbs": {
"type": "array",
"description": "about who the rule applies to or which namespace the rule applies to.",
"items": {
"type": "string"
}
}
}
},
"description": "PolicyRule holds information that describes a policy rule, but does not contain information\n about whom the rule applies to or which namespace the rule applies to."
},
"PolicySpec": {
"required": [
@ -12944,7 +12989,8 @@
"status": {
"$ref": "#/components/schemas/PostStatus"
}
}
},
"description": "\u003cp\u003ePost extension.\u003c/p\u003e"
},
"PostList": {
"required": [
@ -13075,7 +13121,8 @@
"format": "date-time"
},
"releaseSnapshot": {
"type": "string"
"type": "string",
"description": "文章引用到的已发布的内容,用于主题端显示."
},
"slug": {
"minLength": 1,
@ -13133,7 +13180,8 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "see {@link Category.CategorySpec#isHideFromList Category.CategorySpec#isHideFromList()}."
},
"inProgress": {
"type": "boolean"
@ -13174,7 +13222,8 @@
"spec": {
"$ref": "#/components/schemas/ReasonSpec"
}
}
},
"description": "\u003cp\u003e{@link Reason Reason} is a custom extension that defines a reason for a notification, It represents\n an instance of a {@link ReasonType ReasonType}.\u003c/p\u003e\n \u003cp\u003eIt can be understood as an event that triggers a notification.\u003c/p\u003e"
},
"ReasonAttributes": {
"type": "object",
@ -13354,7 +13403,8 @@
"spec": {
"$ref": "#/components/schemas/ReasonTypeSpec"
}
}
},
"description": "\u003cp\u003e{@link ReasonType ReasonType} is a custom extension that defines a type of reason.\u003c/p\u003e\n \u003cp\u003eOne {@link ReasonType ReasonType} can have multiple {@link Reason Reason}s to notify.\u003c/p\u003e"
},
"ReasonTypeList": {
"required": [
@ -13739,6 +13789,7 @@
},
"creationTime": {
"type": "string",
"description": "The user-defined creation time default is \u003ccode\u003emetadata.creationTimestamp\u003c/code\u003e.",
"format": "date-time"
},
"hidden": {
@ -13804,7 +13855,8 @@
"$ref": "#/components/schemas/ReverseProxyRule"
}
}
}
},
"description": "\u003cp\u003eThe reverse proxy custom resource is used to configure a path to proxy it to a directory or\n file.\u003c/p\u003e\n \u003cp\u003eHTTP proxy may be added in the future.\u003c/p\u003e"
},
"ReverseProxyList": {
"required": [
@ -13924,11 +13976,13 @@
},
"subjects": {
"type": "array",
"description": "Subjects holds references to the objects the role applies to.",
"items": {
"$ref": "#/components/schemas/Subject"
}
}
}
},
"description": "RoleBinding references a role, but does not contain it.\n It can reference a Role in the global.\n It adds who information via Subjects."
},
"RoleBindingList": {
"required": [
@ -14052,15 +14106,19 @@
"type": "object",
"properties": {
"apiGroup": {
"type": "string"
"type": "string",
"description": "APIGroup is the group for the resource being referenced."
},
"kind": {
"type": "string"
"type": "string",
"description": "Kind is the type of resource being referenced."
},
"name": {
"type": "string"
"type": "string",
"description": "Name is the name of resource being referenced."
}
}
},
"description": "RoleRef contains information that points to the role being used."
},
"SearchEngine": {
"required": [
@ -14083,7 +14141,8 @@
"spec": {
"$ref": "#/components/schemas/SearchEngineSpec"
}
}
},
"description": "Search engine extension."
},
"SearchEngineList": {
"required": [
@ -14186,7 +14245,8 @@
"additionalProperties": {
"type": "string",
"format": "byte"
}
},
"description": "\u003cp\u003eThe total bytes of the values in\n the Data field must be less than {@link run.halo.app.extension.Secret#MAX_SECRET_SIZE #MAX_SECRET_SIZE} bytes.\u003c/p\u003e\n \u003cp\u003e\u003ccode\u003edata\u003c/code\u003e contains the secret data. Each key must consist of alphanumeric\n characters, \u0027-\u0027, \u0027_\u0027 or \u0027.\u0027. The serialized form of the secret data is a\n base64 encoded string, representing the arbitrary (possibly non-string)\n data value here. Described in\n \u003ca href\u003d\"https://tools.ietf.org/html/rfc4648#section-4\"\u003erfc4648#section-4\u003c/a\u003e\n \u003c/p\u003e"
},
"kind": {
"type": "string"
@ -14198,12 +14258,15 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "\u003ccode\u003estringData\u003c/code\u003e allows specifying non-binary secret data in string form.\n It is provided as a write-only input field for convenience.\n All keys and values are merged into the data field on write, overwriting any existing\n values.\n The stringData field is never output when reading from the API."
},
"type": {
"type": "string"
"type": "string",
"description": "Used to facilitate programmatic handling of secret data.\n More info:\n \u003ca href\u003d\"https://kubernetes.io/docs/concepts/configuration/secret/#secret-types\"\u003esecret-types\u003c/a\u003e"
}
}
},
"description": "Secret is a small piece of sensitive data which should be kept secret, such as a password,\n a token, or a key."
},
"SecretList": {
"required": [
@ -14285,7 +14348,8 @@
"spec": {
"$ref": "#/components/schemas/SettingSpec"
}
}
},
"description": "{@link Setting Setting} is a custom extension to generate forms based on configuration."
},
"SettingForm": {
"minLength": 1,
@ -14424,7 +14488,8 @@
"status": {
"$ref": "#/components/schemas/SinglePageStatus"
}
}
},
"description": "\u003cp\u003eSingle page extension.\u003c/p\u003e"
},
"SinglePageList": {
"required": [
@ -14549,7 +14614,8 @@
"format": "date-time"
},
"releaseSnapshot": {
"type": "string"
"type": "string",
"description": "引用到的已发布的内容,用于主题端显示."
},
"slug": {
"minLength": 1,
@ -14601,7 +14667,8 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "see {@link Category.CategorySpec#isHideFromList Category.CategorySpec#isHideFromList()}."
},
"inProgress": {
"type": "boolean"
@ -14657,7 +14724,8 @@
"rawType": {
"maxLength": 50,
"minLength": 1,
"type": "string"
"type": "string",
"description": "such as: markdown | html | json | asciidoc | latex."
},
"subjectRef": {
"$ref": "#/components/schemas/Ref"
@ -14750,13 +14818,16 @@
"type": "object",
"properties": {
"apiGroup": {
"type": "string"
"type": "string",
"description": "APIGroup holds the API group of the referenced subject.\n Defaults to \"\" for ServiceAccount subjects.\n Defaults to \"rbac.authorization.halo.run\" for User and Group subjects."
},
"kind": {
"type": "string"
"type": "string",
"description": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\",\n and \"ServiceAccount\".\n If the Authorizer does not recognize the kind value, the Authorizer should report\n an error."
},
"name": {
"type": "string"
"type": "string",
"description": "Name of the object being referenced."
}
}
},
@ -14780,7 +14851,8 @@
"spec": {
"$ref": "#/components/schemas/SubscriptionSpec"
}
}
},
"description": "\u003cp\u003e{@link Subscription Subscription} is a custom extension that defines a subscriber to be notified when a\n certain {@link Reason Reason} is triggered.\u003c/p\u003e\n \u003cp\u003eIt holds a {@link Subscriber Subscriber} to the user to be notified, a {@link InterestReason InterestReason} to\n subscribe to.\u003c/p\u003e"
},
"SubscriptionList": {
"required": [
@ -14972,7 +15044,8 @@
"properties": {
"color": {
"pattern": "^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$",
"type": "string"
"type": "string",
"description": "Color regex explanation.\n \u003cpre\u003e\n ^ # start of the line\n # # start with a number sign `#`\n ( # start of (group 1)\n [a-fA-F0-9]{6} # support z-f, A-F and 0-9, with a length of 6\n | # or\n [a-fA-F0-9]{3} # support z-f, A-F and 0-9, with a length of 3\n ) # end of (group 1)\n $ # end of the line\n \u003c/pre\u003e"
},
"cover": {
"type": "string"
@ -15046,7 +15119,8 @@
"screenshot": {
"type": "string"
}
}
},
"description": "Type used to describe custom template page."
},
"TestOperation": {
"required": [
@ -15097,7 +15171,8 @@
"status": {
"$ref": "#/components/schemas/ThemeStatus"
}
}
},
"description": "\u003cp\u003eTheme extension.\u003c/p\u003e"
},
"ThemeList": {
"required": [
@ -15183,7 +15258,8 @@
"type": "string"
},
"homepage": {
"type": "string"
"type": "string",
"description": "Compatible with {@link run.halo.app.core.extension.Theme$ThemeSpec#website #website} property."
},
"issues": {
"type": "string"
@ -15206,7 +15282,8 @@
"deprecated": true
},
"requires": {
"type": "string"
"type": "string",
"description": "if requires is not empty, then return requires, else return require or \u003ccode\u003eWILDCARD\u003c/code\u003e."
},
"settingName": {
"type": "string"
@ -15385,7 +15462,8 @@
"status": {
"$ref": "#/components/schemas/UserStatus"
}
}
},
"description": "The extension represents user details of Halo."
},
"UserConnection": {
"required": [
@ -15408,7 +15486,8 @@
"spec": {
"$ref": "#/components/schemas/UserConnectionSpec"
}
}
},
"description": "User connection extension."
},
"UserConnectionList": {
"required": [
@ -15478,17 +15557,21 @@
"type": "object",
"properties": {
"providerUserId": {
"type": "string"
"type": "string",
"description": "The unique identifier for the user\u0027s connection to the OAuth provider.\n for example, the user\u0027s GitHub id."
},
"registrationId": {
"type": "string"
"type": "string",
"description": "The name of the OAuth provider (e.g. Google, Facebook, Twitter)."
},
"updatedAt": {
"type": "string",
"description": "The time when the user connection was last updated.",
"format": "date-time"
},
"username": {
"type": "string"
"type": "string",
"description": "The {@link Metadata#getName Metadata#getName()} of the user associated with the OAuth connection."
}
}
},

View File

@ -2,7 +2,7 @@
"openapi": "3.0.1",
"info": {
"title": "Halo",
"version": "2.20.11-SNAPSHOT"
"version": "2.21.0-SNAPSHOT"
},
"servers": [
{
@ -1297,14 +1297,17 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "\u003cp\u003eWhether to hide the category from the category list.\u003c/p\u003e\n \u003cp\u003eWhen set to true, the category including its subcategories and related posts will\n not be displayed in the category list, but it can still be accessed by permalink.\u003c/p\u003e\n \u003cp\u003eLimitation: It only takes effect on the theme-side categorized list and it only\n allows to be set to true on the first level(root node) of categories.\u003c/p\u003e"
},
"postTemplate": {
"maxLength": 255,
"type": "string"
"type": "string",
"description": "\u003cp\u003eUsed to specify the template for the posts associated with the category.\u003c/p\u003e\n \u003cp\u003eThe priority is not as high as that of the post.\u003c/p\u003e\n \u003cp\u003eIf the post also specifies a template, the post\u0027s template will prevail.\u003c/p\u003e"
},
"preventParentPostCascadeQuery": {
"type": "boolean"
"type": "boolean",
"description": "\u003cp\u003eif a category is queried for related posts, the default behavior is to\n query all posts under the category including its subcategories, but if this field is\n set to true, cascade query behavior will be terminated here.\u003c/p\u003e\n \u003cp\u003eFor example, if a category has subcategories A and B, and A has subcategories C and\n D and C marked this field as true, when querying posts under A category,all posts under A\n and B will be queried, but C and D will not be queried.\u003c/p\u003e"
},
"priority": {
"type": "integer",
@ -1329,10 +1332,12 @@
},
"postCount": {
"type": "integer",
"description": "包括当前和其下所有层级的文章数量 (depth\u003dmax).",
"format": "int32"
},
"visiblePostCount": {
"type": "integer",
"description": "包括当前和其下所有层级的已发布且公开的文章数量 (depth\u003dmax).",
"format": "int32"
}
}
@ -1356,7 +1361,8 @@
"status": {
"$ref": "#/components/schemas/CategoryStatus"
}
}
},
"description": "A value object for {@link Category Category}."
},
"CategoryVoList": {
"required": [
@ -1447,18 +1453,23 @@
"type": "object",
"properties": {
"avatar": {
"type": "string"
"type": "string",
"description": "avatar for comment owner"
},
"displayName": {
"type": "string"
"type": "string",
"description": "display name for comment owner"
},
"email": {
"type": "string"
"type": "string",
"description": "email for comment owner"
},
"website": {
"type": "string"
"type": "string",
"description": "website for comment owner"
}
}
},
"description": "\u003cp\u003eThe creator info of the comment.\u003c/p\u003e\n This {@link CommentEmailOwner CommentEmailOwner} is only applicable to the user who is allowed to comment\n without logging in."
},
"CommentOwner": {
"required": [
@ -1512,7 +1523,8 @@
"subjectRef": {
"$ref": "#/components/schemas/Ref"
}
}
},
"description": "Request parameter object for {@link Comment Comment}."
},
"CommentSpec": {
"required": [
@ -1546,6 +1558,7 @@
},
"creationTime": {
"type": "string",
"description": "The user-defined creation time default is \u003ccode\u003emetadata.creationTimestamp\u003c/code\u003e.",
"format": "date-time"
},
"hidden": {
@ -1590,7 +1603,8 @@
"type": "integer",
"format": "int32"
}
}
},
"description": "comment stats value object."
},
"CommentStatus": {
"type": "object",
@ -1805,19 +1819,23 @@
"properties": {
"lastTransitionTime": {
"type": "string",
"description": "Last time the condition transitioned from one status to another.",
"format": "date-time"
},
"message": {
"maxLength": 32768,
"type": "string"
"type": "string",
"description": "Human-readable message indicating details about last transition.\n This may be an empty string."
},
"reason": {
"maxLength": 1024,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
"type": "string",
"description": "Unique, one-word, CamelCase reason for the condition\u0027s last transition."
},
"status": {
"type": "string",
"description": "Status is the status of the condition. Can be True, False, Unknown.",
"enum": [
"TRUE",
"FALSE",
@ -1827,9 +1845,11 @@
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
"type": "string",
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.\n example: Ready, Initialized.\n maxLength: 316."
}
}
},
"description": "EqualsAndHashCode 排除了lastTransitionTime否则失败时lastTransitionTime 会被更新\n 导致 equals 为 false一直被加入队列."
},
"ContentVo": {
"type": "object",
@ -1840,7 +1860,8 @@
"raw": {
"type": "string"
}
}
},
"description": "A value object for Content from {@link Snapshot Snapshot}."
},
"ContributorVo": {
"required": [
@ -1866,7 +1887,8 @@
"permalink": {
"type": "string"
}
}
},
"description": "A value object for {@link run.halo.app.core.extension.User run.halo.app.core.extension.User}."
},
"CopyOperation": {
"required": [
@ -1953,62 +1975,79 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Custom metadata. Make sure the map is serializable."
},
"categories": {
"type": "array",
"description": "Document categories. The item in the list is the category metadata name.",
"items": {
"type": "string"
}
},
"content": {
"type": "string"
"type": "string",
"description": "Document content. Safety content, without HTML tag."
},
"creationTimestamp": {
"type": "string",
"description": "Document creation timestamp.",
"format": "date-time"
},
"description": {
"type": "string"
"type": "string",
"description": "Document description."
},
"exposed": {
"type": "boolean"
"type": "boolean",
"description": "Whether the document is exposed to the public."
},
"id": {
"type": "string"
"type": "string",
"description": "Document ID. It should be unique globally."
},
"metadataName": {
"type": "string"
"type": "string",
"description": "Metadata name of the corresponding extension."
},
"ownerName": {
"type": "string"
"type": "string",
"description": "Document owner metadata name."
},
"permalink": {
"type": "string"
"type": "string",
"description": "Document permalink."
},
"published": {
"type": "boolean"
"type": "boolean",
"description": "Whether the document is published."
},
"recycled": {
"type": "boolean"
"type": "boolean",
"description": "Whether the document is recycled."
},
"tags": {
"type": "array",
"description": "Document tags. The item in the list is the tag metadata name.",
"items": {
"type": "string"
}
},
"title": {
"type": "string"
"type": "string",
"description": "Document title."
},
"type": {
"type": "string"
"type": "string",
"description": "Document type. e.g.: post.content.halo.run, singlepage.content.halo.run, moment.moment\n .halo.run, doc.doc.halo.run."
},
"updateTimestamp": {
"type": "string",
"description": "Document update timestamp.",
"format": "date-time"
}
}
},
"description": "Document for search."
},
"JsonPatch": {
"minItems": 1,
@ -2136,7 +2175,8 @@
"$ref": "#/components/schemas/TagVo"
}
}
}
},
"description": "A value object for {@link Post Post}."
},
"ListedPostVoList": {
"required": [
@ -2346,7 +2386,8 @@
"type": "object",
"properties": {
"displayName": {
"type": "string"
"type": "string",
"description": "Gets menu item\u0027s display name."
},
"metadata": {
"$ref": "#/components/schemas/Metadata"
@ -2360,7 +2401,8 @@
"status": {
"$ref": "#/components/schemas/MenuItemStatus"
}
}
},
"description": "A value object for {@link MenuItem MenuItem}."
},
"MenuSpec": {
"required": [
@ -2401,7 +2443,8 @@
"spec": {
"$ref": "#/components/schemas/MenuSpec"
}
}
},
"description": "A value object for {@link Menu Menu}."
},
"Metadata": {
"required": [
@ -2413,15 +2456,18 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Annotations are like key-value format."
},
"creationTimestamp": {
"type": "string",
"description": "Creation timestamp of the Extension.",
"format": "date-time",
"nullable": true
},
"deletionTimestamp": {
"type": "string",
"description": "Deletion timestamp of the Extension.",
"format": "date-time",
"nullable": true
},
@ -2442,7 +2488,8 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Labels are like key-value format."
},
"name": {
"type": "string",
@ -2450,10 +2497,12 @@
},
"version": {
"type": "integer",
"description": "Current version of the Extension. It will be bumped up every update.",
"format": "int64",
"nullable": true
}
}
},
"description": "Metadata of Extension."
},
"MoveOperation": {
"required": [
@ -2495,7 +2544,8 @@
"previous": {
"$ref": "#/components/schemas/PostVo"
}
}
},
"description": "Post navigation vo to hold previous and next item."
},
"OwnerInfo": {
"type": "object",
@ -2515,7 +2565,8 @@
"name": {
"type": "string"
}
}
},
"description": "Comment owner info."
},
"PostSpec": {
"required": [
@ -2587,7 +2638,8 @@
"format": "date-time"
},
"releaseSnapshot": {
"type": "string"
"type": "string",
"description": "文章引用到的已发布的内容,用于主题端显示."
},
"slug": {
"minLength": 1,
@ -2645,7 +2697,8 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "see {@link Category.CategorySpec#isHideFromList Category.CategorySpec#isHideFromList()}."
},
"inProgress": {
"type": "boolean"
@ -2708,7 +2761,8 @@
"$ref": "#/components/schemas/TagVo"
}
}
}
},
"description": "A value object for {@link Post Post}."
},
"Ref": {
"required": [
@ -2833,7 +2887,8 @@
"minLength": 1,
"type": "string"
}
}
},
"description": "A request parameter object for {@link Reply Reply}."
},
"ReplySpec": {
"required": [
@ -2871,6 +2926,7 @@
},
"creationTime": {
"type": "string",
"description": "The user-defined creation time default is \u003ccode\u003emetadata.creationTimestamp\u003c/code\u003e.",
"format": "date-time"
},
"hidden": {
@ -3006,57 +3062,70 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Additional annotations for extending search option by other search engines."
},
"filterExposed": {
"type": "boolean"
"type": "boolean",
"description": "Whether to filter exposed content. If null, it will not filter."
},
"filterPublished": {
"type": "boolean"
"type": "boolean",
"description": "Whether to filter published content. If null, it will not filter."
},
"filterRecycled": {
"type": "boolean"
"type": "boolean",
"description": "Whether to filter recycled content. If null, it will not filter."
},
"highlightPostTag": {
"type": "string"
"type": "string",
"description": "Post HTML tag of highlighted fragment."
},
"highlightPreTag": {
"type": "string"
"type": "string",
"description": "Pre HTML tag of highlighted fragment."
},
"includeCategoryNames": {
"type": "array",
"description": "Category names to include(and). If null, it will include all categories.",
"items": {
"type": "string"
}
},
"includeOwnerNames": {
"type": "array",
"description": "Owner names to include(or). If null, it will include all owners.",
"items": {
"type": "string"
}
},
"includeTagNames": {
"type": "array",
"description": "Tag names to include(and). If null, it will include all tags.",
"items": {
"type": "string"
}
},
"includeTypes": {
"type": "array",
"description": "Types to include(or). If null, it will include all types.",
"items": {
"type": "string"
}
},
"keyword": {
"type": "string"
"type": "string",
"description": "Search keyword."
},
"limit": {
"maximum": 1000,
"minimum": 1,
"type": "integer",
"description": "Limit of result.",
"format": "int32"
}
}
},
"description": "Search option. It is used to control search behavior."
},
"SearchResult": {
"type": "object",
@ -3148,7 +3217,8 @@
"format": "date-time"
},
"releaseSnapshot": {
"type": "string"
"type": "string",
"description": "引用到的已发布的内容,用于主题端显示."
},
"slug": {
"minLength": 1,
@ -3200,7 +3270,8 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "see {@link Category.CategorySpec#isHideFromList Category.CategorySpec#isHideFromList()}."
},
"inProgress": {
"type": "boolean"
@ -3251,7 +3322,8 @@
"status": {
"$ref": "#/components/schemas/SinglePageStatus"
}
}
},
"description": "A value object for {@link SinglePage SinglePage}."
},
"SiteStatsVo": {
"type": "object",
@ -3276,7 +3348,8 @@
"type": "integer",
"format": "int32"
}
}
},
"description": "A value object for site stats."
},
"StatsVo": {
"type": "object",
@ -3293,7 +3366,8 @@
"type": "integer",
"format": "int32"
}
}
},
"description": "Stats value object."
},
"TagSpec": {
"required": [
@ -3304,7 +3378,8 @@
"properties": {
"color": {
"pattern": "^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$",
"type": "string"
"type": "string",
"description": "Color regex explanation.\n \u003cpre\u003e\n ^ # start of the line\n # # start with a number sign `#`\n ( # start of (group 1)\n [a-fA-F0-9]{6} # support z-f, A-F and 0-9, with a length of 6\n | # or\n [a-fA-F0-9]{3} # support z-f, A-F and 0-9, with a length of 3\n ) # end of (group 1)\n $ # end of the line\n \u003c/pre\u003e"
},
"cover": {
"type": "string"
@ -3358,7 +3433,8 @@
"status": {
"$ref": "#/components/schemas/TagStatus"
}
}
},
"description": "A value object for {@link Tag Tag}."
},
"TagVoList": {
"required": [

View File

@ -2,7 +2,7 @@
"openapi": "3.0.1",
"info": {
"title": "Halo",
"version": "2.20.11-SNAPSHOT"
"version": "2.21.0-SNAPSHOT"
},
"servers": [
{
@ -1597,14 +1597,17 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "\u003cp\u003eWhether to hide the category from the category list.\u003c/p\u003e\n \u003cp\u003eWhen set to true, the category including its subcategories and related posts will\n not be displayed in the category list, but it can still be accessed by permalink.\u003c/p\u003e\n \u003cp\u003eLimitation: It only takes effect on the theme-side categorized list and it only\n allows to be set to true on the first level(root node) of categories.\u003c/p\u003e"
},
"postTemplate": {
"maxLength": 255,
"type": "string"
"type": "string",
"description": "\u003cp\u003eUsed to specify the template for the posts associated with the category.\u003c/p\u003e\n \u003cp\u003eThe priority is not as high as that of the post.\u003c/p\u003e\n \u003cp\u003eIf the post also specifies a template, the post\u0027s template will prevail.\u003c/p\u003e"
},
"preventParentPostCascadeQuery": {
"type": "boolean"
"type": "boolean",
"description": "\u003cp\u003eif a category is queried for related posts, the default behavior is to\n query all posts under the category including its subcategories, but if this field is\n set to true, cascade query behavior will be terminated here.\u003c/p\u003e\n \u003cp\u003eFor example, if a category has subcategories A and B, and A has subcategories C and\n D and C marked this field as true, when querying posts under A category,all posts under A\n and B will be queried, but C and D will not be queried.\u003c/p\u003e"
},
"priority": {
"type": "integer",
@ -1629,10 +1632,12 @@
},
"postCount": {
"type": "integer",
"description": "包括当前和其下所有层级的文章数量 (depth\u003dmax).",
"format": "int32"
},
"visiblePostCount": {
"type": "integer",
"description": "包括当前和其下所有层级的已发布且公开的文章数量 (depth\u003dmax).",
"format": "int32"
}
}
@ -1647,19 +1652,23 @@
"properties": {
"lastTransitionTime": {
"type": "string",
"description": "Last time the condition transitioned from one status to another.",
"format": "date-time"
},
"message": {
"maxLength": 32768,
"type": "string"
"type": "string",
"description": "Human-readable message indicating details about last transition.\n This may be an empty string."
},
"reason": {
"maxLength": 1024,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
"type": "string",
"description": "Unique, one-word, CamelCase reason for the condition\u0027s last transition."
},
"status": {
"type": "string",
"description": "Status is the status of the condition. Can be True, False, Unknown.",
"enum": [
"TRUE",
"FALSE",
@ -1669,9 +1678,11 @@
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
"type": "string",
"description": "type of condition in CamelCase or in foo.example.com/CamelCase.\n example: Ready, Initialized.\n maxLength: 316."
}
}
},
"description": "EqualsAndHashCode 排除了lastTransitionTime否则失败时lastTransitionTime 会被更新\n 导致 equals 为 false一直被加入队列."
},
"Contributor": {
"type": "object",
@ -1685,7 +1696,8 @@
"name": {
"type": "string"
}
}
},
"description": "Contributor from user."
},
"CopyOperation": {
"required": [
@ -1954,15 +1966,18 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Annotations are like key-value format."
},
"creationTimestamp": {
"type": "string",
"description": "Creation timestamp of the Extension.",
"format": "date-time",
"nullable": true
},
"deletionTimestamp": {
"type": "string",
"description": "Deletion timestamp of the Extension.",
"format": "date-time",
"nullable": true
},
@ -1983,7 +1998,8 @@
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"description": "Labels are like key-value format."
},
"name": {
"type": "string",
@ -1991,10 +2007,12 @@
},
"version": {
"type": "integer",
"description": "Current version of the Extension. It will be bumped up every update.",
"format": "int64",
"nullable": true
}
}
},
"description": "Metadata of Extension."
},
"MoveOperation": {
"required": [
@ -2044,7 +2062,8 @@
"spec": {
"$ref": "#/components/schemas/NotificationSpec"
}
}
},
"description": "\u003cp\u003e{@link Notification Notification} is a custom extension that used to store notification information for\n inner use, it\u0027s on-site notification.\u003c/p\u003e\n\n \u003cp\u003eSupports the following operations:\u003c/p\u003e\n \u003cul\u003e\n \u003cli\u003eMarked as read: {@link NotificationSpec#setUnread(boolean) NotificationSpec#setUnread(boolean)}\u003c/li\u003e\n \u003cli\u003eGet the last read time: {@link NotificationSpec#getLastReadAt NotificationSpec#getLastReadAt()}\u003c/li\u003e\n \u003cli\u003eFilter by recipient: {@link NotificationSpec#getRecipient NotificationSpec#getRecipient()}\u003c/li\u003e\n \u003c/ul\u003e"
},
"NotificationList": {
"required": [
@ -2267,7 +2286,8 @@
"status": {
"$ref": "#/components/schemas/PostStatus"
}
}
},
"description": "\u003cp\u003ePost extension.\u003c/p\u003e"
},
"PostAttachmentRequest": {
"required": [
@ -2359,7 +2379,8 @@
"format": "date-time"
},
"releaseSnapshot": {
"type": "string"
"type": "string",
"description": "文章引用到的已发布的内容,用于主题端显示."
},
"slug": {
"minLength": 1,
@ -2417,7 +2438,8 @@
"type": "string"
},
"hideFromList": {
"type": "boolean"
"type": "boolean",
"description": "see {@link Category.CategorySpec#isHideFromList Category.CategorySpec#isHideFromList()}."
},
"inProgress": {
"type": "boolean"
@ -2619,7 +2641,8 @@
"rawType": {
"maxLength": 50,
"minLength": 1,
"type": "string"
"type": "string",
"description": "such as: markdown | html | json | asciidoc | latex."
},
"subjectRef": {
"$ref": "#/components/schemas/Ref"
@ -2668,7 +2691,8 @@
"type": "integer",
"format": "int32"
}
}
},
"description": "Stats value object."
},
"Tag": {
"required": [
@ -2705,7 +2729,8 @@
"properties": {
"color": {
"pattern": "^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$",
"type": "string"
"type": "string",
"description": "Color regex explanation.\n \u003cpre\u003e\n ^ # start of the line\n # # start with a number sign `#`\n ( # start of (group 1)\n [a-fA-F0-9]{6} # support z-f, A-F and 0-9, with a length of 6\n | # or\n [a-fA-F0-9]{3} # support z-f, A-F and 0-9, with a length of 3\n ) # end of (group 1)\n $ # end of the line\n \u003c/pre\u003e"
},
"cover": {
"type": "string"
@ -2770,6 +2795,7 @@
"properties": {
"authLink": {
"type": "string",
"description": "QR Code with base64 encoded.",
"format": "uri"
},
"rawSecret": {
@ -2800,7 +2826,8 @@
"type": "object",
"properties": {
"available": {
"type": "boolean"
"type": "boolean",
"description": "Check if 2FA is available."
},
"emailVerified": {
"type": "boolean"
@ -2882,7 +2909,8 @@
"spec": {
"$ref": "#/components/schemas/UserConnectionSpec"
}
}
},
"description": "User connection extension."
},
"UserConnectionSpec": {
"required": [
@ -2893,17 +2921,21 @@
"type": "object",
"properties": {
"providerUserId": {
"type": "string"
"type": "string",
"description": "The unique identifier for the user\u0027s connection to the OAuth provider.\n for example, the user\u0027s GitHub id."
},
"registrationId": {
"type": "string"
"type": "string",
"description": "The name of the OAuth provider (e.g. Google, Facebook, Twitter)."
},
"updatedAt": {
"type": "string",
"description": "The time when the user connection was last updated.",
"format": "date-time"
},
"username": {
"type": "string"
"type": "string",
"description": "The {@link Metadata#getName Metadata#getName()} of the user associated with the OAuth connection."
}
}
},

View File

@ -9,9 +9,15 @@ plugins {
group = 'run.halo.app'
description = 'API of halo project, connecting by other projects.'
tasks.withType(JavaCompile).configureEach {
options.release = 21
options.encoding = 'UTF-8'
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
compileJava.options.encoding = "UTF-8"

View File

@ -17,12 +17,16 @@ plugins {
}
group = 'run.halo.app'
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
tasks.withType(JavaCompile).configureEach {
options.release = 21
options.encoding = 'UTF-8'
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
idea {
@ -101,7 +105,7 @@ tasks.register('createChecksums', Checksum) {
checksumAlgorithm = Checksum.Algorithm.SHA256
}
tasks.named('processResources', ProcessResources) {
tasks.register('copyUiDist', Copy) {
from project(':ui').layout.buildDirectory.dir('dist')
into layout.buildDirectory.dir('resources/main')
configure {
@ -109,6 +113,10 @@ tasks.named('processResources', ProcessResources) {
}
}
tasks.named('processResources', ProcessResources) {
dependsOn tasks.named('copyUiDist')
}
tasks.named('build') {
dependsOn tasks.named('createChecksums')
}

View File

@ -724,6 +724,7 @@ public class UserEndpoint implements CustomEndpoint {
Optional.ofNullable(getKeyword())
.filter(StringUtils::isNotBlank)
.ifPresent(keyword -> builder.andQuery(or(
equal("spec.email", keyword),
contains("spec.displayName", keyword),
equal("metadata.name", keyword)
)));

View File

@ -1,2 +1,2 @@
version=2.20.11-SNAPSHOT
version=2.21.0-SNAPSHOT
r2dbc-mysql.version=1.4.0

Binary file not shown.

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

4
gradlew vendored
View File

@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.

4
gradlew.bat vendored
View File

@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell

View File

@ -1,6 +1,6 @@
{
"name": "@halo-dev/api-client",
"version": "2.20.21",
"version": "2.21.0",
"description": "API Client for Halo 2",
"homepage": "https://github.com/halo-dev/halo/tree/main/ui/packages/api-client#readme",
"bugs": {

View File

@ -1,6 +1,6 @@
{
"name": "@halo-dev/components",
"version": "2.20.21",
"version": "2.21.0",
"description": "",
"files": [
"dist"

View File

@ -1,6 +1,6 @@
{
"name": "@halo-dev/richtext-editor",
"version": "2.20.21",
"version": "2.21.0",
"description": "Default editor for Halo",
"homepage": "https://github.com/halo-dev/halo/tree/main/ui/packages/editor#readme",
"bugs": {

View File

@ -1,6 +1,6 @@
{
"name": "@halo-dev/console-shared",
"version": "2.20.21",
"version": "2.21.0",
"description": "",
"files": [
"dist"

View File

@ -1,6 +1,6 @@
{
"name": "@halo-dev/ui-plugin-bundler-kit",
"version": "2.20.21",
"version": "2.21.0",
"homepage": "https://github.com/halo-dev/halo/tree/main/ui/packages/ui-plugin-bundler-kit#readme",
"bugs": {
"url": "https://github.com/halo-dev/halo/issues"