At the beginning of a session:
- Read this file.
- Read
~/memory/active-projects.md. - Read the last few days of session logs in
~/memory/session-logs/ - Read the relevant project files for the current request.
| import { redirect, type LoaderArgs } from "@remix-run/node"; | |
| export async function removeTrailingSlashes(request: Request) { | |
| let url = new URL(request.url); | |
| if (url.pathname.endsWith("/") && url.pathname !== "/") { | |
| throw redirect(url.pathname.slice(0, -1) + url.search); | |
| } | |
| } | |
| export async function loader({ request }: LoaderArgs) { |
| # frozen_string_literal: true | |
| require "rails_helper" | |
| # Automatically smoke-test all mailer previews | |
| describe "/rails/mailers" do | |
| subject { response } | |
| ActionMailer::Preview.all.each do |preview| | |
| next if preview.emails.empty? |
| # In Active Record, class method scopes have to remember to return `all` otherwise they're break the call chain. | |
| # | |
| # def self.some_scope = nil # Assume more complex conditions that would result in a branch that accidentally didn't return `all`. | |
| # | |
| # User.some_scope.first # => raises NoMethodError `first' for NilClass | |
| # | |
| # Note: Active Record ensures a `scope :some_scope, -> { nil }` returns `all` via `|| all` here: | |
| # https://github.com/rails/rails/blob/c704da66de59262f4e88824589ae4eddefb6ed4a/activerecord/lib/active_record/scoping/named.rb#L181 | |
| # | |
| # Now, this extension allows you to mark a class method as a scope, so you don't have to remember and the code is more clearly demarcated too. |
| module AttributeMemoization | |
| def attr_accessor(*names, &block) | |
| return super(*names) unless block_given? | |
| attr_reader(*names, &block) | |
| attr_writer(*names) | |
| end | |
| def attr_reader(*names, &block) | |
| return super(*names) unless block_given? |
Thank you for all the stars and forks! To better manage updates, issues, and versioning, Minimal Analytics 4 has moved to a dedicated GitHub repository.
This version represents a total architectural overhaul to bring this script in line with professional tracking standards while maintaining a tiny footprint.
| require "faraday" | |
| require "faraday/multipart" | |
| token = ARGV.shift | |
| absolute_path = File.expand_path(ARGV.shift) | |
| # TODO how could we require "active_storage/blob" without eager loading the whole app | |
| blob = ActiveStorage::Blob.build_after_unfurling(io: File.open(absolute_path), filename: File.basename(absolute_path)) |
Caching is a big subject and it can get pretty complicated. Luckily, the browsers have done all the really hard work for us and we just need to #useThePlatform.
There are three types of caches you'll likely deal with in Remix applications:
Cache-Control header.Cache-Control headers.In our E2E tests, when the test runner navigates through the site, we don't want to make real API requests but rather we want to mock these requests so that we can easily test many different scenarios, and so that our tests are more resilient and less likely to flake if API is suffering any downtime.
Up until now, this has been achieved by "mocking the fetch function". For example:
| import { merge } from "lodash"; | |
| import { request } from "https"; | |
| import { v4 as uuidv4 } from "uuid"; | |
| export const name = "analytics-lamdba"; | |
| export const version = "0.1.2"; | |
| export type SegmentMessageTypes = | |
| | "identify" | |
| | "group" |