mirror of
https://github.com/halo-dev/plugin-starter.git
synced 2025-10-19 18:34:12 +00:00
Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c81ec5a2ae | ||
![]() |
e31b994a7f | ||
![]() |
d7629caa1f | ||
![]() |
5a4a25db25 | ||
![]() |
0574a0ea32 | ||
![]() |
b302131c52 | ||
![]() |
dad7849964 | ||
![]() |
bf58bf0637 | ||
![]() |
c891124c6f | ||
![]() |
9f04f1bce7 | ||
![]() |
b3179920ae | ||
![]() |
e9ef894f21 | ||
![]() |
e3bf74f8db | ||
![]() |
6f7d9367cf | ||
![]() |
1182e9497d | ||
![]() |
eb3a128324 | ||
![]() |
ba473f75e4 | ||
![]() |
5d1f25e771 | ||
![]() |
a2986389b1 | ||
![]() |
0dc49191a1 | ||
![]() |
a9735da1f6 | ||
![]() |
b67187a9d2 | ||
![]() |
339f72d11f | ||
![]() |
b82aa9316b | ||
![]() |
6f8b3ddd8a | ||
![]() |
54a6a695c2 | ||
![]() |
43c88472fc | ||
![]() |
d4c6584435 | ||
![]() |
d37eba069c |
510
.editorconfig
Normal file
510
.editorconfig
Normal file
@@ -0,0 +1,510 @@
|
|||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = false
|
||||||
|
max_line_length = 120
|
||||||
|
tab_width = 4
|
||||||
|
ij_continuation_indent_size = 8
|
||||||
|
ij_formatter_off_tag = @formatter:off
|
||||||
|
ij_formatter_on_tag = @formatter:on
|
||||||
|
ij_formatter_tags_enabled = false
|
||||||
|
ij_smart_tabs = false
|
||||||
|
ij_wrap_on_typing = false
|
||||||
|
|
||||||
|
[*.java]
|
||||||
|
max_line_length = 100
|
||||||
|
ij_continuation_indent_size = 4
|
||||||
|
ij_java_align_consecutive_assignments = false
|
||||||
|
ij_java_align_consecutive_variable_declarations = false
|
||||||
|
ij_java_align_group_field_declarations = false
|
||||||
|
ij_java_align_multiline_annotation_parameters = false
|
||||||
|
ij_java_align_multiline_array_initializer_expression = false
|
||||||
|
ij_java_align_multiline_assignment = false
|
||||||
|
ij_java_align_multiline_binary_operation = false
|
||||||
|
ij_java_align_multiline_chained_methods = false
|
||||||
|
ij_java_align_multiline_extends_list = false
|
||||||
|
ij_java_align_multiline_for = true
|
||||||
|
ij_java_align_multiline_method_parentheses = false
|
||||||
|
ij_java_align_multiline_parameters = false
|
||||||
|
ij_java_align_multiline_parameters_in_calls = false
|
||||||
|
ij_java_align_multiline_parenthesized_expression = false
|
||||||
|
ij_java_align_multiline_records = true
|
||||||
|
ij_java_align_multiline_resources = true
|
||||||
|
ij_java_align_multiline_ternary_operation = false
|
||||||
|
ij_java_align_multiline_text_blocks = false
|
||||||
|
ij_java_align_multiline_throws_list = false
|
||||||
|
ij_java_align_subsequent_simple_methods = false
|
||||||
|
ij_java_align_throws_keyword = false
|
||||||
|
ij_java_annotation_parameter_wrap = off
|
||||||
|
ij_java_array_initializer_new_line_after_left_brace = false
|
||||||
|
ij_java_array_initializer_right_brace_on_new_line = false
|
||||||
|
ij_java_array_initializer_wrap = normal
|
||||||
|
ij_java_assert_statement_colon_on_next_line = false
|
||||||
|
ij_java_assert_statement_wrap = normal
|
||||||
|
ij_java_assignment_wrap = normal
|
||||||
|
ij_java_binary_operation_sign_on_next_line = true
|
||||||
|
ij_java_binary_operation_wrap = normal
|
||||||
|
ij_java_blank_lines_after_anonymous_class_header = 0
|
||||||
|
ij_java_blank_lines_after_class_header = 0
|
||||||
|
ij_java_blank_lines_after_imports = 1
|
||||||
|
ij_java_blank_lines_after_package = 1
|
||||||
|
ij_java_blank_lines_around_class = 1
|
||||||
|
ij_java_blank_lines_around_field = 0
|
||||||
|
ij_java_blank_lines_around_field_in_interface = 0
|
||||||
|
ij_java_blank_lines_around_initializer = 1
|
||||||
|
ij_java_blank_lines_around_method = 1
|
||||||
|
ij_java_blank_lines_around_method_in_interface = 1
|
||||||
|
ij_java_blank_lines_before_class_end = 0
|
||||||
|
ij_java_blank_lines_before_imports = 0
|
||||||
|
ij_java_blank_lines_before_method_body = 0
|
||||||
|
ij_java_blank_lines_before_package = 1
|
||||||
|
ij_java_block_brace_style = end_of_line
|
||||||
|
ij_java_block_comment_at_first_column = false
|
||||||
|
ij_java_call_parameters_new_line_after_left_paren = false
|
||||||
|
ij_java_call_parameters_right_paren_on_new_line = false
|
||||||
|
ij_java_call_parameters_wrap = normal
|
||||||
|
ij_java_case_statement_on_separate_line = true
|
||||||
|
ij_java_catch_on_new_line = false
|
||||||
|
ij_java_class_annotation_wrap = split_into_lines
|
||||||
|
ij_java_class_brace_style = end_of_line
|
||||||
|
ij_java_class_count_to_use_import_on_demand = 999
|
||||||
|
ij_java_class_names_in_javadoc = 1
|
||||||
|
ij_java_do_not_indent_top_level_class_members = false
|
||||||
|
ij_java_do_not_wrap_after_single_annotation = false
|
||||||
|
ij_java_do_while_brace_force = always
|
||||||
|
ij_java_doc_add_blank_line_after_description = true
|
||||||
|
ij_java_doc_add_blank_line_after_param_comments = false
|
||||||
|
ij_java_doc_add_blank_line_after_return = false
|
||||||
|
ij_java_doc_add_p_tag_on_empty_lines = true
|
||||||
|
ij_java_doc_align_exception_comments = true
|
||||||
|
ij_java_doc_align_param_comments = false
|
||||||
|
ij_java_doc_do_not_wrap_if_one_line = false
|
||||||
|
ij_java_doc_enable_formatting = true
|
||||||
|
ij_java_doc_enable_leading_asterisks = true
|
||||||
|
ij_java_doc_indent_on_continuation = false
|
||||||
|
ij_java_doc_keep_empty_lines = true
|
||||||
|
ij_java_doc_keep_empty_parameter_tag = true
|
||||||
|
ij_java_doc_keep_empty_return_tag = true
|
||||||
|
ij_java_doc_keep_empty_throws_tag = true
|
||||||
|
ij_java_doc_keep_invalid_tags = true
|
||||||
|
ij_java_doc_param_description_on_new_line = false
|
||||||
|
ij_java_doc_preserve_line_breaks = false
|
||||||
|
ij_java_doc_use_throws_not_exception_tag = true
|
||||||
|
ij_java_else_on_new_line = false
|
||||||
|
ij_java_enum_constants_wrap = normal
|
||||||
|
ij_java_extends_keyword_wrap = normal
|
||||||
|
ij_java_extends_list_wrap = normal
|
||||||
|
ij_java_field_annotation_wrap = split_into_lines
|
||||||
|
ij_java_finally_on_new_line = false
|
||||||
|
ij_java_for_brace_force = always
|
||||||
|
ij_java_for_statement_new_line_after_left_paren = false
|
||||||
|
ij_java_for_statement_right_paren_on_new_line = false
|
||||||
|
ij_java_for_statement_wrap = normal
|
||||||
|
ij_java_generate_final_locals = false
|
||||||
|
ij_java_generate_final_parameters = false
|
||||||
|
ij_java_if_brace_force = always
|
||||||
|
ij_java_imports_layout = $*, |, *, |, *
|
||||||
|
ij_java_indent_case_from_switch = true
|
||||||
|
ij_java_insert_inner_class_imports = false
|
||||||
|
ij_java_insert_override_annotation = true
|
||||||
|
ij_java_keep_blank_lines_before_right_brace = 2
|
||||||
|
ij_java_keep_blank_lines_between_package_declaration_and_header = 2
|
||||||
|
ij_java_keep_blank_lines_in_code = 2
|
||||||
|
ij_java_keep_blank_lines_in_declarations = 2
|
||||||
|
ij_java_keep_control_statement_in_one_line = true
|
||||||
|
ij_java_keep_first_column_comment = true
|
||||||
|
ij_java_keep_indents_on_empty_lines = false
|
||||||
|
ij_java_keep_line_breaks = true
|
||||||
|
ij_java_keep_multiple_expressions_in_one_line = false
|
||||||
|
ij_java_keep_simple_blocks_in_one_line = false
|
||||||
|
ij_java_keep_simple_classes_in_one_line = false
|
||||||
|
ij_java_keep_simple_lambdas_in_one_line = false
|
||||||
|
ij_java_keep_simple_methods_in_one_line = false
|
||||||
|
ij_java_label_indent_absolute = false
|
||||||
|
ij_java_label_indent_size = 0
|
||||||
|
ij_java_lambda_brace_style = end_of_line
|
||||||
|
ij_java_layout_static_imports_separately = true
|
||||||
|
ij_java_line_comment_add_space = true
|
||||||
|
ij_java_line_comment_at_first_column = false
|
||||||
|
ij_java_method_annotation_wrap = split_into_lines
|
||||||
|
ij_java_method_brace_style = end_of_line
|
||||||
|
ij_java_method_call_chain_wrap = normal
|
||||||
|
ij_java_method_parameters_new_line_after_left_paren = false
|
||||||
|
ij_java_method_parameters_right_paren_on_new_line = false
|
||||||
|
ij_java_method_parameters_wrap = normal
|
||||||
|
ij_java_modifier_list_wrap = false
|
||||||
|
ij_java_names_count_to_use_import_on_demand = 999
|
||||||
|
ij_java_new_line_after_lparen_in_record_header = false
|
||||||
|
ij_java_parameter_annotation_wrap = normal
|
||||||
|
ij_java_parentheses_expression_new_line_after_left_paren = false
|
||||||
|
ij_java_parentheses_expression_right_paren_on_new_line = false
|
||||||
|
ij_java_place_assignment_sign_on_next_line = false
|
||||||
|
ij_java_prefer_longer_names = true
|
||||||
|
ij_java_prefer_parameters_wrap = false
|
||||||
|
ij_java_record_components_wrap = normal
|
||||||
|
ij_java_repeat_synchronized = true
|
||||||
|
ij_java_replace_instanceof_and_cast = false
|
||||||
|
ij_java_replace_null_check = true
|
||||||
|
ij_java_replace_sum_lambda_with_method_ref = true
|
||||||
|
ij_java_resource_list_new_line_after_left_paren = false
|
||||||
|
ij_java_resource_list_right_paren_on_new_line = false
|
||||||
|
ij_java_resource_list_wrap = normal
|
||||||
|
ij_java_rparen_on_new_line_in_record_header = false
|
||||||
|
ij_java_space_after_closing_angle_bracket_in_type_argument = false
|
||||||
|
ij_java_space_after_colon = true
|
||||||
|
ij_java_space_after_comma = true
|
||||||
|
ij_java_space_after_comma_in_type_arguments = true
|
||||||
|
ij_java_space_after_for_semicolon = true
|
||||||
|
ij_java_space_after_quest = true
|
||||||
|
ij_java_space_after_type_cast = true
|
||||||
|
ij_java_space_before_annotation_array_initializer_left_brace = false
|
||||||
|
ij_java_space_before_annotation_parameter_list = false
|
||||||
|
ij_java_space_before_array_initializer_left_brace = true
|
||||||
|
ij_java_space_before_catch_keyword = true
|
||||||
|
ij_java_space_before_catch_left_brace = true
|
||||||
|
ij_java_space_before_catch_parentheses = true
|
||||||
|
ij_java_space_before_class_left_brace = true
|
||||||
|
ij_java_space_before_colon = true
|
||||||
|
ij_java_space_before_colon_in_foreach = true
|
||||||
|
ij_java_space_before_comma = false
|
||||||
|
ij_java_space_before_do_left_brace = true
|
||||||
|
ij_java_space_before_else_keyword = true
|
||||||
|
ij_java_space_before_else_left_brace = true
|
||||||
|
ij_java_space_before_finally_keyword = true
|
||||||
|
ij_java_space_before_finally_left_brace = true
|
||||||
|
ij_java_space_before_for_left_brace = true
|
||||||
|
ij_java_space_before_for_parentheses = true
|
||||||
|
ij_java_space_before_for_semicolon = false
|
||||||
|
ij_java_space_before_if_left_brace = true
|
||||||
|
ij_java_space_before_if_parentheses = true
|
||||||
|
ij_java_space_before_method_call_parentheses = false
|
||||||
|
ij_java_space_before_method_left_brace = true
|
||||||
|
ij_java_space_before_method_parentheses = false
|
||||||
|
ij_java_space_before_opening_angle_bracket_in_type_parameter = false
|
||||||
|
ij_java_space_before_quest = true
|
||||||
|
ij_java_space_before_switch_left_brace = true
|
||||||
|
ij_java_space_before_switch_parentheses = true
|
||||||
|
ij_java_space_before_synchronized_left_brace = true
|
||||||
|
ij_java_space_before_synchronized_parentheses = true
|
||||||
|
ij_java_space_before_try_left_brace = true
|
||||||
|
ij_java_space_before_try_parentheses = true
|
||||||
|
ij_java_space_before_type_parameter_list = false
|
||||||
|
ij_java_space_before_while_keyword = true
|
||||||
|
ij_java_space_before_while_left_brace = true
|
||||||
|
ij_java_space_before_while_parentheses = true
|
||||||
|
ij_java_space_inside_one_line_enum_braces = false
|
||||||
|
ij_java_space_within_empty_array_initializer_braces = false
|
||||||
|
ij_java_space_within_empty_method_call_parentheses = false
|
||||||
|
ij_java_space_within_empty_method_parentheses = false
|
||||||
|
ij_java_spaces_around_additive_operators = true
|
||||||
|
ij_java_spaces_around_assignment_operators = true
|
||||||
|
ij_java_spaces_around_bitwise_operators = true
|
||||||
|
ij_java_spaces_around_equality_operators = true
|
||||||
|
ij_java_spaces_around_lambda_arrow = true
|
||||||
|
ij_java_spaces_around_logical_operators = true
|
||||||
|
ij_java_spaces_around_method_ref_dbl_colon = false
|
||||||
|
ij_java_spaces_around_multiplicative_operators = true
|
||||||
|
ij_java_spaces_around_relational_operators = true
|
||||||
|
ij_java_spaces_around_shift_operators = true
|
||||||
|
ij_java_spaces_around_type_bounds_in_type_parameters = true
|
||||||
|
ij_java_spaces_around_unary_operator = false
|
||||||
|
ij_java_spaces_within_angle_brackets = false
|
||||||
|
ij_java_spaces_within_annotation_parentheses = false
|
||||||
|
ij_java_spaces_within_array_initializer_braces = false
|
||||||
|
ij_java_spaces_within_braces = false
|
||||||
|
ij_java_spaces_within_brackets = false
|
||||||
|
ij_java_spaces_within_cast_parentheses = false
|
||||||
|
ij_java_spaces_within_catch_parentheses = false
|
||||||
|
ij_java_spaces_within_for_parentheses = false
|
||||||
|
ij_java_spaces_within_if_parentheses = false
|
||||||
|
ij_java_spaces_within_method_call_parentheses = false
|
||||||
|
ij_java_spaces_within_method_parentheses = false
|
||||||
|
ij_java_spaces_within_parentheses = false
|
||||||
|
ij_java_spaces_within_switch_parentheses = false
|
||||||
|
ij_java_spaces_within_synchronized_parentheses = false
|
||||||
|
ij_java_spaces_within_try_parentheses = false
|
||||||
|
ij_java_spaces_within_while_parentheses = false
|
||||||
|
ij_java_special_else_if_treatment = true
|
||||||
|
ij_java_subclass_name_suffix = Impl
|
||||||
|
ij_java_ternary_operation_signs_on_next_line = true
|
||||||
|
ij_java_ternary_operation_wrap = normal
|
||||||
|
ij_java_test_name_suffix = Test
|
||||||
|
ij_java_throws_keyword_wrap = normal
|
||||||
|
ij_java_throws_list_wrap = normal
|
||||||
|
ij_java_use_external_annotations = false
|
||||||
|
ij_java_use_fq_class_names = false
|
||||||
|
ij_java_use_relative_indents = false
|
||||||
|
ij_java_use_single_class_imports = true
|
||||||
|
ij_java_variable_annotation_wrap = normal
|
||||||
|
ij_java_visibility = public
|
||||||
|
ij_java_while_brace_force = always
|
||||||
|
ij_java_while_on_new_line = false
|
||||||
|
ij_java_wrap_comments = false
|
||||||
|
ij_java_wrap_first_method_in_call_chain = false
|
||||||
|
ij_java_wrap_long_lines = true
|
||||||
|
|
||||||
|
[*.properties]
|
||||||
|
ij_properties_align_group_field_declarations = false
|
||||||
|
ij_properties_keep_blank_lines = false
|
||||||
|
ij_properties_key_value_delimiter = equals
|
||||||
|
ij_properties_spaces_around_key_value_delimiter = false
|
||||||
|
|
||||||
|
[.editorconfig]
|
||||||
|
ij_editorconfig_align_group_field_declarations = false
|
||||||
|
ij_editorconfig_space_after_colon = false
|
||||||
|
ij_editorconfig_space_after_comma = true
|
||||||
|
ij_editorconfig_space_before_colon = false
|
||||||
|
ij_editorconfig_space_before_comma = false
|
||||||
|
ij_editorconfig_spaces_around_assignment_operators = true
|
||||||
|
|
||||||
|
[{*.ant, *.fxml, *.jhm, *.jnlp, *.jrxml, *.jspx, *.pom, *.rng, *.tagx, *.tld, *.wsdl, *.xml, *.xsd, *.xsl, *.xslt, *.xul}]
|
||||||
|
ij_xml_align_attributes = true
|
||||||
|
ij_xml_align_text = false
|
||||||
|
ij_xml_attribute_wrap = normal
|
||||||
|
ij_xml_block_comment_at_first_column = true
|
||||||
|
ij_xml_keep_blank_lines = 2
|
||||||
|
ij_xml_keep_indents_on_empty_lines = false
|
||||||
|
ij_xml_keep_line_breaks = true
|
||||||
|
ij_xml_keep_line_breaks_in_text = true
|
||||||
|
ij_xml_keep_whitespaces = false
|
||||||
|
ij_xml_keep_whitespaces_around_cdata = preserve
|
||||||
|
ij_xml_keep_whitespaces_inside_cdata = false
|
||||||
|
ij_xml_line_comment_at_first_column = true
|
||||||
|
ij_xml_space_after_tag_name = false
|
||||||
|
ij_xml_space_around_equals_in_attribute = false
|
||||||
|
ij_xml_space_inside_empty_tag = false
|
||||||
|
ij_xml_text_wrap = normal
|
||||||
|
|
||||||
|
[{*.bash, *.sh, *.zsh}]
|
||||||
|
indent_size = 2
|
||||||
|
tab_width = 2
|
||||||
|
ij_shell_binary_ops_start_line = false
|
||||||
|
ij_shell_keep_column_alignment_padding = false
|
||||||
|
ij_shell_minify_program = false
|
||||||
|
ij_shell_redirect_followed_by_space = false
|
||||||
|
ij_shell_switch_cases_indented = false
|
||||||
|
|
||||||
|
[{*.gant, *.gradle, *.groovy, *.gy}]
|
||||||
|
ij_groovy_align_group_field_declarations = false
|
||||||
|
ij_groovy_align_multiline_array_initializer_expression = false
|
||||||
|
ij_groovy_align_multiline_assignment = false
|
||||||
|
ij_groovy_align_multiline_binary_operation = false
|
||||||
|
ij_groovy_align_multiline_chained_methods = false
|
||||||
|
ij_groovy_align_multiline_extends_list = false
|
||||||
|
ij_groovy_align_multiline_for = true
|
||||||
|
ij_groovy_align_multiline_list_or_map = true
|
||||||
|
ij_groovy_align_multiline_method_parentheses = false
|
||||||
|
ij_groovy_align_multiline_parameters = true
|
||||||
|
ij_groovy_align_multiline_parameters_in_calls = false
|
||||||
|
ij_groovy_align_multiline_resources = true
|
||||||
|
ij_groovy_align_multiline_ternary_operation = false
|
||||||
|
ij_groovy_align_multiline_throws_list = false
|
||||||
|
ij_groovy_align_named_args_in_map = true
|
||||||
|
ij_groovy_align_throws_keyword = false
|
||||||
|
ij_groovy_array_initializer_new_line_after_left_brace = false
|
||||||
|
ij_groovy_array_initializer_right_brace_on_new_line = false
|
||||||
|
ij_groovy_array_initializer_wrap = off
|
||||||
|
ij_groovy_assert_statement_wrap = off
|
||||||
|
ij_groovy_assignment_wrap = off
|
||||||
|
ij_groovy_binary_operation_wrap = off
|
||||||
|
ij_groovy_blank_lines_after_class_header = 0
|
||||||
|
ij_groovy_blank_lines_after_imports = 1
|
||||||
|
ij_groovy_blank_lines_after_package = 1
|
||||||
|
ij_groovy_blank_lines_around_class = 1
|
||||||
|
ij_groovy_blank_lines_around_field = 0
|
||||||
|
ij_groovy_blank_lines_around_field_in_interface = 0
|
||||||
|
ij_groovy_blank_lines_around_method = 1
|
||||||
|
ij_groovy_blank_lines_around_method_in_interface = 1
|
||||||
|
ij_groovy_blank_lines_before_imports = 1
|
||||||
|
ij_groovy_blank_lines_before_method_body = 0
|
||||||
|
ij_groovy_blank_lines_before_package = 0
|
||||||
|
ij_groovy_block_brace_style = end_of_line
|
||||||
|
ij_groovy_block_comment_at_first_column = true
|
||||||
|
ij_groovy_call_parameters_new_line_after_left_paren = false
|
||||||
|
ij_groovy_call_parameters_right_paren_on_new_line = false
|
||||||
|
ij_groovy_call_parameters_wrap = off
|
||||||
|
ij_groovy_catch_on_new_line = false
|
||||||
|
ij_groovy_class_annotation_wrap = split_into_lines
|
||||||
|
ij_groovy_class_brace_style = end_of_line
|
||||||
|
ij_groovy_class_count_to_use_import_on_demand = 5
|
||||||
|
ij_groovy_do_while_brace_force = never
|
||||||
|
ij_groovy_else_on_new_line = false
|
||||||
|
ij_groovy_enum_constants_wrap = off
|
||||||
|
ij_groovy_extends_keyword_wrap = off
|
||||||
|
ij_groovy_extends_list_wrap = off
|
||||||
|
ij_groovy_field_annotation_wrap = split_into_lines
|
||||||
|
ij_groovy_finally_on_new_line = false
|
||||||
|
ij_groovy_for_brace_force = never
|
||||||
|
ij_groovy_for_statement_new_line_after_left_paren = false
|
||||||
|
ij_groovy_for_statement_right_paren_on_new_line = false
|
||||||
|
ij_groovy_for_statement_wrap = off
|
||||||
|
ij_groovy_if_brace_force = never
|
||||||
|
ij_groovy_import_annotation_wrap = 2
|
||||||
|
ij_groovy_indent_case_from_switch = true
|
||||||
|
ij_groovy_indent_label_blocks = true
|
||||||
|
ij_groovy_insert_inner_class_imports = false
|
||||||
|
ij_groovy_keep_blank_lines_before_right_brace = 2
|
||||||
|
ij_groovy_keep_blank_lines_in_code = 2
|
||||||
|
ij_groovy_keep_blank_lines_in_declarations = 2
|
||||||
|
ij_groovy_keep_control_statement_in_one_line = true
|
||||||
|
ij_groovy_keep_first_column_comment = true
|
||||||
|
ij_groovy_keep_indents_on_empty_lines = false
|
||||||
|
ij_groovy_keep_line_breaks = true
|
||||||
|
ij_groovy_keep_multiple_expressions_in_one_line = false
|
||||||
|
ij_groovy_keep_simple_blocks_in_one_line = false
|
||||||
|
ij_groovy_keep_simple_classes_in_one_line = true
|
||||||
|
ij_groovy_keep_simple_lambdas_in_one_line = true
|
||||||
|
ij_groovy_keep_simple_methods_in_one_line = true
|
||||||
|
ij_groovy_label_indent_absolute = false
|
||||||
|
ij_groovy_label_indent_size = 0
|
||||||
|
ij_groovy_lambda_brace_style = end_of_line
|
||||||
|
ij_groovy_layout_static_imports_separately = true
|
||||||
|
ij_groovy_line_comment_add_space = false
|
||||||
|
ij_groovy_line_comment_at_first_column = true
|
||||||
|
ij_groovy_method_annotation_wrap = split_into_lines
|
||||||
|
ij_groovy_method_brace_style = end_of_line
|
||||||
|
ij_groovy_method_call_chain_wrap = off
|
||||||
|
ij_groovy_method_parameters_new_line_after_left_paren = false
|
||||||
|
ij_groovy_method_parameters_right_paren_on_new_line = false
|
||||||
|
ij_groovy_method_parameters_wrap = off
|
||||||
|
ij_groovy_modifier_list_wrap = false
|
||||||
|
ij_groovy_names_count_to_use_import_on_demand = 3
|
||||||
|
ij_groovy_parameter_annotation_wrap = off
|
||||||
|
ij_groovy_parentheses_expression_new_line_after_left_paren = false
|
||||||
|
ij_groovy_parentheses_expression_right_paren_on_new_line = false
|
||||||
|
ij_groovy_prefer_parameters_wrap = false
|
||||||
|
ij_groovy_resource_list_new_line_after_left_paren = false
|
||||||
|
ij_groovy_resource_list_right_paren_on_new_line = false
|
||||||
|
ij_groovy_resource_list_wrap = off
|
||||||
|
ij_groovy_space_after_assert_separator = true
|
||||||
|
ij_groovy_space_after_colon = true
|
||||||
|
ij_groovy_space_after_comma = true
|
||||||
|
ij_groovy_space_after_comma_in_type_arguments = true
|
||||||
|
ij_groovy_space_after_for_semicolon = true
|
||||||
|
ij_groovy_space_after_quest = true
|
||||||
|
ij_groovy_space_after_type_cast = true
|
||||||
|
ij_groovy_space_before_annotation_parameter_list = false
|
||||||
|
ij_groovy_space_before_array_initializer_left_brace = false
|
||||||
|
ij_groovy_space_before_assert_separator = false
|
||||||
|
ij_groovy_space_before_catch_keyword = true
|
||||||
|
ij_groovy_space_before_catch_left_brace = true
|
||||||
|
ij_groovy_space_before_catch_parentheses = true
|
||||||
|
ij_groovy_space_before_class_left_brace = true
|
||||||
|
ij_groovy_space_before_closure_left_brace = true
|
||||||
|
ij_groovy_space_before_colon = true
|
||||||
|
ij_groovy_space_before_comma = false
|
||||||
|
ij_groovy_space_before_do_left_brace = true
|
||||||
|
ij_groovy_space_before_else_keyword = true
|
||||||
|
ij_groovy_space_before_else_left_brace = true
|
||||||
|
ij_groovy_space_before_finally_keyword = true
|
||||||
|
ij_groovy_space_before_finally_left_brace = true
|
||||||
|
ij_groovy_space_before_for_left_brace = true
|
||||||
|
ij_groovy_space_before_for_parentheses = true
|
||||||
|
ij_groovy_space_before_for_semicolon = false
|
||||||
|
ij_groovy_space_before_if_left_brace = true
|
||||||
|
ij_groovy_space_before_if_parentheses = true
|
||||||
|
ij_groovy_space_before_method_call_parentheses = false
|
||||||
|
ij_groovy_space_before_method_left_brace = true
|
||||||
|
ij_groovy_space_before_method_parentheses = false
|
||||||
|
ij_groovy_space_before_quest = true
|
||||||
|
ij_groovy_space_before_switch_left_brace = true
|
||||||
|
ij_groovy_space_before_switch_parentheses = true
|
||||||
|
ij_groovy_space_before_synchronized_left_brace = true
|
||||||
|
ij_groovy_space_before_synchronized_parentheses = true
|
||||||
|
ij_groovy_space_before_try_left_brace = true
|
||||||
|
ij_groovy_space_before_try_parentheses = true
|
||||||
|
ij_groovy_space_before_while_keyword = true
|
||||||
|
ij_groovy_space_before_while_left_brace = true
|
||||||
|
ij_groovy_space_before_while_parentheses = true
|
||||||
|
ij_groovy_space_in_named_argument = true
|
||||||
|
ij_groovy_space_in_named_argument_before_colon = false
|
||||||
|
ij_groovy_space_within_empty_array_initializer_braces = false
|
||||||
|
ij_groovy_space_within_empty_method_call_parentheses = false
|
||||||
|
ij_groovy_spaces_around_additive_operators = true
|
||||||
|
ij_groovy_spaces_around_assignment_operators = true
|
||||||
|
ij_groovy_spaces_around_bitwise_operators = true
|
||||||
|
ij_groovy_spaces_around_equality_operators = true
|
||||||
|
ij_groovy_spaces_around_lambda_arrow = true
|
||||||
|
ij_groovy_spaces_around_logical_operators = true
|
||||||
|
ij_groovy_spaces_around_multiplicative_operators = true
|
||||||
|
ij_groovy_spaces_around_regex_operators = true
|
||||||
|
ij_groovy_spaces_around_relational_operators = true
|
||||||
|
ij_groovy_spaces_around_shift_operators = true
|
||||||
|
ij_groovy_spaces_within_annotation_parentheses = false
|
||||||
|
ij_groovy_spaces_within_array_initializer_braces = false
|
||||||
|
ij_groovy_spaces_within_braces = true
|
||||||
|
ij_groovy_spaces_within_brackets = false
|
||||||
|
ij_groovy_spaces_within_cast_parentheses = false
|
||||||
|
ij_groovy_spaces_within_catch_parentheses = false
|
||||||
|
ij_groovy_spaces_within_for_parentheses = false
|
||||||
|
ij_groovy_spaces_within_gstring_injection_braces = false
|
||||||
|
ij_groovy_spaces_within_if_parentheses = false
|
||||||
|
ij_groovy_spaces_within_list_or_map = false
|
||||||
|
ij_groovy_spaces_within_method_call_parentheses = false
|
||||||
|
ij_groovy_spaces_within_method_parentheses = false
|
||||||
|
ij_groovy_spaces_within_parentheses = false
|
||||||
|
ij_groovy_spaces_within_switch_parentheses = false
|
||||||
|
ij_groovy_spaces_within_synchronized_parentheses = false
|
||||||
|
ij_groovy_spaces_within_try_parentheses = false
|
||||||
|
ij_groovy_spaces_within_tuple_expression = false
|
||||||
|
ij_groovy_spaces_within_while_parentheses = false
|
||||||
|
ij_groovy_special_else_if_treatment = true
|
||||||
|
ij_groovy_ternary_operation_wrap = off
|
||||||
|
ij_groovy_throws_keyword_wrap = off
|
||||||
|
ij_groovy_throws_list_wrap = off
|
||||||
|
ij_groovy_use_flying_geese_braces = false
|
||||||
|
ij_groovy_use_fq_class_names = false
|
||||||
|
ij_groovy_use_fq_class_names_in_javadoc = true
|
||||||
|
ij_groovy_use_relative_indents = false
|
||||||
|
ij_groovy_use_single_class_imports = true
|
||||||
|
ij_groovy_variable_annotation_wrap = off
|
||||||
|
ij_groovy_while_brace_force = never
|
||||||
|
ij_groovy_while_on_new_line = false
|
||||||
|
ij_groovy_wrap_long_lines = false
|
||||||
|
|
||||||
|
[{*.har, *.json}]
|
||||||
|
indent_size = 2
|
||||||
|
ij_json_keep_blank_lines_in_code = 0
|
||||||
|
ij_json_keep_indents_on_empty_lines = false
|
||||||
|
ij_json_keep_line_breaks = true
|
||||||
|
ij_json_space_after_colon = true
|
||||||
|
ij_json_space_after_comma = true
|
||||||
|
ij_json_space_before_colon = true
|
||||||
|
ij_json_space_before_comma = false
|
||||||
|
ij_json_spaces_within_braces = false
|
||||||
|
ij_json_spaces_within_brackets = false
|
||||||
|
ij_json_wrap_long_lines = false
|
||||||
|
|
||||||
|
[{*.htm, *.html, *.sht, *.shtm, *.shtml}]
|
||||||
|
ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
|
||||||
|
ij_html_align_attributes = true
|
||||||
|
ij_html_align_text = false
|
||||||
|
ij_html_attribute_wrap = normal
|
||||||
|
ij_html_block_comment_at_first_column = true
|
||||||
|
ij_html_do_not_align_children_of_min_lines = 0
|
||||||
|
ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p
|
||||||
|
ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot
|
||||||
|
ij_html_enforce_quotes = false
|
||||||
|
ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var
|
||||||
|
ij_html_keep_blank_lines = 2
|
||||||
|
ij_html_keep_indents_on_empty_lines = false
|
||||||
|
ij_html_keep_line_breaks = true
|
||||||
|
ij_html_keep_line_breaks_in_text = true
|
||||||
|
ij_html_keep_whitespaces = false
|
||||||
|
ij_html_keep_whitespaces_inside = span, pre, textarea
|
||||||
|
ij_html_line_comment_at_first_column = true
|
||||||
|
ij_html_new_line_after_last_attribute = never
|
||||||
|
ij_html_new_line_before_first_attribute = never
|
||||||
|
ij_html_quote_style = double
|
||||||
|
ij_html_remove_new_line_before_tags = br
|
||||||
|
ij_html_space_after_tag_name = false
|
||||||
|
ij_html_space_around_equality_in_attribute = false
|
||||||
|
ij_html_space_inside_empty_tag = false
|
||||||
|
ij_html_text_wrap = normal
|
||||||
|
|
||||||
|
[{*.yaml, *.yml}]
|
||||||
|
indent_size = 2
|
||||||
|
ij_yaml_keep_indents_on_empty_lines = false
|
||||||
|
ij_yaml_keep_line_breaks = true
|
17
.github/workflows/cd.yaml
vendored
Normal file
17
.github/workflows/cd.yaml
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
name: CD
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- published
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cd:
|
||||||
|
uses: halo-sigs/reusable-workflows/.github/workflows/plugin-cd.yaml@v3
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
with:
|
||||||
|
pnpm-version: 9
|
||||||
|
node-version: 22
|
||||||
|
java-version: 21
|
||||||
|
skip-appstore-release: true
|
18
.github/workflows/ci.yaml
vendored
Normal file
18
.github/workflows/ci.yaml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
uses: halo-sigs/reusable-workflows/.github/workflows/plugin-ci.yaml@v3
|
||||||
|
with:
|
||||||
|
ui-path: "ui"
|
||||||
|
pnpm-version: 9
|
||||||
|
node-version: 22
|
||||||
|
java-version: 21
|
105
.github/workflows/workflow.yaml
vendored
105
.github/workflows/workflow.yaml
vendored
@@ -1,105 +0,0 @@
|
|||||||
name: Build Plugin JAR File
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- created
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: true
|
|
||||||
- name: Set up JDK 17
|
|
||||||
uses: actions/setup-java@v2
|
|
||||||
with:
|
|
||||||
distribution: 'temurin'
|
|
||||||
cache: 'gradle'
|
|
||||||
java-version: 17
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
- uses: pnpm/action-setup@v2.0.1
|
|
||||||
name: Install pnpm
|
|
||||||
id: pnpm-install
|
|
||||||
with:
|
|
||||||
version: 7
|
|
||||||
run_install: false
|
|
||||||
- name: Get pnpm store directory
|
|
||||||
id: pnpm-cache
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
name: Setup pnpm cache
|
|
||||||
with:
|
|
||||||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
|
||||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/console/pnpm-lock.yaml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-pnpm-store-
|
|
||||||
- name: Install Frontend Dependencies
|
|
||||||
run: |
|
|
||||||
./gradlew pnpmInstall
|
|
||||||
- name: Build with Gradle
|
|
||||||
run: |
|
|
||||||
# Set the version with tag name when releasing
|
|
||||||
version=${{ github.event.release.tag_name }}
|
|
||||||
version=${version#v}
|
|
||||||
sed -i "s/version=.*-SNAPSHOT$/version=$version/1" gradle.properties
|
|
||||||
./gradlew clean build -x test
|
|
||||||
- name: Archive plugin-starter jar
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: plugin-starter
|
|
||||||
path: |
|
|
||||||
build/libs/*.jar
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
github-release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: build
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
steps:
|
|
||||||
- name: Download plugin-starter jar
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: plugin-starter
|
|
||||||
path: build/libs
|
|
||||||
- name: Get Name of Artifact
|
|
||||||
id: get_artifact
|
|
||||||
run: |
|
|
||||||
ARTIFACT_PATHNAME=$(ls build/libs/*.jar | head -n 1)
|
|
||||||
ARTIFACT_NAME=$(basename ${ARTIFACT_PATHNAME})
|
|
||||||
echo "Artifact pathname: ${ARTIFACT_PATHNAME}"
|
|
||||||
echo "Artifact name: ${ARTIFACT_NAME}"
|
|
||||||
echo "ARTIFACT_PATHNAME=${ARTIFACT_PATHNAME}" >> $GITHUB_ENV
|
|
||||||
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
|
|
||||||
echo "RELEASE_ID=${{ github.event.release.id }}" >> $GITHUB_ENV
|
|
||||||
- name: Upload a Release Asset
|
|
||||||
uses: actions/github-script@v2
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
with:
|
|
||||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
|
||||||
script: |
|
|
||||||
console.log('environment', process.versions);
|
|
||||||
|
|
||||||
const fs = require('fs').promises;
|
|
||||||
|
|
||||||
const { repo: { owner, repo }, sha } = context;
|
|
||||||
console.log({ owner, repo, sha });
|
|
||||||
|
|
||||||
const releaseId = process.env.RELEASE_ID
|
|
||||||
const artifactPathName = process.env.ARTIFACT_PATHNAME
|
|
||||||
const artifactName = process.env.ARTIFACT_NAME
|
|
||||||
console.log('Releasing', releaseId, artifactPathName, artifactName)
|
|
||||||
|
|
||||||
await github.repos.uploadReleaseAsset({
|
|
||||||
owner, repo,
|
|
||||||
release_id: releaseId,
|
|
||||||
name: artifactName,
|
|
||||||
data: await fs.readFile(artifactPathName)
|
|
||||||
});
|
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -70,5 +70,6 @@ application-local.yml
|
|||||||
application-local.yaml
|
application-local.yaml
|
||||||
application-local.properties
|
application-local.properties
|
||||||
|
|
||||||
/admin-frontend/node_modules/
|
/ui/node_modules/
|
||||||
/workplace/
|
/workplace/
|
||||||
|
/src/main/resources/console/
|
||||||
|
10
OWNERS
10
OWNERS
@@ -1,10 +0,0 @@
|
|||||||
reviewers:
|
|
||||||
- ruibaby
|
|
||||||
- guqing
|
|
||||||
- JohnNiang
|
|
||||||
- wangzhen-fit2cloud
|
|
||||||
|
|
||||||
approvers:
|
|
||||||
- ruibaby
|
|
||||||
- guqing
|
|
||||||
- JohnNiang
|
|
407
README.md
407
README.md
@@ -1,393 +1,76 @@
|
|||||||
# plugin-starter
|
# plugin-starter
|
||||||
|
|
||||||
Halo 2.0 插件开发快速开始模板(WIP)
|
Halo 2.x 插件开发快速开始模板。
|
||||||
|
|
||||||
## 项目结构介绍
|
|
||||||
|
|
||||||
```text
|
|
||||||
.
|
|
||||||
├── LICENSE
|
|
||||||
├── README.md
|
|
||||||
├── console
|
|
||||||
│ ├── README.md
|
|
||||||
│ ├── env.d.ts
|
|
||||||
│ ├── package.json
|
|
||||||
│ ├── pnpm-lock.yaml
|
|
||||||
│ ├── src
|
|
||||||
│ │ ├── assets
|
|
||||||
│ │ │ └── logo.svg
|
|
||||||
│ │ ├── components
|
|
||||||
│ │ │ └── HelloWorld.vue
|
|
||||||
│ │ ├── index.ts # Console Frontend Entry file
|
|
||||||
│ │ ├── styles
|
|
||||||
│ │ │ └── index.css
|
|
||||||
│ │ └── views
|
|
||||||
│ │ └── DefaultView.vue # Views Component
|
|
||||||
│ ├── tsconfig.app.json
|
|
||||||
│ ├── tsconfig.config.json
|
|
||||||
│ ├── tsconfig.json
|
|
||||||
│ ├── tsconfig.vitest.json
|
|
||||||
│ └── vite.config.ts
|
|
||||||
├── build.gradle
|
|
||||||
├── gradle
|
|
||||||
│ └── wrapper
|
|
||||||
│ ├── gradle-wrapper.jar
|
|
||||||
│ └── gradle-wrapper.properties
|
|
||||||
├── gradlew
|
|
||||||
├── gradlew.bat
|
|
||||||
├── lib
|
|
||||||
│ └── halo-2.0.0-SNAPSHOT-plain.jar
|
|
||||||
├── settings.gradle
|
|
||||||
└── src
|
|
||||||
└── main
|
|
||||||
├── java
|
|
||||||
│ └── run
|
|
||||||
│ └── halo
|
|
||||||
│ └── starter
|
|
||||||
│ ├── Apple.java
|
|
||||||
│ ├── ApplesController.java
|
|
||||||
│ └── StarterPlugin.java # Main Class
|
|
||||||
└── resources
|
|
||||||
├── console
|
|
||||||
│ ├── main.js # Console Frontend Entry file(production build)
|
|
||||||
│ └── style.css
|
|
||||||
├── extensions
|
|
||||||
│ ├── apple.yaml
|
|
||||||
│ ├── reverseProxy.yaml # Reverse Proxy Config
|
|
||||||
│ ├── roleTemplate.yaml # Role Template Config
|
|
||||||
│ └── settings.yaml # Settings Config
|
|
||||||
├── plugin.yaml # Plugin Config
|
|
||||||
└── static
|
|
||||||
├── image.jpeg
|
|
||||||
├── some.txt
|
|
||||||
└── test.html
|
|
||||||
```
|
|
||||||
|
|
||||||
对于以上目录树:
|
|
||||||
|
|
||||||
- `console`: 插件前端项目目录,为一个 Vue 项目,技术栈为 Vue 3 + Vite,其中已经预配置好了构建策略。
|
|
||||||
- `build`:插件后端构建目录,`build/libs` 下的 jar 包为最终插件产物。
|
|
||||||
- `lib`:为临时的 Halo 依赖,为了使用 Halo 中提供的类在 `build.gradle`
|
|
||||||
中作为编译时依赖引入 `compileOnly files("lib/halo-2.0.0-SNAPSHOT-plain.jar")`
|
|
||||||
,待 `2.0` 正式发布会将其发布到 `maven` 中央仓库,便可通过 `gradle` 依赖。
|
|
||||||
- `src`: 为插件后端源码目录。
|
|
||||||
- `Apple.java`: 为自定义模型。
|
|
||||||
|
|
||||||
```java
|
|
||||||
@GVK(group = "apple.guqing.xyz", kind = "Apple",
|
|
||||||
version = "v1alpha1", singular = "apple", plural = "apples")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public class Apple extends AbstractExtension {
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
关键在于标注 `@GVK` 注解和 `extends AbstractExtension`,当如此定义了一个模型后,插件启动时会根据 `@GVK`
|
|
||||||
配置自动生成`CRUD`的 `RESTful API`
|
|
||||||
,以此为例子会生成如下 `APIs`
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET /apis/apple.guqing.xyz/v1alpha1/apples
|
|
||||||
|
|
||||||
POST /apis/apple.guqing.xyz/v1alpha1/apples
|
|
||||||
|
|
||||||
GET /apis/apple.guqing.xyz/v1alpha1/apples/{name}
|
|
||||||
|
|
||||||
PUT /apis/apple.guqing.xyz/v1alpha1/apples/{name}
|
|
||||||
|
|
||||||
DELETE /apis/apple.guqing.xyz/v1alpha1/apples/{name}
|
|
||||||
```
|
|
||||||
|
|
||||||
生成规则见:[Halo extension RFC](https://github.com/halo-dev/rfcs/tree/main/extension)
|
|
||||||
|
|
||||||
- `TemplatePlugin.java`:插件生命周期入口,它继承 `BasePlugin`,可以通过 `getApplicationContext()`
|
|
||||||
方法获取到 `SchemeManager`,然后在 `start()`
|
|
||||||
方法中注册自定义模型,这一步必不可少,所有定义的自定义模型都需要在此注册,并在 `stop()` 生命周期方法中清理资源。
|
|
||||||
|
|
||||||
```java
|
|
||||||
public class StarterPlugin extends BasePlugin {
|
|
||||||
// ...
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
schemeManager.register(Apple.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop() {
|
|
||||||
Scheme scheme = schemeManager.get(Apple.class);
|
|
||||||
schemeManager.unregister(scheme);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
注意:该类不能标注 `@Component` 等能将其声明为 `Spring Bean` 的注解
|
|
||||||
|
|
||||||
- `ApplesController.java`:如果根据模型自动生成的 `CURD RESTful APIs` 无法满足业务需要,可以写常规 `Controller`
|
|
||||||
来自定义 `APIs`,示例:
|
|
||||||
|
|
||||||
```java
|
|
||||||
|
|
||||||
@ApiVersion("v1alpha1")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("colors")
|
|
||||||
public class ApplesController {
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public Mono<String> hello() {
|
|
||||||
return Mono.just("Hello world");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
插件定义 `Controller` 必须要标注 `@ApiVersion` 注解,否则启动时会报错。如果定义了这样的 `Controller`
|
|
||||||
,插件启动后会生成如下的 `APIs`:
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET /api/v1alpha1/plugins/apples/colors
|
|
||||||
```
|
|
||||||
|
|
||||||
生成规则为 `/api/{version}/plugins/{plugin-name}/{mapping-in-class}/{mapping-in-method}`
|
|
||||||
|
|
||||||
其中:
|
|
||||||
|
|
||||||
- `version`:来自 `@ApiVersion("v1alpha1")` 的
|
|
||||||
value,详情参考:[Halo plugin API composition](https://github.com/halo-dev/rfcs/blob/main/plugin/pluggable-design.md#api-%E6%9E%84%E6%88%90%E8%AE%A8%E8%AE%BA)
|
|
||||||
- `plugin-name`:值来自 `plugin.yaml` 中的 `metadata.name` 属性
|
|
||||||
- `mapping-in-class`:来自标注在类上的 `@RequestMapping("colors")`
|
|
||||||
- `mapping-in-method`:来自标注在方法上的 `@GetMapping`
|
|
||||||
|
|
||||||
插件还允许使用 `@Service`、`@Component` 注解将其声明为一个 `Spring Bean`,便可通过依赖注入使用 `Spring Bean`,示例:
|
|
||||||
|
|
||||||
```java
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ColorService {
|
|
||||||
public String getColor(String appleName) {
|
|
||||||
return "red";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiVersion("v1alpha1")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("colors")
|
|
||||||
public class ApplesController {
|
|
||||||
private final ColorService colorService;
|
|
||||||
|
|
||||||
// 构造器注入,当然也同样允许 @Autowired 注入 和 setter 方法注入
|
|
||||||
public ApplesController(ColorService colorService) {
|
|
||||||
this.colorService = colorService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `resources`:目录为插件资源目录
|
|
||||||
- `console` 目录下为插件前端打包后的产物存放目录,固定为 `main.js` 和 `style.css `两个文件
|
|
||||||
- `extensions` 存放自定义模型资源配置
|
|
||||||
- `plugin.yaml`为插件描述配置
|
|
||||||
- `static` 为静态资源示例目录
|
|
||||||
|
|
||||||
插件启动时会加载 `extensions` 目录的 `yaml` 保存到数据库,`apple.yaml` 为本项目自定义的模型的数据示例,当启用插件后调用
|
|
||||||
|
|
||||||
```text
|
|
||||||
GET /apis/apple.guqing.xyz/v1alpha1/apples
|
|
||||||
```
|
|
||||||
|
|
||||||
便可查询到 `apple.yaml` 中定义的记录
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"spec": {
|
|
||||||
"varieties": "Fuji",
|
|
||||||
"color": "red",
|
|
||||||
"size": "middle",
|
|
||||||
"producingArea": "China"
|
|
||||||
},
|
|
||||||
"apiVersion": "apple.guqing.xyz/v1alpha1",
|
|
||||||
"kind": "Apple",
|
|
||||||
"metadata": {
|
|
||||||
"name": "Fuji-apple",
|
|
||||||
"labels": {
|
|
||||||
"plugin.halo.run/plugin-name": "apples"
|
|
||||||
},
|
|
||||||
"version": 0,
|
|
||||||
"creationTimestamp": "2022-06-24T04:03:22.890741Z"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
`reverseProxy.yaml` 为 Halo 中提供的模型,表示反向代理,允许插件配置规则代理到插件目录
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: plugin.halo.run/v1alpha1
|
|
||||||
kind: ReverseProxy
|
|
||||||
metadata:
|
|
||||||
name: reverse-proxy-template
|
|
||||||
rules:
|
|
||||||
- path: /static/**
|
|
||||||
file:
|
|
||||||
directory: static
|
|
||||||
```
|
|
||||||
|
|
||||||
它表示访问 `GET /assets/{plugin-name}/static/**` 时代理访问到插件的 `resources/static` 目录,本插件便可访问到一下静态资源
|
|
||||||
|
|
||||||
```
|
|
||||||
GET /assets/apples/static/image.jpeg
|
|
||||||
GET /assets/apples/static/some.txt
|
|
||||||
GET /assets/apples/static/test.html
|
|
||||||
```
|
|
||||||
|
|
||||||
`roleTemplate.yaml` 文件中 `kind: Role` 表示插件允许提供角色模版,定义格式如下:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1alpha1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: a name here
|
|
||||||
labels:
|
|
||||||
plugin.halo.run/role-template: "true"
|
|
||||||
annotations:
|
|
||||||
plugin.halo.run/module: "module name"
|
|
||||||
plugin.halo.run/alias-name: "display name"
|
|
||||||
rules:
|
|
||||||
# ...
|
|
||||||
```
|
|
||||||
|
|
||||||
必须带有`plugin.halo.run/role-template: "true"` labels,表示该角色为角色模版,当用户启用插件后,创建角色或修改角色时会将其列在权限列表位置。
|
|
||||||
|
|
||||||
插件如果不提供角色模版除非是超级管理员否则其他账号没有权限访问,因为 Halo 规定 `/api` 和 `/apis` 开头的 `api`
|
|
||||||
都需要授权才能访问,因此插件不提供角色模版的自定义资源,就无法将其分配给用户。
|
|
||||||
|
|
||||||
更多详情参考:[Halo security RFC](https://github.com/halo-dev/rfcs/blob/main/identity/002-security.md)
|
|
||||||
|
|
||||||
## 开发环境
|
## 开发环境
|
||||||
|
|
||||||
### 环境要求
|
插件开发的详细文档请查阅:<https://docs.halo.run/developer-guide/plugin/introduction>
|
||||||
|
|
||||||
- OpenJDK 17
|
所需环境:
|
||||||
- NodeJS 16+
|
|
||||||
- pnpm 7+
|
|
||||||
|
|
||||||
### 拉取 Halo 相关项目源码
|
1. JDK 21
|
||||||
|
2. Node 20
|
||||||
|
3. pnpm 9
|
||||||
|
4. Docker (可选)
|
||||||
|
|
||||||
|
克隆项目:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir ./halo-dev
|
git clone git@github.com:halo-sigs/plugin-starter.git
|
||||||
|
|
||||||
mkdir ./halo-dev/dev-plugins # 存放插件源码
|
# 或者当你 fork 之后
|
||||||
|
|
||||||
|
git clone git@github.com:{your_github_id}/plugin-starter.git
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ./halo-dev
|
cd path/to/plugin-starter
|
||||||
|
```
|
||||||
|
|
||||||
git clone https://github.com/halo-dev/halo --branch main
|
### 运行方式 1(推荐)
|
||||||
|
|
||||||
|
> 此方式需要本地安装 Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# macOS / Linux
|
||||||
|
./gradlew pnpmInstall
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
./gradlew.bat pnpmInstall
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/halo-dev/console --branch main
|
# macOS / Linux
|
||||||
|
./gradlew haloServer
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
./gradlew.bat haloServer
|
||||||
```
|
```
|
||||||
|
|
||||||
|
执行此命令后,会自动创建一个 Halo 的 Docker 容器并加载当前的插件,更多文档可查阅:<https://docs.halo.run/developer-guide/plugin/basics/devtools>
|
||||||
|
|
||||||
|
### 运行方式 2
|
||||||
|
|
||||||
|
> 此方式需要使用源码运行 Halo
|
||||||
|
|
||||||
|
编译插件:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ./dev-plugins
|
# macOS / Linux
|
||||||
|
./gradlew build
|
||||||
|
|
||||||
git clone https://github.com/halo-dev/plugin-starter
|
# Windows
|
||||||
|
./gradlew.bat build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Halo 配置文件修改
|
修改 Halo 配置文件:
|
||||||
|
|
||||||
修改 halo/src/main/resources/application-dev.yaml
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
halo:
|
halo:
|
||||||
security:
|
|
||||||
initializer:
|
|
||||||
super-admin-username: admin
|
|
||||||
super-admin-password: P@88w0rd
|
|
||||||
oauth2:
|
|
||||||
jwt:
|
|
||||||
jwsAlgorithm: rs512
|
|
||||||
public-key-location: classpath:app.pub
|
|
||||||
private-key-location: classpath:app.key
|
|
||||||
plugin:
|
plugin:
|
||||||
runtime-mode: development # development, deployment
|
runtime-mode: development
|
||||||
classes-directories:
|
|
||||||
- "build/classes"
|
|
||||||
- "build/resources"
|
|
||||||
lib-directories:
|
|
||||||
- "libs"
|
|
||||||
fixedPluginPath:
|
fixedPluginPath:
|
||||||
- "/path/to/plugin-starter"
|
- "/path/to/plugin-starter"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 编译插件
|
最后重启 Halo 项目即可。
|
||||||
|
|
||||||
下载前端依赖:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ./halo-dev/dev-plugins/plugin-starter
|
|
||||||
|
|
||||||
./gradlew.bat pnpmInstall
|
|
||||||
|
|
||||||
# or macOS/Linux
|
|
||||||
|
|
||||||
./gradlew pnpmInstall
|
|
||||||
```
|
|
||||||
|
|
||||||
构建:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew.bat build
|
|
||||||
|
|
||||||
# or macOS/Linux
|
|
||||||
|
|
||||||
./gradlew build
|
|
||||||
```
|
|
||||||
|
|
||||||
### 启动 Halo
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ./halo-dev/halo
|
|
||||||
|
|
||||||
./gradlew.bat bootRun --args="--spring.profiles.active=dev"
|
|
||||||
|
|
||||||
# or macOS/Linux
|
|
||||||
|
|
||||||
./gradlew bootRun --args="--spring.profiles.active=dev"
|
|
||||||
```
|
|
||||||
|
|
||||||
或者在 IntelliJ IDEA 中运行 Application 启动类。但注意需要配置好 `spring.profiles.active` 为 dev。
|
|
||||||
|
|
||||||
### 启动 Console
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ./halo-dev/console
|
|
||||||
|
|
||||||
pnpm install
|
|
||||||
|
|
||||||
pnpm build:packages
|
|
||||||
|
|
||||||
pnpm dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 访问后台
|
|
||||||
|
|
||||||
在浏览器中访问 https://localhost:3000 即可,登录用户名和密码为上方 `application-dev.yaml` 配置中的 `super-admin-username`
|
|
||||||
和 `super-admin-password`。
|
|
||||||
|
|
||||||
然后在左侧菜单中选择 `插件`,即可查看所有插件的状态。
|
|
||||||
|
|
||||||
### 开发
|
|
||||||
|
|
||||||
修改前端代码或者后端代码,然后运行 `./gradlew.bat build` 或者 `./gradlew build`(macOS/Linux)即可构建插件,无需重启
|
|
||||||
Halo。但修改配置文件后需要 build 插件以及重启 Halo。
|
|
||||||
|
|
||||||
## 构建生产产物
|
|
||||||
|
|
||||||
```
|
|
||||||
./gradlew -x build
|
|
||||||
```
|
|
||||||
|
|
||||||
然后只需复制例如`build/libs/plugin-starter-0.0.1-SNAPSHOT-plain.jar` 的 `jar` 包即可使用。
|
|
||||||
|
61
build.gradle
61
build.gradle
@@ -1,63 +1,48 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "com.github.node-gradle.node" version "3.3.0"
|
|
||||||
id "io.github.guqing.plugin-development" version "0.0.6-SNAPSHOT"
|
|
||||||
id 'java'
|
id 'java'
|
||||||
|
id "io.freefair.lombok" version "8.13"
|
||||||
|
id "run.halo.plugin.devtools" version "0.6.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'run.halo.starter'
|
group 'run.halo.starter'
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://s01.oss.sonatype.org/content/repositories/releases' }
|
|
||||||
maven { url 'https://repo.spring.io/milestone' }
|
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
|
||||||
enabled = true
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
||||||
manifest.attributes(
|
|
||||||
'Plugin-Version': "${project.version}",
|
|
||||||
)
|
|
||||||
from {
|
|
||||||
configurations.runtimeClasspath.collect {
|
|
||||||
it.isDirectory() ? it : zipTree(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly platform("run.halo.dependencies:halo-dependencies:1.0.0")
|
implementation platform('run.halo.tools.platform:plugin:2.21.0')
|
||||||
|
compileOnly 'run.halo.app:api'
|
||||||
|
|
||||||
compileOnly files("lib/halo-2.0.0-SNAPSHOT-plain.jar")
|
testImplementation 'run.halo.app:api'
|
||||||
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.22'
|
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.22'
|
|
||||||
|
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
|
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
node {
|
java {
|
||||||
nodeProjectDir = file("${project.projectDir}/console")
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(21)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task buildFrontend(type: NpxTask) {
|
tasks.withType(JavaCompile).configureEach {
|
||||||
command = 'pnpm'
|
options.encoding = "UTF-8"
|
||||||
args = ['build']
|
options.release = 21
|
||||||
}
|
}
|
||||||
|
|
||||||
task pnpmInstall(type: NpxTask) {
|
tasks.register('processUiResources', Copy) {
|
||||||
command = "pnpm"
|
from project(':ui').tasks.named('buildFrontend')
|
||||||
args = ["install"]
|
into layout.buildDirectory.dir('resources/main/console')
|
||||||
}
|
}
|
||||||
|
|
||||||
build {
|
tasks.named('processResources', ProcessResources) {
|
||||||
// build frontend before build
|
dependsOn tasks.named('processUiResources')
|
||||||
tasks.getByName('compileJava').dependsOn('buildFrontend')
|
}
|
||||||
tasks.getByName("buildFrontend").dependsOn("pnpmInstall")
|
|
||||||
|
halo {
|
||||||
|
version = '2.21'
|
||||||
}
|
}
|
||||||
|
@@ -1,57 +0,0 @@
|
|||||||
# Halo 前后端服务的 Docker Compose
|
|
||||||
|
|
||||||
通过 Docker Compose 的方式启动 Halo 前后端服务快速查看插件效果。
|
|
||||||
|
|
||||||
## 开发指引
|
|
||||||
|
|
||||||
### 环境要求
|
|
||||||
|
|
||||||
- OpenJDK 17
|
|
||||||
- NodeJS 16+
|
|
||||||
- pnpm 7+
|
|
||||||
- Docker
|
|
||||||
- Docker Compose
|
|
||||||
|
|
||||||
### 编译插件
|
|
||||||
|
|
||||||
下载前端依赖:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ./plugin-starter
|
|
||||||
|
|
||||||
./gradlew.bat pnpmInstall
|
|
||||||
|
|
||||||
# or macOS/Linux
|
|
||||||
|
|
||||||
./gradlew pnpmInstall
|
|
||||||
```
|
|
||||||
|
|
||||||
构建:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew.bat build
|
|
||||||
|
|
||||||
# or macOS/Linux
|
|
||||||
|
|
||||||
./gradlew build
|
|
||||||
```
|
|
||||||
|
|
||||||
### 启动 Halo
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd plugin-starter/compose
|
|
||||||
docker-compose up -d
|
|
||||||
docker-compose ps
|
|
||||||
```
|
|
||||||
|
|
||||||
### 访问后台
|
|
||||||
|
|
||||||
在浏览器中访问 <https://localhost:8090/console> 即可,登录用户名和密码为当前目录中 `application-dev.yaml` 配置中的 `super-admin-username`
|
|
||||||
和 `super-admin-password`。
|
|
||||||
|
|
||||||
然后在左侧菜单中选择 `插件`,即可查看所有插件的状态。
|
|
||||||
|
|
||||||
### 开发
|
|
||||||
|
|
||||||
修改前端代码或者后端代码,然后运行 `./gradlew.bat build` 或者 `./gradlew build`(macOS/Linux)即可构建插件,无需重启
|
|
||||||
Halo。但修改配置文件后需要 build 插件以及重启 Halo。
|
|
@@ -1,40 +0,0 @@
|
|||||||
server:
|
|
||||||
port: 8090
|
|
||||||
spring:
|
|
||||||
profiles:
|
|
||||||
active: dev
|
|
||||||
halo:
|
|
||||||
external-url: http://localhost:8090/
|
|
||||||
security:
|
|
||||||
initializer:
|
|
||||||
super-admin-username: admin
|
|
||||||
super-admin-password: P@88w0rd
|
|
||||||
oauth2:
|
|
||||||
jwt:
|
|
||||||
jwsAlgorithm: rs512
|
|
||||||
public-key-location: classpath:app.pub
|
|
||||||
private-key-location: classpath:app.key
|
|
||||||
plugin:
|
|
||||||
runtime-mode: development # development, deployment
|
|
||||||
classes-directories:
|
|
||||||
- "build/classes"
|
|
||||||
- "build/resources"
|
|
||||||
lib-directories:
|
|
||||||
- "libs"
|
|
||||||
fixedPluginPath:
|
|
||||||
- "/plugin"
|
|
||||||
springdoc:
|
|
||||||
api-docs:
|
|
||||||
enabled: true
|
|
||||||
swagger-ui:
|
|
||||||
enabled: true
|
|
||||||
show-login-endpoint: false
|
|
||||||
show-actuator: false
|
|
||||||
use-management-port: false
|
|
||||||
management:
|
|
||||||
endpoints:
|
|
||||||
web:
|
|
||||||
exposure:
|
|
||||||
include: health,info,metrics,startup,shutdown
|
|
||||||
server:
|
|
||||||
port: 8090
|
|
@@ -1,14 +0,0 @@
|
|||||||
services:
|
|
||||||
halo-next:
|
|
||||||
image: halohub/halo-dev:main
|
|
||||||
ports:
|
|
||||||
- 8090:8090
|
|
||||||
environment:
|
|
||||||
- SPRING_CONFIG_ADDITIONAL_LOCATION=optional:file:/etc/config/
|
|
||||||
volumes:
|
|
||||||
- ./application.yaml:/etc/config/application.yaml
|
|
||||||
- ../:/plugin
|
|
||||||
networks:
|
|
||||||
- halo
|
|
||||||
networks:
|
|
||||||
halo: {}
|
|
@@ -1,12 +0,0 @@
|
|||||||
# EditorConfig is awesome: https://EditorConfig.org
|
|
||||||
|
|
||||||
# top-most EditorConfig file
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
insert_final_newline = true
|
|
@@ -1,15 +0,0 @@
|
|||||||
/* eslint-env node */
|
|
||||||
require("@rushstack/eslint-patch/modern-module-resolution");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
"root": true,
|
|
||||||
"extends": [
|
|
||||||
"plugin:vue/vue3-essential",
|
|
||||||
"eslint:recommended",
|
|
||||||
"@vue/eslint-config-typescript/recommended",
|
|
||||||
"@vue/eslint-config-prettier"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"vue/setup-compiler-macros": true
|
|
||||||
}
|
|
||||||
}
|
|
6
console/env.d.ts
vendored
6
console/env.d.ts
vendored
@@ -1,6 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
||||||
|
|
||||||
declare module "*.vue" {
|
|
||||||
import Vue from "vue";
|
|
||||||
export default Vue;
|
|
||||||
}
|
|
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@halo-dev/plugin-starter",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite build --watch",
|
|
||||||
"build": "vite build",
|
|
||||||
"preview": "vite preview --port 4173",
|
|
||||||
"test:unit": "vitest --environment jsdom",
|
|
||||||
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
|
||||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@halo-dev/components": "^1.0.0",
|
|
||||||
"@halo-dev/console-shared": "^2.0.0",
|
|
||||||
"vue": "^3.2.41"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@rushstack/eslint-patch": "^1.2.0",
|
|
||||||
"@types/jsdom": "^20.0.0",
|
|
||||||
"@types/node": "^16.18.0",
|
|
||||||
"@vitejs/plugin-vue": "^3.1.2",
|
|
||||||
"@vitejs/plugin-vue-jsx": "^2.0.1",
|
|
||||||
"@vue/eslint-config-prettier": "^7.0.0",
|
|
||||||
"@vue/eslint-config-typescript": "^11.0.2",
|
|
||||||
"@vue/test-utils": "^2.2.0",
|
|
||||||
"@vue/tsconfig": "^0.1.3",
|
|
||||||
"eslint": "^8.26.0",
|
|
||||||
"eslint-plugin-vue": "^9.6.0",
|
|
||||||
"jsdom": "^19.0.0",
|
|
||||||
"npm-run-all": "^4.1.5",
|
|
||||||
"prettier": "^2.7.1",
|
|
||||||
"typescript": "~4.7.4",
|
|
||||||
"vite": "^3.1.8",
|
|
||||||
"vitest": "^0.24.3",
|
|
||||||
"vue-tsc": "^1.0.9"
|
|
||||||
}
|
|
||||||
}
|
|
3449
console/pnpm-lock.yaml
generated
3449
console/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import {defineComponent, ref} from "vue";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "HelloWorld",
|
|
||||||
setup() {
|
|
||||||
const msg = ref("Hello World");
|
|
||||||
return {
|
|
||||||
msg,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div>{{ msg }}</div>
|
|
||||||
</template>
|
|
@@ -1,42 +0,0 @@
|
|||||||
import {definePlugin} from "@halo-dev/console-shared";
|
|
||||||
import DefaultView from "./views/DefaultView.vue";
|
|
||||||
import {IconGrid} from "@halo-dev/components";
|
|
||||||
import "./styles/index.css";
|
|
||||||
import {markRaw} from "vue";
|
|
||||||
|
|
||||||
export default definePlugin({
|
|
||||||
name: "PluginStarter",
|
|
||||||
components: [],
|
|
||||||
routes: [
|
|
||||||
{
|
|
||||||
parentName: "Root",
|
|
||||||
route:
|
|
||||||
{
|
|
||||||
path: "/hello-world",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: "",
|
|
||||||
name: "HelloWorld",
|
|
||||||
component: DefaultView,
|
|
||||||
meta: {
|
|
||||||
permissions: ["plugin:apples:view"],
|
|
||||||
title: "HelloWorld",
|
|
||||||
searchable: true,
|
|
||||||
menu: {
|
|
||||||
name: "迁移",
|
|
||||||
group: "From PluginStarter",
|
|
||||||
icon: markRaw(IconGrid),
|
|
||||||
priority: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
extensionPoints: {},
|
|
||||||
activated() {
|
|
||||||
},
|
|
||||||
deactivated() {
|
|
||||||
},
|
|
||||||
});
|
|
@@ -1,3 +0,0 @@
|
|||||||
.title {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
@@ -1,22 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import {defineComponent} from "vue";
|
|
||||||
import logo from "../assets/logo.svg";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "DefaultView",
|
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
logo,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div class="title">Hello World</div>
|
|
||||||
<img v-permission="['plugin:apples:view']" :src="logo" alt="logo"/>
|
|
||||||
</template>
|
|
||||||
<style scoped>
|
|
||||||
.title {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "@vue/tsconfig/tsconfig.web.json",
|
|
||||||
"include": ["./env.d.ts", "./src/**/*", "./src/**/*.vue"],
|
|
||||||
"exclude": ["./src/**/__tests__/*"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": true,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "@vue/tsconfig/tsconfig.node.json",
|
|
||||||
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": true,
|
|
||||||
"types": ["node"]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,44 +0,0 @@
|
|||||||
import { fileURLToPath, URL } from "url";
|
|
||||||
|
|
||||||
import { defineConfig } from "vite";
|
|
||||||
import vue from "@vitejs/plugin-vue";
|
|
||||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [vue(), vueJsx()],
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
outDir: fileURLToPath(
|
|
||||||
new URL("../src/main/resources/console", import.meta.url)
|
|
||||||
),
|
|
||||||
emptyOutDir: true,
|
|
||||||
lib: {
|
|
||||||
entry: "src/index.ts",
|
|
||||||
name: "PluginStarter",
|
|
||||||
formats: ["iife"],
|
|
||||||
fileName: () => "main.js",
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
external: [
|
|
||||||
"vue",
|
|
||||||
"@halo-dev/shared",
|
|
||||||
"@halo-dev/components",
|
|
||||||
"vue-router",
|
|
||||||
],
|
|
||||||
output: {
|
|
||||||
globals: {
|
|
||||||
vue: "Vue",
|
|
||||||
"vue-router": "VueRouter",
|
|
||||||
"@halo-dev/components": "HaloComponents",
|
|
||||||
"@halo-dev/console-shared": "HaloConsoleShared",
|
|
||||||
},
|
|
||||||
extend: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
18
gradlew
vendored
18
gradlew
vendored
@@ -55,7 +55,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -80,10 +80,10 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
@@ -143,12 +143,16 @@ fi
|
|||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC3045
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC3045
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@@ -205,6 +209,12 @@ set -- \
|
|||||||
org.gradle.wrapper.GradleWrapperMain \
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
15
gradlew.bat
vendored
15
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@@ -25,7 +25,8 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
Binary file not shown.
@@ -1,11 +1,7 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots' }
|
|
||||||
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
|
|
||||||
maven { url 'https://maven.aliyun.com/repository/spring-plugin' }
|
|
||||||
maven { url 'https://repo.spring.io/milestone' }
|
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootProject.name = 'plugin-starter'
|
rootProject.name = 'plugin-starter'
|
||||||
|
include 'ui'
|
||||||
|
@@ -1,20 +1,22 @@
|
|||||||
package run.halo.starter;
|
package run.halo.starter;
|
||||||
|
|
||||||
import org.pf4j.PluginWrapper;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.extension.Scheme;
|
|
||||||
import run.halo.app.extension.SchemeManager;
|
|
||||||
import run.halo.app.plugin.BasePlugin;
|
import run.halo.app.plugin.BasePlugin;
|
||||||
|
import run.halo.app.plugin.PluginContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* <p>Plugin main class to manage the lifecycle of the plugin.</p>
|
||||||
|
* <p>This class must be public and have a public constructor.</p>
|
||||||
|
* <p>Only one main class extending {@link BasePlugin} is allowed per plugin.</p>
|
||||||
|
*
|
||||||
* @author guqing
|
* @author guqing
|
||||||
* @since 2.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class StarterPlugin extends BasePlugin {
|
public class StarterPlugin extends BasePlugin {
|
||||||
|
|
||||||
public StarterPlugin(PluginWrapper wrapper) {
|
public StarterPlugin(PluginContext pluginContext) {
|
||||||
super(wrapper);
|
super(pluginContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
.title[data-v-e98165fe]{color:red}.title{font-size:20px}
|
|
BIN
src/main/resources/logo.png
Normal file
BIN
src/main/resources/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
@@ -1,23 +1,22 @@
|
|||||||
|
# Refer https://docs.halo.run/developer-guide/plugin/basics/manifest
|
||||||
|
|
||||||
apiVersion: plugin.halo.run/v1alpha1
|
apiVersion: plugin.halo.run/v1alpha1
|
||||||
kind: Plugin
|
kind: Plugin
|
||||||
metadata:
|
metadata:
|
||||||
# The name defines how the plugin is invoked,A unique name
|
# The name defines how the plugin is invoked, A unique name
|
||||||
name: PluginStarter
|
name: starter
|
||||||
spec:
|
spec:
|
||||||
enabled: true
|
enabled: true
|
||||||
# 'version' is a valid semantic version string (see semver.org).
|
requires: ">=2.21.0"
|
||||||
version: 1.0.0-SNAPSHOT
|
|
||||||
requires: "*"
|
|
||||||
author:
|
author:
|
||||||
name: Halo OSS Team
|
name: Halo
|
||||||
website: https://github.com/halo-dev
|
website: https://github.com/halo-dev
|
||||||
logo: https://halo.run/logo
|
logo: logo.png
|
||||||
settingName: starter-settings
|
homepage: https://github.com/halo-dev/plugin-starter#readme
|
||||||
configMapName: starter-settings
|
repo: https://github.com/halo-dev/plugin-starter
|
||||||
# 'homepage' usually links to the GitHub repository of the plugin
|
issues: https://github.com/halo-dev/plugin-starter/issues
|
||||||
homepage: https://github.com/halo-dev/plugin-starter
|
|
||||||
# 'displayName' explains what the plugin does in only a few words
|
|
||||||
displayName: "插件快速开始模板"
|
displayName: "插件快速开始模板"
|
||||||
description: "这是一个插件快速开始模板"
|
description: "这是一个插件快速开始模板"
|
||||||
license:
|
license:
|
||||||
- name: "MIT"
|
- name: "GPL-3.0"
|
||||||
|
url: "https://github.com/halo-dev/plugin-starter/blob/main/LICENSE"
|
||||||
|
24
src/test/java/run/halo/starter/StarterPluginTest.java
Normal file
24
src/test/java/run/halo/starter/StarterPluginTest.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package run.halo.starter;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import run.halo.app.plugin.PluginContext;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class StarterPluginTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
PluginContext context;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
StarterPlugin plugin;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
plugin.start();
|
||||||
|
plugin.stop();
|
||||||
|
}
|
||||||
|
}
|
9
ui/.editorconfig
Normal file
9
ui/.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
|
||||||
|
charset = utf-8
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
end_of_line = lf
|
||||||
|
max_line_length = 100
|
0
console/.gitignore → ui/.gitignore
vendored
0
console/.gitignore → ui/.gitignore
vendored
7
ui/.prettierrc.json
Normal file
7
ui/.prettierrc.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/prettierrc",
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 100,
|
||||||
|
"tabWidth": 2
|
||||||
|
}
|
30
ui/build.gradle
Normal file
30
ui/build.gradle
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
plugins {
|
||||||
|
id 'base'
|
||||||
|
id "com.github.node-gradle.node" version "7.1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
group 'run.halo.starter.ui'
|
||||||
|
|
||||||
|
tasks.register('buildFrontend', PnpmTask) {
|
||||||
|
args = ['build']
|
||||||
|
dependsOn tasks.named('pnpmInstall')
|
||||||
|
inputs.dir(layout.projectDirectory.dir('src'))
|
||||||
|
inputs.files(fileTree(
|
||||||
|
dir: layout.projectDirectory,
|
||||||
|
includes: ['*.cjs', '*.ts', '*.js', '*.json', '*.yaml']))
|
||||||
|
outputs.dir(layout.buildDirectory.dir('dist'))
|
||||||
|
shouldRunAfter(tasks.named('check'))
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register('checkFrontend', PnpmTask) {
|
||||||
|
args = ['test:unit']
|
||||||
|
dependsOn tasks.named('pnpmInstall')
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.named('check') {
|
||||||
|
dependsOn tasks.named('checkFrontend')
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.named('build') {
|
||||||
|
dependsOn tasks.named('buildFrontend')
|
||||||
|
}
|
2
ui/env.d.ts
vendored
Normal file
2
ui/env.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
|
/// <reference types="unplugin-icons/types/vue" />
|
30
ui/eslint.config.ts
Normal file
30
ui/eslint.config.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { globalIgnores } from 'eslint/config'
|
||||||
|
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
|
||||||
|
import pluginVue from 'eslint-plugin-vue'
|
||||||
|
import pluginVitest from '@vitest/eslint-plugin'
|
||||||
|
import pluginOxlint from 'eslint-plugin-oxlint'
|
||||||
|
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
|
||||||
|
|
||||||
|
// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
|
||||||
|
// import { configureVueProject } from '@vue/eslint-config-typescript'
|
||||||
|
// configureVueProject({ scriptLangs: ['ts', 'tsx'] })
|
||||||
|
// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup
|
||||||
|
|
||||||
|
export default defineConfigWithVueTs(
|
||||||
|
{
|
||||||
|
name: 'app/files-to-lint',
|
||||||
|
files: ['**/*.{ts,mts,tsx,vue}'],
|
||||||
|
},
|
||||||
|
|
||||||
|
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
||||||
|
|
||||||
|
pluginVue.configs['flat/essential'],
|
||||||
|
vueTsConfigs.recommended,
|
||||||
|
|
||||||
|
{
|
||||||
|
...pluginVitest.configs.recommended,
|
||||||
|
files: ['src/**/__tests__/*'],
|
||||||
|
},
|
||||||
|
...pluginOxlint.configs['flat/recommended'],
|
||||||
|
skipFormatting,
|
||||||
|
)
|
50
ui/package.json
Normal file
50
ui/package.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "run-p type-check \"build-only {@}\" --",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"dev": "vite build --watch --mode=development",
|
||||||
|
"lint:oxlint": "oxlint . --fix -D correctness --ignore-path .gitignore",
|
||||||
|
"lint:eslint": "eslint . --fix",
|
||||||
|
"lint": "run-s lint:*",
|
||||||
|
"prettier": "prettier --write src/",
|
||||||
|
"test:unit": "vitest --passWithNoTests",
|
||||||
|
"type-check": "vue-tsc --build"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@halo-dev/api-client": "^2.21.0",
|
||||||
|
"@halo-dev/components": "^2.21.0",
|
||||||
|
"@halo-dev/console-shared": "^2.21.0",
|
||||||
|
"axios": "^1.7.2",
|
||||||
|
"canvas-confetti": "^1.9.3",
|
||||||
|
"vue": "^3.5.17"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@halo-dev/ui-plugin-bundler-kit": "^2.21.1",
|
||||||
|
"@iconify/json": "^2.2.350",
|
||||||
|
"@tsconfig/node20": "^20.1.6",
|
||||||
|
"@types/canvas-confetti": "^1.9.0",
|
||||||
|
"@types/jsdom": "^21.1.7",
|
||||||
|
"@types/node": "^20.19.1",
|
||||||
|
"@vitejs/plugin-vue": "^5.2.4",
|
||||||
|
"@vitest/eslint-plugin": "^1.2.7",
|
||||||
|
"@vue/eslint-config-prettier": "^10.2.0",
|
||||||
|
"@vue/eslint-config-typescript": "^14.5.1",
|
||||||
|
"@vue/test-utils": "^2.4.6",
|
||||||
|
"@vue/tsconfig": "^0.7.0",
|
||||||
|
"eslint": "^9.29.0",
|
||||||
|
"eslint-plugin-oxlint": "^0.16.12",
|
||||||
|
"eslint-plugin-vue": "~10.0.1",
|
||||||
|
"jsdom": "^26.1.0",
|
||||||
|
"npm-run-all2": "^7.0.2",
|
||||||
|
"oxlint": "^0.16.12",
|
||||||
|
"prettier": "3.5.3",
|
||||||
|
"sass": "^1.89.2",
|
||||||
|
"typescript": "~5.8.3",
|
||||||
|
"unplugin-icons": "^22.1.0",
|
||||||
|
"vite": "^5.3.2",
|
||||||
|
"vitest": "^3.2.4",
|
||||||
|
"vue-tsc": "^2.2.10"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@9.15.9"
|
||||||
|
}
|
4744
ui/pnpm-lock.yaml
generated
Normal file
4744
ui/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
29
ui/src/index.ts
Normal file
29
ui/src/index.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { definePlugin } from '@halo-dev/console-shared'
|
||||||
|
import HomeView from './views/HomeView.vue'
|
||||||
|
import { IconPlug } from '@halo-dev/components'
|
||||||
|
import { markRaw } from 'vue'
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
components: {},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
parentName: 'Root',
|
||||||
|
route: {
|
||||||
|
path: '/example',
|
||||||
|
name: 'Example',
|
||||||
|
component: HomeView,
|
||||||
|
meta: {
|
||||||
|
title: '示例页面',
|
||||||
|
searchable: true,
|
||||||
|
menu: {
|
||||||
|
name: '示例页面',
|
||||||
|
group: '示例分组',
|
||||||
|
icon: markRaw(IconPlug),
|
||||||
|
priority: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
extensionPoints: {},
|
||||||
|
})
|
166
ui/src/views/HomeView.vue
Normal file
166
ui/src/views/HomeView.vue
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import confetti from 'canvas-confetti'
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import RiShareCircleLine from '~icons/ri/share-circle-line'
|
||||||
|
import RiCodeBoxLine from '~icons/ri/code-box-line'
|
||||||
|
import RiBookReadLine from '~icons/ri/book-read-line'
|
||||||
|
import RiComputerLine from '~icons/ri/computer-line'
|
||||||
|
import RiArrowRightSLine from '~icons/ri/arrow-right-s-line'
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
confetti({
|
||||||
|
particleCount: 100,
|
||||||
|
spread: 70,
|
||||||
|
origin: { y: 0.6, x: 0.58 },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<section id="plugin-starter">
|
||||||
|
<div class="wrapper">
|
||||||
|
<span class="title"> 你已经成功运行起了插件! </span>
|
||||||
|
<span class="message">你可以点击下方文档继续下一步</span>
|
||||||
|
<div class="docs">
|
||||||
|
<a
|
||||||
|
href="https://docs.halo.run/developer-guide/plugin/publish"
|
||||||
|
class="docs__box"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<h2 class="docs__box-title"><RiShareCircleLine />发布一个插件</h2>
|
||||||
|
<span class="docs__box-message"> 了解如何与我们的社区分享您的扩展。 </span>
|
||||||
|
<span class="docs__box-arrow">
|
||||||
|
<RiArrowRightSLine />
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://docs.halo.run/category/%E5%9F%BA%E7%A1%80"
|
||||||
|
class="docs__box"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<h2 class="docs__box-title"><RiComputerLine />基础概览</h2>
|
||||||
|
<span class="docs__box-message"> 了解插件的项目结构、生命周期、资源配置等。 </span>
|
||||||
|
<span class="docs__box-arrow">
|
||||||
|
<RiArrowRightSLine />
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://docs.halo.run/developer-guide/plugin/examples/todolist"
|
||||||
|
class="docs__box group"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<h2 class="docs__box-title"><RiBookReadLine />示例插件</h2>
|
||||||
|
<span class="docs__box-message">帮助你从 0 到 1 完成一个插件。</span>
|
||||||
|
<span class="docs__box-arrow">
|
||||||
|
<RiArrowRightSLine />
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://docs.halo.run/category/api-%E5%8F%82%E8%80%83"
|
||||||
|
class="docs__box"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<h2 class="docs__box-title"><RiCodeBoxLine />API 参考</h2>
|
||||||
|
<span class="docs__box-message">插件中的 API 列表。</span>
|
||||||
|
<span class="docs__box-arrow">
|
||||||
|
<RiArrowRightSLine />
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#plugin-starter {
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
gap: 1.5rem;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.25rem;
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
max-width: 48rem;
|
||||||
|
|
||||||
|
.docs__box {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
transition-property: all;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 300ms;
|
||||||
|
cursor: pointer;
|
||||||
|
filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.1)) drop-shadow(0 1px 1px rgb(0 0 0 / 0.06));
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow:
|
||||||
|
0 0 0 0px #fff,
|
||||||
|
0 0 0 1px rgb(59 130 246 / 0.5),
|
||||||
|
0 0 #0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs__box-title {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
line-height: 1.75rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
gap: 0.5rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs__box-message {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.25rem;
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docs__box-arrow {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
transition-property: all;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 150ms;
|
||||||
|
color: #d1d5db;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.docs__box-arrow {
|
||||||
|
color: #9ca3af;
|
||||||
|
transform: translate(00.375rem, 0) rotate(0) skewX(0) skewY(0) scaleX(1) scaleY(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
.docs {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
12
ui/tsconfig.app.json
Normal file
12
ui/tsconfig.app.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||||
|
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||||
|
"exclude": ["src/**/__tests__/*"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
"files": [],
|
"files": [],
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
"path": "./tsconfig.config.json"
|
"path": "./tsconfig.node.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "./tsconfig.app.json"
|
"path": "./tsconfig.app.json"
|
12
ui/tsconfig.node.json
Normal file
12
ui/tsconfig.node.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/node20/tsconfig.json",
|
||||||
|
"include": ["vite.config.*", "vitest.config.*"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": true,
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"types": ["node"]
|
||||||
|
}
|
||||||
|
}
|
@@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
"extends": "./tsconfig.app.json",
|
"extends": "./tsconfig.app.json",
|
||||||
|
"include": ["src/**/__tests__/*", "env.d.ts"],
|
||||||
"exclude": [],
|
"exclude": [],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"composite": true,
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
|
||||||
|
|
||||||
"lib": [],
|
"lib": [],
|
||||||
"types": ["node", "jsdom"]
|
"types": ["node", "jsdom"]
|
||||||
}
|
}
|
25
ui/vite.config.ts
Normal file
25
ui/vite.config.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { fileURLToPath, URL } from 'url'
|
||||||
|
|
||||||
|
import { viteConfig } from '@halo-dev/ui-plugin-bundler-kit'
|
||||||
|
import Icons from 'unplugin-icons/vite'
|
||||||
|
import { configDefaults } from 'vitest/config'
|
||||||
|
|
||||||
|
// For more info,
|
||||||
|
// please see https://github.com/halo-dev/halo/tree/main/ui/packages/ui-plugin-bundler-kit
|
||||||
|
export default viteConfig({
|
||||||
|
vite: {
|
||||||
|
plugins: [Icons({ compiler: 'vue3' })],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// If you don't use Vitest, you can remove the following configuration
|
||||||
|
test: {
|
||||||
|
environment: 'jsdom',
|
||||||
|
exclude: [...configDefaults.exclude, 'e2e/**'],
|
||||||
|
root: fileURLToPath(new URL('./', import.meta.url)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
Reference in New Issue
Block a user