Skip to content

Instantly share code, notes, and snippets.

View fsubal's full-sized avatar

fsubal fsubal

View GitHub Profile
# MyClass.configure { ... } および config_accessor(:name) を提供するモジュール
#
# ```ruby
# class MyClass
# include Configurable
# config_accessor :name
# end
#
# MyClass.configure { |config| config.name = 'value' }
# MyClass.new.name # => 'value'
@fsubal
fsubal / has_json_snapshot.rb
Created July 28, 2026 01:57
has_json_snapshot.rb
module HasJsonSnapshot
extend ActiveSupport::Concern
class_methods do
def has_one_json_snapshot(attribute_name, class_name: attribute_name.to_s.classify)
klass = class_name.constantize
raise "#{class_name} does not have #as_json method" unless klass.method_defined?(:as_json)
composed_of(
attribute_name,
class PdfgateClient
class Error < StandardError
attr_reader :code
def initialize(code, message)
super("PdfgateClient Error (#{code}): #{message}")
@code = code
end
end
import React, { Suspense } from "react";
interface Props {
renderLoading?: () => React.ReactNode;
renderError?: (error: Error) => React.ReactNode;
children: React.ReactNode;
}
interface State {
hasError: boolean;
interface Action<T = unknown> {
type: string;
payload: T;
}
interface StateChangeDetail<A extends Action<unknown>, T> {
action: A;
previousState: T;
nextState: T;
}
import React from 'react'
interface Props {
ruby: string | string[]
children: string
}
function zipFurigana(ruby: string | string[], text: string) {
const rubyChars = Array.isArray(ruby) ? ruby : [ruby]
const textChars = Array.from(text)
@fsubal
fsubal / note.html
Last active August 10, 2025 06:39
漫画用に、架空のツイートや架空の記事のスクショが作れるジェネレーター( Generated by ChatGPT + GPT-5。利用自由 ) https://fsubal.github.io/fake-sns-screen/
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>note.com風記事モックジェネレータ</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", sans-serif;
margin: 0;
padding: 20px;
@fsubal
fsubal / sw.ts
Last active June 17, 2025 00:57
/// <reference lib="webworker" />
/**
* Rails の CSRF トークンを取得し、それを使ってリクエストを送信する
*
* ワーカースクリプトで動作する
*
* ワーカースクリプトの場合、メインスクリプトからメッセージを送信して CSRF トークンを更新する
* メインスクリプトからメッセージを送信して CSRF トークンを更新する
* メインスクリプトからメッセージを送信して CSRF トークンを更新する
export type UnionToIntersection<Union> = (
Union extends unknown ? (distributedUnion: Union) => void : never
) extends (
(mergedIntersection: infer Intersection) => void
) ? Intersection & Union : never;
type TemplateString<Varname extends string> = UnionToIntersection<`${string}{{${Varname}}}${string}`>
declare const phantom: unique symbol
import { resolve } from 'node:path'
import { readFile } from 'node:fs/promises'
import { exec } from 'node:child_process'
import { promisify } from 'node:util'
const execp = promisify(exec)
/**
* @see https://git-scm.com/docs/git-status#_porcelain_format_version_1
*/