app_store_dev_api 0.1.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.claude/settings.local.json +40 -0
  4. data/CHANGELOG.md +59 -2
  5. data/CLAUDE.md +256 -0
  6. data/Gemfile.lock +29 -20
  7. data/README.md +212 -20
  8. data/Rakefile +99 -1
  9. data/SCRIPTS_ANALYSIS.md +261 -0
  10. data/docs/openapi.oas4.2.json +231546 -0
  11. data/install_local.bat +166 -0
  12. data/install_local.sh +84 -0
  13. data/install_local_fixed.sh +84 -0
  14. data/lib/.DS_Store +0 -0
  15. data/lib/app_store_dev_api/client/authorization.rb +7 -2
  16. data/lib/app_store_dev_api/client/builder.rb +43 -38
  17. data/lib/app_store_dev_api/client/options.rb +1 -1
  18. data/lib/app_store_dev_api/client.rb +31 -60
  19. data/lib/app_store_dev_api/object/attributes.rb +1 -1
  20. data/lib/app_store_dev_api/object/data.rb +6 -2
  21. data/lib/app_store_dev_api/object/relationships.rb +47 -0
  22. data/lib/app_store_dev_api/requests/v1/accessibility_declaration/create.rb +28 -0
  23. data/lib/app_store_dev_api/requests/v1/accessibility_declaration/update.rb +26 -0
  24. data/lib/app_store_dev_api/requests/v1/age_rating_declaration/update.rb +43 -0
  25. data/lib/app_store_dev_api/requests/v1/alternative_distribution_domain/create.rb +22 -0
  26. data/lib/app_store_dev_api/requests/v1/alternative_distribution_key/create.rb +25 -0
  27. data/lib/app_store_dev_api/requests/v1/alternative_distribution_package/create.rb +22 -0
  28. data/lib/app_store_dev_api/requests/v1/analytics_report_request/create.rb +25 -0
  29. data/lib/app_store_dev_api/requests/v1/android_to_ios_app_mapping_detail/create.rb +26 -0
  30. data/lib/app_store_dev_api/requests/v1/android_to_ios_app_mapping_detail/update.rb +22 -0
  31. data/lib/app_store_dev_api/requests/v1/app/update.rb +18 -20
  32. data/lib/app_store_dev_api/requests/v1/app_clip_advanced_experience/create.rb +32 -0
  33. data/lib/app_store_dev_api/requests/v1/app_clip_advanced_experience/update.rb +32 -0
  34. data/lib/app_store_dev_api/requests/v1/app_clip_advanced_experience_image/create.rb +22 -0
  35. data/lib/app_store_dev_api/requests/v1/app_clip_advanced_experience_image/update.rb +22 -0
  36. data/lib/app_store_dev_api/requests/v1/app_clip_app_store_review_detail/create.rb +19 -0
  37. data/lib/app_store_dev_api/requests/v1/{builds → app_clip_app_store_review_detail}/update.rb +4 -5
  38. data/lib/app_store_dev_api/requests/v1/app_clip_default_experience/create.rb +27 -0
  39. data/lib/app_store_dev_api/requests/v1/app_clip_default_experience/update.rb +25 -0
  40. data/lib/app_store_dev_api/requests/v1/app_clip_default_experience_localization/create.rb +26 -0
  41. data/lib/app_store_dev_api/requests/v1/app_clip_default_experience_localization/update.rb +21 -0
  42. data/lib/app_store_dev_api/requests/v1/app_clip_header_image/create.rb +26 -0
  43. data/lib/app_store_dev_api/requests/v1/app_clip_header_image/update.rb +22 -0
  44. data/lib/app_store_dev_api/requests/v1/app_custom_product_page/create.rb +28 -0
  45. data/lib/app_store_dev_api/requests/v1/app_custom_product_page/update.rb +22 -0
  46. data/lib/app_store_dev_api/requests/v1/app_custom_product_page_localization/create.rb +26 -0
  47. data/lib/app_store_dev_api/requests/v1/app_custom_product_page_localization/update.rb +21 -0
  48. data/lib/app_store_dev_api/requests/v1/app_custom_product_page_version/create.rb +26 -0
  49. data/lib/app_store_dev_api/requests/v1/app_custom_product_page_version/update.rb +21 -0
  50. data/lib/app_store_dev_api/requests/v1/app_encryption_declaration/create.rb +22 -0
  51. data/lib/app_store_dev_api/requests/v1/app_encryption_declaration_document/create.rb +24 -0
  52. data/lib/app_store_dev_api/requests/v1/app_encryption_declaration_document/update.rb +21 -0
  53. data/lib/app_store_dev_api/requests/v1/app_event/create.rb +26 -0
  54. data/lib/app_store_dev_api/requests/v1/app_event/update.rb +24 -0
  55. data/lib/app_store_dev_api/requests/v1/app_event_localization/create.rb +28 -0
  56. data/lib/app_store_dev_api/requests/v1/app_event_localization/update.rb +23 -0
  57. data/lib/app_store_dev_api/requests/v1/app_event_screenshot/create.rb +27 -0
  58. data/lib/app_store_dev_api/requests/v1/app_event_screenshot/update.rb +21 -0
  59. data/lib/app_store_dev_api/requests/v1/app_event_video_clip/create.rb +22 -0
  60. data/lib/app_store_dev_api/requests/v1/{promoted_purchases_image → app_event_video_clip}/update.rb +4 -4
  61. data/lib/app_store_dev_api/requests/v1/app_info/update.rb +15 -18
  62. data/lib/app_store_dev_api/requests/v1/app_info_localization/create.rb +17 -17
  63. data/lib/app_store_dev_api/requests/v1/app_info_localization/update.rb +14 -18
  64. data/lib/app_store_dev_api/requests/v1/app_preview/create.rb +22 -0
  65. data/lib/app_store_dev_api/requests/v1/app_preview/update.rb +22 -0
  66. data/lib/app_store_dev_api/requests/v1/app_preview_set/create.rb +25 -0
  67. data/lib/app_store_dev_api/requests/v1/app_preview_set/replace_app_previews_linkage.rb +19 -0
  68. data/lib/app_store_dev_api/requests/v1/app_price_schedule/create.rb +24 -0
  69. data/lib/app_store_dev_api/requests/v1/app_screenshot/create.rb +24 -0
  70. data/lib/app_store_dev_api/requests/v1/app_screenshot/update.rb +21 -0
  71. data/lib/app_store_dev_api/requests/v1/app_screenshot_set/create.rb +25 -0
  72. data/lib/app_store_dev_api/requests/v1/app_screenshot_set/replace_app_screenshots_linkage.rb +19 -0
  73. data/lib/app_store_dev_api/requests/v1/app_store_review_attachment/create.rb +20 -0
  74. data/lib/app_store_dev_api/requests/v1/app_store_review_attachment/update.rb +21 -0
  75. data/lib/app_store_dev_api/requests/v1/app_store_review_detail/create.rb +19 -20
  76. data/lib/app_store_dev_api/requests/v1/app_store_review_detail/update.rb +17 -18
  77. data/lib/app_store_dev_api/requests/v1/app_store_version/create.rb +20 -16
  78. data/lib/app_store_dev_api/requests/v1/app_store_version/update.rb +20 -18
  79. data/lib/app_store_dev_api/requests/v1/app_store_version_experiment/create.rb +26 -0
  80. data/lib/app_store_dev_api/requests/v1/app_store_version_experiment/update.rb +23 -0
  81. data/lib/app_store_dev_api/requests/v1/app_store_version_experiment_treatment/create.rb +27 -0
  82. data/lib/app_store_dev_api/requests/v1/app_store_version_experiment_treatment/update.rb +22 -0
  83. data/lib/app_store_dev_api/requests/v1/app_store_version_experiment_treatment_localization/create.rb +25 -0
  84. data/lib/app_store_dev_api/requests/v1/app_store_version_localization/create.rb +18 -18
  85. data/lib/app_store_dev_api/requests/v1/app_store_version_localization/update.rb +15 -18
  86. data/lib/app_store_dev_api/requests/v1/{app_store_version_phased_releases → app_store_version_phased_release}/create.rb +7 -2
  87. data/lib/app_store_dev_api/requests/v1/{app_store_version_phased_releases → app_store_version_phased_release}/update.rb +2 -2
  88. data/lib/app_store_dev_api/requests/v1/app_store_version_promotion/create.rb +10 -13
  89. data/lib/app_store_dev_api/requests/v1/{app_store_version_releases_request → app_store_version_release_request}/create.rb +5 -3
  90. data/lib/app_store_dev_api/requests/v1/app_tag/update.rb +21 -0
  91. data/lib/app_store_dev_api/requests/v1/background_asset/create.rb +19 -0
  92. data/lib/app_store_dev_api/requests/v1/background_asset/update.rb +21 -0
  93. data/lib/app_store_dev_api/requests/v1/background_asset_upload_file/create.rb +27 -0
  94. data/lib/app_store_dev_api/requests/v1/background_asset_upload_file/update.rb +23 -0
  95. data/lib/app_store_dev_api/requests/v1/background_asset_version/create.rb +16 -0
  96. data/lib/app_store_dev_api/requests/v1/beta_app_clip_invocation/create.rb +26 -0
  97. data/lib/app_store_dev_api/requests/v1/beta_app_clip_invocation/update.rb +21 -0
  98. data/lib/app_store_dev_api/requests/v1/beta_app_clip_invocation_localization/create.rb +26 -0
  99. data/lib/app_store_dev_api/requests/v1/beta_app_clip_invocation_localization/update.rb +21 -0
  100. data/lib/app_store_dev_api/requests/v1/beta_app_localization/create.rb +30 -0
  101. data/lib/app_store_dev_api/requests/v1/beta_app_localization/update.rb +25 -0
  102. data/lib/app_store_dev_api/requests/v1/beta_app_review_detail/update.rb +28 -0
  103. data/lib/app_store_dev_api/requests/v1/beta_app_review_submission/create.rb +22 -0
  104. data/lib/app_store_dev_api/requests/v1/beta_build_localization/create.rb +18 -18
  105. data/lib/app_store_dev_api/requests/v1/beta_build_localization/update.rb +15 -20
  106. data/lib/app_store_dev_api/requests/v1/beta_group/create.rb +33 -0
  107. data/lib/app_store_dev_api/requests/v1/beta_group/update.rb +27 -0
  108. data/lib/app_store_dev_api/requests/v1/beta_license_agreement/update.rb +21 -0
  109. data/lib/app_store_dev_api/requests/v1/beta_recruitment_criterion/create.rb +25 -0
  110. data/lib/app_store_dev_api/requests/v1/beta_recruitment_criterion/update.rb +21 -0
  111. data/lib/app_store_dev_api/requests/v1/beta_tester/create.rb +28 -0
  112. data/lib/app_store_dev_api/requests/v1/beta_tester_invitation/create.rb +23 -0
  113. data/lib/app_store_dev_api/requests/v1/build_beta_detail/update.rb +10 -13
  114. data/lib/app_store_dev_api/requests/v1/{subscription_price_change_consent_reason → build_beta_notification}/create.rb +8 -2
  115. data/lib/app_store_dev_api/requests/v1/build_upload/create.rb +27 -0
  116. data/lib/app_store_dev_api/requests/v1/build_upload_file/create.rb +28 -0
  117. data/lib/app_store_dev_api/requests/v1/build_upload_file/update.rb +22 -0
  118. data/lib/app_store_dev_api/requests/v1/bundle_id/create.rb +12 -15
  119. data/lib/app_store_dev_api/requests/v1/bundle_id/update.rb +20 -0
  120. data/lib/app_store_dev_api/requests/v1/bundle_id_capability/create.rb +13 -16
  121. data/lib/app_store_dev_api/requests/v1/bundle_id_capability/update.rb +18 -0
  122. data/lib/app_store_dev_api/requests/v1/certificate/create.rb +14 -15
  123. data/lib/app_store_dev_api/requests/v1/certificate/update.rb +17 -0
  124. data/lib/app_store_dev_api/requests/v1/ci_build_run/create.rb +28 -0
  125. data/lib/app_store_dev_api/requests/v1/ci_workflow/create.rb +41 -0
  126. data/lib/app_store_dev_api/requests/v1/ci_workflow/update.rb +39 -0
  127. data/lib/app_store_dev_api/requests/v1/customer_review_response_v1/create.rb +25 -0
  128. data/lib/app_store_dev_api/requests/v1/device/update.rb +18 -0
  129. data/lib/app_store_dev_api/requests/v1/end_app_availability_pre_order/create.rb +16 -0
  130. data/lib/app_store_dev_api/requests/v1/end_user_license_agreement/create.rb +24 -0
  131. data/lib/app_store_dev_api/requests/v1/end_user_license_agreement/update.rb +24 -0
  132. data/lib/app_store_dev_api/requests/v1/game_center_achievement/create.rb +31 -0
  133. data/lib/app_store_dev_api/requests/v1/game_center_achievement/update.rb +26 -0
  134. data/lib/app_store_dev_api/requests/v1/game_center_achievement_image/create.rb +26 -0
  135. data/lib/app_store_dev_api/requests/v1/game_center_achievement_image/update.rb +21 -0
  136. data/lib/app_store_dev_api/requests/v1/game_center_achievement_localization/create.rb +28 -0
  137. data/lib/app_store_dev_api/requests/v1/game_center_achievement_localization/update.rb +23 -0
  138. data/lib/app_store_dev_api/requests/v1/game_center_achievement_release/create.rb +23 -0
  139. data/lib/app_store_dev_api/requests/v1/game_center_activity/create.rb +32 -0
  140. data/lib/app_store_dev_api/requests/v1/game_center_activity/update.rb +27 -0
  141. data/lib/app_store_dev_api/requests/v1/game_center_activity_image/create.rb +27 -0
  142. data/lib/app_store_dev_api/requests/v1/game_center_activity_image/update.rb +21 -0
  143. data/lib/app_store_dev_api/requests/v1/game_center_activity_localization/create.rb +27 -0
  144. data/lib/app_store_dev_api/requests/v1/game_center_activity_localization/update.rb +22 -0
  145. data/lib/app_store_dev_api/requests/v1/game_center_activity_version/create.rb +25 -0
  146. data/lib/app_store_dev_api/requests/v1/game_center_activity_version/update.rb +21 -0
  147. data/lib/app_store_dev_api/requests/v1/game_center_activity_version_release/create.rb +23 -0
  148. data/lib/app_store_dev_api/requests/v1/game_center_app_version/create.rb +22 -0
  149. data/lib/app_store_dev_api/requests/v1/game_center_app_version/update.rb +21 -0
  150. data/lib/app_store_dev_api/requests/v1/game_center_challenge/create.rb +31 -0
  151. data/lib/app_store_dev_api/requests/v1/game_center_challenge/update.rb +28 -0
  152. data/lib/app_store_dev_api/requests/v1/game_center_challenge_image/create.rb +27 -0
  153. data/lib/app_store_dev_api/requests/v1/game_center_challenge_image/update.rb +21 -0
  154. data/lib/app_store_dev_api/requests/v1/game_center_challenge_localization/create.rb +27 -0
  155. data/lib/app_store_dev_api/requests/v1/game_center_challenge_localization/update.rb +22 -0
  156. data/lib/app_store_dev_api/requests/v1/game_center_challenge_version/create.rb +22 -0
  157. data/lib/app_store_dev_api/requests/v1/game_center_challenge_version_release/create.rb +23 -0
  158. data/lib/app_store_dev_api/requests/v1/{subscription_review_screenshot → game_center_detail}/create.rb +9 -4
  159. data/lib/app_store_dev_api/requests/v1/game_center_detail/update.rb +29 -0
  160. data/lib/app_store_dev_api/requests/v1/{customer_review_response → game_center_group}/create.rb +6 -4
  161. data/lib/app_store_dev_api/requests/v1/game_center_group/update.rb +21 -0
  162. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard/create.rb +38 -0
  163. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard/update.rb +32 -0
  164. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_entry_submission/create.rb +27 -0
  165. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_image/create.rb +26 -0
  166. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_image/update.rb +21 -0
  167. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_localization/create.rb +30 -0
  168. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_localization/update.rb +25 -0
  169. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_release/create.rb +23 -0
  170. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set/create.rb +28 -0
  171. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set/update.rb +21 -0
  172. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_image/create.rb +26 -0
  173. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_image/update.rb +21 -0
  174. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_localization/create.rb +26 -0
  175. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_localization/update.rb +21 -0
  176. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_member_localization/create.rb +27 -0
  177. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_member_localization/update.rb +21 -0
  178. data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_release/create.rb +23 -0
  179. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_queue/create.rb +27 -0
  180. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_queue/update.rb +26 -0
  181. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule/create.rb +29 -0
  182. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule/update.rb +23 -0
  183. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule_set/create.rb +24 -0
  184. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule_set/update.rb +22 -0
  185. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule_set_test/create.rb +23 -0
  186. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_team/create.rb +27 -0
  187. data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_team/update.rb +22 -0
  188. data/lib/app_store_dev_api/requests/v1/game_center_player_achievement_submission/create.rb +26 -0
  189. data/lib/app_store_dev_api/requests/v1/{in_app_purchase_review_screenshot → in_app_purchase_app_store_review_screenshot}/create.rb +9 -3
  190. data/lib/app_store_dev_api/requests/v1/{in_app_purchase_review_screenshot → in_app_purchase_app_store_review_screenshot}/update.rb +4 -3
  191. data/lib/app_store_dev_api/requests/v1/in_app_purchase_availability/create.rb +13 -12
  192. data/lib/app_store_dev_api/requests/v1/in_app_purchase_image/create.rb +24 -0
  193. data/lib/app_store_dev_api/requests/v1/in_app_purchase_image/update.rb +18 -0
  194. data/lib/app_store_dev_api/requests/v1/in_app_purchase_localization/create.rb +14 -14
  195. data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code/create.rb +27 -0
  196. data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code/update.rb +21 -0
  197. data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code_custom_code/create.rb +27 -0
  198. data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code_custom_code/update.rb +21 -0
  199. data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code_one_time_use_code/create.rb +27 -0
  200. data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code_one_time_use_code/update.rb +21 -0
  201. data/lib/app_store_dev_api/requests/v1/in_app_purchase_price_schedule/create.rb +11 -10
  202. data/lib/app_store_dev_api/requests/v1/in_app_purchase_submission/create.rb +9 -10
  203. data/lib/app_store_dev_api/requests/v1/marketplace_search_detail/create.rb +25 -0
  204. data/lib/app_store_dev_api/requests/v1/marketplace_search_detail/update.rb +21 -0
  205. data/lib/app_store_dev_api/requests/v1/{promoted_purchases → marketplace_webhook}/create.rb +7 -5
  206. data/lib/app_store_dev_api/requests/v1/marketplace_webhook/update.rb +22 -0
  207. data/lib/app_store_dev_api/requests/v1/merchant_id/create.rb +22 -0
  208. data/lib/app_store_dev_api/requests/v1/{app_price_schedule → merchant_id}/update.rb +7 -3
  209. data/lib/app_store_dev_api/requests/v1/nomination/create.rb +39 -0
  210. data/lib/app_store_dev_api/requests/v1/nomination/update.rb +40 -0
  211. data/lib/app_store_dev_api/requests/v1/pass_type_id/create.rb +22 -0
  212. data/lib/app_store_dev_api/requests/v1/pass_type_id/update.rb +21 -0
  213. data/lib/app_store_dev_api/requests/v1/profile/create.rb +14 -23
  214. data/lib/app_store_dev_api/requests/v1/promoted_purchase/create.rb +28 -0
  215. data/lib/app_store_dev_api/requests/v1/{promoted_purchases → promoted_purchase}/update.rb +4 -3
  216. data/lib/app_store_dev_api/requests/v1/review_submission/create.rb +11 -7
  217. data/lib/app_store_dev_api/requests/v1/review_submission/update.rb +12 -15
  218. data/lib/app_store_dev_api/requests/v1/review_submission_item/create.rb +20 -8
  219. data/lib/app_store_dev_api/requests/v1/review_submission_item/update.rb +18 -0
  220. data/lib/app_store_dev_api/requests/v1/routing_app_coverage/create.rb +24 -0
  221. data/lib/app_store_dev_api/requests/v1/routing_app_coverage/update.rb +21 -0
  222. data/lib/app_store_dev_api/requests/v1/subscription/create.rb +17 -17
  223. data/lib/app_store_dev_api/requests/v1/subscription/update.rb +19 -17
  224. data/lib/app_store_dev_api/requests/v1/subscription_app_store_review_screenshot/create.rb +26 -0
  225. data/lib/app_store_dev_api/requests/v1/{subscription_review_screenshot → subscription_app_store_review_screenshot}/update.rb +4 -3
  226. data/lib/app_store_dev_api/requests/v1/subscription_availability/create.rb +13 -12
  227. data/lib/app_store_dev_api/requests/v1/subscription_grace_period/update.rb +13 -16
  228. data/lib/app_store_dev_api/requests/v1/subscription_group/create.rb +12 -13
  229. data/lib/app_store_dev_api/requests/v1/subscription_group/update.rb +10 -14
  230. data/lib/app_store_dev_api/requests/v1/subscription_group_localization/create.rb +14 -16
  231. data/lib/app_store_dev_api/requests/v1/subscription_group_localization/update.rb +11 -16
  232. data/lib/app_store_dev_api/requests/v1/subscription_group_submission/create.rb +9 -10
  233. data/lib/app_store_dev_api/requests/v1/subscription_image/create.rb +20 -0
  234. data/lib/app_store_dev_api/requests/v1/subscription_image/update.rb +21 -0
  235. data/lib/app_store_dev_api/requests/v1/subscription_introductory_offer/create.rb +18 -18
  236. data/lib/app_store_dev_api/requests/v1/subscription_introductory_offer/update.rb +10 -15
  237. data/lib/app_store_dev_api/requests/v1/subscription_localization/create.rb +14 -16
  238. data/lib/app_store_dev_api/requests/v1/subscription_offer_code/create.rb +19 -19
  239. data/lib/app_store_dev_api/requests/v1/{subscription_offer_code_cunstom_code → subscription_offer_code_custom_code}/create.rb +9 -5
  240. data/lib/app_store_dev_api/requests/v1/{subscription_offer_code_cunstom_code → subscription_offer_code_custom_code}/update.rb +2 -3
  241. data/lib/app_store_dev_api/requests/v1/subscription_offer_code_one_time_use_code/create.rb +14 -15
  242. data/lib/app_store_dev_api/requests/v1/subscription_price/create.rb +15 -13
  243. data/lib/app_store_dev_api/requests/v1/subscription_promotional_offer/create.rb +17 -18
  244. data/lib/app_store_dev_api/requests/v1/subscription_promotional_offer/update.rb +10 -12
  245. data/lib/app_store_dev_api/requests/v1/subscription_submission/create.rb +9 -8
  246. data/lib/app_store_dev_api/requests/v1/{app_availability → territory_availability}/update.rb +4 -7
  247. data/lib/app_store_dev_api/requests/v1/user/update.rb +27 -0
  248. data/lib/app_store_dev_api/requests/v1/user_invitation/create.rb +30 -0
  249. data/lib/app_store_dev_api/requests/v1/webhook/create.rb +23 -0
  250. data/lib/app_store_dev_api/requests/v1/webhook/update.rb +21 -0
  251. data/lib/app_store_dev_api/requests/v1/webhook_delivery/create.rb +16 -0
  252. data/lib/app_store_dev_api/requests/v1/webhook_ping/create.rb +16 -0
  253. data/lib/app_store_dev_api/requests/v1/win_back_offer/create.rb +31 -0
  254. data/lib/app_store_dev_api/requests/v1/win_back_offer/update.rb +23 -0
  255. data/lib/app_store_dev_api/requests/v1/win_back_offer/update_prices_linkages.rb +18 -0
  256. data/lib/app_store_dev_api/requests/v2/app_availability/create.rb +13 -14
  257. data/lib/app_store_dev_api/requests/v2/app_availability_v2/create.rb +26 -0
  258. data/lib/app_store_dev_api/requests/v2/app_store_version_experiment_v2/create.rb +27 -0
  259. data/lib/app_store_dev_api/requests/v2/app_store_version_experiment_v2/update.rb +23 -0
  260. data/lib/app_store_dev_api/requests/v2/game_center_achievement_image_v2/create.rb +26 -0
  261. data/lib/app_store_dev_api/requests/v2/game_center_achievement_image_v2/update.rb +21 -0
  262. data/lib/app_store_dev_api/requests/v2/game_center_achievement_localization_v2/create.rb +28 -0
  263. data/lib/app_store_dev_api/requests/v2/game_center_achievement_localization_v2/update.rb +23 -0
  264. data/lib/app_store_dev_api/requests/v2/game_center_achievement_v2/create.rb +32 -0
  265. data/lib/app_store_dev_api/requests/v2/game_center_achievement_v2/update.rb +26 -0
  266. data/lib/app_store_dev_api/requests/v2/game_center_achievement_version_v2/create.rb +22 -0
  267. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_image_v2/create.rb +26 -0
  268. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_image_v2/update.rb +21 -0
  269. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_localization_v2/create.rb +30 -0
  270. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_localization_v2/update.rb +25 -0
  271. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_image_v2/create.rb +26 -0
  272. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_image_v2/update.rb +21 -0
  273. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_localization_v2/create.rb +26 -0
  274. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_localization_v2/update.rb +21 -0
  275. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_v2/create.rb +29 -0
  276. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_v2/update.rb +21 -0
  277. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_version_v2/create.rb +22 -0
  278. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_v2/create.rb +39 -0
  279. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_v2/update.rb +32 -0
  280. data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_version_v2/create.rb +22 -0
  281. data/lib/app_store_dev_api/requests/v2/in_app_purchase/create.rb +16 -17
  282. data/lib/app_store_dev_api/requests/v2/in_app_purchase/update.rb +12 -15
  283. data/lib/app_store_dev_api/requests/v2/in_app_purchase_v2/create.rb +29 -0
  284. data/lib/app_store_dev_api/requests/v2/in_app_purchase_v2/update.rb +23 -0
  285. data/lib/app_store_dev_api/requests/v2/{sandbox_tester → sandbox_tester_v2}/update.rb +5 -4
  286. data/lib/app_store_dev_api/requests/v2/{sandbox_tester_clear_purchase_history/update.rb → sandbox_testers_clear_purchase_history_request_v2/create.rb} +9 -3
  287. data/lib/app_store_dev_api/version.rb +1 -1
  288. data/lib/config/{schema.json → schema_backup.json} +1185 -51
  289. data/lib/config/schema_v4.2.json +7317 -0
  290. data/release_remote.sh +121 -0
  291. data/scripts/README.md +126 -0
  292. data/scripts/cleanup_scripts.sh +73 -0
  293. data/scripts/comprehensive_validation.rb +359 -0
  294. data/scripts/comprehensive_validation_report.json +12 -0
  295. data/scripts/final_validation_report.rb +134 -0
  296. data/scripts/find_deprecated_requests.rb +145 -0
  297. data/scripts/test_request_body_classes.rb +185 -0
  298. data/scripts/validate_requests.rb +192 -0
  299. metadata +241 -34
  300. data/CODE_OF_CONDUCT.md +0 -84
  301. data/lib/app_store_dev_api/requests/v1/app_promoted_purchases/update.rb +0 -16
  302. data/lib/app_store_dev_api/requests/v1/app_store_version_build_linkage_request/update.rb +0 -17
  303. data/lib/app_store_dev_api/requests/v1/build_beta_groups/create.rb +0 -16
  304. data/lib/app_store_dev_api/requests/v1/build_beta_groups/delete.rb +0 -16
  305. data/lib/app_store_dev_api/requests/v1/promoted_purchases_image/create.rb +0 -20
  306. data/lib/app_store_dev_api/requests/v2/sandbox_tester/create.rb +0 -23
  307. data/release.sh +0 -55
