app_store_dev_api 0.1.9 → 0.3.1
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.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.claude/settings.local.json +23 -0
- data/CHANGELOG.md +59 -2
- data/CLAUDE.md +256 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +35 -20
- data/README.md +212 -20
- data/Rakefile +99 -1
- data/SCRIPTS_ANALYSIS.md +261 -0
- data/docs/bundle_id_capabilities.md +382 -0
- data/docs/bundle_ids.md +417 -0
- data/docs/creating_api_keys.md +137 -0
- data/docs/generating_tokens.md +189 -0
- data/docs/openapi.oas4.2.json +231546 -0
- data/docs/openapi.oas4.3.json +230597 -0
- data/docs/pindo_usage_reference.md +234 -0
- data/docs/revoking_api_keys.md +118 -0
- data/install_local.bat +166 -0
- data/install_local.sh +95 -0
- data/install_local_fixed.sh +84 -0
- data/lib/.DS_Store +0 -0
- data/lib/app_store_dev_api/client/authorization.rb +7 -2
- data/lib/app_store_dev_api/client/builder.rb +43 -38
- data/lib/app_store_dev_api/client/options.rb +1 -1
- data/lib/app_store_dev_api/client.rb +31 -60
- data/lib/app_store_dev_api/object/attributes.rb +1 -1
- data/lib/app_store_dev_api/object/data.rb +6 -2
- data/lib/app_store_dev_api/object/relationships.rb +47 -0
- data/lib/app_store_dev_api/requests/v1/accessibility_declaration/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/accessibility_declaration/update.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/age_rating_declaration/update.rb +43 -0
- data/lib/app_store_dev_api/requests/v1/alternative_distribution_domain/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/alternative_distribution_key/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/alternative_distribution_package/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/analytics_report_request/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/android_to_ios_app_mapping_detail/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/android_to_ios_app_mapping_detail/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app/update.rb +18 -20
- data/lib/app_store_dev_api/requests/v1/app_clip_advanced_experience/create.rb +32 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_advanced_experience/update.rb +32 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_advanced_experience_image/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_advanced_experience_image/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_app_store_review_detail/create.rb +19 -0
- data/lib/app_store_dev_api/requests/v1/{builds → app_clip_app_store_review_detail}/update.rb +4 -5
- data/lib/app_store_dev_api/requests/v1/app_clip_default_experience/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_default_experience/update.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_default_experience_localization/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_default_experience_localization/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_header_image/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/app_clip_header_image/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app_custom_product_page/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/app_custom_product_page/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app_custom_product_page_localization/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/app_custom_product_page_localization/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/app_custom_product_page_version/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/app_custom_product_page_version/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/app_encryption_declaration/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app_encryption_declaration_document/create.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/app_encryption_declaration_document/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/app_event/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/app_event/update.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/app_event_localization/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/app_event_localization/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/app_event_screenshot/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/app_event_screenshot/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/app_event_video_clip/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/{promoted_purchases_image → app_event_video_clip}/update.rb +4 -4
- data/lib/app_store_dev_api/requests/v1/app_info/update.rb +15 -18
- data/lib/app_store_dev_api/requests/v1/app_info_localization/create.rb +17 -17
- data/lib/app_store_dev_api/requests/v1/app_info_localization/update.rb +14 -18
- data/lib/app_store_dev_api/requests/v1/app_preview/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app_preview/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app_preview_set/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/app_preview_set/replace_app_previews_linkage.rb +19 -0
- data/lib/app_store_dev_api/requests/v1/app_price_schedule/create.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/app_screenshot/create.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/app_screenshot/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/app_screenshot_set/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/app_screenshot_set/replace_app_screenshots_linkage.rb +19 -0
- data/lib/app_store_dev_api/requests/v1/app_store_review_attachment/create.rb +20 -0
- data/lib/app_store_dev_api/requests/v1/app_store_review_attachment/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/app_store_review_detail/create.rb +19 -20
- data/lib/app_store_dev_api/requests/v1/app_store_review_detail/update.rb +17 -18
- data/lib/app_store_dev_api/requests/v1/app_store_version/create.rb +20 -16
- data/lib/app_store_dev_api/requests/v1/app_store_version/update.rb +20 -18
- data/lib/app_store_dev_api/requests/v1/app_store_version_experiment/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/app_store_version_experiment/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/app_store_version_experiment_treatment/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/app_store_version_experiment_treatment/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/app_store_version_experiment_treatment_localization/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/app_store_version_localization/create.rb +18 -18
- data/lib/app_store_dev_api/requests/v1/app_store_version_localization/update.rb +15 -18
- data/lib/app_store_dev_api/requests/v1/{app_store_version_phased_releases → app_store_version_phased_release}/create.rb +7 -2
- data/lib/app_store_dev_api/requests/v1/{app_store_version_phased_releases → app_store_version_phased_release}/update.rb +2 -2
- data/lib/app_store_dev_api/requests/v1/app_store_version_promotion/create.rb +10 -13
- data/lib/app_store_dev_api/requests/v1/{app_store_version_releases_request → app_store_version_release_request}/create.rb +5 -3
- data/lib/app_store_dev_api/requests/v1/app_tag/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/background_asset/create.rb +19 -0
- data/lib/app_store_dev_api/requests/v1/background_asset/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/background_asset_upload_file/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/background_asset_upload_file/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/background_asset_version/create.rb +16 -0
- data/lib/app_store_dev_api/requests/v1/beta_app_clip_invocation/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/beta_app_clip_invocation/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/beta_app_clip_invocation_localization/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/beta_app_clip_invocation_localization/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/beta_app_localization/create.rb +30 -0
- data/lib/app_store_dev_api/requests/v1/beta_app_localization/update.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/beta_app_review_detail/update.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/beta_app_review_submission/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/beta_build_localization/create.rb +18 -18
- data/lib/app_store_dev_api/requests/v1/beta_build_localization/update.rb +15 -20
- data/lib/app_store_dev_api/requests/v1/beta_group/create.rb +33 -0
- data/lib/app_store_dev_api/requests/v1/beta_group/update.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/beta_license_agreement/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/beta_recruitment_criterion/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/beta_recruitment_criterion/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/beta_tester/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/beta_tester_invitation/create.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/build_beta_detail/update.rb +10 -13
- data/lib/app_store_dev_api/requests/v1/{subscription_price_change_consent_reason → build_beta_notification}/create.rb +8 -2
- data/lib/app_store_dev_api/requests/v1/build_upload/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/build_upload_file/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/build_upload_file/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/bundle_id/create.rb +12 -15
- data/lib/app_store_dev_api/requests/v1/bundle_id/update.rb +20 -0
- data/lib/app_store_dev_api/requests/v1/bundle_id_capability/create.rb +13 -16
- data/lib/app_store_dev_api/requests/v1/bundle_id_capability/update.rb +18 -0
- data/lib/app_store_dev_api/requests/v1/certificate/create.rb +14 -15
- data/lib/app_store_dev_api/requests/v1/certificate/update.rb +17 -0
- data/lib/app_store_dev_api/requests/v1/ci_build_run/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/ci_workflow/create.rb +41 -0
- data/lib/app_store_dev_api/requests/v1/ci_workflow/update.rb +39 -0
- data/lib/app_store_dev_api/requests/v1/customer_review_response_v1/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/device/update.rb +18 -0
- data/lib/app_store_dev_api/requests/v1/end_app_availability_pre_order/create.rb +16 -0
- data/lib/app_store_dev_api/requests/v1/end_user_license_agreement/create.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/end_user_license_agreement/update.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/game_center_achievement/create.rb +31 -0
- data/lib/app_store_dev_api/requests/v1/game_center_achievement/update.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/game_center_achievement_image/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/game_center_achievement_image/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_achievement_localization/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/game_center_achievement_localization/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/game_center_achievement_release/create.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity/create.rb +32 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity/update.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity_image/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity_image/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity_localization/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity_localization/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity_version/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity_version/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_activity_version_release/create.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/game_center_app_version/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/game_center_app_version/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_challenge/create.rb +31 -0
- data/lib/app_store_dev_api/requests/v1/game_center_challenge/update.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/game_center_challenge_image/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_challenge_image/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_challenge_localization/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_challenge_localization/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/game_center_challenge_version/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/game_center_challenge_version_release/create.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/{subscription_review_screenshot → game_center_detail}/create.rb +9 -4
- data/lib/app_store_dev_api/requests/v1/game_center_detail/update.rb +29 -0
- data/lib/app_store_dev_api/requests/v1/{customer_review_response → game_center_group}/create.rb +6 -4
- data/lib/app_store_dev_api/requests/v1/game_center_group/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard/create.rb +38 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard/update.rb +32 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_entry_submission/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_image/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_image/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_localization/create.rb +30 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_localization/update.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_release/create.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_image/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_image/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_localization/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_localization/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_member_localization/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_member_localization/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/game_center_leaderboard_set_release/create.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_queue/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_queue/update.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule/create.rb +29 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule_set/create.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule_set/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_rule_set_test/create.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_team/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/game_center_matchmaking_team/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/game_center_player_achievement_submission/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/{in_app_purchase_review_screenshot → in_app_purchase_app_store_review_screenshot}/create.rb +9 -3
- data/lib/app_store_dev_api/requests/v1/{in_app_purchase_review_screenshot → in_app_purchase_app_store_review_screenshot}/update.rb +4 -3
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_availability/create.rb +13 -12
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_image/create.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_image/update.rb +18 -0
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_localization/create.rb +14 -14
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code_custom_code/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code_custom_code/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code_one_time_use_code/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_offer_code_one_time_use_code/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_price_schedule/create.rb +11 -10
- data/lib/app_store_dev_api/requests/v1/in_app_purchase_submission/create.rb +9 -10
- data/lib/app_store_dev_api/requests/v1/marketplace_search_detail/create.rb +25 -0
- data/lib/app_store_dev_api/requests/v1/marketplace_search_detail/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/{promoted_purchases → marketplace_webhook}/create.rb +7 -5
- data/lib/app_store_dev_api/requests/v1/marketplace_webhook/update.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/merchant_id/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/{app_price_schedule → merchant_id}/update.rb +7 -3
- data/lib/app_store_dev_api/requests/v1/nomination/create.rb +39 -0
- data/lib/app_store_dev_api/requests/v1/nomination/update.rb +40 -0
- data/lib/app_store_dev_api/requests/v1/pass_type_id/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v1/pass_type_id/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/profile/create.rb +14 -23
- data/lib/app_store_dev_api/requests/v1/promoted_purchase/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v1/{promoted_purchases → promoted_purchase}/update.rb +4 -3
- data/lib/app_store_dev_api/requests/v1/review_submission/create.rb +11 -7
- data/lib/app_store_dev_api/requests/v1/review_submission/update.rb +12 -15
- data/lib/app_store_dev_api/requests/v1/review_submission_item/create.rb +20 -8
- data/lib/app_store_dev_api/requests/v1/review_submission_item/update.rb +18 -0
- data/lib/app_store_dev_api/requests/v1/routing_app_coverage/create.rb +24 -0
- data/lib/app_store_dev_api/requests/v1/routing_app_coverage/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/subscription/create.rb +17 -17
- data/lib/app_store_dev_api/requests/v1/subscription/update.rb +19 -17
- data/lib/app_store_dev_api/requests/v1/subscription_app_store_review_screenshot/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v1/{subscription_review_screenshot → subscription_app_store_review_screenshot}/update.rb +4 -3
- data/lib/app_store_dev_api/requests/v1/subscription_availability/create.rb +13 -12
- data/lib/app_store_dev_api/requests/v1/subscription_grace_period/update.rb +13 -16
- data/lib/app_store_dev_api/requests/v1/subscription_group/create.rb +12 -13
- data/lib/app_store_dev_api/requests/v1/subscription_group/update.rb +10 -14
- data/lib/app_store_dev_api/requests/v1/subscription_group_localization/create.rb +14 -16
- data/lib/app_store_dev_api/requests/v1/subscription_group_localization/update.rb +11 -16
- data/lib/app_store_dev_api/requests/v1/subscription_group_submission/create.rb +9 -10
- data/lib/app_store_dev_api/requests/v1/subscription_image/create.rb +20 -0
- data/lib/app_store_dev_api/requests/v1/subscription_image/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/subscription_introductory_offer/create.rb +18 -18
- data/lib/app_store_dev_api/requests/v1/subscription_introductory_offer/update.rb +10 -15
- data/lib/app_store_dev_api/requests/v1/subscription_localization/create.rb +14 -16
- data/lib/app_store_dev_api/requests/v1/subscription_offer_code/create.rb +19 -19
- data/lib/app_store_dev_api/requests/v1/{subscription_offer_code_cunstom_code → subscription_offer_code_custom_code}/create.rb +9 -5
- data/lib/app_store_dev_api/requests/v1/{subscription_offer_code_cunstom_code → subscription_offer_code_custom_code}/update.rb +2 -3
- data/lib/app_store_dev_api/requests/v1/subscription_offer_code_one_time_use_code/create.rb +14 -15
- data/lib/app_store_dev_api/requests/v1/subscription_price/create.rb +15 -13
- data/lib/app_store_dev_api/requests/v1/subscription_promotional_offer/create.rb +17 -18
- data/lib/app_store_dev_api/requests/v1/subscription_promotional_offer/update.rb +10 -12
- data/lib/app_store_dev_api/requests/v1/subscription_submission/create.rb +9 -8
- data/lib/app_store_dev_api/requests/v1/{app_availability → territory_availability}/update.rb +4 -7
- data/lib/app_store_dev_api/requests/v1/user/update.rb +27 -0
- data/lib/app_store_dev_api/requests/v1/user_invitation/create.rb +30 -0
- data/lib/app_store_dev_api/requests/v1/webhook/create.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/webhook/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v1/webhook_delivery/create.rb +16 -0
- data/lib/app_store_dev_api/requests/v1/webhook_ping/create.rb +16 -0
- data/lib/app_store_dev_api/requests/v1/win_back_offer/create.rb +31 -0
- data/lib/app_store_dev_api/requests/v1/win_back_offer/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v1/win_back_offer/update_prices_linkages.rb +18 -0
- data/lib/app_store_dev_api/requests/v2/app_availability/create.rb +13 -14
- data/lib/app_store_dev_api/requests/v2/app_availability_v2/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v2/app_store_version_experiment_v2/create.rb +27 -0
- data/lib/app_store_dev_api/requests/v2/app_store_version_experiment_v2/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v2/game_center_achievement_image_v2/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v2/game_center_achievement_image_v2/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v2/game_center_achievement_localization_v2/create.rb +28 -0
- data/lib/app_store_dev_api/requests/v2/game_center_achievement_localization_v2/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v2/game_center_achievement_v2/create.rb +32 -0
- data/lib/app_store_dev_api/requests/v2/game_center_achievement_v2/update.rb +26 -0
- data/lib/app_store_dev_api/requests/v2/game_center_achievement_version_v2/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_image_v2/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_image_v2/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_localization_v2/create.rb +30 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_localization_v2/update.rb +25 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_image_v2/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_image_v2/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_localization_v2/create.rb +26 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_localization_v2/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_v2/create.rb +29 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_v2/update.rb +21 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_set_version_v2/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_v2/create.rb +39 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_v2/update.rb +32 -0
- data/lib/app_store_dev_api/requests/v2/game_center_leaderboard_version_v2/create.rb +22 -0
- data/lib/app_store_dev_api/requests/v2/in_app_purchase/create.rb +16 -17
- data/lib/app_store_dev_api/requests/v2/in_app_purchase/update.rb +12 -15
- data/lib/app_store_dev_api/requests/v2/in_app_purchase_v2/create.rb +29 -0
- data/lib/app_store_dev_api/requests/v2/in_app_purchase_v2/update.rb +23 -0
- data/lib/app_store_dev_api/requests/v2/{sandbox_tester → sandbox_tester_v2}/update.rb +5 -4
- 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
- data/lib/app_store_dev_api/version.rb +1 -1
- data/lib/config/{schema.json → schema_backup.json} +1185 -51
- data/lib/config/schema_v4.3.json +7307 -0
- data/push_all.sh +6 -0
- data/release_remote.sh +140 -0
- data/scripts/README.md +126 -0
- data/scripts/cleanup_scripts.sh +73 -0
- data/scripts/comprehensive_validation.rb +359 -0
- data/scripts/comprehensive_validation_report.json +12 -0
- data/scripts/final_validation_report.rb +134 -0
- data/scripts/find_deprecated_requests.rb +145 -0
- data/scripts/test_request_body_classes.rb +185 -0
- data/scripts/validate_requests.rb +192 -0
- data/test_library.rb +160 -0
- metadata +250 -34
- data/CODE_OF_CONDUCT.md +0 -84
- data/lib/app_store_dev_api/requests/v1/app_promoted_purchases/update.rb +0 -16
- data/lib/app_store_dev_api/requests/v1/app_store_version_build_linkage_request/update.rb +0 -17
- data/lib/app_store_dev_api/requests/v1/build_beta_groups/create.rb +0 -16
- data/lib/app_store_dev_api/requests/v1/build_beta_groups/delete.rb +0 -16
- data/lib/app_store_dev_api/requests/v1/promoted_purchases_image/create.rb +0 -20
- data/lib/app_store_dev_api/requests/v2/sandbox_tester/create.rb +0 -23
- data/release.sh +0 -55
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Pindo 项目中 app_store_dev_api 使用参考
|
|
2
|
+
|
|
3
|
+
> 本文档记录 [pindo](../../pindo) CLI 工具如何使用 `app_store_dev_api` gem 进行 App Store Connect API 认证和调用,作为集成参考。
|
|
4
|
+
|
|
5
|
+
## Gem 依赖
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# pindo.gemspec
|
|
9
|
+
spec.add_runtime_dependency "app_store_dev_api", '~> 0.3.0'
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 认证流程
|
|
13
|
+
|
|
14
|
+
Pindo 采用 **本地 JSON 文件 + 交互式输入** 的方式管理 API 密钥凭证。
|
|
15
|
+
|
|
16
|
+
### 流程图
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
启动命令 (pindo appstore iap)
|
|
20
|
+
↓
|
|
21
|
+
从项目 config.json 读取 apple_id、bundle_id
|
|
22
|
+
↓
|
|
23
|
+
检查 {pindo_dir}/api_key.json 是否存在该 apple_id 的凭证
|
|
24
|
+
↓
|
|
25
|
+
┌─── 存在 ───┐ ┌─── 不存在 ───┐
|
|
26
|
+
│ │ │ │
|
|
27
|
+
│ 直接加载 │ │ 交互式输入 │
|
|
28
|
+
│ issuer_id │ │ issuer_id │
|
|
29
|
+
│ key_id │ │ key_id │
|
|
30
|
+
│ private_key│ │ .p8 文件路径 │
|
|
31
|
+
│ │ │ │
|
|
32
|
+
└─────┬──────┘ │ 读取 .p8 文件 │
|
|
33
|
+
│ │ 用户确认 │
|
|
34
|
+
│ │ 保存到 JSON │
|
|
35
|
+
│ └──────┬────────┘
|
|
36
|
+
│ │
|
|
37
|
+
└────────┬───────────────┘
|
|
38
|
+
↓
|
|
39
|
+
AppStoreDevApi::Client.new(
|
|
40
|
+
issuer_id: issuer_id,
|
|
41
|
+
key_id: key_id,
|
|
42
|
+
private_key: private_key
|
|
43
|
+
)
|
|
44
|
+
↓
|
|
45
|
+
开始调用 API
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 核心代码
|
|
49
|
+
|
|
50
|
+
**文件:** `pindo/lib/pindo/command/appstore/iap.rb`
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
def login_api_key(apple_id: nil)
|
|
54
|
+
load_apikey_config = false
|
|
55
|
+
api_key_json = nil
|
|
56
|
+
pindo_dir = File.expand_path(pindo_single_config.pindo_dir)
|
|
57
|
+
api_key_file = File.join(pindo_dir, "api_key.json")
|
|
58
|
+
|
|
59
|
+
# 步骤1:尝试从本地配置文件加载
|
|
60
|
+
if File.exist?(api_key_file)
|
|
61
|
+
api_key_json = JSON.parse(File.read(api_key_file))
|
|
62
|
+
if !api_key_json.nil? && !api_key_json[apple_id].nil? && !api_key_json[apple_id]["issuer_id"].nil?
|
|
63
|
+
issuer_id = api_key_json[apple_id]["issuer_id"]
|
|
64
|
+
key_id = api_key_json[apple_id]["key_id"]
|
|
65
|
+
private_key = api_key_json[apple_id]["private_key"]
|
|
66
|
+
load_apikey_config = true
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# 步骤2:如果未加载,交互式输入凭证
|
|
71
|
+
if !load_apikey_config
|
|
72
|
+
issuer_id = ask('请输入 issuer_id: ')
|
|
73
|
+
key_id = ask('请输入 key_id: ')
|
|
74
|
+
private_key_file = ask('请输入private key的文件路径: ')
|
|
75
|
+
private_key = File.read(File.new(private_key_file))
|
|
76
|
+
|
|
77
|
+
# 构建配置
|
|
78
|
+
api_key_json = api_key_json || {}
|
|
79
|
+
api_key_json[apple_id] = api_key_json[apple_id] || {}
|
|
80
|
+
api_key_json[apple_id]["issuer_id"] = issuer_id
|
|
81
|
+
api_key_json[apple_id]["key_id"] = key_id
|
|
82
|
+
api_key_json[apple_id]["private_key"] = private_key
|
|
83
|
+
|
|
84
|
+
# 步骤3:用户确认
|
|
85
|
+
answer = agree("请确认上面信息是否正确(Y/n):")
|
|
86
|
+
unless answer
|
|
87
|
+
raise Informative, "重新输入 !!!"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# 步骤4:持久化到本地文件
|
|
91
|
+
File.open(api_key_file, "w") do |f|
|
|
92
|
+
f.write(JSON.pretty_generate(api_key_json))
|
|
93
|
+
end
|
|
94
|
+
load_apikey_config = true
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# 步骤5:初始化 API 客户端
|
|
98
|
+
if load_apikey_config
|
|
99
|
+
@app_store_connect = AppStoreDevApi::Client.new(
|
|
100
|
+
issuer_id: issuer_id,
|
|
101
|
+
key_id: key_id,
|
|
102
|
+
private_key: private_key
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 凭证存储格式
|
|
109
|
+
|
|
110
|
+
### 存储路径
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
{pindo_dir}/api_key.json
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`pindo_dir` 由 `pindo_single_config.pindo_dir` 确定,通常位于用户本地配置目录。
|
|
117
|
+
|
|
118
|
+
### JSON 结构(支持多账户)
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"user1@example.com": {
|
|
123
|
+
"issuer_id": "57246542-96fe-1a63-e053-0824d011072a",
|
|
124
|
+
"key_id": "2X9R4HXF34",
|
|
125
|
+
"private_key": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg...\n-----END PRIVATE KEY-----"
|
|
126
|
+
},
|
|
127
|
+
"user2@example.com": {
|
|
128
|
+
"issuer_id": "69384721-abcd-efgh-ijkl-123456789012",
|
|
129
|
+
"key_id": "ABC123DEF4",
|
|
130
|
+
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**关键设计:**
|
|
136
|
+
- 以 Apple ID(邮箱)作为一级 key,支持多账户切换
|
|
137
|
+
- `private_key` 直接存储 PEM 格式的私钥内容(非文件路径)
|
|
138
|
+
- 首次输入时从 `.p8` 文件读取,之后直接使用存储的内容
|
|
139
|
+
|
|
140
|
+
## API 调用示例
|
|
141
|
+
|
|
142
|
+
### 初始化入口
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
def run
|
|
146
|
+
# 从项目 config.json 加载 apple_id 和 bundle_id
|
|
147
|
+
config_file = File.join(project_dir, "config.json")
|
|
148
|
+
config_parser = Pindo::IosConfigParser.instance
|
|
149
|
+
config_parser.load_config(config_file: config_file)
|
|
150
|
+
@bundle_id = config_parser.bundle_id
|
|
151
|
+
@apple_id = config_parser.apple_id
|
|
152
|
+
|
|
153
|
+
# 登录并初始化客户端
|
|
154
|
+
login_api_key(apple_id: @apple_id)
|
|
155
|
+
|
|
156
|
+
# 开始使用 API...
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 查询应用
|
|
161
|
+
|
|
162
|
+
```ruby
|
|
163
|
+
app_list_response = @app_store_connect.list_apps(
|
|
164
|
+
filter: { bundle_id: @bundle_id }
|
|
165
|
+
)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 获取内购项目
|
|
169
|
+
|
|
170
|
+
```ruby
|
|
171
|
+
# 消耗型内购
|
|
172
|
+
get_consumable_iap_items(
|
|
173
|
+
appstore_client: @app_store_connect,
|
|
174
|
+
app_id: app_id,
|
|
175
|
+
in_app_purchase_type: "CONSUMABLE"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# 订阅组
|
|
179
|
+
get_subscriptions_groups(
|
|
180
|
+
appstore_client: @app_store_connect,
|
|
181
|
+
app_id: app_id
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 沙盒测试账户
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
@app_store_connect.list_sandbox_testers()
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## 其他集成点
|
|
192
|
+
|
|
193
|
+
Pindo 中还有以下任务类支持 API Key 认证参数(通过 options 传递):
|
|
194
|
+
|
|
195
|
+
### 截图上传任务
|
|
196
|
+
|
|
197
|
+
**文件:** `pindo/lib/pindo/module/task/model/appstore/appstore_upload_screenshot_task.rb`
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
def initialize(app_id, screenshot_path, options = {})
|
|
201
|
+
@api_key_id = options[:api_key_id] # API Key ID
|
|
202
|
+
@api_issuer_id = options[:api_issuer_id] # Issuer ID
|
|
203
|
+
@api_key_path = options[:api_key_path] # .p8 文件路径
|
|
204
|
+
end
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 元数据上传任务
|
|
208
|
+
|
|
209
|
+
**文件:** `pindo/lib/pindo/module/task/model/appstore/appstore_upload_metadata_task.rb`
|
|
210
|
+
|
|
211
|
+
```ruby
|
|
212
|
+
@api_key_id = options[:api_key_id]
|
|
213
|
+
@api_issuer_id = options[:api_issuer_id]
|
|
214
|
+
@api_key_path = options[:api_key_path]
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
> 注意:这些任务类使用的是 **文件路径** (`api_key_path`) 而非私钥内容,与 IAP 命令的处理方式略有不同。
|
|
218
|
+
|
|
219
|
+
## 设计要点总结
|
|
220
|
+
|
|
221
|
+
| 特性 | 说明 |
|
|
222
|
+
|------|------|
|
|
223
|
+
| 多账户支持 | 以 Apple ID 为 key 管理多套凭证 |
|
|
224
|
+
| 本地持久化 | JSON 文件存储,首次输入后免重复 |
|
|
225
|
+
| 交互式输入 | 首次使用通过命令行交互式收集凭证 |
|
|
226
|
+
| 私钥存储方式 | 存储 PEM 内容而非文件路径 |
|
|
227
|
+
| Client 初始化 | 三个参数: `issuer_id`, `key_id`, `private_key` |
|
|
228
|
+
| Token 管理 | 由 `app_store_dev_api` gem 内部自动处理 JWT 生成 |
|
|
229
|
+
|
|
230
|
+
## 相关文档
|
|
231
|
+
|
|
232
|
+
- [创建 API 密钥](creating_api_keys.md)
|
|
233
|
+
- [生成 API 请求 Token](generating_tokens.md)
|
|
234
|
+
- [撤销 API 密钥](revoking_api_keys.md)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# 撤销 API 密钥
|
|
2
|
+
|
|
3
|
+
> 官方文档: https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys
|
|
4
|
+
|
|
5
|
+
## 概述
|
|
6
|
+
|
|
7
|
+
当 API 密钥不再需要、可能泄露、或需要轮换时,应及时撤销。撤销后的密钥将永久失效,使用该密钥生成的所有 JWT Token 也将立即失效。
|
|
8
|
+
|
|
9
|
+
## 撤销步骤
|
|
10
|
+
|
|
11
|
+
### 撤销团队密钥
|
|
12
|
+
|
|
13
|
+
1. 登录 [App Store Connect](https://appstoreconnect.apple.com/)
|
|
14
|
+
2. 导航到 **用户和访问 (Users and Access)**
|
|
15
|
+
3. 选择 **集成 (Integrations)** 选项卡
|
|
16
|
+
4. 在左侧导航中选择 **App Store Connect API**
|
|
17
|
+
5. 选择 **团队密钥 (Team Keys)** 标签页
|
|
18
|
+
6. 找到要撤销的密钥
|
|
19
|
+
7. 点击密钥名称旁的 **撤销 (Revoke)** 按钮
|
|
20
|
+
8. 在确认对话框中确认撤销
|
|
21
|
+
|
|
22
|
+
### 撤销个人密钥
|
|
23
|
+
|
|
24
|
+
1. 登录 [App Store Connect](https://appstoreconnect.apple.com/)
|
|
25
|
+
2. 导航到 **用户和访问 (Users and Access)**
|
|
26
|
+
3. 选择 **集成 (Integrations)** 选项卡
|
|
27
|
+
4. 选择 **个人密钥 (Individual Keys)** 标签页
|
|
28
|
+
5. 找到要撤销的密钥并点击 **撤销 (Revoke)**
|
|
29
|
+
|
|
30
|
+
## 撤销后的影响
|
|
31
|
+
|
|
32
|
+
### 立即生效
|
|
33
|
+
|
|
34
|
+
- 密钥状态变为 **已撤销 (Revoked)**
|
|
35
|
+
- 使用该密钥签名的所有 JWT Token 立即失效
|
|
36
|
+
- 所有使用该 Token 的 API 请求将返回 `401 NOT_AUTHORIZED`
|
|
37
|
+
|
|
38
|
+
### 不可逆操作
|
|
39
|
+
|
|
40
|
+
> ⚠️ **警告**: 密钥撤销是**永久性**操作,无法恢复。一旦撤销,该密钥将无法重新激活。
|
|
41
|
+
|
|
42
|
+
- 已撤销的密钥仍会显示在密钥列表中(标记为已撤销),但无法使用
|
|
43
|
+
- 私钥文件(`.p8`)即使仍存在也无法再用于生成有效 Token
|
|
44
|
+
- Key ID 不会被回收利用
|
|
45
|
+
|
|
46
|
+
### 对正在运行的服务的影响
|
|
47
|
+
|
|
48
|
+
- 所有依赖该密钥的 CI/CD 流水线将立即中断
|
|
49
|
+
- 所有使用该密钥的自动化脚本将失败
|
|
50
|
+
- 所有后端服务的 API 调用将返回认证错误
|
|
51
|
+
|
|
52
|
+
## 何时应该撤销密钥
|
|
53
|
+
|
|
54
|
+
| 场景 | 紧急程度 | 建议操作 |
|
|
55
|
+
|------|----------|----------|
|
|
56
|
+
| 私钥文件泄露(提交到公开仓库等) | 🔴 立即 | 立刻撤销,创建新密钥 |
|
|
57
|
+
| 团队成员离职 | 🟡 尽快 | 撤销其创建的密钥 |
|
|
58
|
+
| 密钥定期轮换 | 🟢 计划中 | 先创建新密钥,迁移后再撤销旧密钥 |
|
|
59
|
+
| 密钥权限过高 | 🟡 尽快 | 创建权限适当的新密钥后撤销 |
|
|
60
|
+
| 密钥不再使用 | 🟢 常规 | 确认无依赖后撤销 |
|
|
61
|
+
|
|
62
|
+
## 安全的密钥轮换流程
|
|
63
|
+
|
|
64
|
+
为避免服务中断,建议按以下步骤进行密钥轮换:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
1. 创建新密钥
|
|
68
|
+
↓
|
|
69
|
+
2. 下载新私钥文件 (.p8)
|
|
70
|
+
↓
|
|
71
|
+
3. 更新所有服务/脚本使用新密钥
|
|
72
|
+
↓
|
|
73
|
+
4. 验证所有服务正常运行
|
|
74
|
+
↓
|
|
75
|
+
5. 撤销旧密钥
|
|
76
|
+
↓
|
|
77
|
+
6. 删除旧私钥文件
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 在本项目中轮换密钥
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
# 1. 使用新密钥创建客户端
|
|
84
|
+
new_client = AppStoreDevApi::Client.new(
|
|
85
|
+
issuer_id: ENV['APP_STORE_CONNECT_ISSUER_ID'], # Issuer ID 不变
|
|
86
|
+
key_id: 'NEW_KEY_ID',
|
|
87
|
+
private_key: File.read('/path/to/new_AuthKey.p8')
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# 2. 验证新密钥可用
|
|
91
|
+
apps = new_client.list_apps
|
|
92
|
+
puts "新密钥验证成功,共 #{apps['data'].size} 个应用"
|
|
93
|
+
|
|
94
|
+
# 3. 确认后,在 App Store Connect 中撤销旧密钥
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 常见问题
|
|
98
|
+
|
|
99
|
+
### 撤销密钥后可以恢复吗?
|
|
100
|
+
|
|
101
|
+
不可以。密钥撤销是永久性操作。如果误操作,只能创建新密钥。
|
|
102
|
+
|
|
103
|
+
### 撤销密钥会影响应用吗?
|
|
104
|
+
|
|
105
|
+
不会。撤销 API 密钥只影响 API 访问能力,不会影响已发布的应用、用户数据或 App Store 上架状态。
|
|
106
|
+
|
|
107
|
+
### 一个团队最多可以有多少个活跃密钥?
|
|
108
|
+
|
|
109
|
+
Apple 对每个团队的活跃 API 密钥数量有限制。建议只保留实际使用的密钥,及时撤销不再需要的密钥。
|
|
110
|
+
|
|
111
|
+
### 撤销后 Issuer ID 会变吗?
|
|
112
|
+
|
|
113
|
+
不会。Issuer ID 是团队级别的标识,不受单个密钥撤销的影响。
|
|
114
|
+
|
|
115
|
+
## 相关文档
|
|
116
|
+
|
|
117
|
+
- [创建 API 密钥](creating_api_keys.md)
|
|
118
|
+
- [生成 API 请求 Token](generating_tokens.md)
|
data/install_local.bat
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
rem Windows批处理脚本,用于快速构建和安装当前Ruby gem到本机测试
|
|
3
|
+
chcp 65001 >nul 2>&1
|
|
4
|
+
|
|
5
|
+
setlocal enabledelayedexpansion
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
rem 获取当前脚本目录
|
|
9
|
+
set "CURRENT_DIR=%~dp0"
|
|
10
|
+
set "CURRENT_DIR=%CURRENT_DIR:~0,-1%"
|
|
11
|
+
echo [LOG] Step 1: Get current directory
|
|
12
|
+
echo 当前目录: %CURRENT_DIR%
|
|
13
|
+
|
|
14
|
+
rem 自动检测当前项目名称
|
|
15
|
+
echo [LOG] Step 2: Detect project name
|
|
16
|
+
set "PROJECT_NAME="
|
|
17
|
+
for %%i in ("%CURRENT_DIR%\*.gemspec") do (
|
|
18
|
+
if exist "%%i" (
|
|
19
|
+
set "GEMSPEC_FILE=%%i"
|
|
20
|
+
for /f %%j in ("%%i") do set "PROJECT_NAME=%%~nj"
|
|
21
|
+
goto :found_gemspec
|
|
22
|
+
)
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
echo [LOG] 错误: 未找到gemspec文件!
|
|
26
|
+
exit /b 1
|
|
27
|
+
|
|
28
|
+
:found_gemspec
|
|
29
|
+
echo [LOG] Step 3: Found project
|
|
30
|
+
echo 检测到项目: %PROJECT_NAME%
|
|
31
|
+
|
|
32
|
+
rem 清理旧的gem文件
|
|
33
|
+
echo [LOG] Step 4: Clean old gem files
|
|
34
|
+
if exist "%CURRENT_DIR%\%PROJECT_NAME%-*.gem" (
|
|
35
|
+
echo 清理旧的gem文件...
|
|
36
|
+
del /q "%CURRENT_DIR%\%PROJECT_NAME%-*.gem"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
rem 自动检测版本文件
|
|
40
|
+
echo [LOG] Step 5: Detect version file
|
|
41
|
+
set "VERSION_FILE="
|
|
42
|
+
for /r "%CURRENT_DIR%\lib" %%i in (version.rb) do (
|
|
43
|
+
if exist "%%i" (
|
|
44
|
+
set "VERSION_FILE=%%i"
|
|
45
|
+
goto :found_version
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
echo [LOG] 错误: 未找到version.rb文件!
|
|
50
|
+
exit /b 1
|
|
51
|
+
|
|
52
|
+
:found_version
|
|
53
|
+
echo [LOG] Step 6: Found version file
|
|
54
|
+
echo 检测到版本文件: %VERSION_FILE%
|
|
55
|
+
|
|
56
|
+
rem 从version.rb文件提取版本号
|
|
57
|
+
echo [LOG] Step 7: Extract version number
|
|
58
|
+
set "VERSION_TAG_NAME="
|
|
59
|
+
for /f "tokens=*" %%i in ('findstr /r "VERSION.*=" "%VERSION_FILE%"') do (
|
|
60
|
+
set "line=%%i"
|
|
61
|
+
rem 提取引号中的版本号
|
|
62
|
+
for /f "tokens=2 delims='" %%j in ("!line!") do set "VERSION_TAG_NAME=%%j"
|
|
63
|
+
if "!VERSION_TAG_NAME!"=="" (
|
|
64
|
+
for /f "tokens=2 delims=""" %%j in ("!line!") do set "VERSION_TAG_NAME=%%j"
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if "%VERSION_TAG_NAME%"=="" (
|
|
69
|
+
echo [LOG] 错误: 无法从版本文件中解析版本号
|
|
70
|
+
echo 版本文件内容:
|
|
71
|
+
type "%VERSION_FILE%"
|
|
72
|
+
exit /b 1
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
echo [LOG] Step 8: Version number parsed successfully
|
|
76
|
+
echo 检测到版本: %VERSION_TAG_NAME%
|
|
77
|
+
|
|
78
|
+
rem 验证版本号格式 (基本检查是否包含点号)
|
|
79
|
+
echo %VERSION_TAG_NAME% | findstr "." >nul
|
|
80
|
+
if errorlevel 1 (
|
|
81
|
+
echo 警告: 版本号格式可能不正确: %VERSION_TAG_NAME%
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
rem 构建gem
|
|
85
|
+
echo [LOG] Step 9: Start building gem
|
|
86
|
+
echo 构建 %PROJECT_NAME% gem...
|
|
87
|
+
cd /d "%CURRENT_DIR%"
|
|
88
|
+
|
|
89
|
+
rem 构建gem,忽略警告的退出码
|
|
90
|
+
echo [LOG] Step 10: Execute gem build command
|
|
91
|
+
gem build "%GEMSPEC_FILE%"
|
|
92
|
+
rem 重置错误级别,防止警告阻止脚本继续
|
|
93
|
+
cd .
|
|
94
|
+
echo [LOG] Step 11: gem build command completed, checking result
|
|
95
|
+
echo [DEBUG] Looking for file: %PROJECT_NAME%-%VERSION_TAG_NAME%.gem
|
|
96
|
+
|
|
97
|
+
rem 检查是否生成了gem文件来判断构建是否成功
|
|
98
|
+
if not exist "%PROJECT_NAME%-%VERSION_TAG_NAME%.gem" (
|
|
99
|
+
echo [LOG] 错误: gem构建失败,未找到生成的gem文件!
|
|
100
|
+
echo [DEBUG] 当前目录文件列表:
|
|
101
|
+
dir *.gem
|
|
102
|
+
exit /b 1
|
|
103
|
+
) else (
|
|
104
|
+
echo [LOG] Step 12: gem build success confirmed
|
|
105
|
+
echo ✓ gem构建成功
|
|
106
|
+
echo.
|
|
107
|
+
echo ==========================================
|
|
108
|
+
echo 构建完成!现在可以安装到本地:
|
|
109
|
+
echo.
|
|
110
|
+
echo 安装命令:
|
|
111
|
+
echo gem install --local --force %PROJECT_NAME%-%VERSION_TAG_NAME%.gem
|
|
112
|
+
echo.
|
|
113
|
+
echo 安装后验证:
|
|
114
|
+
echo %PROJECT_NAME% --version
|
|
115
|
+
echo %PROJECT_NAME% --help
|
|
116
|
+
echo ==========================================
|
|
117
|
+
echo.
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
rem 查找生成的gem文件
|
|
121
|
+
echo [LOG] Step 13: Search for generated gem file
|
|
122
|
+
set "GEM_FILE="
|
|
123
|
+
if exist "%PROJECT_NAME%-%VERSION_TAG_NAME%.gem" (
|
|
124
|
+
set "GEM_FILE=%PROJECT_NAME%-%VERSION_TAG_NAME%.gem"
|
|
125
|
+
) else (
|
|
126
|
+
rem 尝试查找任何版本的gem文件
|
|
127
|
+
for %%i in ("%PROJECT_NAME%-*.gem") do (
|
|
128
|
+
set "GEM_FILE=%%i"
|
|
129
|
+
goto :found_gem
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
:found_gem
|
|
134
|
+
if "%GEM_FILE%"=="" (
|
|
135
|
+
echo [LOG] 错误: 未找到生成的gem文件!
|
|
136
|
+
exit /b 1
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
echo [LOG] Step 14: Found gem file
|
|
140
|
+
echo 找到gem文件: %GEM_FILE%
|
|
141
|
+
echo [LOG] Step 15: Start installing gem
|
|
142
|
+
echo 安装 %GEM_FILE%...
|
|
143
|
+
|
|
144
|
+
rem 安装gem(使用force参数忽略依赖检查)
|
|
145
|
+
echo [LOG] Step 16: Execute gem install command
|
|
146
|
+
gem install --local --force "%GEM_FILE%"
|
|
147
|
+
echo [LOG] Step 17: gem install command completed
|
|
148
|
+
|
|
149
|
+
if errorlevel 1 (
|
|
150
|
+
echo [LOG] 错误: gem安装失败!
|
|
151
|
+
echo 尝试手动安装: gem install --local --force "%GEM_FILE%"
|
|
152
|
+
exit /b 1
|
|
153
|
+
) else (
|
|
154
|
+
echo [LOG] Step 18: gem installation successful
|
|
155
|
+
echo ✓ %PROJECT_NAME% 安装成功!
|
|
156
|
+
echo [LOG] Step 19: Verify installed version
|
|
157
|
+
echo 当前版本:
|
|
158
|
+
%PROJECT_NAME% --version
|
|
159
|
+
echo.
|
|
160
|
+
echo 可以使用以下命令测试:
|
|
161
|
+
echo %PROJECT_NAME% --help
|
|
162
|
+
echo %PROJECT_NAME% --version
|
|
163
|
+
echo [LOG] Step 20: Script execution completed
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
pause
|
data/install_local.sh
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
#当前脚本目录 (macOS兼容)
|
|
4
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
5
|
+
CURRENT_DIR=$(dirname $(greadlink -f $0 2>/dev/null || readlink $0 2>/dev/null || echo $0))
|
|
6
|
+
else
|
|
7
|
+
CURRENT_DIR=$(dirname $(readlink -f $0))
|
|
8
|
+
fi
|
|
9
|
+
CURRENT_DIR=$(cd "$CURRENT_DIR" && pwd)
|
|
10
|
+
echo $CURRENT_DIR
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Make all files and directories in the current directory readable, writable, and executable for all users.
|
|
14
|
+
/bin/chmod -R a+rwx $CURRENT_DIR
|
|
15
|
+
# Change the owner of the current directory to the current user.
|
|
16
|
+
/usr/sbin/chown $(whoami) $CURRENT_DIR
|
|
17
|
+
# Change the group of the current directory to "admin".
|
|
18
|
+
/usr/bin/chgrp admin $CURRENT_DIR
|
|
19
|
+
|
|
20
|
+
function readConfigValue()
|
|
21
|
+
{
|
|
22
|
+
File=$1
|
|
23
|
+
KEY=$2
|
|
24
|
+
VALUE=$(grep -m 1 -o "^[ ]*$KEY[ ]*=[ ]*[\"]*.*[\"]*" $File | sed -e "s/^[ ]*$KEY[ ]*=[ ]*[\"]*//" -e "s/[\"]*$//")
|
|
25
|
+
echo $VALUE
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# 自动检测当前项目名称
|
|
30
|
+
GEMSPEC_FILE=$(find $CURRENT_DIR -maxdepth 1 -name "*.gemspec" | head -n 1)
|
|
31
|
+
if [ -z "$GEMSPEC_FILE" ]; then
|
|
32
|
+
echo "错误: 未找到gemspec文件!"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# 从gemspec文件名获取项目名称
|
|
37
|
+
PROJECT_NAME=$(basename $GEMSPEC_FILE .gemspec)
|
|
38
|
+
echo "检测到项目: $PROJECT_NAME"
|
|
39
|
+
|
|
40
|
+
# 清理旧的gem文件
|
|
41
|
+
rm -rf $CURRENT_DIR/*${PROJECT_NAME}-*.gem
|
|
42
|
+
|
|
43
|
+
# 自动检测版本文件
|
|
44
|
+
VERSION_FILE=$(find $CURRENT_DIR/lib -name "version.rb" | head -n 1)
|
|
45
|
+
if [ -z "$VERSION_FILE" ]; then
|
|
46
|
+
echo "错误: 未找到version.rb文件!"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
echo "检测到版本文件: $VERSION_FILE"
|
|
51
|
+
VERSION_KEY="VERSION"
|
|
52
|
+
# 改进版本号提取方式,确保只获取版本号部分
|
|
53
|
+
VERSION_TAG_NAME=$(grep -o "${VERSION_KEY}.*=.*['\"]\(.*\)['\"]" ${VERSION_FILE} | head -1 | sed -E "s/.*['\"]([0-9]+\.[0-9]+\.[0-9]+)['\"].*/\1/")
|
|
54
|
+
echo "检测到版本: $VERSION_TAG_NAME"
|
|
55
|
+
|
|
56
|
+
# 验证版本号格式
|
|
57
|
+
if [[ ! $VERSION_TAG_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
58
|
+
echo "错误: 无法正确解析版本号,获取到的值: '$VERSION_TAG_NAME'"
|
|
59
|
+
echo "直接查看版本文件内容:"
|
|
60
|
+
cat $VERSION_FILE
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# 构建和安装gem
|
|
66
|
+
echo "构建 $PROJECT_NAME gem..."
|
|
67
|
+
gem build $GEMSPEC_FILE
|
|
68
|
+
|
|
69
|
+
# 查找生成的gem文件(在当前目录和CURRENT_DIR中查找)
|
|
70
|
+
GEM_FILE=$(find . -maxdepth 1 -name "${PROJECT_NAME}-${VERSION_TAG_NAME}.gem" | head -n 1)
|
|
71
|
+
if [ -z "$GEM_FILE" ]; then
|
|
72
|
+
GEM_FILE=$(find $CURRENT_DIR -maxdepth 1 -name "${PROJECT_NAME}-${VERSION_TAG_NAME}.gem" | head -n 1)
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
if [ -n "$GEM_FILE" ]; then
|
|
76
|
+
echo "找到gem文件: $GEM_FILE"
|
|
77
|
+
echo "安装 $PROJECT_NAME-${VERSION_TAG_NAME}.gem..."
|
|
78
|
+
gem install --local "$GEM_FILE"
|
|
79
|
+
else
|
|
80
|
+
echo "错误: 未找到生成的gem文件! 尝试查找任何版本的gem..."
|
|
81
|
+
ANY_GEM=$(find . -maxdepth 1 -name "${PROJECT_NAME}-*.gem" | head -n 1)
|
|
82
|
+
if [ -n "$ANY_GEM" ]; then
|
|
83
|
+
echo "找到gem文件: $ANY_GEM"
|
|
84
|
+
echo "安装 $ANY_GEM..."
|
|
85
|
+
gem install --local "$ANY_GEM"
|
|
86
|
+
else
|
|
87
|
+
echo "未找到任何${PROJECT_NAME}的gem文件"
|
|
88
|
+
fi
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 简化的本地安装脚本 - 适用于库 gem 项目
|
|
3
|
+
|
|
4
|
+
set -e # 遇到错误立即退出
|
|
5
|
+
|
|
6
|
+
# 获取当前目录
|
|
7
|
+
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
cd "$CURRENT_DIR"
|
|
9
|
+
|
|
10
|
+
echo "=========================================="
|
|
11
|
+
echo "本地构建和安装 Gem"
|
|
12
|
+
echo "=========================================="
|
|
13
|
+
echo
|
|
14
|
+
|
|
15
|
+
# 1. 自动检测项目名称
|
|
16
|
+
GEMSPEC_FILE=$(find . -maxdepth 1 -name "*.gemspec" | head -n 1)
|
|
17
|
+
if [ -z "$GEMSPEC_FILE" ]; then
|
|
18
|
+
echo "❌ 错误: 未找到 .gemspec 文件"
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
PROJECT_NAME=$(basename "$GEMSPEC_FILE" .gemspec)
|
|
23
|
+
echo "项目: $PROJECT_NAME"
|
|
24
|
+
|
|
25
|
+
# 2. 自动检测版本号
|
|
26
|
+
VERSION_FILE=$(find ./lib -name "version.rb" | head -n 1)
|
|
27
|
+
if [ -z "$VERSION_FILE" ]; then
|
|
28
|
+
echo "❌ 错误: 未找到 version.rb 文件"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# 提取版本号
|
|
33
|
+
VERSION=$(grep -o "VERSION.*=.*['\"][0-9.]*['\"]" "$VERSION_FILE" | sed -E "s/.*['\"]([0-9.]+)['\"].*/\1/")
|
|
34
|
+
|
|
35
|
+
if [ -z "$VERSION" ]; then
|
|
36
|
+
echo "❌ 错误: 无法解析版本号"
|
|
37
|
+
cat "$VERSION_FILE"
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
echo "版本: $VERSION"
|
|
42
|
+
echo
|
|
43
|
+
|
|
44
|
+
# 3. 清理旧的 gem 文件
|
|
45
|
+
echo "清理旧的 gem 文件..."
|
|
46
|
+
rm -f *.gem
|
|
47
|
+
echo "✓ 清理完成"
|
|
48
|
+
echo
|
|
49
|
+
|
|
50
|
+
# 4. 构建 gem
|
|
51
|
+
echo "构建 gem..."
|
|
52
|
+
gem build "$GEMSPEC_FILE"
|
|
53
|
+
|
|
54
|
+
GEM_FILE="${PROJECT_NAME}-${VERSION}.gem"
|
|
55
|
+
|
|
56
|
+
if [ ! -f "$GEM_FILE" ]; then
|
|
57
|
+
echo "❌ 错误: gem 构建失败,未找到 $GEM_FILE"
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
echo "✓ 构建成功: $GEM_FILE"
|
|
62
|
+
echo
|
|
63
|
+
|
|
64
|
+
# 5. 安装到本地
|
|
65
|
+
echo "安装到本地..."
|
|
66
|
+
gem install "$GEM_FILE"
|
|
67
|
+
|
|
68
|
+
echo
|
|
69
|
+
echo "=========================================="
|
|
70
|
+
echo "✅ 安装成功!"
|
|
71
|
+
echo "=========================================="
|
|
72
|
+
echo
|
|
73
|
+
echo "使用方法 (Ruby 代码中):"
|
|
74
|
+
echo " require 'app_store_dev_api'"
|
|
75
|
+
echo " client = AppStoreDevApi::Client.new("
|
|
76
|
+
echo " key_id: 'YOUR_KEY_ID',"
|
|
77
|
+
echo " issuer_id: 'YOUR_ISSUER_ID',"
|
|
78
|
+
echo " private_key: File.read('AuthKey.p8')"
|
|
79
|
+
echo " )"
|
|
80
|
+
echo
|
|
81
|
+
echo "验证安装:"
|
|
82
|
+
echo " gem list | grep $PROJECT_NAME"
|
|
83
|
+
echo " ruby -r app_store_dev_api -e 'puts AppStoreDevApi::VERSION'"
|
|
84
|
+
echo "=========================================="
|
data/lib/.DS_Store
CHANGED
|
Binary file
|