mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-16 09:18:46 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b554ecfcb4 | ||
|
|
50244ba682 | ||
|
|
01cf5c103d | ||
|
|
5bda54d15a | ||
|
|
07f5573cd6 | ||
|
|
2b0b537152 | ||
|
|
c49e261ad0 | ||
|
|
915bcb267f | ||
|
|
ff37011057 | ||
|
|
8f5e95a159 | ||
|
|
16ee628d24 | ||
|
|
64a0b060a8 | ||
|
|
fa52f4361a | ||
|
|
7f7d6697c1 | ||
|
|
c2fb12d22d | ||
|
|
2dc4552229 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [4.4.9] - 2025-11-20
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix `tootctl upgrade storage-schema` failing with `ArgumentError` (#36914 by @shugo)
|
||||||
|
- Fix old previously-undiscovered posts being treated as new when receiving an `Update` (#36848 by @ClearlyClaire)
|
||||||
|
- Fix filters not being applied to quotes in detailed view (#36843 by @ClearlyClaire)
|
||||||
|
|
||||||
|
## [4.4.8] - 2025-10-21
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix quote control bypass ([GHSA-8h43-rcqj-wpc6](https://github.com/mastodon/mastodon/security/advisories/GHSA-8h43-rcqj-wpc6))
|
||||||
|
|
||||||
## [4.4.7] - 2025-10-15
|
## [4.4.7] - 2025-10-15
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through
|
|||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| ------- | ---------------- |
|
| ------- | ---------------- |
|
||||||
| 4.4.x | Yes |
|
| 4.4.x | Yes |
|
||||||
| 4.3.x | Yes |
|
| 4.3.x | Until 2026-05-06 |
|
||||||
| 4.2.x | Until 2026-01-08 |
|
| 4.2.x | Until 2026-01-08 |
|
||||||
| < 4.2 | No |
|
| < 4.2 | No |
|
||||||
|
|||||||
@@ -421,6 +421,7 @@ export const DetailedStatus: React.FC<{
|
|||||||
<QuotedStatus
|
<QuotedStatus
|
||||||
quote={status.get('quote')}
|
quote={status.get('quote')}
|
||||||
parentQuotePostId={status.get('id')}
|
parentQuotePostId={status.get('id')}
|
||||||
|
contextType='thread'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -384,6 +384,7 @@ export const DetailedStatus: React.FC<{
|
|||||||
<QuotedStatus
|
<QuotedStatus
|
||||||
quote={status.get('quote')}
|
quote={status.get('quote')}
|
||||||
parentQuotePostId={status.get('id')}
|
parentQuotePostId={status.get('id')}
|
||||||
|
contextType='thread'
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ActivityPub::Activity::Update < ActivityPub::Activity
|
class ActivityPub::Activity::Update < ActivityPub::Activity
|
||||||
|
# Updates to unknown objects older than that are ignored
|
||||||
|
OBJECT_AGE_THRESHOLD = 1.day
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
@account.schedule_refresh_if_stale!
|
@account.schedule_refresh_if_stale!
|
||||||
|
|
||||||
@@ -28,6 +31,9 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
|
|||||||
|
|
||||||
@status = Status.find_by(uri: object_uri, account_id: @account.id)
|
@status = Status.find_by(uri: object_uri, account_id: @account.id)
|
||||||
|
|
||||||
|
# Ignore updates for old unknown objects, since those are updates we are not interested in
|
||||||
|
return if @status.nil? && object_too_old?
|
||||||
|
|
||||||
# We may be getting `Create` and `Update` out of order
|
# We may be getting `Create` and `Update` out of order
|
||||||
@status ||= ActivityPub::Activity::Create.new(@json, @account, **@options).perform
|
@status ||= ActivityPub::Activity::Create.new(@json, @account, **@options).perform
|
||||||
|
|
||||||
@@ -35,4 +41,10 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
|
|||||||
|
|
||||||
ActivityPub::ProcessStatusUpdateService.new.call(@status, @json, @object, request_id: @options[:request_id])
|
ActivityPub::ProcessStatusUpdateService.new.call(@status, @json, @object, request_id: @options[:request_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def object_too_old?
|
||||||
|
@object['published'].present? && @object['published'].to_datetime < OBJECT_AGE_THRESHOLD.ago
|
||||||
|
rescue Date::Error
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class Quote < ApplicationRecord
|
|||||||
before_validation :set_activity_uri, only: :create, if: -> { account.local? && quoted_account&.remote? }
|
before_validation :set_activity_uri, only: :create, if: -> { account.local? && quoted_account&.remote? }
|
||||||
validates :activity_uri, presence: true, if: -> { account.local? && quoted_account&.remote? }
|
validates :activity_uri, presence: true, if: -> { account.local? && quoted_account&.remote? }
|
||||||
validate :validate_visibility
|
validate :validate_visibility
|
||||||
|
validate :validate_original_quoted_status
|
||||||
|
|
||||||
def accept!
|
def accept!
|
||||||
update!(state: :accepted)
|
update!(state: :accepted)
|
||||||
@@ -70,6 +71,10 @@ class Quote < ApplicationRecord
|
|||||||
errors.add(:quoted_status_id, :visibility_mismatch)
|
errors.add(:quoted_status_id, :visibility_mismatch)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_original_quoted_status
|
||||||
|
errors.add(:quoted_status_id, :reblog_unallowed) if quoted_status&.reblog?
|
||||||
|
end
|
||||||
|
|
||||||
def set_activity_uri
|
def set_activity_uri
|
||||||
self.activity_uri = [ActivityPub::TagManager.instance.uri_for(account), '/quote_requests/', SecureRandom.uuid].join
|
self.activity_uri = [ActivityPub::TagManager.instance.uri_for(account), '/quote_requests/', SecureRandom.uuid].join
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class REST::BaseQuoteSerializer < ActiveModel::Serializer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def quoted_status
|
def quoted_status
|
||||||
object.quoted_status if object.accepted? && object.quoted_status.present? && !status_filter.filtered_for_quote?
|
object.quoted_status if object.accepted? && object.quoted_status.present? && !object.quoted_status&.reblog? && !status_filter.filtered_for_quote?
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class ActivityPub::VerifyQuoteService < BaseService
|
|||||||
|
|
||||||
status ||= ActivityPub::FetchRemoteStatusService.new.call(uri, on_behalf_of: @quote.account.followers.local.first, prefetched_body:, request_id: @request_id, depth: @depth + 1)
|
status ||= ActivityPub::FetchRemoteStatusService.new.call(uri, on_behalf_of: @quote.account.followers.local.first, prefetched_body:, request_id: @request_id, depth: @depth + 1)
|
||||||
|
|
||||||
@quote.update(quoted_status: status) if status.present?
|
@quote.update(quoted_status: status) if status.present? && !status.reblog?
|
||||||
rescue Mastodon::RecursionLimitExceededError, Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS => e
|
rescue Mastodon::RecursionLimitExceededError, Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS => e
|
||||||
@fetching_error = e
|
@fetching_error = e
|
||||||
end
|
end
|
||||||
@@ -90,7 +90,7 @@ class ActivityPub::VerifyQuoteService < BaseService
|
|||||||
|
|
||||||
status = ActivityPub::FetchRemoteStatusService.new.call(object['id'], prefetched_body: object, on_behalf_of: @quote.account.followers.local.first, request_id: @request_id, depth: @depth)
|
status = ActivityPub::FetchRemoteStatusService.new.call(object['id'], prefetched_body: object, on_behalf_of: @quote.account.followers.local.first, request_id: @request_id, depth: @depth)
|
||||||
|
|
||||||
if status.present?
|
if status.present? && !status.reblog?
|
||||||
@quote.update(quoted_status: status)
|
@quote.update(quoted_status: status)
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ services:
|
|||||||
web:
|
web:
|
||||||
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
|
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
|
||||||
# build: .
|
# build: .
|
||||||
image: ghcr.io/glitch-soc/mastodon:v4.4.7
|
image: ghcr.io/glitch-soc/mastodon:v4.4.9
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bundle exec puma -C config/puma.rb
|
command: bundle exec puma -C config/puma.rb
|
||||||
@@ -83,7 +83,7 @@ services:
|
|||||||
# build:
|
# build:
|
||||||
# dockerfile: ./streaming/Dockerfile
|
# dockerfile: ./streaming/Dockerfile
|
||||||
# context: .
|
# context: .
|
||||||
image: ghcr.io/glitch-soc/mastodon-streaming:v4.4.7
|
image: ghcr.io/glitch-soc/mastodon-streaming:v4.4.9
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: node ./streaming/index.js
|
command: node ./streaming/index.js
|
||||||
@@ -102,7 +102,7 @@ services:
|
|||||||
sidekiq:
|
sidekiq:
|
||||||
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
|
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
|
||||||
# build: .
|
# build: .
|
||||||
image: ghcr.io/glitch-soc/mastodon:v4.4.7
|
image: ghcr.io/glitch-soc/mastodon:v4.4.9
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bundle exec sidekiq
|
command: bundle exec sidekiq
|
||||||
|
|||||||
@@ -123,12 +123,12 @@ module Mastodon::CLI
|
|||||||
progress.log("Moving #{previous_path} to #{upgraded_path}") if options[:verbose]
|
progress.log("Moving #{previous_path} to #{upgraded_path}") if options[:verbose]
|
||||||
|
|
||||||
begin
|
begin
|
||||||
move_previous_to_upgraded
|
move_previous_to_upgraded(previous_path, upgraded_path)
|
||||||
rescue => e
|
rescue => e
|
||||||
progress.log(pastel.red("Error processing #{previous_path}: #{e}"))
|
progress.log(pastel.red("Error processing #{previous_path}: #{e}"))
|
||||||
success = false
|
success = false
|
||||||
|
|
||||||
remove_directory
|
remove_directory(upgraded_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module Mastodon
|
|||||||
end
|
end
|
||||||
|
|
||||||
def patch
|
def patch
|
||||||
7
|
9
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_prerelease
|
def default_prerelease
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
"http-link-header": "^1.1.1",
|
"http-link-header": "^1.1.1",
|
||||||
"immutable": "^4.3.0",
|
"immutable": "^4.3.0",
|
||||||
"intl-messageformat": "^10.7.16",
|
"intl-messageformat": "^10.7.16",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.1",
|
||||||
"lande": "^1.0.10",
|
"lande": "^1.0.10",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"marky": "^1.2.5",
|
"marky": "^1.2.5",
|
||||||
|
|||||||
@@ -1096,6 +1096,60 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with a quote of a known reblog that is otherwise valid' do
|
||||||
|
let(:quoted_account) { Fabricate(:account, domain: 'quoted.example.com') }
|
||||||
|
let(:quoted_status) { Fabricate(:status, account: quoted_account, reblog: Fabricate(:status)) }
|
||||||
|
let(:approval_uri) { 'https://quoted.example.com/quote-approval' }
|
||||||
|
|
||||||
|
let(:object_json) do
|
||||||
|
build_object(
|
||||||
|
type: 'Note',
|
||||||
|
content: 'woah what she said is amazing',
|
||||||
|
quote: ActivityPub::TagManager.instance.uri_for(quoted_status),
|
||||||
|
quoteAuthorization: approval_uri
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_request(:get, approval_uri).to_return(headers: { 'Content-Type': 'application/activity+json' }, body: Oj.dump({
|
||||||
|
'@context': [
|
||||||
|
'https://www.w3.org/ns/activitystreams',
|
||||||
|
{
|
||||||
|
QuoteAuthorization: 'https://w3id.org/fep/044f#QuoteAuthorization',
|
||||||
|
gts: 'https://gotosocial.org/ns#',
|
||||||
|
interactionPolicy: {
|
||||||
|
'@id': 'gts:interactionPolicy',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
|
interactingObject: {
|
||||||
|
'@id': 'gts:interactingObject',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
|
interactionTarget: {
|
||||||
|
'@id': 'gts:interactionTarget',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
type: 'QuoteAuthorization',
|
||||||
|
id: approval_uri,
|
||||||
|
attributedTo: ActivityPub::TagManager.instance.uri_for(quoted_status.account),
|
||||||
|
interactingObject: object_json[:id],
|
||||||
|
interactionTarget: ActivityPub::TagManager.instance.uri_for(quoted_status),
|
||||||
|
}))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates a status without the verified quote' do
|
||||||
|
expect { subject.perform }.to change(sender.statuses, :count).by(1)
|
||||||
|
|
||||||
|
status = sender.statuses.first
|
||||||
|
expect(status).to_not be_nil
|
||||||
|
expect(status.quote).to_not be_nil
|
||||||
|
expect(status.quote.state).to_not eq 'accepted'
|
||||||
|
expect(status.quote.quoted_status).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when a vote to a local poll' do
|
context 'when a vote to a local poll' do
|
||||||
let(:poll) { Fabricate(:poll, options: %w(Yellow Blue)) }
|
let(:poll) { Fabricate(:poll, options: %w(Yellow Blue)) }
|
||||||
let!(:local_status) { Fabricate(:status, poll: poll) }
|
let!(:local_status) { Fabricate(:status, poll: poll) }
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ RSpec.describe ActivityPub::Activity do
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let(:publication_date) { 1.hour.ago.utc }
|
||||||
|
|
||||||
let(:create_json) do
|
let(:create_json) do
|
||||||
{
|
{
|
||||||
'@context': [
|
'@context': [
|
||||||
@@ -52,7 +54,7 @@ RSpec.describe ActivityPub::Activity do
|
|||||||
'https://www.w3.org/ns/activitystreams#Public',
|
'https://www.w3.org/ns/activitystreams#Public',
|
||||||
],
|
],
|
||||||
content: 'foo',
|
content: 'foo',
|
||||||
published: '2025-05-24T11:03:10Z',
|
published: publication_date.iso8601,
|
||||||
quote: ActivityPub::TagManager.instance.uri_for(quoted_status),
|
quote: ActivityPub::TagManager.instance.uri_for(quoted_status),
|
||||||
},
|
},
|
||||||
}.deep_stringify_keys
|
}.deep_stringify_keys
|
||||||
@@ -77,7 +79,7 @@ RSpec.describe ActivityPub::Activity do
|
|||||||
'https://www.w3.org/ns/activitystreams#Public',
|
'https://www.w3.org/ns/activitystreams#Public',
|
||||||
],
|
],
|
||||||
content: 'foo',
|
content: 'foo',
|
||||||
published: '2025-05-24T11:03:10Z',
|
published: publication_date.iso8601,
|
||||||
quote: ActivityPub::TagManager.instance.uri_for(quoted_status),
|
quote: ActivityPub::TagManager.instance.uri_for(quoted_status),
|
||||||
quoteAuthorization: approval_uri,
|
quoteAuthorization: approval_uri,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -733,6 +733,72 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the status adds a verifiable quote of a reblog through an explicit update' do
|
||||||
|
let(:quoted_account) { Fabricate(:account, domain: 'quoted.example.com') }
|
||||||
|
let(:quoted_status) { Fabricate(:status, account: quoted_account, reblog: Fabricate(:status)) }
|
||||||
|
let(:approval_uri) { 'https://quoted.example.com/approvals/1' }
|
||||||
|
|
||||||
|
let(:payload) do
|
||||||
|
{
|
||||||
|
'@context': [
|
||||||
|
'https://www.w3.org/ns/activitystreams',
|
||||||
|
{
|
||||||
|
'@id': 'https://w3id.org/fep/044f#quote',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'@id': 'https://w3id.org/fep/044f#quoteAuthorization',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
id: 'foo',
|
||||||
|
type: 'Note',
|
||||||
|
summary: 'Show more',
|
||||||
|
content: 'Hello universe',
|
||||||
|
updated: '2021-09-08T22:39:25Z',
|
||||||
|
quote: ActivityPub::TagManager.instance.uri_for(quoted_status),
|
||||||
|
quoteAuthorization: approval_uri,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_request(:get, approval_uri).to_return(headers: { 'Content-Type': 'application/activity+json' }, body: Oj.dump({
|
||||||
|
'@context': [
|
||||||
|
'https://www.w3.org/ns/activitystreams',
|
||||||
|
{
|
||||||
|
QuoteAuthorization: 'https://w3id.org/fep/044f#QuoteAuthorization',
|
||||||
|
gts: 'https://gotosocial.org/ns#',
|
||||||
|
interactionPolicy: {
|
||||||
|
'@id': 'gts:interactionPolicy',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
|
interactingObject: {
|
||||||
|
'@id': 'gts:interactingObject',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
|
interactionTarget: {
|
||||||
|
'@id': 'gts:interactionTarget',
|
||||||
|
'@type': '@id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
type: 'QuoteAuthorization',
|
||||||
|
id: approval_uri,
|
||||||
|
attributedTo: ActivityPub::TagManager.instance.uri_for(quoted_status.account),
|
||||||
|
interactingObject: ActivityPub::TagManager.instance.uri_for(status),
|
||||||
|
interactionTarget: ActivityPub::TagManager.instance.uri_for(quoted_status),
|
||||||
|
}))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates the approval URI but does not verify the quote' do
|
||||||
|
expect { subject.call(status, json, json) }
|
||||||
|
.to change(status, :quote).from(nil)
|
||||||
|
expect(status.quote.approval_uri).to eq approval_uri
|
||||||
|
expect(status.quote.state).to_not eq 'accepted'
|
||||||
|
expect(status.quote.quoted_status).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the status adds a unverifiable quote through an implicit update' do
|
context 'when the status adds a unverifiable quote through an implicit update' do
|
||||||
let(:quoted_account) { Fabricate(:account, domain: 'quoted.example.com') }
|
let(:quoted_account) { Fabricate(:account, domain: 'quoted.example.com') }
|
||||||
let(:quoted_status) { Fabricate(:status, account: quoted_account) }
|
let(:quoted_status) { Fabricate(:status, account: quoted_account) }
|
||||||
|
|||||||
19
yarn.lock
19
yarn.lock
@@ -2689,7 +2689,7 @@ __metadata:
|
|||||||
husky: "npm:^9.0.11"
|
husky: "npm:^9.0.11"
|
||||||
immutable: "npm:^4.3.0"
|
immutable: "npm:^4.3.0"
|
||||||
intl-messageformat: "npm:^10.7.16"
|
intl-messageformat: "npm:^10.7.16"
|
||||||
js-yaml: "npm:^4.1.0"
|
js-yaml: "npm:^4.1.1"
|
||||||
lande: "npm:^1.0.10"
|
lande: "npm:^1.0.10"
|
||||||
lint-staged: "npm:^16.0.0"
|
lint-staged: "npm:^16.0.0"
|
||||||
lodash: "npm:^4.17.21"
|
lodash: "npm:^4.17.21"
|
||||||
@@ -7769,8 +7769,8 @@ __metadata:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.1":
|
"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.1":
|
||||||
version: 10.4.5
|
version: 10.5.0
|
||||||
resolution: "glob@npm:10.4.5"
|
resolution: "glob@npm:10.5.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
foreground-child: "npm:^3.1.0"
|
foreground-child: "npm:^3.1.0"
|
||||||
jackspeak: "npm:^3.1.2"
|
jackspeak: "npm:^3.1.2"
|
||||||
@@ -7780,7 +7780,7 @@ __metadata:
|
|||||||
path-scurry: "npm:^1.11.1"
|
path-scurry: "npm:^1.11.1"
|
||||||
bin:
|
bin:
|
||||||
glob: dist/esm/bin.mjs
|
glob: dist/esm/bin.mjs
|
||||||
checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e
|
checksum: 10c0/100705eddbde6323e7b35e1d1ac28bcb58322095bd8e63a7d0bef1a2cdafe0d0f7922a981b2b48369a4f8c1b077be5c171804534c3509dfe950dde15fbe6d828
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -8762,6 +8762,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"js-yaml@npm:^4.1.1":
|
||||||
|
version: 4.1.1
|
||||||
|
resolution: "js-yaml@npm:4.1.1"
|
||||||
|
dependencies:
|
||||||
|
argparse: "npm:^2.0.1"
|
||||||
|
bin:
|
||||||
|
js-yaml: bin/js-yaml.js
|
||||||
|
checksum: 10c0/561c7d7088c40a9bb53cc75becbfb1df6ae49b34b5e6e5a81744b14ae8667ec564ad2527709d1a6e7d5e5fa6d483aa0f373a50ad98d42fde368ec4a190d4fae7
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"jsdoc-type-pratt-parser@npm:~4.1.0":
|
"jsdoc-type-pratt-parser@npm:~4.1.0":
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
resolution: "jsdoc-type-pratt-parser@npm:4.1.0"
|
resolution: "jsdoc-type-pratt-parser@npm:4.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user