diff --git a/app/assets/stylesheets/framework/emojis.scss b/app/assets/stylesheets/framework/emojis.scss index cfdf17f00db..06ea9ac1aa2 100644 --- a/app/assets/stylesheets/framework/emojis.scss +++ b/app/assets/stylesheets/framework/emojis.scss @@ -1,16 +1,15 @@ gl-emoji { font-style: normal; - display: inline-flex; + display: inline-block; vertical-align: baseline; font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; font-size: 1.2em; line-height: 1; img { - width: 1.2em; - height: 1.2em; - position: relative; - top: 0.25em; + width: 1em; + object-fit: scale-down; + height: 1em; } } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 6486ecbacfd..1bd5541585f 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -508,8 +508,8 @@ $board-swimlanes-headers-height: 64px; /* Source Editor theme overrides */ -$source-editor-hover-light-text-color: #ececef; -$source-editor-hover-dark-text-color: #333238; +$source-editor-hover-light-text-color: $gl-color-neutral-50; +$source-editor-hover-dark-text-color: $gl-color-neutral-900; /** Bootstrap 4.2.0 introduced new icons for validating forms. diff --git a/app/models/packages/npm/metadatum.rb b/app/models/packages/npm/metadatum.rb index 481c1947880..2fc1c05cd48 100644 --- a/app/models/packages/npm/metadatum.rb +++ b/app/models/packages/npm/metadatum.rb @@ -15,10 +15,6 @@ class Packages::Npm::Metadatum < ApplicationRecord scope :package_id_in, ->(package_ids) { where(package_id: package_ids) } - def package_json_scripts - package_json.try(:[], 'scripts') - end - private def ensure_npm_package_type diff --git a/app/services/loose_foreign_keys/batch_cleaner_service.rb b/app/services/loose_foreign_keys/batch_cleaner_service.rb index 8796ac03f6c..d43ee5cf508 100644 --- a/app/services/loose_foreign_keys/batch_cleaner_service.rb +++ b/app/services/loose_foreign_keys/batch_cleaner_service.rb @@ -5,12 +5,20 @@ module LooseForeignKeys CLEANUP_ATTEMPTS_BEFORE_RESCHEDULE = 3 CONSUME_AFTER_RESCHEDULE = 5.minutes - def initialize(parent_table:, loose_foreign_key_definitions:, deleted_parent_records:, connection:, modification_tracker: LooseForeignKeys::ModificationTracker.new) + def initialize( + parent_table:, + loose_foreign_key_definitions:, + deleted_parent_records:, + connection:, + logger: Sidekiq.logger, + modification_tracker: LooseForeignKeys::ModificationTracker.new + ) @parent_table = parent_table @loose_foreign_key_definitions = loose_foreign_key_definitions @deleted_parent_records = deleted_parent_records @modification_tracker = modification_tracker @connection = connection + @logger = logger @deleted_records_counter = Gitlab::Metrics.counter( :loose_foreign_key_processed_deleted_records, 'The number of processed loose foreign key deleted records' @@ -54,7 +62,7 @@ module LooseForeignKeys private - attr_reader :parent_table, :loose_foreign_key_definitions, :deleted_parent_records, :modification_tracker, :deleted_records_counter, :deleted_records_rescheduled_count, :deleted_records_incremented_count, :connection + attr_reader :parent_table, :loose_foreign_key_definitions, :deleted_parent_records, :modification_tracker, :deleted_records_counter, :deleted_records_rescheduled_count, :deleted_records_incremented_count, :connection, :logger def handle_over_limit records_to_reschedule = [] @@ -82,6 +90,9 @@ module LooseForeignKeys modification_tracker.add_deletions(result[:table], result[:affected_rows]) elsif cleaner.async_nullify? modification_tracker.add_updates(result[:table], result[:affected_rows]) + else + logger.error("Invalid on_delete argument for definition: #{result[:table]}") + false end end @@ -104,14 +115,15 @@ module LooseForeignKeys loose_foreign_key_definition: loose_foreign_key_definition, connection: base_model.connection, deleted_parent_records: deleted_parent_records, - with_skip_locked: with_skip_locked + with_skip_locked: with_skip_locked, + logger: logger ) loop do result = cleaner.execute - record_result(cleaner, result) + recorded = record_result(cleaner, result) - break if modification_tracker.over_limit? || result[:affected_rows] == 0 + break if modification_tracker.over_limit? || result[:affected_rows] == 0 || !recorded end end end diff --git a/app/services/loose_foreign_keys/cleaner_service.rb b/app/services/loose_foreign_keys/cleaner_service.rb index 44a922aad87..d12f7c2b6ea 100644 --- a/app/services/loose_foreign_keys/cleaner_service.rb +++ b/app/services/loose_foreign_keys/cleaner_service.rb @@ -6,11 +6,12 @@ module LooseForeignKeys DELETE_LIMIT = 1000 UPDATE_LIMIT = 500 - def initialize(loose_foreign_key_definition:, connection:, deleted_parent_records:, with_skip_locked: false) + def initialize(loose_foreign_key_definition:, connection:, deleted_parent_records:, logger: Sidekiq.logger, with_skip_locked: false) @loose_foreign_key_definition = loose_foreign_key_definition @connection = connection @deleted_parent_records = deleted_parent_records @with_skip_locked = with_skip_locked + @logger = logger end def execute @@ -29,7 +30,7 @@ module LooseForeignKeys private - attr_reader :loose_foreign_key_definition, :connection, :deleted_parent_records, :with_skip_locked + attr_reader :loose_foreign_key_definition, :connection, :deleted_parent_records, :with_skip_locked, :logger def build_query query = if async_delete? @@ -37,11 +38,13 @@ module LooseForeignKeys elsif async_nullify? update_query else - raise "Invalid on_delete argument: #{loose_foreign_key_definition.on_delete}" + logger.error("Invalid on_delete argument: #{loose_foreign_key_definition.on_delete}") + return "" end unless query.include?(%{"#{loose_foreign_key_definition.column}" IN (}) - raise("FATAL: foreign key condition is missing from the generated query: #{query}") + logger.error("FATAL: foreign key condition is missing from the generated query: #{query}") + return "" end query diff --git a/app/services/loose_foreign_keys/process_deleted_records_service.rb b/app/services/loose_foreign_keys/process_deleted_records_service.rb index bb7064d0cf2..b3e79815ac9 100644 --- a/app/services/loose_foreign_keys/process_deleted_records_service.rb +++ b/app/services/loose_foreign_keys/process_deleted_records_service.rb @@ -4,9 +4,10 @@ module LooseForeignKeys class ProcessDeletedRecordsService BATCH_SIZE = 1000 - def initialize(connection:, modification_tracker: LooseForeignKeys::ModificationTracker.new) + def initialize(connection:, logger: Sidekiq.logger, modification_tracker: LooseForeignKeys::ModificationTracker.new) @connection = connection @modification_tracker = modification_tracker + @logger = logger end def execute @@ -31,6 +32,7 @@ module LooseForeignKeys loose_foreign_key_definitions: loose_foreign_key_definitions, deleted_parent_records: records, connection: connection, + logger: logger, modification_tracker: modification_tracker) .execute @@ -55,7 +57,7 @@ module LooseForeignKeys private - attr_reader :connection, :modification_tracker + attr_reader :connection, :logger, :modification_tracker def db_config_name ::Gitlab::Database.db_config_name(connection) diff --git a/app/services/packages/npm/check_manifest_coherence_service.rb b/app/services/packages/npm/check_manifest_coherence_service.rb index 98d787fcd45..d8cf0d2440e 100644 --- a/app/services/packages/npm/check_manifest_coherence_service.rb +++ b/app/services/packages/npm/check_manifest_coherence_service.rb @@ -9,9 +9,6 @@ module Packages MANIFEST_NOT_COHERENT_ERROR = 'Package manifest is not coherent' VERSION_NOT_COMPLIANT_ERROR = 'Version in package.json is not SemVer compliant' - delegate :npm_metadatum, to: :package, private: true - delegate :package_json_scripts, to: :npm_metadatum, private: true, allow_nil: true - def initialize(package, package_json_entry) @package = package @package_json_entry = package_json_entry @@ -31,8 +28,7 @@ module Packages def coherent?(package_json) package_json['name'] == package.name && - same_version?(package_json['version'], package.version) && - (package_json['scripts'] || {}) == (package_json_scripts || {}) + same_version?(package_json['version'], package.version) end def same_version?(version1, version2) diff --git a/app/views/admin/spam_logs/index.html.haml b/app/views/admin/spam_logs/index.html.haml index d301570288f..bb787d5d5e4 100644 --- a/app/views/admin/spam_logs/index.html.haml +++ b/app/views/admin/spam_logs/index.html.haml @@ -16,4 +16,4 @@ = render @spam_logs = paginate_collection @spam_logs - else - %h4= _('There are no Spam Logs') + %h4= _('There are no spam logs') diff --git a/app/workers/loose_foreign_keys/cleanup_worker.rb b/app/workers/loose_foreign_keys/cleanup_worker.rb index e5aeb15fe8d..8f0ad91a9ab 100644 --- a/app/workers/loose_foreign_keys/cleanup_worker.rb +++ b/app/workers/loose_foreign_keys/cleanup_worker.rb @@ -22,7 +22,8 @@ module LooseForeignKeys in_lock(self.class.name.underscore, ttl: lock_ttl, retries: 0) do stats = ProcessDeletedRecordsService.new( connection: base_model.connection, - modification_tracker: modification_tracker + modification_tracker: modification_tracker, + logger: Sidekiq.logger ).execute stats[:connection] = connection_name stats[:turbo_mode] = turbo_mode diff --git a/db/docs/sbom_sources.yml b/db/docs/sbom_sources.yml index e9621b6d895..e7738a554ee 100644 --- a/db/docs/sbom_sources.yml +++ b/db/docs/sbom_sources.yml @@ -7,5 +7,5 @@ feature_categories: description: Stores information about where an SBoM component originated from introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90812 milestone: '15.2' -gitlab_schema: gitlab_main +gitlab_schema: gitlab_sec sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/457096 diff --git a/db/migrate/20240708074520_add_scan_status_to_scan_result_policy_violation.rb b/db/migrate/20240708074520_add_scan_status_to_scan_result_policy_violation.rb new file mode 100644 index 00000000000..db9e4b517b6 --- /dev/null +++ b/db/migrate/20240708074520_add_scan_status_to_scan_result_policy_violation.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class AddScanStatusToScanResultPolicyViolation < Gitlab::Database::Migration[2.2] + milestone '17.2' + + def up + with_lock_retries do + add_column :scan_result_policy_violations, + :status, :integer, null: false, limit: 2, default: 1 + end + end + + def down + with_lock_retries do + remove_column :scan_result_policy_violations, + :status, :integer + end + end +end diff --git a/db/schema_migrations/20240708074520 b/db/schema_migrations/20240708074520 new file mode 100644 index 00000000000..724b2c5397b --- /dev/null +++ b/db/schema_migrations/20240708074520 @@ -0,0 +1 @@ +1100281c2adaaeaa03d97f6a6b43a1bbe2d29bb1702e0ff541d29a15926d1faa \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index c1cf821e93b..0bd64431086 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -17192,7 +17192,8 @@ CREATE TABLE scan_result_policy_violations ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, violation_data jsonb, - approval_policy_rule_id bigint + approval_policy_rule_id bigint, + status smallint DEFAULT 1 NOT NULL ); CREATE SEQUENCE scan_result_policy_violations_id_seq @@ -21208,8 +21209,6 @@ ALTER TABLE ONLY p_catalog_resource_sync_events ALTER COLUMN id SET DEFAULT next ALTER TABLE ONLY p_ci_builds_metadata ALTER COLUMN id SET DEFAULT nextval('ci_builds_metadata_id_seq'::regclass); -ALTER TABLE ONLY p_ci_job_annotations ALTER COLUMN id SET DEFAULT nextval('p_ci_job_annotations_id_seq'::regclass); - ALTER TABLE ONLY packages_build_infos ALTER COLUMN id SET DEFAULT nextval('packages_build_infos_id_seq'::regclass); ALTER TABLE ONLY packages_composer_cache_files ALTER COLUMN id SET DEFAULT nextval('packages_composer_cache_files_id_seq'::regclass); diff --git a/doc/administration/review_spam_logs.md b/doc/administration/review_spam_logs.md index 96dc19512db..10f9b61acac 100644 --- a/doc/administration/review_spam_logs.md +++ b/doc/administration/review_spam_logs.md @@ -23,7 +23,7 @@ View and resolve spam logs to moderate user activity in your instance. To view spam logs: 1. On the left sidebar, at the bottom, select **Admin area**. -1. Select **Spam Logs**. +1. Select **Spam logs**. 1. Optional. To resolve a spam log, select **More actions** (**{ellipsis_v}**), then **Remove user**, **Block user**, **Remove log**, or **Trust user**. ### Resolving spam logs diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index a2f057b27ce..75b8037a630 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -848,7 +848,7 @@ to a pipeline with `include`. Use `include:inputs` to define the values to use w Use the inputs to customize the behavior of the configuration when included in CI/CD configuration. -Use the interpolation format `$[[ input.input-id ]]` to reference the values outside of the header section. +Use the interpolation format `$[[ inputs.input-id ]]` to reference the values outside of the header section. Inputs are evaluated and interpolated when the configuration is fetched during pipeline creation, but before the configuration is merged with the contents of the `.gitlab-ci.yml` file. diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md index fc5925f0c3d..8adbf99815a 100644 --- a/doc/development/documentation/styleguide/word_list.md +++ b/doc/development/documentation/styleguide/word_list.md @@ -879,13 +879,6 @@ do not say: You can use **GA** to indicate general availability if you spell it out on first use. -## Git suggestions - -Use sentence case for **Git suggestions**. - -On first mention on a page, use **GitLab Duo Git suggestions**. -Thereafter, use **Git suggestions** by itself. - ## GitLab Do not make **GitLab** possessive (GitLab's). This guidance follows [GitLab Trademark Guidelines](https://handbook.gitlab.com/handbook/marketing/brand-and-product-marketing/brand/brand-activation/trademark-guidelines/). @@ -916,7 +909,7 @@ the following are the names of GitLab Duo features: - GitLab Duo Vulnerability explanation - GitLab Duo Vulnerability resolution - GitLab Duo Test generation -- GitLab Duo Git suggestions +- GitLab Duo for the CLI - GitLab Duo Root cause analysis - GitLab Duo Issue description generation diff --git a/doc/development/spam_protection_and_captcha/index.md b/doc/development/spam_protection_and_captcha/index.md index f48dc8e9189..1b71b11a2f9 100644 --- a/doc/development/spam_protection_and_captcha/index.md +++ b/doc/development/spam_protection_and_captcha/index.md @@ -50,4 +50,4 @@ The possible values include: - [Spam and CAPTCHA support in the GraphQL API](../../api/graphql/index.md#resolve-mutations-detected-as-spam) - [Spam and CAPTCHA support in the REST API](../../api/rest/index.md#resolve-requests-detected-as-spam) - [reCAPTCHA Spam and Anti-bot Protection](../../integration/recaptcha.md) -- [Akismet and Spam Logs](../../integration/akismet.md) +- [Akismet and spam logs](../../integration/akismet.md) diff --git a/doc/development/spam_protection_and_captcha/model_and_services.md b/doc/development/spam_protection_and_captcha/model_and_services.md index e4e2630e9d1..acebad56d80 100644 --- a/doc/development/spam_protection_and_captcha/model_and_services.md +++ b/doc/development/spam_protection_and_captcha/model_and_services.md @@ -57,7 +57,7 @@ To do this: The `SpammableActions::AkismetMarkAsSpamAction` module adds support for a `#mark_as_spam` action to a controller. This controller allows administrators to manage spam for the associated -`Spammable` model in the [Spam Log section](../../integration/akismet.md) of the Admin area page. +`Spammable` model in the [**Spam log** section](../../integration/akismet.md) of the Admin area page. 1. Include the `SpammableActions::AkismetMarkAsSpamAction` module in the controller. diff --git a/doc/integration/akismet.md b/doc/integration/akismet.md index 4eacd22f2d2..84d1ac41a34 100644 --- a/doc/integration/akismet.md +++ b/doc/integration/akismet.md @@ -15,7 +15,7 @@ spam issues on public projects. Issues created through the web UI or the API can Akismet for review, and instance administrators can [mark snippets as spam](../user/snippets.md#mark-snippet-as-spam). -Detected spam is rejected, and an entry is added in the **Spam Log** section of the +Detected spam is rejected, and an entry is added in the **Spam log** section of the Admin area. Privacy note: GitLab submits the user's IP and user agent to Akismet. @@ -56,12 +56,12 @@ DETAILS: To better differentiate between spam and ham, you can train the Akismet filter whenever there is a false positive or false negative. -When an entry is recognized as spam, it is rejected and added to the Spam Logs. +When an entry is recognized as spam, it is rejected and added to the spam logs. From here you can review if entries are really spam. If one of them is not really spam, you can use the **Submit as ham** button to tell Akismet that it falsely recognized an entry as spam. -![Screenshot of Spam Logs](img/spam_log.png) +![Screenshot of spam logs](img/spam_log.png) If an entry that is actually spam was not recognized as such, you can also submit this information to Akismet. The **Submit as spam** button is only displayed diff --git a/doc/security/hardening_nist_800_53.md b/doc/security/hardening_nist_800_53.md index 2b49acce5ce..10bf64d5980 100644 --- a/doc/security/hardening_nist_800_53.md +++ b/doc/security/hardening_nist_800_53.md @@ -161,7 +161,7 @@ requirements: FedRAMP requires organizations to monitor accounts for atypical use (AC-2(12)). GitLab empowers users to flag abuse in abuse reports, where administrators can remove access pending investigation. Spam - logs are consolidated in the Spam Logs section of the Admin area. + logs are consolidated in the **Spam logs** section of the Admin area. Administrators can remove, block, or trust users flagged in that area. diff --git a/doc/tutorials/observability/observability_rails_tutorial.md b/doc/tutorials/observability/observability_rails_tutorial.md index 590e888acd5..61e154780b8 100644 --- a/doc/tutorials/observability/observability_rails_tutorial.md +++ b/doc/tutorials/observability/observability_rails_tutorial.md @@ -97,10 +97,10 @@ To create an application: 1. Find your group ID: 1. On the left sidebar, select **Search or go to** and find the top-level group with the `animal` project. For example, if your project URL is `https://gitlab.com/tankui/observability/animal`, the top-level group is `tanuki`. - 1. On the group overview page, in the upper-right corner, select **Actions ({ellipsis_v})**. + 1. On the group overview page, in the upper-right corner, select **Actions** (**{ellipsis_v}**). 1. Select **Copy group ID**. Save the copied ID for later. 1. Find your project ID: - 1. On the `animal` project overview page, in the upper-right corner, select **Actions ({ellipsis_v})**. + 1. On the `animal` project overview page, in the upper-right corner, select **Actions** (**{ellipsis_v}**). 1. Select **Copy project ID**. Save the copied ID for later. 1. Edit `.env` and add the following code: diff --git a/lib/gitlab/themes.rb b/lib/gitlab/themes.rb index 387fbb32638..c7c5296be95 100644 --- a/lib/gitlab/themes.rb +++ b/lib/gitlab/themes.rb @@ -26,7 +26,7 @@ module Gitlab Theme.new(8, s_('NavigationTheme|Light Green'), 'ui-light-green', '#1b653f'), Theme.new(9, s_('NavigationTheme|Red'), 'ui-red', '#580d02'), Theme.new(10, s_('NavigationTheme|Light Red'), 'ui-light-red', '#a02e1c'), - Theme.new(2, s_('NavigationTheme|Gray'), 'ui-gray', '#333238'), + Theme.new(2, s_('NavigationTheme|Gray'), 'ui-gray', '#28272d'), Theme.new(3, s_('NavigationTheme|Neutral'), 'ui-neutral', '#ececef') ] end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 655ee11de12..2dbdd9f86d7 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -53647,9 +53647,6 @@ msgstr "" msgid "There are no SSH keys with access to your account." msgstr "" -msgid "There are no Spam Logs" -msgstr "" - msgid "There are no approval rules for the given `represent_as` parameter. Use a valid User/Group/Role name instead." msgstr "" @@ -53716,6 +53713,9 @@ msgstr "" msgid "There are no secure files yet." msgstr "" +msgid "There are no spam logs" +msgstr "" + msgid "There are no topics to show" msgstr "" diff --git a/package.json b/package.json index e24e896f80c..5644eaeaeed 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@gitlab/favicon-overlay": "2.0.0", "@gitlab/fonts": "^1.3.0", "@gitlab/svgs": "3.105.0", - "@gitlab/ui": "^86.9.1", + "@gitlab/ui": "^86.10.1", "@gitlab/web-ide": "^0.0.1-dev-20240613133550", "@mattiasbuelens/web-streams-adapter": "^0.1.0", "@rails/actioncable": "7.0.8-4", @@ -241,7 +241,7 @@ "yaml": "^2.0.0-10" }, "devDependencies": { - "@gitlab/eslint-plugin": "19.5.0", + "@gitlab/eslint-plugin": "19.6.0", "@gitlab/stylelint-config": "6.1.0", "@graphql-eslint/eslint-plugin": "3.20.1", "@originjs/vite-plugin-commonjs": "^1.0.3", diff --git a/scripts/frontend/lib/tailwind_migration.mjs b/scripts/frontend/lib/tailwind_migration.mjs index 9976ffe7523..23b909526de 100644 --- a/scripts/frontend/lib/tailwind_migration.mjs +++ b/scripts/frontend/lib/tailwind_migration.mjs @@ -88,47 +88,47 @@ const hardcodedColorsToCSSVarsMap = { shadow: {}, // This util already uses hardcoded colors in its legacy version 'shadow-x0-y2-b4-s0': {}, // This util already uses hardcoded colors in its legacy version 'shadow-sm': { - '#1f1e2414': '--t-gray-a-08', // The dark theme override does not yet exist + '#05050614': '--gl-color-alpha-dark-8', // The dark theme override does not yet exist }, 'shadow-md': { - '#1f1e2429': '--t-gray-a-16', // The dark theme override does not yet exist + '#05050629': '--gl-color-alpha-dark-6', // The dark theme override does not yet exist }, 'shadow-lg': { - '#1f1e2429': '--t-gray-a-16', // The dark theme override does not yet exist + '#05050629': '--gl-color-alpha-dark-6', // The dark theme override does not yet exist }, 'text-contrast-light': {}, // The legacy util references the $white-contrast variable for which we have no dark theme override 'text-black-normal': { - '#333': '--gray-900', + '#333': '--gl-text-color-default', }, 'text-body': { - '#333238': '--gl-text-primary', + '#28272d': '--gl-text-color-default', }, 'text-secondary': { '#737278': '--gl-text-secondary', }, 'border-gray-a-08': { - '#1f1e2414': '--t-gray-a-08', // The dark theme override does not yet exist + '#05050614': '--gl-color-alpha-dark-8', // The dark theme override does not yet exist }, 'inset-border-1-gray-a-08': { - '#1f1e2414': '--t-gray-a-08', // The dark theme override does not yet exist + '#05050614': '--gl-color-alpha-dark-8', // The dark theme override does not yet exist }, 'border-gray-a-24': { - '#1f1e243d': '--t-gray-a-24', // The dark theme override does not yet exist + '#0505063d': '--gl-color-alpha-dark-24', // The dark theme override does not yet exist }, border: { - '#dcdcde': '--gray-100', + '#dcdcde': '--gl-border-color-default', }, 'border-t': { - '#dcdcde': '--gray-100', + '#dcdcde': '--gl-border-color-default', }, 'border-r': { - '#dcdcde': '--gray-100', + '#dcdcde': '--gl-border-color-default', }, 'border-b': { - '#dcdcde': '--gray-100', + '#dcdcde': '--gl-border-color-default', }, 'border-l': { - '#dcdcde': '--gray-100', + '#dcdcde': '--gl-border-color-default', }, '-focus': { '#fff': '--white', @@ -166,7 +166,7 @@ export function getColorTokens(tokens) { * Returns a reverse mapping of hex values to tokens, e.g. * * { - * '#333238': [ 'color-neutral-900', 'icon-color-strong', 'gray-900' ] + * '#28272d': [ 'color-neutral-900', 'icon-color-strong', 'gray-900' ] * } * * @param rawTokens @@ -205,7 +205,7 @@ export const darkModeTokenToHex = Object.fromEntries( // We overwrite the following classes in // app/assets/stylesheets/themes/_dark.scss -darkModeTokenToHex['t-gray-a-08'] = '#fbfafd14'; // rgba($gray-950, 0.08); +darkModeTokenToHex['gl-color-alpha-dark-8'] = '#fbfafd14'; // rgba($gray-950, 0.08); darkModeTokenToHex['gl-text-secondary'] = '#bfbfc3'; // $gray-700 function isImportant(selector) { diff --git a/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb b/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb index dd16c7993f8..84fe45074b4 100644 --- a/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb +++ b/spec/lib/gitlab/database/no_cross_db_foreign_keys_spec.rb @@ -31,7 +31,8 @@ RSpec.describe 'cross-database foreign keys' do 'user_group_callouts.user_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/421287 'subscription_user_add_on_assignments.user_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/444666 'subscription_add_on_purchases.subscription_add_on_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/444666 - 'sbom_occurrences.source_package_id' # https://gitlab.com/groups/gitlab-org/-/epics/14116#identified-cross-joins + 'sbom_occurrences.source_package_id', # https://gitlab.com/groups/gitlab-org/-/epics/14116#identified-cross-joins + 'sbom_occurrences.source_id' # https://gitlab.com/groups/gitlab-org/-/epics/14116#identified-cross-joins ] end diff --git a/spec/models/packages/npm/metadatum_spec.rb b/spec/models/packages/npm/metadatum_spec.rb index f66d6e548db..e5586dca15c 100644 --- a/spec/models/packages/npm/metadatum_spec.rb +++ b/spec/models/packages/npm/metadatum_spec.rb @@ -61,12 +61,4 @@ RSpec.describe Packages::Npm::Metadatum, type: :model, feature_category: :packag end end end - - describe '#package_json_scripts' do - let(:metadatum) { build_stubbed(:npm_metadatum) } - - subject { metadatum.package_json_scripts } - - it { is_expected.to eq({ 'test' => 'echo "Test"' }) } - end end diff --git a/spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb b/spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb index e57e28a3f70..dbe1a7aa7f8 100644 --- a/spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb +++ b/spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb @@ -252,4 +252,48 @@ RSpec.describe LooseForeignKeys::BatchCleanerService, feature_category: :databas end end end + + describe 'when the definition is invalid' do + let(:loose_foreign_key_definitions) do + [ + ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new( + '_test_loose_fk_child_table_1', + '_test_loose_fk_parent_table', + { + column: 'parent_id', + on_delete: :async_delete, + gitlab_schema: :gitlab_main + } + ), + ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new( + '_test_loose_fk_child_table_2', + '_test_loose_fk_parent_table', + { + column: 'parent_id_with_different_column', + on_delete: :not_valid, + gitlab_schema: :gitlab_main + } + ) + ] + end + + before do + parent_record_1.delete + end + + it 'logs error and skips the definition' do + expect(Sidekiq.logger).to receive(:error).with("Invalid on_delete argument: not_valid").twice + expect(Sidekiq.logger).to receive(:error).with("Invalid on_delete argument for definition: _test_loose_fk_child_table_2").twice + + described_class.new( + parent_table: '_test_loose_fk_parent_table', + loose_foreign_key_definitions: loose_foreign_key_definitions, + deleted_parent_records: LooseForeignKeys::DeletedRecord.load_batch_for_table('public._test_loose_fk_parent_table', 100), + connection: ::ApplicationRecord.connection + ).execute + + expect(loose_fk_child_table_1.where(parent_id: parent_record_1.id)).to be_empty + expect(loose_fk_child_table_2.where(parent_id_with_different_column: parent_record_1.id).count).to eq(2) + end + end end diff --git a/spec/services/loose_foreign_keys/cleaner_service_spec.rb b/spec/services/loose_foreign_keys/cleaner_service_spec.rb index 7f92ba96800..979945b439c 100644 --- a/spec/services/loose_foreign_keys/cleaner_service_spec.rb +++ b/spec/services/loose_foreign_keys/cleaner_service_spec.rb @@ -36,8 +36,10 @@ RSpec.describe LooseForeignKeys::CleanerService, feature_category: :database do loose_fk_definition.options[:on_delete] = :invalid end - it 'raises KeyError' do - expect { cleaner_service.execute }.to raise_error(StandardError, /Invalid on_delete argument/) + it 'logs argument error' do + expect(Sidekiq.logger).to receive(:error).with("Invalid on_delete argument: invalid") + + cleaner_service.execute end end end @@ -118,12 +120,14 @@ RSpec.describe LooseForeignKeys::CleanerService, feature_category: :database do end context 'when the query generation is incorrect (paranoid check)' do - it 'raises error if the foreign key condition is missing' do + it 'logs error if the foreign key condition is missing' do expect_next_instance_of(LooseForeignKeys::CleanerService) do |instance| expect(instance).to receive(:delete_query).and_return('wrong query') end - expect { cleaner_service.execute }.to raise_error(/FATAL: foreign key condition is missing from the generated query/) + expect(Sidekiq.logger).to receive(:error).with("FATAL: foreign key condition is missing from the generated query: wrong query") + + cleaner_service.execute end end end diff --git a/spec/services/loose_foreign_keys/partition_cleaner_service_spec.rb b/spec/services/loose_foreign_keys/partition_cleaner_service_spec.rb index f595923f7bb..916f2ede0f4 100644 --- a/spec/services/loose_foreign_keys/partition_cleaner_service_spec.rb +++ b/spec/services/loose_foreign_keys/partition_cleaner_service_spec.rb @@ -70,11 +70,14 @@ RSpec.describe LooseForeignKeys::PartitionCleanerService, feature_category: :dat context 'when the query generation is incorrect (paranoid check)' do it 'raises error if the foreign key condition is missing' do expect_next_instance_of(LooseForeignKeys::PartitionCleanerService) do |instance| - expect(instance).to receive(:update_query).and_return('wrong query') + expect(instance).to receive(:update_query).and_return('wrong query').twice end - expect { cleaner_service.execute } - .to raise_error(/FATAL: foreign key condition is missing from the generated query/) + expect(Sidekiq.logger) + .to receive(:error) + .with("FATAL: foreign key condition is missing from the generated query: wrong query").twice + + cleaner_service.execute end end end diff --git a/spec/services/packages/npm/check_manifest_coherence_service_spec.rb b/spec/services/packages/npm/check_manifest_coherence_service_spec.rb index 1f3157af12f..ebfdcaab14b 100644 --- a/spec/services/packages/npm/check_manifest_coherence_service_spec.rb +++ b/spec/services/packages/npm/check_manifest_coherence_service_spec.rb @@ -4,7 +4,6 @@ require 'spec_helper' RSpec.describe Packages::Npm::CheckManifestCoherenceService, :aggregate_failures, feature_category: :package_registry do let_it_be(:package) { build(:npm_package) } - let_it_be(:package_metadata) { build(:npm_metadatum, package: package) } let(:tar_header) { Gem::Package::TarHeader.new(name: 'json', size: package_json.size, mode: 0o644, prefix: '') } let(:package_json_entry) { Gem::Package::TarReader::Entry.new(tar_header, StringIO.new(package_json)) } @@ -17,22 +16,19 @@ RSpec.describe Packages::Npm::CheckManifestCoherenceService, :aggregate_failures let(:package_name) { package.name } let(:package_version) { package.version } - let(:package_scripts) { package_metadata.package_json_scripts } - where(:name, :version, :scripts, :coherent) do - ref(:package_name) | ref(:package_version) | ref(:package_scripts) | true - 'foo' | ref(:package_version) | ref(:package_scripts) | false - ref(:package_name) | '5.0.3' | ref(:package_scripts) | false - ref(:package_name) | ref(:package_version) | { test: 'different script' } | false - 'foo' | '5.0.3' | { test: 'different script' } | false + where(:name, :version, :coherent) do + ref(:package_name) | ref(:package_version) | true + 'foo' | ref(:package_version) | false + ref(:package_name) | '5.0.3' | false + 'foo' | '5.0.3' | false end with_them do let(:package_json) do { name: name, - version: version, - scripts: scripts + version: version }.to_json end @@ -46,14 +42,13 @@ RSpec.describe Packages::Npm::CheckManifestCoherenceService, :aggregate_failures end end - %i[name version scripts].each do |field| + %i[name version].each do |field| context "with field #{field} present in sub key" do let(:package_json) do { name: package.name, version: package.version, - subkey: { field => 'test' }, - scripts: package_metadata.package_json_scripts + subkey: { field => 'test' } }.to_json end @@ -83,8 +78,7 @@ RSpec.describe Packages::Npm::CheckManifestCoherenceService, :aggregate_failures let(:package_json) do { name: package.name, - version: version_in_tarball, - scripts: package_metadata.package_json_scripts + version: version_in_tarball }.to_json end @@ -102,15 +96,5 @@ RSpec.describe Packages::Npm::CheckManifestCoherenceService, :aggregate_failures end end end - - context 'when the package metadata is missing' do - let(:package_json) { { name: package_name, version: package_version, scripts: {} }.to_json } - - before do - package.npm_metadatum = nil - end - - it { is_expected.to be_success } - end end end diff --git a/yarn.lock b/yarn.lock index aa2ea1a6e3f..9affdbb525d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1245,10 +1245,10 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.6.1": - version "4.6.2" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" - integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" + integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -1319,11 +1319,12 @@ core-js "^3.29.1" mitt "^3.0.1" -"@gitlab/eslint-plugin@19.5.0": - version "19.5.0" - resolved "https://registry.yarnpkg.com/@gitlab/eslint-plugin/-/eslint-plugin-19.5.0.tgz#4b5d397c1c5bb23fb37594ca8d094198ef28b315" - integrity sha512-Yb3D3IaARRDPcnQWhHbW2FUwndsZc+QtCHy2dYUiaT8AFobTshmdisDa7YGhKs+SQN6iMTV9p6ywnbD3JjaBSQ== +"@gitlab/eslint-plugin@19.6.0": + version "19.6.0" + resolved "https://registry.yarnpkg.com/@gitlab/eslint-plugin/-/eslint-plugin-19.6.0.tgz#988413bc8f1ecea5815c08f7e0d2706850279dc1" + integrity sha512-fD85FlMAOKirfRMKuzJGrQwUGdxuYFsszQ5O8cKsn8wqDevQyjp2jT/tOUAPv0UUQTG93iM/DW2ZntLjbakQ5g== dependencies: + "@typescript-eslint/eslint-plugin" "^7.14.1" eslint-config-airbnb-base "^15.0.0" eslint-config-prettier "^6.10.0" eslint-plugin-import "^2.28.0" @@ -1332,6 +1333,7 @@ eslint-plugin-unicorn "^40.1.0" eslint-plugin-vue "^9.17.0" lodash "^4.17.21" + vue-eslint-parser "^9.3.1" "@gitlab/favicon-overlay@2.0.0": version "2.0.0" @@ -1357,10 +1359,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.105.0.tgz#0d15978755093b79e5c9b883a27d8074bf316e9a" integrity sha512-JrXE7T3j+9FyQakG4XVg/uhXL3TZvmFgTuggaiSXdyelVOqAzYdPPm1oergdp8C+Io0zBKlLkJv/4nWG3AgkfQ== -"@gitlab/ui@^86.9.1": - version "86.9.1" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-86.9.1.tgz#ec02a4c77c3642a3b0b5391ede6a15dedde31628" - integrity sha512-91mctMAFNgugLf7Q126cZvMfhT0W5j5cPOA7oSKk8flCyGODDt7X3g53gDwQZ0kCYDp1oHXK9MenE+BWxK0Elw== +"@gitlab/ui@^86.10.1": + version "86.10.1" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-86.10.1.tgz#16463b1aff04683c62316b9c8b1a0e9e2917916f" + integrity sha512-LOV8HmZcgDTKq4/Yp45kncYjl20pTPWdhUWUwcTQlX6ewMYBkO/ip6wTLAQx7LVrBGXMlbHlk5PVbiwgatgulA== dependencies: "@floating-ui/dom" "1.4.3" echarts "^5.3.2" @@ -3214,6 +3216,21 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/eslint-plugin@^7.14.1": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz#b3563927341eca15124a18c6f94215f779f5c02a" + integrity sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "7.16.0" + "@typescript-eslint/type-utils" "7.16.0" + "@typescript-eslint/utils" "7.16.0" + "@typescript-eslint/visitor-keys" "7.16.0" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^1.3.0" + "@typescript-eslint/scope-manager@5.38.0": version "5.38.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.38.0.tgz#8f0927024b6b24e28671352c93b393a810ab4553" @@ -3222,11 +3239,34 @@ "@typescript-eslint/types" "5.38.0" "@typescript-eslint/visitor-keys" "5.38.0" +"@typescript-eslint/scope-manager@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz#eb0757af5720c9c53c8010d7a0355ae27e17b7e5" + integrity sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw== + dependencies: + "@typescript-eslint/types" "7.16.0" + "@typescript-eslint/visitor-keys" "7.16.0" + +"@typescript-eslint/type-utils@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz#ec52b1932b8fb44a15a3e20208e0bd49d0b6bd00" + integrity sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg== + dependencies: + "@typescript-eslint/typescript-estree" "7.16.0" + "@typescript-eslint/utils" "7.16.0" + debug "^4.3.4" + ts-api-utils "^1.3.0" + "@typescript-eslint/types@5.38.0": version "5.38.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.38.0.tgz#8cd15825e4874354e31800dcac321d07548b8a5f" integrity sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA== +"@typescript-eslint/types@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.16.0.tgz#60a19d7e7a6b1caa2c06fac860829d162a036ed2" + integrity sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw== + "@typescript-eslint/typescript-estree@5.38.0": version "5.38.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.0.tgz#89f86b2279815c6fb7f57d68cf9b813f0dc25d98" @@ -3240,6 +3280,30 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz#98ac779d526fab2a781e5619c9250f3e33867c09" + integrity sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw== + dependencies: + "@typescript-eslint/types" "7.16.0" + "@typescript-eslint/visitor-keys" "7.16.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/utils@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.16.0.tgz#b38dc0ce1778e8182e227c98d91d3418449aa17f" + integrity sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "7.16.0" + "@typescript-eslint/types" "7.16.0" + "@typescript-eslint/typescript-estree" "7.16.0" + "@typescript-eslint/utils@^5.10.0": version "5.38.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.38.0.tgz#5b31f4896471818153790700eb02ac869a1543f4" @@ -3260,6 +3324,14 @@ "@typescript-eslint/types" "5.38.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz#a1d99fa7a3787962d6e0efd436575ef840e23b06" + integrity sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg== + dependencies: + "@typescript-eslint/types" "7.16.0" + eslint-visitor-keys "^3.4.3" + "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" @@ -8062,7 +8134,7 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= -ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.0: +ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.0, ignore@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== @@ -10343,10 +10415,10 @@ minimatch@^7.4.3: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== +minimatch@^9.0.1, minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== dependencies: brace-expansion "^2.0.1" @@ -12430,7 +12502,7 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7, semver@^7.5.0, semver@^7.5.3, semver@^7.5.4: +semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7, semver@^7.5.0, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0: version "7.6.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== @@ -13576,6 +13648,11 @@ trough@^2.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== +ts-api-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + ts-dedent@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5"