bsky rkey based post tracking
This commit is contained in:
@@ -24,7 +24,8 @@
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"1YiB.rust-bundle",
|
||||
"rust-lang.rust-analyzer"
|
||||
"rust-lang.rust-analyzer",
|
||||
"saoudrizwan.claude-dev"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,11 +8,13 @@ module Tasks::Bluesky
|
||||
CURSOR_KEY = "task-bluesky-jetstream-cursor-1"
|
||||
|
||||
def initialize
|
||||
@resolver = DIDKit::Resolver.new
|
||||
@dids = T.let(Concurrent::Set.new, Concurrent::Set)
|
||||
@dids.merge(Bluesky::MonitoredDid.pluck(:did))
|
||||
logger.info(
|
||||
"loaded #{@dids.size} #{"did".pluralize(@dids.size)} from database",
|
||||
)
|
||||
logger.info("dids: #{@dids.to_a.join(", ")}")
|
||||
|
||||
@bluesky_client =
|
||||
T.let(
|
||||
@@ -72,7 +74,31 @@ module Tasks::Bluesky
|
||||
return unless @dids.include?(msg.did)
|
||||
msg.operations.each do |op|
|
||||
next unless op.action == :create && op.type == :bsky_post
|
||||
logger.info("op: #{op.repo} / #{op.collection} / #{op.action}")
|
||||
post =
|
||||
Domain::Post::BlueskyPost.find_or_create_by!(at_uri: op.uri) do |post|
|
||||
post.bluesky_rkey = op.rkey
|
||||
post.text = op.raw_record["text"]
|
||||
post.bluesky_created_at = msg.time.in_time_zone("UTC")
|
||||
post.creator = creator_for(msg)
|
||||
end
|
||||
logger.info(
|
||||
"created bluesky post: `#{post.bluesky_rkey}` / `#{post.at_uri}`",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
sig do
|
||||
params(msg: Skyfall::Jetstream::CommitMessage).returns(
|
||||
T.nilable(Domain::User::BlueskyUser),
|
||||
)
|
||||
end
|
||||
def creator_for(msg)
|
||||
did = msg.did
|
||||
Domain::User::BlueskyUser.find_or_create_by!(did:) do |creator|
|
||||
creator.handle = @resolver.get_validated_handle(did) || did
|
||||
logger.info(
|
||||
"created bluesky user: `#{creator.handle}` / `#{creator.did}`",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -10,21 +10,16 @@ class Domain::Post::BlueskyPost < Domain::Post
|
||||
|
||||
after_initialize { self.state ||= "ok" if new_record? }
|
||||
|
||||
enum :state,
|
||||
{
|
||||
ok: "ok",
|
||||
removed: "removed",
|
||||
scan_error: "scan_error",
|
||||
file_error: "file_error",
|
||||
},
|
||||
prefix: "state"
|
||||
enum :state, { ok: "ok", removed: "removed" }, prefix: "state"
|
||||
|
||||
validates :state, presence: true
|
||||
validates :bluesky_id, presence: true
|
||||
validates :at_uri, presence: true, uniqueness: true
|
||||
validates :bluesky_rkey, presence: true
|
||||
validates :bluesky_created_at, presence: true
|
||||
|
||||
sig { override.returns([String, Symbol]) }
|
||||
def self.param_prefix_and_attribute
|
||||
["bsky", :bluesky_id]
|
||||
["bsky", :bluesky_rkey]
|
||||
end
|
||||
|
||||
sig { override.returns(String) }
|
||||
@@ -34,7 +29,7 @@ class Domain::Post::BlueskyPost < Domain::Post
|
||||
|
||||
sig { override.returns(Symbol) }
|
||||
def self.post_order_attribute
|
||||
:bluesky_id
|
||||
:bluesky_created_at
|
||||
end
|
||||
|
||||
sig { override.returns(Domain::DomainType) }
|
||||
@@ -49,15 +44,15 @@ class Domain::Post::BlueskyPost < Domain::Post
|
||||
|
||||
sig { override.returns(T.nilable(T.any(String, Integer))) }
|
||||
def domain_id_for_view
|
||||
self.bluesky_id
|
||||
self.bluesky_rkey
|
||||
end
|
||||
|
||||
sig { override.returns(T.nilable(Addressable::URI)) }
|
||||
def external_url_for_view
|
||||
handle = self.creator&.handle
|
||||
if bluesky_id.present? && handle.present?
|
||||
if bluesky_rkey.present? && handle.present?
|
||||
Addressable::URI.parse(
|
||||
"https://bsky.app/profile/#{handle}/post/#{bluesky_id}",
|
||||
"https://bsky.app/profile/#{handle}/post/#{bluesky_rkey}",
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -99,48 +94,6 @@ class Domain::Post::BlueskyPost < Domain::Post
|
||||
current_text.present? ? current_text.truncate(50) : "Bluesky Post"
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
def status_for_view
|
||||
case self.state
|
||||
when "ok"
|
||||
"OK"
|
||||
when "removed"
|
||||
"Removed"
|
||||
when "scan_error"
|
||||
"Scan error"
|
||||
when "file_error"
|
||||
"File error"
|
||||
end
|
||||
end
|
||||
|
||||
sig do
|
||||
params(
|
||||
at_uri: String,
|
||||
creator: Domain::User::BlueskyUser,
|
||||
first_seen_log_entry: T.nilable(HttpLogEntry),
|
||||
).returns(Domain::Post::BlueskyPost)
|
||||
end
|
||||
def self.find_or_initialize_by_at_uri(
|
||||
at_uri,
|
||||
creator:,
|
||||
first_seen_log_entry: nil
|
||||
)
|
||||
# Extract the record key (post ID) from AT URI
|
||||
# e.g., "at://did:plc:abc123/app.bsky.feed.post/xyz789" -> "xyz789"
|
||||
bluesky_id = at_uri.split("/").last
|
||||
|
||||
post =
|
||||
Domain::Post::BlueskyPost.find_or_initialize_by(
|
||||
bluesky_id: bluesky_id,
|
||||
) do |post|
|
||||
post.first_seen_entry = first_seen_log_entry
|
||||
post.at_uri = at_uri
|
||||
end
|
||||
|
||||
post.creator ||= creator
|
||||
post
|
||||
end
|
||||
|
||||
sig { override.returns(T.nilable(T::Array[TagForView])) }
|
||||
def tags_for_view
|
||||
return nil unless hashtags.present?
|
||||
|
||||
@@ -13,6 +13,7 @@ class Domain::User::BlueskyUser < Domain::User
|
||||
prefix: :state
|
||||
|
||||
validates :handle, presence: true
|
||||
validates :did, presence: true
|
||||
validates :state, presence: true
|
||||
|
||||
after_initialize { self.state ||= "ok" if new_record? }
|
||||
|
||||
@@ -9,6 +9,7 @@ class AddAuxTablesForDomainUsersBlueskyUsers < ActiveRecord::Migration[7.2]
|
||||
add_enum_value :domain_user_type, "Domain::User::BlueskyUser"
|
||||
create_aux_table :domain_users, :bluesky do |t|
|
||||
t.string :state, null: false
|
||||
t.string :did, null: false, index: true # Decentralized identifier
|
||||
# handle is the "username"
|
||||
t.string :handle, null: false, index: true
|
||||
t.string :display_name
|
||||
@@ -16,7 +17,6 @@ class AddAuxTablesForDomainUsersBlueskyUsers < ActiveRecord::Migration[7.2]
|
||||
t.text :description
|
||||
|
||||
# Bluesky-specific fields
|
||||
t.string :did, index: true # Decentralized identifier
|
||||
t.integer :followers_count
|
||||
t.integer :following_count
|
||||
t.integer :posts_count
|
||||
@@ -27,16 +27,6 @@ class AddAuxTablesForDomainUsersBlueskyUsers < ActiveRecord::Migration[7.2]
|
||||
t.datetime :scanned_profile_at
|
||||
t.datetime :scanned_posts_at
|
||||
|
||||
# Log entries for tracking scans
|
||||
t.references :first_seen_entry,
|
||||
foreign_key: {
|
||||
to_table: :http_log_entries,
|
||||
}
|
||||
t.references :last_seen_entry,
|
||||
foreign_key: {
|
||||
to_table: :http_log_entries,
|
||||
}
|
||||
|
||||
# Raw data storage for debugging/analysis
|
||||
t.column :profile_raw, :jsonb, default: {}
|
||||
end
|
||||
|
||||
@@ -9,11 +9,12 @@ class AddAuxTablesForDomainPostsBlueskyPosts < ActiveRecord::Migration[7.2]
|
||||
add_enum_value :domain_post_type, "Domain::Post::BlueskyPost"
|
||||
create_aux_table :domain_posts, :bluesky do |t|
|
||||
t.string :state, null: false
|
||||
t.string :bluesky_id, null: false, index: true # Record key from AT URI
|
||||
t.string :at_uri, index: true # Full AT Protocol URI
|
||||
t.string :bluesky_rkey, null: false, index: true # Record key from AT URI
|
||||
t.string :at_uri # Full AT Protocol URI
|
||||
t.text :text # Post content
|
||||
|
||||
# Post metadata (posted_at is in main table)
|
||||
t.datetime :bluesky_created_at, index: true
|
||||
t.datetime :scanned_at
|
||||
t.string :language
|
||||
|
||||
@@ -32,12 +33,6 @@ class AddAuxTablesForDomainPostsBlueskyPosts < ActiveRecord::Migration[7.2]
|
||||
t.string :reply_to_uri # AT URI of post being replied to
|
||||
t.string :quote_uri # AT URI of post being quoted
|
||||
|
||||
# Log entries for tracking scans
|
||||
t.references :first_seen_entry,
|
||||
foreign_key: {
|
||||
to_table: :http_log_entries,
|
||||
}
|
||||
|
||||
# Raw data storage for debugging/analysis
|
||||
t.column :post_raw, :jsonb, default: {}
|
||||
|
||||
|
||||
@@ -1406,9 +1406,10 @@ CREATE TABLE public.domain_posts (
|
||||
CREATE TABLE public.domain_posts_bluesky_aux (
|
||||
base_table_id bigint NOT NULL,
|
||||
state character varying NOT NULL,
|
||||
bluesky_id character varying NOT NULL,
|
||||
bluesky_rkey character varying NOT NULL,
|
||||
at_uri character varying,
|
||||
text text,
|
||||
bluesky_created_at timestamp(6) without time zone,
|
||||
scanned_at timestamp(6) without time zone,
|
||||
language character varying,
|
||||
like_count integer,
|
||||
@@ -1420,7 +1421,6 @@ CREATE TABLE public.domain_posts_bluesky_aux (
|
||||
links jsonb DEFAULT '[]'::jsonb,
|
||||
reply_to_uri character varying,
|
||||
quote_uri character varying,
|
||||
first_seen_entry_id bigint,
|
||||
post_raw jsonb DEFAULT '{}'::jsonb,
|
||||
scan_error character varying
|
||||
);
|
||||
@@ -1943,17 +1943,15 @@ CREATE TABLE public.domain_users (
|
||||
CREATE TABLE public.domain_users_bluesky_aux (
|
||||
base_table_id bigint NOT NULL,
|
||||
state character varying NOT NULL,
|
||||
did character varying NOT NULL,
|
||||
handle character varying NOT NULL,
|
||||
display_name character varying,
|
||||
description text,
|
||||
did character varying,
|
||||
followers_count integer,
|
||||
following_count integer,
|
||||
posts_count integer,
|
||||
scanned_profile_at timestamp(6) without time zone,
|
||||
scanned_posts_at timestamp(6) without time zone,
|
||||
first_seen_entry_id bigint,
|
||||
last_seen_entry_id bigint,
|
||||
profile_raw jsonb DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
@@ -4372,13 +4370,6 @@ CREATE INDEX index_domain_post_group_joins_on_type ON public.domain_post_group_j
|
||||
CREATE INDEX index_domain_post_groups_on_type ON public.domain_post_groups USING btree (type);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_domain_posts_bluesky_aux_on_at_uri; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_domain_posts_bluesky_aux_on_at_uri ON public.domain_posts_bluesky_aux USING btree (at_uri);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_domain_posts_bluesky_aux_on_base_table_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
@@ -4387,17 +4378,17 @@ CREATE INDEX index_domain_posts_bluesky_aux_on_base_table_id ON public.domain_po
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_domain_posts_bluesky_aux_on_bluesky_id; Type: INDEX; Schema: public; Owner: -
|
||||
-- Name: index_domain_posts_bluesky_aux_on_bluesky_created_at; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_domain_posts_bluesky_aux_on_bluesky_id ON public.domain_posts_bluesky_aux USING btree (bluesky_id);
|
||||
CREATE INDEX index_domain_posts_bluesky_aux_on_bluesky_created_at ON public.domain_posts_bluesky_aux USING btree (bluesky_created_at);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_domain_posts_bluesky_aux_on_first_seen_entry_id; Type: INDEX; Schema: public; Owner: -
|
||||
-- Name: index_domain_posts_bluesky_aux_on_bluesky_rkey; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_domain_posts_bluesky_aux_on_first_seen_entry_id ON public.domain_posts_bluesky_aux USING btree (first_seen_entry_id);
|
||||
CREATE INDEX index_domain_posts_bluesky_aux_on_bluesky_rkey ON public.domain_posts_bluesky_aux USING btree (bluesky_rkey);
|
||||
|
||||
|
||||
--
|
||||
@@ -4666,13 +4657,6 @@ CREATE INDEX index_domain_users_bluesky_aux_on_base_table_id ON public.domain_us
|
||||
CREATE INDEX index_domain_users_bluesky_aux_on_did ON public.domain_users_bluesky_aux USING btree (did);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_domain_users_bluesky_aux_on_first_seen_entry_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_domain_users_bluesky_aux_on_first_seen_entry_id ON public.domain_users_bluesky_aux USING btree (first_seen_entry_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_domain_users_bluesky_aux_on_handle; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
@@ -4680,13 +4664,6 @@ CREATE INDEX index_domain_users_bluesky_aux_on_first_seen_entry_id ON public.dom
|
||||
CREATE INDEX index_domain_users_bluesky_aux_on_handle ON public.domain_users_bluesky_aux USING btree (handle);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_domain_users_bluesky_aux_on_last_seen_entry_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_domain_users_bluesky_aux_on_last_seen_entry_id ON public.domain_users_bluesky_aux USING btree (last_seen_entry_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_domain_users_e621_aux_on_base_table_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
@@ -5649,14 +5626,6 @@ ALTER TABLE ONLY public.domain_users_bluesky_aux
|
||||
ADD CONSTRAINT fk_rails_673dd1243a FOREIGN KEY (base_table_id) REFERENCES public.domain_users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: domain_posts_bluesky_aux fk_rails_7393623916; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.domain_posts_bluesky_aux
|
||||
ADD CONSTRAINT fk_rails_7393623916 FOREIGN KEY (first_seen_entry_id) REFERENCES public.http_log_entries(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: domain_posts_e621_aux fk_rails_73ac068c64; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -5697,14 +5666,6 @@ ALTER TABLE ONLY public.domain_user_search_names
|
||||
ADD CONSTRAINT fk_rails_8475fe75b5 FOREIGN KEY (user_id) REFERENCES public.domain_users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: domain_users_bluesky_aux fk_rails_986ba96a1b; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.domain_users_bluesky_aux
|
||||
ADD CONSTRAINT fk_rails_986ba96a1b FOREIGN KEY (first_seen_entry_id) REFERENCES public.http_log_entries(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: good_job_execution_log_lines_collections fk_rails_98c288034f; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -5865,14 +5826,6 @@ ALTER TABLE ONLY public.domain_user_avatars
|
||||
ADD CONSTRAINT fk_rails_f89912a20f FOREIGN KEY (user_id) REFERENCES public.domain_users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: domain_users_bluesky_aux fk_rails_fd9e7916ad; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.domain_users_bluesky_aux
|
||||
ADD CONSTRAINT fk_rails_fd9e7916ad FOREIGN KEY (last_seen_entry_id) REFERENCES public.http_log_entries(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: domain_twitter_tweets on_author_id; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
198
sorbet/rbi/dsl/domain/post/bluesky_post.rbi
generated
198
sorbet/rbi/dsl/domain/post/bluesky_post.rbi
generated
@@ -452,12 +452,6 @@ class Domain::Post::BlueskyPost
|
||||
end
|
||||
|
||||
module EnumMethodsModule
|
||||
sig { void }
|
||||
def state_file_error!; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def state_file_error?; end
|
||||
|
||||
sig { void }
|
||||
def state_ok!; end
|
||||
|
||||
@@ -469,12 +463,6 @@ class Domain::Post::BlueskyPost
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def state_removed?; end
|
||||
|
||||
sig { void }
|
||||
def state_scan_error!; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def state_scan_error?; end
|
||||
end
|
||||
|
||||
module GeneratedAssociationMethods
|
||||
@@ -860,50 +848,105 @@ class Domain::Post::BlueskyPost
|
||||
sig { void }
|
||||
def at_uri_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at; end
|
||||
|
||||
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
|
||||
def bluesky_id=(value); end
|
||||
sig { params(value: T.nilable(::ActiveSupport::TimeWithZone)).returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def bluesky_id?; end
|
||||
def bluesky_created_at?; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id_before_last_save; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def bluesky_id_before_type_cast; end
|
||||
def bluesky_created_at_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def bluesky_id_came_from_user?; end
|
||||
def bluesky_created_at_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_id_change; end
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def bluesky_created_at_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_id_change_to_be_saved; end
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def bluesky_created_at_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def bluesky_id_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
sig do
|
||||
params(
|
||||
from: T.nilable(::ActiveSupport::TimeWithZone),
|
||||
to: T.nilable(::ActiveSupport::TimeWithZone)
|
||||
).returns(T::Boolean)
|
||||
end
|
||||
def bluesky_created_at_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id_in_database; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_id_previous_change; end
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def bluesky_created_at_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def bluesky_id_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
sig do
|
||||
params(
|
||||
from: T.nilable(::ActiveSupport::TimeWithZone),
|
||||
to: T.nilable(::ActiveSupport::TimeWithZone)
|
||||
).returns(T::Boolean)
|
||||
end
|
||||
def bluesky_created_at_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id_previously_was; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id_was; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at_was; end
|
||||
|
||||
sig { void }
|
||||
def bluesky_id_will_change!; end
|
||||
def bluesky_created_at_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey; end
|
||||
|
||||
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
|
||||
def bluesky_rkey=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def bluesky_rkey?; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def bluesky_rkey_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def bluesky_rkey_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_rkey_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_rkey_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def bluesky_rkey_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_rkey_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def bluesky_rkey_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey_was; end
|
||||
|
||||
sig { void }
|
||||
def bluesky_rkey_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def created_at; end
|
||||
@@ -960,6 +1003,51 @@ class Domain::Post::BlueskyPost
|
||||
sig { void }
|
||||
def created_at_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did; end
|
||||
|
||||
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
|
||||
def creator_did=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def creator_did?; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def creator_did_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def creator_did_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def creator_did_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def creator_did_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def creator_did_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def creator_did_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def creator_did_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did_was; end
|
||||
|
||||
sig { void }
|
||||
def creator_did_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def first_seen_entry_id; end
|
||||
|
||||
@@ -1739,11 +1827,17 @@ class Domain::Post::BlueskyPost
|
||||
def restore_at_uri!; end
|
||||
|
||||
sig { void }
|
||||
def restore_bluesky_id!; end
|
||||
def restore_bluesky_created_at!; end
|
||||
|
||||
sig { void }
|
||||
def restore_bluesky_rkey!; end
|
||||
|
||||
sig { void }
|
||||
def restore_created_at!; end
|
||||
|
||||
sig { void }
|
||||
def restore_creator_did!; end
|
||||
|
||||
sig { void }
|
||||
def restore_first_seen_entry_id!; end
|
||||
|
||||
@@ -1819,11 +1913,17 @@ class Domain::Post::BlueskyPost
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_at_uri?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def saved_change_to_bluesky_id; end
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def saved_change_to_bluesky_created_at; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_bluesky_id?; end
|
||||
def saved_change_to_bluesky_created_at?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def saved_change_to_bluesky_rkey; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_bluesky_rkey?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def saved_change_to_created_at; end
|
||||
@@ -1831,6 +1931,12 @@ class Domain::Post::BlueskyPost
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_created_at?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def saved_change_to_creator_did; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_creator_did?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_first_seen_entry_id; end
|
||||
|
||||
@@ -2263,11 +2369,17 @@ class Domain::Post::BlueskyPost
|
||||
def will_save_change_to_at_uri?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_bluesky_id?; end
|
||||
def will_save_change_to_bluesky_created_at?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_bluesky_rkey?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_created_at?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_creator_did?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_first_seen_entry_id?; end
|
||||
|
||||
|
||||
222
sorbet/rbi/dsl/domain_posts_bluesky_aux.rbi
generated
222
sorbet/rbi/dsl/domain_posts_bluesky_aux.rbi
generated
@@ -420,12 +420,6 @@ class DomainPostsBlueskyAux
|
||||
end
|
||||
|
||||
module EnumMethodsModule
|
||||
sig { void }
|
||||
def state_file_error!; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def state_file_error?; end
|
||||
|
||||
sig { void }
|
||||
def state_ok!; end
|
||||
|
||||
@@ -437,12 +431,6 @@ class DomainPostsBlueskyAux
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def state_removed?; end
|
||||
|
||||
sig { void }
|
||||
def state_scan_error!; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def state_scan_error?; end
|
||||
end
|
||||
|
||||
module GeneratedAssociationMethods
|
||||
@@ -547,18 +535,12 @@ class DomainPostsBlueskyAux
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def none(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def not_state_file_error(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def not_state_ok(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def not_state_removed(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def not_state_scan_error(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def null_relation?(*args, &blk); end
|
||||
|
||||
@@ -623,18 +605,12 @@ class DomainPostsBlueskyAux
|
||||
end
|
||||
def select(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def state_file_error(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def state_ok(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def state_removed(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def state_scan_error(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
|
||||
def strict_loading(*args, &blk); end
|
||||
|
||||
@@ -757,50 +733,150 @@ class DomainPostsBlueskyAux
|
||||
sig { void }
|
||||
def base_table_id_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at; end
|
||||
|
||||
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
|
||||
def bluesky_id=(value); end
|
||||
sig { params(value: T.nilable(::ActiveSupport::TimeWithZone)).returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def bluesky_id?; end
|
||||
def bluesky_created_at?; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id_before_last_save; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def bluesky_id_before_type_cast; end
|
||||
def bluesky_created_at_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def bluesky_id_came_from_user?; end
|
||||
def bluesky_created_at_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_id_change; end
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def bluesky_created_at_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_id_change_to_be_saved; end
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def bluesky_created_at_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def bluesky_id_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
sig do
|
||||
params(
|
||||
from: T.nilable(::ActiveSupport::TimeWithZone),
|
||||
to: T.nilable(::ActiveSupport::TimeWithZone)
|
||||
).returns(T::Boolean)
|
||||
end
|
||||
def bluesky_created_at_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id_in_database; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_id_previous_change; end
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def bluesky_created_at_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def bluesky_id_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
sig do
|
||||
params(
|
||||
from: T.nilable(::ActiveSupport::TimeWithZone),
|
||||
to: T.nilable(::ActiveSupport::TimeWithZone)
|
||||
).returns(T::Boolean)
|
||||
end
|
||||
def bluesky_created_at_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id_previously_was; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_id_was; end
|
||||
sig { returns(T.nilable(::ActiveSupport::TimeWithZone)) }
|
||||
def bluesky_created_at_was; end
|
||||
|
||||
sig { void }
|
||||
def bluesky_id_will_change!; end
|
||||
def bluesky_created_at_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey; end
|
||||
|
||||
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
|
||||
def bluesky_rkey=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def bluesky_rkey?; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def bluesky_rkey_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def bluesky_rkey_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_rkey_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_rkey_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def bluesky_rkey_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def bluesky_rkey_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def bluesky_rkey_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def bluesky_rkey_was; end
|
||||
|
||||
sig { void }
|
||||
def bluesky_rkey_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did; end
|
||||
|
||||
sig { params(value: T.nilable(::String)).returns(T.nilable(::String)) }
|
||||
def creator_did=(value); end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def creator_did?; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did_before_last_save; end
|
||||
|
||||
sig { returns(T.untyped) }
|
||||
def creator_did_before_type_cast; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def creator_did_came_from_user?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def creator_did_change; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def creator_did_change_to_be_saved; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def creator_did_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did_in_database; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def creator_did_previous_change; end
|
||||
|
||||
sig { params(from: T.nilable(::String), to: T.nilable(::String)).returns(T::Boolean) }
|
||||
def creator_did_previously_changed?(from: T.unsafe(nil), to: T.unsafe(nil)); end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did_previously_was; end
|
||||
|
||||
sig { returns(T.nilable(::String)) }
|
||||
def creator_did_was; end
|
||||
|
||||
sig { void }
|
||||
def creator_did_will_change!; end
|
||||
|
||||
sig { returns(T.nilable(::Integer)) }
|
||||
def first_seen_entry_id; end
|
||||
@@ -1394,7 +1470,13 @@ class DomainPostsBlueskyAux
|
||||
def restore_base_table_id!; end
|
||||
|
||||
sig { void }
|
||||
def restore_bluesky_id!; end
|
||||
def restore_bluesky_created_at!; end
|
||||
|
||||
sig { void }
|
||||
def restore_bluesky_rkey!; end
|
||||
|
||||
sig { void }
|
||||
def restore_creator_did!; end
|
||||
|
||||
sig { void }
|
||||
def restore_first_seen_entry_id!; end
|
||||
@@ -1459,11 +1541,23 @@ class DomainPostsBlueskyAux
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_base_table_id?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def saved_change_to_bluesky_id; end
|
||||
sig { returns(T.nilable([T.nilable(::ActiveSupport::TimeWithZone), T.nilable(::ActiveSupport::TimeWithZone)])) }
|
||||
def saved_change_to_bluesky_created_at; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_bluesky_id?; end
|
||||
def saved_change_to_bluesky_created_at?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def saved_change_to_bluesky_rkey; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_bluesky_rkey?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::String), T.nilable(::String)])) }
|
||||
def saved_change_to_creator_did; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def saved_change_to_creator_did?; end
|
||||
|
||||
sig { returns(T.nilable([T.nilable(::Integer), T.nilable(::Integer)])) }
|
||||
def saved_change_to_first_seen_entry_id; end
|
||||
@@ -1774,7 +1868,13 @@ class DomainPostsBlueskyAux
|
||||
def will_save_change_to_base_table_id?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_bluesky_id?; end
|
||||
def will_save_change_to_bluesky_created_at?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_bluesky_rkey?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_creator_did?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def will_save_change_to_first_seen_entry_id?; end
|
||||
@@ -1901,18 +2001,12 @@ class DomainPostsBlueskyAux
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def none(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def not_state_file_error(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def not_state_ok(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def not_state_removed(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def not_state_scan_error(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def null_relation?(*args, &blk); end
|
||||
|
||||
@@ -1977,18 +2071,12 @@ class DomainPostsBlueskyAux
|
||||
end
|
||||
def select(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def state_file_error(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def state_ok(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def state_removed(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def state_scan_error(*args, &blk); end
|
||||
|
||||
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
|
||||
def strict_loading(*args, &blk); end
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ class Skyfall::Jetstream::Message
|
||||
sig { returns(Symbol) }
|
||||
def type
|
||||
end
|
||||
|
||||
sig { returns(Time) }
|
||||
def time
|
||||
end
|
||||
end
|
||||
|
||||
class Skyfall::Jetstream::CommitMessage
|
||||
|
||||
Reference in New Issue
Block a user