Binxtils

Bike Index utility modules. Install it by adding the following line to your Gemfile

gem "binxtils"

Modules

  • Binxtils::InputNormalizer - Sanitize and normalize user input strings
  • Binxtils::Secure - Constant-time comparison of a value against an expected secret
  • Binxtils::TimeParser - Parse fuzzy time/date strings into Time objects
  • Binxtils::TimeZoneParser - Parse and resolve time zone strings

Functionable modules

These modules use Functionable and are called as class methods:

Binxtils::TimeParser.parse("next thursday")
Binxtils::InputNormalizer.string("  Some Input  ")
Binxtils::TimeZoneParser.parse("Eastern Time")
Binxtils::Secure.compare?(params[:token], ENV["WEBHOOK_TOKEN"])

Rails concerns

  • Binxtils::SetPeriod - Controller concern for time period filtering (hour, day, week, month, year, all, custom). Parses period params, manages timezones, and sets @time_range.
  • Binxtils::SortableTable - Controller concern providing sort_column and sort_direction helpers with configurable defaults.
  • Binxtils::SortableHelper - View helper for rendering sortable column header links with active-state indicators.

Include them in your controllers and helpers:

class ApplicationController < ActionController::Base
  include Binxtils::SetPeriod
  include Binxtils::SortableTable

  # Optionally configure the earliest date for the "all" period
  self.default_earliest_time = Time.at(1714460400).freeze
end

module ApplicationHelper
  include Binxtils::SortableHelper
end

# Optionally extend the permitted search params (e.g. in an initializer)
Binxtils::SortableHelper.extra_search_keys = [:organization_id, query_items: []]

SortableTable requires a sortable_columns method in your controller:

class BikesController < ApplicationController
  def sortable_columns
    %w[created_at updated_at manufacturer_id]
  end
end

npm package

This repo also publishes @bikeindex/time-localizer, an npm package for localizing time elements in the browser. It ships two builds of the same source:

Build Luxon Use when
dist/index.js (default) external — install it yourself You have a bundler. Luxon stays deduped with your own copy, so Settings.defaultLocale, Settings.now etc. apply to both.
dist/index.bundle.js bundled in You have no bundler (e.g. importmap-rails). One request, nothing to resolve.

Import the default as @bikeindex/time-localizer and the standalone as @bikeindex/time-localizer/bundle, or reference either file path directly over a CDN.

Don't use the bundled build alongside your own Luxon: you'd ship two copies, and because Luxon's Settings are module-scoped, your global config would silently apply to only one of them.

To publish a new version: update the version in package.json, then run npm publish from the repo root (requires npm login with access to the @bikeindex scope). The prepublishOnly script builds both artifacts before publishing.

Releasing

From the main branch, run bin/release with a version number:

bin/release 0.3.0

This bumps the version, commits, tags, pushes, builds and publishes the gem to RubyGems, and creates a GitHub release.