data/release_remote.sh ADDED
@@ -0,0 +1,121 @@
1
+ #!/bin/bash
2
+
3
+ #当前脚本目录
4
+ CURRENT_DIR=$(dirname $(readlink -f $0))
5
+ echo $CURRENT_DIR
6
+
7
+
8
+ # Make all files and directories in the current directory readable, writable, and executable for all users.
9
+ /bin/chmod -R a+rwx $CURRENT_DIR
10
+ # Change the owner of the current directory to the current user.
11
+ /usr/sbin/chown $(whoami) $CURRENT_DIR
12
+ # Change the group of the current directory to "admin".
13
+ /usr/bin/chgrp admin $CURRENT_DIR
14
+
15
+ function readConfigValue()
16
+ {
17
+ File=$1
18
+ KEY=$2
19
+ VALUE=$(grep -m 1 -o "^[ ]*$KEY[ ]*=[ ]*[\"]*.*[\"]*" $File | sed -e "s/^[ ]*$KEY[ ]*=[ ]*[\"]*//" -e "s/[\"]*$//")VALUE=$(grep -m 1 -o "^[ ]*$KEY[ ]*=[ ]*[\"]*.*[\"]*" $File | sed -e "s/^[ ]*$KEY[ ]*=[ ]*[\"]*//" -e "s/[\"]*$//")
20
+ echo $VALUE
21
+ }
22
+
23
+
24
+ rm -rf $CURRENT_DIR/*app_store_dev_api-*.gem
25
+
26
+ VERSION_FILE=${CURRENT_DIR}/lib/app_store_dev_api/version.rb
27
+ VERSION_TAG_NAME=$(grep VERSION ${VERSION_FILE} | cut -d"'" -f2)
28
+ TAG_NAME="v${VERSION_TAG_NAME}"
29
+
30
+ COMMIT_FILE_LIST=$(git -C $CURRENT_DIR ls-files --other --modified --exclude-standard)
31
+ echo $COMMIT_FILE_LIST
32
+
33
+ if [ -z "$COMMIT_FILE_LIST" ]; then
34
+ echo "没有需要提交的文件!"
35
+ else
36
+ echo "提交没有提交的文件!"
37
+ # $(git -C $CURRENT_DIR ls-files --other --modified --exclude-standard)
38
+ git -C $CURRENT_DIR add -A
39
+ git -C $CURRENT_DIR commit -m "res ${VERSION_TAG_NAME}"
40
+ git -C $CURRENT_DIR push
41
+ fi
42
+
43
+
44
+
45
+ #合并到master分支
46
+ RELEASE_BRANCH="master"
47
+ CODING_BRANCH=$(git -C $CURRENT_DIR rev-parse --abbrev-ref HEAD)
48
+
49
+ if [[ "$CODING_BRANCH" == "$RELEASE_BRANCH" ]]; then
50
+ echo "在master分支不需要处理"
51
+ else
52
+ git -C $CURRENT_DIR checkout $RELEASE_BRANCH
53
+ git -C $CURRENT_DIR merge $CODING_BRANCH
54
+ git -C $CURRENT_DIR push
55
+
56
+ git -C $CURRENT_DIR checkout $CODING_BRANCH
57
+ git -C $CURRENT_DIR merge $RELEASE_BRANCH
58
+ git -C $CURRENT_DIR push
59
+
60
+ fi
61
+
62
+
63
+
64
+ gem build $CURRENT_DIR/app_store_dev_api.gemspec
65
+ if [[ -f $CURRENT_DIR/app_store_dev_api-${VERSION_TAG_NAME}.gem ]]; then
66
+ gem install --local $CURRENT_DIR/app_store_dev_api-${VERSION_TAG_NAME}.gem
67
+ fi
68
+
69
+
70
+ #添加tag
71
+ git -C $CURRENT_DIR checkout $RELEASE_BRANCH
72
+ EXIST_LOCAL_TAG=$(git -C $CURRENT_DIR tag --list ${TAG_NAME})
73
+ if [ -z "$EXIST_LOCAL_TAG" ]; then
74
+ #statements
75
+ echo "无本地tag:${TAG_NAME}"
76
+ else
77
+
78
+ echo "删除本地tag:${TAG_NAME}"
79
+ git -C $CURRENT_DIR tag -d ${TAG_NAME}
80
+ fi
81
+
82
+ REMOTE_EXIST_TAG=$(git -C $CURRENT_DIR ls-remote --tags origin "refs/tags/${TAG_NAME}")
83
+ if [ -z "$REMOTE_EXIST_TAG" ]; then
84
+ #statements
85
+ echo "无远程tag:${TAG_NAME}"
86
+ else
87
+
88
+ DELETE_REMOTE_TAG=""
89
+ read -p "存在远程分支,确认要删除远程分支吗?[Y/n]: " DELETE_REMOTE_TAG
90
+ case "${DELETE_REMOTE_TAG}" in
91
+ [yY][eE][sS] | [yY])
92
+ echo "删除远程tag:${TAG_NAME}"
93
+ git -C $CURRENT_DIR push origin :${TAG_NAME}
94
+ ;;
95
+ # [nN][oO] | [nN])
96
+ # echo "exit!"
97
+ # exit 1
98
+ # ;;
99
+ *)
100
+ echo "Exit!"
101
+ exit 1
102
+ ;;
103
+ esac
104
+ fi
105
+
106
+ git -C $CURRENT_DIR tag ${TAG_NAME}
107
+ git -C $CURRENT_DIR push origin ${TAG_NAME}
108
+ git -C $CURRENT_DIR checkout $CODING_BRANCH
109
+
110
+
111
+ if [[ -f $CURRENT_DIR/app_store_dev_api-${VERSION_TAG_NAME}.gem ]]; then
112
+ gem push $CURRENT_DIR/app_store_dev_api-${VERSION_TAG_NAME}.gem
113
+ fi
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
data/scripts/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # Scripts 目录说明
2
+
3
+ 本目录包含用于维护和验证 AppStoreDevApi 的工具脚本。
4
+
5
+ ## 🔧 核心工具(建议保留)
6
+
7
+ ### 1. `validate_requests.rb` ⭐ 核心验证工具
8
+ **用途**: 验证所有 Request 类与 OpenAPI 规范的一致性
9
+ **使用场景**:
10
+ - API 升级后验证
11
+ - 定期检查一致性
12
+ - CI/CD 流程集成
13
+
14
+ **使用方法**:
15
+ ```bash
16
+ ruby scripts/validate_requests.rb
17
+ ```
18
+
19
+ ### 2. `comprehensive_validation.rb` ⭐ 全面验证工具
20
+ **用途**: 三方交叉验证(schema.json ↔ Request 类 ↔ OpenAPI)
21
+ **使用场景**:
22
+ - 重大更新后的全面检查
23
+ - 发布前验证
24
+
25
+ **使用方法**:
26
+ ```bash
27
+ ruby scripts/comprehensive_validation.rb
28
+ ```
29
+
30
+ ### 3. `test_request_body_classes.rb` ⭐ 功能测试
31
+ **用途**: 测试 Request Body 类的功能是否正常
32
+ **使用场景**:
33
+ - 修改核心代码后测试
34
+ - 回归测试
35
+
36
+ **使用方法**:
37
+ ```bash
38
+ ruby scripts/test_request_body_classes.rb
39
+ ```
40
+
41
+ ### 4. `find_deprecated_requests.rb` ⭐ 废弃检测工具
42
+ **用途**: 查找代码库中不在 OpenAPI 规范中的废弃接口
43
+ **使用场景**:
44
+ - OpenAPI 规范更新后
45
+ - 定期清理
46
+
47
+ **使用方法**:
48
+ ```bash
49
+ ruby scripts/find_deprecated_requests.rb
50
+ ```
51
+
52
+ ## 🛠️ 一次性工具(可以删除)
53
+
54
+ ### 修复和分析工具
55
+ 这些脚本用于一次性修复问题,完成后可以删除:
56
+
57
+ - `fix_requests.rb` - 自动修复工具(已完成使用)
58
+ - `analyze_deprecated.rb` - 废弃接口分析(已完成使用)
59
+ - `check_naming_conflicts.rb` - 命名冲突检查(已完成使用)
60
+
61
+ ### 代码生成工具
62
+ 这些是早期开发使用的工具,可以删除:
63
+
64
+ - `generate_request_body_classes.rb`
65
+ - `generate_smart_schema.rb`
66
+ - `generate_smart_schema_v2.rb`
67
+ - `openapi_to_schema.rb`
68
+
69
+ ### 分析和对比工具
70
+ 一次性分析工具,可以删除:
71
+
72
+ - `analyze_alias_changes.rb`
73
+ - `analyze_request_body_coverage.rb`
74
+ - `architecture_compatibility_test.rb`
75
+ - `check_missing_endpoints.rb`
76
+ - `check_request_body_types.rb`
77
+ - `compare_schemas.rb`
78
+ - `compare_types.rb`
79
+ - `comprehensive_code_review.rb`
80
+ - `comprehensive_uniqueness_check.rb`
81
+ - `deep_validation.rb`
82
+ - `detailed_compatibility_check.rb`
83
+ - `detect_duplicate_aliases.rb`
84
+ - `extract_naming_rules.rb`
85
+ - `list_alias_changes.rb`
86
+ - `verify_compatibility.rb`
87
+ - `verify_all_requests.rb`
88
+
89
+ ## 📄 报告文件(可以删除)
90
+
91
+ 所有 JSON 报告文件都是临时生成的,可以删除:
92
+
93
+ - `validation_report.json`
94
+ - `comprehensive_validation_report.json`
95
+ - `deprecated_requests.json`
96
+ - `deprecated_analysis.json`
97
+ - `validation_certificate.json`
98
+
99
+ 如果需要,这些文件可以通过运行对应的脚本重新生成。
100
+
101
+ ## 📋 最终清理方案
102
+
103
+ ### 建议保留(4个核心脚本)
104
+ ```
105
+ scripts/
106
+ ├── validate_requests.rb # API 一致性验证
107
+ ├── comprehensive_validation.rb # 三方交叉验证
108
+ ├── test_request_body_classes.rb # 功能测试
109
+ ├── find_deprecated_requests.rb # 废弃检测
110
+ └── README.md # 本说明文件
111
+ ```
112
+
113
+ ### 可以删除的文件
114
+ - 所有其他 .rb 脚本(30+ 个)
115
+ - 所有 .json 报告文件(5+ 个)
116
+
117
+ ## 🔄 未来维护
118
+
119
+ 当 Apple 发布新的 API 版本时:
120
+
121
+ 1. 更新 `docs/openapi.oas{version}.json`
122
+ 2. 运行 `validate_requests.rb` 检查不一致
123
+ 3. 运行 `find_deprecated_requests.rb` 查找废弃接口
124
+ 4. 修复发现的问题
125
+ 5. 运行 `comprehensive_validation.rb` 全面验证
126
+ 6. 运行 `test_request_body_classes.rb` 确保功能正常
@@ -0,0 +1,73 @@
1
+ #!/bin/bash
2
+ # 清理 scripts 目录中的临时文件
3
+
4
+ echo "=========================================="
5
+ echo "清理 scripts 目录"
6
+ echo "=========================================="
7
+ echo
8
+
9
+ # 要保留的核心脚本
10
+ KEEP_FILES=(
11
+ "validate_requests.rb"
12
+ "comprehensive_validation.rb"
13
+ "test_request_body_classes.rb"
14
+ "find_deprecated_requests.rb"
15
+ "final_validation_report.rb"
16
+ "README.md"
17
+ "cleanup_scripts.sh"
18
+ )
19
+
20
+ cd "$(dirname "$0")"
21
+
22
+ echo "📋 将保留以下文件:"
23
+ for file in "${KEEP_FILES[@]}"; do
24
+ echo " ✓ $file"
25
+ done
26
+ echo
27
+
28
+ # 收集要删除的文件
29
+ FILES_TO_DELETE=()
30
+
31
+ for file in *.rb *.json *.sh; do
32
+ if [[ -f "$file" ]]; then
33
+ # 检查是否在保留列表中
34
+ should_keep=false
35
+ for keep in "${KEEP_FILES[@]}"; do
36
+ if [[ "$file" == "$keep" ]]; then
37
+ should_keep=true
38
+ break
39
+ fi
40
+ done
41
+
42
+ if [[ "$should_keep" == false ]]; then
43
+ FILES_TO_DELETE+=("$file")
44
+ fi
45
+ fi
46
+ done
47
+
48
+ if [ ${#FILES_TO_DELETE[@]} -eq 0 ]; then
49
+ echo "✅ 没有需要删除的文件"
50
+ exit 0
51
+ fi
52
+
53
+ echo "🗑️ 将删除以下文件 (${#FILES_TO_DELETE[@]} 个):"
54
+ for file in "${FILES_TO_DELETE[@]}"; do
55
+ echo " ✗ $file"
56
+ done
57
+ echo
58
+
59
+ read -p "确认删除? (y/n) " -n 1 -r
60
+ echo
61
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
62
+ for file in "${FILES_TO_DELETE[@]}"; do
63
+ rm "$file"
64
+ echo " 已删除: $file"
65
+ done
66
+ echo
67
+ echo "✅ 清理完成!"
68
+ echo
69
+ echo "保留的核心工具:"
70
+ ls -lh *.rb *.md 2>/dev/null | awk '{print " " $9 " (" $5 ")"}'
71
+ else
72
+ echo "❌ 取消删除"
73
+ fi
@@ -0,0 +1,359 @@
1
+ #!/usr/bin/env ruby
2
+ # 全面验证:schema.json、Request 类、OpenAPI v4.2 三方一致性
3
+
4
+ require 'json'
5
+ require 'set'
6
+
7
+ puts "=" * 100
8
+ puts "🔍 全面一致性验证:schema.json ↔ Request 类 ↔ OpenAPI v4.2"
9
+ puts "=" * 100
10
+ puts
11
+
12
+ # 1. 读取 OpenAPI 规范
13
+ openapi_file = File.join(__dir__, '../docs/openapi.oas4.2.json')
14
+ openapi_data = JSON.parse(File.read(openapi_file))
15
+ openapi_schemas = openapi_data['components']['schemas']
16
+ openapi_paths = openapi_data['paths']
17
+
18
+ # 2. 读取 schema.json 配置
19
+ schema_files = [
20
+ File.join(__dir__, '../lib/config/schema_v4.2.json'),
21
+ File.join(__dir__, '../lib/config/schema.json')
22
+ ].find { |f| File.exist?(f) }
23
+
24
+ if schema_files.nil?
25
+ puts "❌ 错误: 未找到 schema.json 文件"
26
+ exit 1
27
+ end
28
+
29
+ schema_data = JSON.parse(File.read(schema_files))
30
+ schema_endpoints = schema_data['web_service_endpoints'] || []
31
+
32
+ # 3. 扫描所有 Request 类文件
33
+ def scan_request_classes
34
+ request_classes = []
35
+
36
+ ['v1', 'v2'].each do |version|
37
+ base_dir = File.join(__dir__, "../lib/app_store_dev_api/requests/#{version}")
38
+ next unless Dir.exist?(base_dir)
39
+
40
+ Dir.glob("#{base_dir}/**/{create,update}.rb").each do |file|
41
+ request_classes << {
42
+ file: file.gsub(__dir__ + '/../', ''),
43
+ version: version,
44
+ action: File.basename(file, '.rb')
45
+ }
46
+ end
47
+ end
48
+
49
+ request_classes
50
+ end
51
+
52
+ request_classes = scan_request_classes
53
+
54
+ puts "📊 统计信息:"
55
+ puts " OpenAPI 路径数: #{openapi_paths.size}"
56
+ puts " OpenAPI Request Schemas: #{openapi_schemas.select { |k, _| k.end_with?('Request') }.size}"
57
+ puts " schema.json 端点数: #{schema_endpoints.size}"
58
+ puts " Request 类文件数: #{request_classes.size}"
59
+ puts
60
+
61
+ # ==================== 验证 1: schema.json vs OpenAPI ====================
62
+ puts "=" * 100
63
+ puts "📋 验证 1/3: schema.json 配置 vs OpenAPI 路径"
64
+ puts "=" * 100
65
+ puts
66
+
67
+ schema_issues = []
68
+
69
+ schema_endpoints.each do |endpoint|
70
+ alias_name = endpoint['alias']
71
+ http_method = endpoint['http_method']
72
+ url = endpoint['url']
73
+
74
+ # 提取路径(去掉 base URL)
75
+ path = url.gsub('https://api.appstoreconnect.apple.com', '')
76
+
77
+ # 检查路径是否存在
78
+ unless openapi_paths.key?(path)
79
+ schema_issues << {
80
+ type: 'path_not_found',
81
+ alias: alias_name,
82
+ path: path,
83
+ method: http_method
84
+ }
85
+ next
86
+ end
87
+
88
+ # 检查 HTTP 方法是否存在
89
+ path_methods = openapi_paths[path]
90
+ unless path_methods.key?(http_method)
91
+ schema_issues << {
92
+ type: 'method_not_found',
93
+ alias: alias_name,
94
+ path: path,
95
+ method: http_method,
96
+ available_methods: path_methods.keys
97
+ }
98
+ end
99
+ end
100
+
101
+ if schema_issues.empty?
102
+ puts "✅ 所有 schema.json 端点都在 OpenAPI 中存在"
103
+ else
104
+ puts "⚠️ 发现 #{schema_issues.size} 个问题:"
105
+ schema_issues.each_with_index do |issue, idx|
106
+ puts "\n#{idx + 1}. #{issue[:alias]}"
107
+ if issue[:type] == 'path_not_found'
108
+ puts " 路径不存在: #{issue[:method].upcase} #{issue[:path]}"
109
+ else
110
+ puts " 方法不存在: #{issue[:method].upcase} #{issue[:path]}"
111
+ puts " 可用方法: #{issue[:available_methods].map(&:upcase).join(', ')}"
112
+ end
113
+ end
114
+ end
115
+ puts
116
+
117
+ # ==================== 验证 2: Request 类 vs OpenAPI Schemas ====================
118
+ puts "=" * 100
119
+ puts "📋 验证 2/3: Request 类实现 vs OpenAPI Request Schemas"
120
+ puts "=" * 100
121
+ puts
122
+
123
+ # 从文件路径推断 schema 名称
124
+ def file_to_schema_name(file_path, version, action)
125
+ parts = file_path.split('/')
126
+ module_name = parts[-2]
127
+
128
+ camel_case = module_name.split('_').map(&:capitalize).join
129
+
130
+ if version == 'v2' && !camel_case.end_with?('V2')
131
+ camel_case += 'V2'
132
+ end
133
+
134
+ action_suffix = action.capitalize + 'Request'
135
+ "#{camel_case}#{action_suffix}"
136
+ end
137
+
138
+ # 提取 Request 类的属性定义
139
+ def extract_request_properties(file_path)
140
+ return nil unless File.exist?(file_path)
141
+
142
+ content = File.read(file_path)
143
+
144
+ attributes = []
145
+ relationships = []
146
+
147
+ in_attributes = false
148
+ in_relationships = false
149
+
150
+ content.each_line do |line|
151
+ line = line.strip
152
+
153
+ if line == 'attributes do'
154
+ in_attributes = true
155
+ in_relationships = false
156
+ elsif line == 'relationships do'
157
+ in_relationships = true
158
+ in_attributes = false
159
+ elsif line == 'end'
160
+ in_attributes = false if in_attributes
161
+ in_relationships = false if in_relationships
162
+ elsif line.start_with?('property :')
163
+ match = line.match(/property :(\w+)/)
164
+ if match
165
+ prop_name = match[1]
166
+ next if prop_name == 'id' # 跳过 id
167
+
168
+ if in_attributes
169
+ attributes << prop_name
170
+ elsif in_relationships
171
+ relationships << prop_name
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ { attributes: attributes, relationships: relationships }
178
+ end
179
+
180
+ # 提取 OpenAPI Schema 的属性定义
181
+ def extract_openapi_schema_properties(schema_data)
182
+ return nil unless schema_data
183
+
184
+ data_props = schema_data.dig('properties', 'data', 'properties')
185
+ return nil unless data_props
186
+
187
+ attributes = data_props.dig('attributes', 'properties')&.keys || []
188
+ relationships = data_props.dig('relationships', 'properties')&.keys || []
189
+
190
+ { attributes: attributes, relationships: relationships }
191
+ end
192
+
193
+ request_issues = []
194
+
195
+ request_classes.each do |req|
196
+ schema_name = file_to_schema_name(req[:file], req[:version], req[:action])
197
+
198
+ # 检查 schema 是否存在
199
+ unless openapi_schemas.key?(schema_name)
200
+ request_issues << {
201
+ type: 'schema_not_found',
202
+ file: req[:file],
203
+ schema: schema_name
204
+ }
205
+ next
206
+ end
207
+
208
+ # 提取属性
209
+ file_path = File.join(__dir__, '..', req[:file])
210
+ request_props = extract_request_properties(file_path)
211
+ openapi_props = extract_openapi_schema_properties(openapi_schemas[schema_name])
212
+
213
+ next unless request_props && openapi_props
214
+
215
+ # 对比属性
216
+ req_attrs = Set.new(request_props[:attributes])
217
+ api_attrs = Set.new(openapi_props[:attributes])
218
+
219
+ missing_attrs = api_attrs - req_attrs
220
+ extra_attrs = req_attrs - api_attrs
221
+
222
+ # 对比关系
223
+ req_rels = Set.new(request_props[:relationships])
224
+ api_rels = Set.new(openapi_props[:relationships])
225
+
226
+ missing_rels = api_rels - req_rels
227
+ extra_rels = req_rels - api_rels
228
+
229
+ if missing_attrs.any? || extra_attrs.any? || missing_rels.any? || extra_rels.any?
230
+ request_issues << {
231
+ type: 'property_mismatch',
232
+ file: req[:file],
233
+ schema: schema_name,
234
+ missing_attributes: missing_attrs.to_a,
235
+ extra_attributes: extra_attrs.to_a,
236
+ missing_relationships: missing_rels.to_a,
237
+ extra_relationships: extra_rels.to_a
238
+ }
239
+ end
240
+ end
241
+
242
+ if request_issues.empty?
243
+ puts "✅ 所有 Request 类都与 OpenAPI Schemas 一致"
244
+ else
245
+ puts "⚠️ 发现 #{request_issues.size} 个问题:"
246
+ request_issues.each_with_index do |issue, idx|
247
+ puts "\n#{idx + 1}. #{issue[:schema]}"
248
+ puts " 文件: #{issue[:file]}"
249
+
250
+ if issue[:type] == 'schema_not_found'
251
+ puts " ❌ OpenAPI 中不存在此 Schema"
252
+ else
253
+ if issue[:missing_attributes].any?
254
+ puts " ❌ 缺失属性: #{issue[:missing_attributes].join(', ')}"
255
+ end
256
+ if issue[:extra_attributes].any?
257
+ puts " ⚠️ 多余属性: #{issue[:extra_attributes].join(', ')}"
258
+ end
259
+ if issue[:missing_relationships].any?
260
+ puts " ❌ 缺失关系: #{issue[:missing_relationships].join(', ')}"
261
+ end
262
+ if issue[:extra_relationships].any?
263
+ puts " ⚠️ 多余关系: #{issue[:extra_relationships].join(', ')}"
264
+ end
265
+ end
266
+ end
267
+ end
268
+ puts
269
+
270
+ # ==================== 验证 3: 三方完整性检查 ====================
271
+ puts "=" * 100
272
+ puts "📋 验证 3/3: 三方完整性检查"
273
+ puts "=" * 100
274
+ puts
275
+
276
+ # 检查 OpenAPI 中所有 POST/PATCH/PUT 端点是否都有对应的配置和实现
277
+ completeness_issues = []
278
+
279
+ openapi_paths.each do |path, methods|
280
+ methods.each do |method, details|
281
+ next unless ['post', 'patch', 'put'].include?(method)
282
+
283
+ operation_id = details['operationId']
284
+ next unless operation_id
285
+
286
+ # 检查是否有对应的 schema.json 配置
287
+ schema_endpoint = schema_endpoints.find do |ep|
288
+ ep['url'].include?(path) && ep['http_method'] == method
289
+ end
290
+
291
+ unless schema_endpoint
292
+ completeness_issues << {
293
+ type: 'missing_in_schema',
294
+ path: path,
295
+ method: method,
296
+ operation_id: operation_id
297
+ }
298
+ end
299
+ end
300
+ end
301
+
302
+ if completeness_issues.empty?
303
+ puts "✅ OpenAPI 中所有 POST/PATCH/PUT 端点都有对应配置"
304
+ else
305
+ puts "⚠️ 发现 #{completeness_issues.size} 个端点缺少 schema.json 配置:"
306
+ completeness_issues.take(10).each_with_index do |issue, idx|
307
+ puts " #{idx + 1}. #{issue[:method].upcase} #{issue[:path]}"
308
+ puts " operationId: #{issue[:operation_id]}"
309
+ end
310
+
311
+ if completeness_issues.size > 10
312
+ puts " ... 还有 #{completeness_issues.size - 10} 个"
313
+ end
314
+ end
315
+ puts
316
+
317
+ # ==================== 总结 ====================
318
+ puts "=" * 100
319
+ puts "📊 验证总结"
320
+ puts "=" * 100
321
+ puts
322
+
323
+ total_issues = schema_issues.size + request_issues.size + completeness_issues.size
324
+
325
+ if total_issues == 0
326
+ puts "🎉 完美!所有验证都通过:"
327
+ puts " ✅ schema.json 配置完全匹配 OpenAPI"
328
+ puts " ✅ Request 类实现完全匹配 OpenAPI Schemas"
329
+ puts " ✅ 所有端点都有完整的实现"
330
+ puts
331
+ puts "当前状态: 100% 符合 OpenAPI v4.2 规范"
332
+ else
333
+ puts "⚠️ 发现 #{total_issues} 个问题需要修复:"
334
+ puts " - schema.json 配置问题: #{schema_issues.size}"
335
+ puts " - Request 类实现问题: #{request_issues.size}"
336
+ puts " - 完整性问题: #{completeness_issues.size}"
337
+ puts
338
+ puts "建议: 根据上述问题进行修复"
339
+ end
340
+
341
+ # 保存详细报告
342
+ report = {
343
+ timestamp: Time.now.iso8601,
344
+ summary: {
345
+ total_issues: total_issues,
346
+ schema_issues: schema_issues.size,
347
+ request_issues: request_issues.size,
348
+ completeness_issues: completeness_issues.size
349
+ },
350
+ schema_issues: schema_issues,
351
+ request_issues: request_issues,
352
+ completeness_issues: completeness_issues
353
+ }
354
+
355
+ report_file = File.join(__dir__, 'comprehensive_validation_report.json')
356
+ File.write(report_file, JSON.pretty_generate(report))
357
+
358
+ puts
359
+ puts "详细报告已保存到: #{report_file}"
@@ -0,0 +1,12 @@
1
+ {
2
+ "timestamp": "2026-01-05T18:13:18+08:00",
3
+ "summary": {
4
+ "total_issues": 0,
5
+ "schema_issues": 0,
6
+ "request_issues": 0,
7
+ "completeness_issues": 0
8
+ },
9
+ "schema_issues": [],
10
+ "request_issues": [],
11
+ "completeness_issues": []
12
+ }