chrono_forge 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/Appraisals +4 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +0 -0
- data/Rakefile +14 -0
- data/config.ru +6 -0
- data/export.json +102 -0
- data/export.rb +48 -0
- data/gemfiles/rails_7.1.gemfile +8 -0
- data/gemfiles/rails_7.1.gemfile.lock +258 -0
- data/lib/chrono_forge/version.rb +5 -0
- data/lib/chrono_forge.rb +16 -0
- data/sig/chrono_forge.rbs +4 -0
- metadata +201 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: be157f4c6a7dbf68348d63c5a67b3c07de4cb981dac1ef8e28e1eebe1d382088
|
4
|
+
data.tar.gz: 4b60dcf5976495716fd1ff661a87dcc0b866daa8c48672723d2d438b5ced4f1d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 473a8bb888d88fb8df928c935a8fdeb9941fdfa8cd006e7e90491ce02c64fd73bc5e185c45db94dd8d4152385f8ffcae594ec5a82b7bbc6b7aecfddbf9d147bc
|
7
|
+
data.tar.gz: 0ba90ad3610d55c0dd7c092b6d7140de86a7a380411685d777d9a4aa6c172836930cef5aa0ffbeeda6dbbab34a0a0faff4a4928dc50e5e037e20038fff12863a
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.2.2
|
data/Appraisals
ADDED
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 Stefan Froelich
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
require "standard/rake"
|
6
|
+
|
7
|
+
task default: %i[test standard]
|
8
|
+
|
9
|
+
# https://juincc.medium.com/how-to-setup-minitest-for-your-gems-development-f29c4bee13c2
|
10
|
+
Rake::TestTask.new do |t|
|
11
|
+
t.libs << "test"
|
12
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
13
|
+
t.verbose = true
|
14
|
+
end
|
data/config.ru
ADDED
data/export.json
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/CHANGELOG.md",
|
4
|
+
"contents": "## [Unreleased]\n\n## [0.2.0] - 2024-07-31\n\n- Initial release\n"
|
5
|
+
},
|
6
|
+
{
|
7
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/README.md",
|
8
|
+
"contents": "# Phlexi::Form \n\nPhlexi::Form is a flexible and powerful form builder for Ruby applications. It provides a more customizable and extensible way to create forms compared to traditional form helpers.\n\n[](https://github.com/radioactive-labs/phlexi-form/actions/workflows/main.yml)\n\n## Features\n\n- Customizable form components (input, select, checkbox, radio button, etc.)\n- Automatic field type and attribute inference based on model attributes\n- Built-in support for validations and error handling\n- Flexible form structure with support for nested attributes\n- Works with Phlex or erb views\n- Extract input from parameters that match your form definition. No need to strong paramters.\n- Rails compatible form inputs\n\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'phlexi-form'\n```\n\nAnd then execute:\n\n```\n$ bundle install\n```\n\nOr install it yourself as:\n\n```\n$ gem install phlexi-form\n```\n\n## Usage\n\nThere are 2 ways to use Phlexi::Form:\n\n### Direct Usage\n\n```ruby\nPhlexi::Form(User.new) do\n field(:name) do |name|\n render name.label_tag\n render name.input_tag\n end\n\n field(:email) do |email|\n render email.label_tag\n render email.input_tag\n end\n\n nest_one(:address) do |address|\n address.field(:street) do |street|\n render street.label_tag\n render street.input_tag\n end\n\n address.field(:city) do |city|\n render city.label_tag\n render city.input_tag\n end\n end\n\n render submit_button\nend\n```\n\n> **Important**\n>\n> If you are rendering your form inline e.g. \n> ```ruby\n> render Phlexi::Form(User.new) {\n> render field(:name).label_tag\n> render field(:name).input_tag\n> }\n> ```\n>\n> Make sure you use `{...}` in defining your block instead of `do...end`\n> This might be fixed in a future version.\n\n### Inherit form\n\n```ruby\nclass UserForm < Phlexi::Form::Base\n def form_template\n field(:name) do |name|\n render name.label_tag\n render name.input_tag\n end\n\n field(:email) do |email|\n render email.label_tag\n render email.input_tag\n end\n\n nest_one(:address) do |address|\n address.field(:street) do |street|\n render street.label_tag\n render street.input_tag\n end\n\n address.field(:city) do |city|\n render city.label_tag\n render city.input_tag\n end\n end\n\n render submit_button\n end\nend\n\n\n# In your view or controller\nform = UserForm.new(User.new)\n\n# Render the form\nrender form\n\n# Extract params\nform.extract_input({\n name: \"Brad Pitt\",\n email: \"brad@pitt.com\",\n address: {\n street: \"Plumbago\",\n city: \"Accra\",\n }\n})\n```\n\n## Advanced Usage\n\n### Custom Components\n\nYou can create custom form components by inheriting from `Phlexi::Form::Components::Base`:\n\n```ruby\nclass CustomInput < Phlexi::Form::Components::Base\n def template\n div(class: \"custom-input\") do\n input(**attributes)\n span(class: \"custom-icon\")\n end\n end\nend\n\n# Usage in your form\nfield(:custom_field) do |field|\n render CustomInput.new(field)\nend\n```\n\n### Theming\n\nPhlexi::Form supports theming through a flexible theming system:\n\n```ruby\nclass ThemedForm < Phlexi::Form::Base\n class FieldBuilder < FieldBuilder\n private\n \n def default_theme\n {\n input: \"border rounded px-2 py-1\",\n label: \"font-bold text-gray-700\",\n # Add more theme options here\n }\n end\n end\nend\n```\n\n<!-- ## Configuration\n\nYou can configure Phlexi::Form globally by creating an initializer:\n\n```ruby\n# config/initializers/phlexi_form.rb\nPhlexi::Form.configure do |config|\n config.default_theme = {\n # Your default theme options\n }\n # Add more configuration options here\nend\n``` -->\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/radioactive-labs/phlexi-form.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/export.rb",
|
12
|
+
"contents": "require \"json\"\nrequire \"find\"\n\ndef export_files_to_json(directory, extensions, output_file, exceptions = [])\n # Convert extensions to lowercase for case-insensitive matching\n extensions = extensions.map(&:downcase)\n\n # Array to store file data\n files_data = []\n\n # Find all files in directory and subdirectories\n Find.find(directory) do |path|\n # Skip if not a file\n next unless File.file?(path)\n next if exceptions.any? { |exception| path.include?(exception) }\n\n # Check if file extension matches any in our list\n ext = File.extname(path).downcase[1..-1] # Remove the leading dot\n next unless extensions.include?(ext)\n\n puts path\n\n begin\n # Read file contents\n contents = File.read(path)\n\n # Add to our array\n files_data << {\n \"path\" => path,\n \"contents\" => contents\n }\n rescue => e\n puts \"Error reading file #{path}: #{e.message}\"\n end\n end\n\n # Write to JSON file\n File.write(output_file, JSON.pretty_generate(files_data))\n\n puts \"Successfully exported #{files_data.length} files to #{output_file}\"\nend\n\n# Example usage (uncomment and modify as needed):\ndirectory = \"/Users/stefan/Documents/plutonium/chrono_forge\"\nexceptions = [\"/.github/\", \"/.vscode/\", \"gemfiles\", \"pkg\", \"test\", \"node_modules\"]\nextensions = [\"rb\", \"md\", \"yml\", \"yaml\", \"gemspec\"]\noutput_file = \"export.json\"\nexport_files_to_json(directory, extensions, output_file, exceptions)\n"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/builder.rb",
|
16
|
+
"contents": "# frozen_string_literal: true\n\nrequire \"phlex\"\n\nmodule Phlexi\n module Field\n # Builder class is responsible for building fields with various options and components.\n #\n # @attr_reader [Structure::DOM] dom The DOM structure for the field.\n # @attr_reader [Hash] options Options for the field.\n # @attr_reader [Object] object The object associated with the field.\n # @attr_reader [Hash] attributes Attributes for the field.\n # @attr_accessor [Object] value The value of the field.\n class Builder < Structure::Node\n include Phlex::Helpers\n include Options::Validators\n include Options::InferredTypes\n include Options::Multiple\n include Options::Labels\n include Options::Placeholders\n include Options::Descriptions\n include Options::Hints\n include Options::Associations\n include Options::Attachments\n\n class DOM < Structure::DOM; end\n\n class FieldCollection < Structure::FieldCollection; end\n\n attr_reader :dom, :options, :object, :value\n\n # Initializes a new FieldBuilder instance.\n #\n # @param key [Symbol, String] The key for the field.\n # @param parent [Structure::Namespace] The parent object.\n # @param object [Object, nil] The associated object.\n # @param value [Object] The initial value for the field.\n # @param options [Hash] Additional options for the field.\n def initialize(key, parent:, object: nil, value: NIL_VALUE, **options)\n super(key, parent: parent)\n\n @object = object\n @value = determine_initial_value(value)\n @options = options\n @dom = self.class::DOM.new(field: self)\n end\n\n # Creates a repeated field collection.\n #\n # @param range [#each] The collection of items to generate displays for.\n # @yield [block] The block to be executed for each item in the collection.\n # @return [FieldCollection] The field collection.\n def repeated(collection = nil, &)\n self.class::FieldCollection.new(field: self, collection:, &)\n end\n\n def has_value?\n attachment_reflection.present? ? value.attached? : (value.present? || value == false)\n end\n\n protected\n\n def determine_initial_value(value)\n return value unless value == NIL_VALUE\n\n determine_value_from_object\n end\n\n def determine_value_from_object\n ChronoForge::Support::Value.from(object, key)\n end\n end\n end\nend\n"
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/components/base.rb",
|
20
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Components\n class Base < COMPONENT_BASE\n attr_reader :field, :attributes\n\n def initialize(field, **attributes)\n @field = field\n @attributes = attributes\n\n build_attributes\n build_component_class\n end\n\n protected\n\n def build_attributes\n attributes.fetch(:id) { attributes[:id] = \"#{field.dom.id}_#{component_name}\" }\n end\n\n def build_component_class\n return if attributes[:class] == false\n\n attributes[:class] = tokens(component_name, attributes[:class])\n end\n\n def component_name\n @component_name ||= self.class.name.demodulize.underscore\n end\n end\n end\n end\nend\n"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/associations.rb",
|
24
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Options\n module Associations\n def association_reflection\n @association_reflection ||= find_association_reflection\n end\n\n protected\n\n def find_association_reflection\n if object.class.respond_to?(:reflect_on_association)\n object.class.reflect_on_association(key)\n end\n end\n end\n end\n end\nend\n"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/attachments.rb",
|
28
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Options\n module Attachments\n def attachment_reflection\n @attachment_reflection ||= find_attachment_reflection\n end\n\n protected\n\n def find_attachment_reflection\n if object.class.respond_to?(:reflect_on_attachment)\n object.class.reflect_on_attachment(key)\n end\n end\n end\n end\n end\nend\n"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/descriptions.rb",
|
32
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Options\n module Descriptions\n def description(description = nil)\n if description.nil?\n options[:description]\n else\n options[:description] = description\n self\n end\n end\n\n def has_description?\n description.present?\n end\n end\n end\n end\nend\n"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/hints.rb",
|
36
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Options\n module Hints\n def hint(hint = nil)\n if hint.nil?\n options[:hint]\n else\n options[:hint] = hint\n self\n end\n end\n\n def has_hint?\n hint.present?\n end\n end\n end\n end\nend\n"
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/inferred_types.rb",
|
40
|
+
"contents": "# frozen_string_literal: true\n\nrequire \"bigdecimal\"\n\nmodule Phlexi\n module Field\n module Options\n module InferredTypes\n def inferred_field_component\n @inferred_component ||= infer_field_component\n end\n\n def inferred_field_type\n @inferred_field_type ||= infer_field_type\n end\n\n def inferred_string_field_type\n @inferred_string_field_type || infer_string_field_type\n end\n\n private\n\n def infer_field_component\n inferred_field_type\n end\n\n def infer_field_type\n # Check attachments first since they are implemented as associations\n return :attachment if attachment_reflection\n\n return :association if association_reflection\n\n if object.class.respond_to?(:defined_enums)\n return :enum if object.class.defined_enums.key?(key.to_s)\n end\n\n if object.class.respond_to?(:columns_hash)\n # ActiveRecord\n column = object.class.columns_hash[key.to_s]\n return column.type if column&.type\n end\n\n if object.class.respond_to?(:attribute_types)\n # ActiveModel::Attributes\n custom_type = object.class.attribute_types[key.to_s]\n return custom_type.type if custom_type&.type\n end\n\n # Fallback to inferring type from the value\n value = ChronoForge::Support::Value.from(object, key)\n return infer_field_type_from_value(value) unless value.nil?\n\n # Default to string if we can't determine the type\n :string\n end\n\n def infer_field_type_from_value(value)\n case value\n when Integer\n :integer\n when Float\n :float\n when BigDecimal\n :decimal\n when TrueClass, FalseClass\n :boolean\n when Date\n :date\n when Time, DateTime\n :datetime\n when Hash\n :json\n else\n :string\n end\n end\n\n def infer_string_field_type\n infer_string_field_type_from_key || infer_string_field_type_from_validations\n end\n\n def infer_string_field_type_from_validations\n return unless has_validators?\n\n if attribute_validators.find { |v| v.kind == :numericality }\n :number\n elsif attribute_validators.find { |v| v.kind == :format && v.options[:with] == URI::MailTo::EMAIL_REGEXP }\n :email\n end\n end\n\n def infer_string_field_type_from_key\n key = self.key.to_s.downcase\n return :password if is_password_field?(key)\n\n custom_mappings = {\n /url$|^link|^site/ => :url,\n /^email/ => :email,\n /^search/ => :search,\n /phone|tel(ephone)?/ => :phone,\n /^time/ => :time,\n /^date/ => :date,\n /^number|_count$|_amount$/ => :number,\n /^color|_color$/ => :color\n }\n\n custom_mappings.each do |pattern, type|\n return type if key.match?(pattern)\n end\n\n nil\n end\n\n def is_password_field?(key)\n exact_matches = [\"password\"]\n prefixes = [\"encrypted_\"]\n suffixes = [\"_password\", \"_digest\", \"_hash\", \"_token\"]\n\n exact_matches.include?(key) ||\n prefixes.any? { |prefix| key.start_with?(prefix) } ||\n suffixes.any? { |suffix| key.end_with?(suffix) }\n end\n end\n end\n end\nend\n"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/labels.rb",
|
44
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Options\n module Labels\n def label(label = nil)\n if label.nil?\n options[:label] = options.fetch(:label) { calculate_label }\n else\n options[:label] = label\n self\n end\n end\n\n private\n\n def calculate_label\n if object.class.respond_to?(:human_attribute_name)\n object.class.human_attribute_name(key.to_s, {base: object})\n else\n key.to_s.humanize\n end\n end\n end\n end\n end\nend\n"
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/multiple.rb",
|
48
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Options\n module Multiple\n def multiple?\n options[:multiple] = options.fetch(:multiple) { calculate_multiple_field_value }\n end\n\n def multiple!(multiple = true)\n options[:multiple] = multiple\n self\n end\n\n private\n\n def calculate_multiple_field_value\n return true if attachment_reflection&.macro == :has_many_attached\n return true if %i[has_many has_and_belongs_to_many].include?(association_reflection&.macro)\n return true if multiple_field_array_attribute?\n\n check_multiple_field_from_validators\n end\n\n def multiple_field_array_attribute?\n return false unless object.class.respond_to?(:columns_hash)\n\n column = object.class.columns_hash[key.to_s]\n return false unless column\n\n case object.class.connection.adapter_name.downcase\n when \"postgresql\"\n column.array? || (column.type == :string && column.sql_type.include?(\"[]\"))\n end # || object.class.attribute_types[key.to_s].is_a?(ActiveRecord::Type::Serialized)\n rescue\n # Rails.logger.warn(\"Error checking multiple field array attribute: #{e.message}\")\n false\n end\n\n def check_multiple_field_from_validators\n inclusion_validator = find_validator(:inclusion)\n length_validator = find_validator(:length)\n\n return false unless inclusion_validator || length_validator\n\n check_multiple_field_inclusion_validator(inclusion_validator) ||\n check_multiple_field_length_validator(length_validator)\n end\n\n def check_multiple_field_inclusion_validator(validator)\n return false unless validator\n in_option = validator.options[:in] || validator.options[:within]\n return false unless in_option.is_a?(Array)\n\n validator.options[:multiple] == true || (multiple_field_array_attribute? && in_option.size > 1)\n end\n\n def check_multiple_field_length_validator(validator)\n return false unless validator\n validator.options[:maximum].to_i > 1 if validator.options[:maximum]\n end\n end\n end\n end\nend\n"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/placeholders.rb",
|
52
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Options\n module Placeholders\n def placeholder(placeholder = nil)\n if placeholder.nil?\n options[:placeholder]\n else\n\n options[:placeholder] = placeholder\n self\n end\n end\n end\n end\n end\nend\n"
|
53
|
+
},
|
54
|
+
{
|
55
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/options/validators.rb",
|
56
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Options\n module Validators\n private\n\n def has_validators?\n @has_validators ||= object.class.respond_to?(:validators_on)\n end\n\n def attribute_validators\n object.class.validators_on(key)\n end\n\n def association_reflection_validators\n association_reflection ? object.class.validators_on(association_reflection.name) : []\n end\n\n def valid_validator?(validator)\n !conditional_validators?(validator) && action_validator_match?(validator)\n end\n\n def conditional_validators?(validator)\n validator.options.include?(:if) || validator.options.include?(:unless)\n end\n\n def action_validator_match?(validator)\n return true unless validator.options.include?(:on)\n\n case validator.options[:on]\n when :save\n true\n when :create\n !object.persisted?\n when :update\n object.persisted?\n end\n end\n\n def find_validator(kind)\n attribute_validators.find { |v| v.kind == kind && valid_validator?(v) } if has_validators?\n end\n end\n end\n end\nend\n"
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/structure/dom.rb",
|
60
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Structure\n # Generates DOM IDs, names, etc. for a Field, Namespace, or Node based on\n # norms that were established by Rails. These can be used outside of or Rails in\n # other Ruby web frameworks since it has no dependencies on Rails.\n class DOM\n def initialize(field:)\n @field = field\n end\n\n # Converts the value of the field to a String, which is required to work\n # with Phlex. Assumes that `Object#to_s` emits a format suitable for display.\n def value\n @field.value.to_s\n end\n\n # Walks from the current node to the parent node, grabs the names, and separates\n # them with a `_` for a DOM ID.\n def id\n @id ||= begin\n root, *rest = lineage\n root_key = if root.respond_to?(:dom_id)\n root.dom_id\n else\n root.key\n end\n rest.map(&:key).unshift(root_key).join(\"_\")\n end\n end\n\n # The `name` attribute of a node, which is influenced by Rails.\n # All node names, except the parent node, are wrapped in a `[]` and collections\n # are left empty. For example, `user[addresses][][street]` would be created for a form with\n # data shaped like `{user: {addresses: [{street: \"Sesame Street\"}]}}`.\n def name\n @name ||= begin\n root, *names = keys\n names.map { |name| \"[#{name}]\" }.unshift(root).join\n end\n end\n\n # One-liner way of walking from the current node all the way up to the parent.\n def lineage\n @lineage ||= Enumerator.produce(@field, &:parent).take_while(&:itself).reverse\n end\n\n # Emit the id, name, and value in an HTML tag-ish that doesnt have an element.\n def inspect\n \"<#{self.class.name} id=#{id.inspect} name=#{name.inspect} value=#{value.inspect}/>\"\n end\n\n private\n\n def keys\n @keys ||= lineage.map do |node|\n # If the parent of a field is a field, the name should be nil.\n node.key unless node.parent.is_a? Builder\n end\n end\n end\n end\n end\nend\n"
|
61
|
+
},
|
62
|
+
{
|
63
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/structure/field_collection.rb",
|
64
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Structure\n class FieldCollection\n include Enumerable\n\n class Builder\n include Phlex::Helpers\n\n attr_reader :key, :index\n\n def initialize(key, field, index)\n @key = key.to_s\n @field = field\n @index = index\n end\n\n def field(**)\n @field.class.new(key, **, parent: @field).tap do |field|\n yield field if block_given?\n end\n end\n end\n\n def initialize(field:, collection:, &)\n @field = field\n @collection = build_collection(collection)\n each(&) if block_given?\n end\n\n def each(&)\n @collection.each.with_index do |item, index|\n yield self.class::Builder.new(item, @field, index)\n end\n end\n\n private\n\n def build_collection(collection)\n collection\n end\n end\n end\n end\nend\n"
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/structure/namespace.rb",
|
68
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Structure\n # A Namespace maps an object to values, but doesn't actually have a value itself. For\n # example, a `User` object or ActiveRecord model could be passed into the `:user` namespace.\n #\n # To access single values on a Namespace, #field can be used.\n #\n # To access nested objects within a namespace, two methods are available:\n #\n # 1. #nest_one: Used for single nested objects, such as if a `User belongs_to :profile` in\n # ActiveRecord. This method returns another Namespace object.\n #\n # 2. #nest_many: Used for collections of nested objects, such as if a `User has_many :addresses` in\n # ActiveRecord. This method returns a NamespaceCollection object.\n class Namespace < Structure::Node\n include Enumerable\n\n class NamespaceCollection < Structure::NamespaceCollection; end\n\n attr_reader :builder_klass, :object\n\n def initialize(key, parent:, builder_klass:, object: nil, dom_id: nil)\n super(key, parent: parent)\n @builder_klass = builder_klass\n @object = object\n @dom_id = dom_id\n @children = {}\n yield self if block_given?\n end\n\n def field(key, template: false, **attributes)\n create_child(key, attributes.delete(:builder_klass) || builder_klass, object: object, template:, **attributes).tap do |field|\n yield field if block_given?\n end\n end\n\n # Creates a `Namespace` child instance with the parent set to the current instance, adds to\n # the `@children` Hash to ensure duplicate child namespaces aren't created, then calls the\n # method on the `@object` to get the child object to pass into that namespace.\n #\n # For example, if a `User#permission` returns a `Permission` object, we could map that to a\n # form like this:\n #\n # ```ruby\n # Phlexi::Form(User.new, as: :user) do\n # nest_one :profile do |profile|\n # render profile.field(:gender).input_tag\n # end\n # end\n # ```\n def nest_one(key, as: nil, object: nil, default: nil, template: false, &)\n object ||= object_value_for(key: key) || default\n key = as || key\n create_child(key, self.class, object:, template:, builder_klass:, &)\n end\n\n # Wraps an array of objects in Namespace classes. For example, if `User#addresses` returns\n # an enumerable or array of `Address` classes:\n #\n # ```ruby\n # Phlexi::Form(User.new) do\n # render field(:email).input_tag\n # render field(:name).input_tag\n # nest_many :addresses do |address|\n # render address.field(:street).input_tag\n # render address.field(:state).input_tag\n # render address.field(:zip).input_tag\n # end\n # end\n # ```\n # The object within the block is a `Namespace` object that maps each object within the enumerable\n # to another `Namespace` or `Field`.\n def nest_many(key, as: nil, collection: nil, default: nil, template: false, &)\n collection ||= Array(object_value_for(key: key)).presence || default\n key = as || key\n create_child(key, self.class::NamespaceCollection, collection:, template:, &)\n end\n\n # Iterates through the children of the current namespace, which could be `Namespace` or `Field`\n # objects.\n def each(&)\n @children.values.each(&)\n end\n\n def dom_id\n @dom_id ||= begin\n object_id = if object.nil?\n nil\n elsif (primary_key = ChronoForge.object_primary_key(object))\n primary_key&.to_s || :new\n end\n [key, object_id].compact.join(\"_\").underscore\n end\n end\n\n # Creates a root Namespace.\n def self.root(*, builder_klass:, **, &)\n new(*, parent: nil, builder_klass:, **, &)\n end\n\n protected\n\n def object_value_for(key:)\n ChronoForge::Support::Value.from(@object, key)\n end\n\n private\n\n # Checks if the child exists. If it does then it returns that. If it doesn't, it will\n # build the child.\n def create_child(key, child_class, template: false, **, &)\n if template\n child_class.new(key, parent: self, **, &)\n else\n @children.fetch(key) { @children[key] = child_class.new(key, parent: self, **, &) }\n end\n end\n end\n end\n end\nend\n"
|
69
|
+
},
|
70
|
+
{
|
71
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/structure/namespace_collection.rb",
|
72
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Structure\n class NamespaceCollection < Node\n include Enumerable\n\n def initialize(key, parent:, collection: nil, &block)\n raise ArgumentError, \"block is required\" unless block.present?\n\n super(key, parent: parent)\n\n @collection = collection\n @block = block\n each(&block)\n end\n\n def object\n @collection\n end\n\n private\n\n def each(&)\n namespaces.each(&)\n end\n\n # Builds and memoizes namespaces for the collection.\n #\n # @return [Array<Namespace>] An array of namespace objects.\n def namespaces\n @namespaces ||= case @collection\n when Hash\n @collection.map do |key, object|\n build_namespace(key, object: object)\n end\n when Array\n @collection.map.with_index do |object, key|\n build_namespace(key, object: object)\n end\n end\n end\n\n def build_namespace(index, **)\n parent.class.new(index, parent: self, builder_klass: parent.builder_klass, **)\n end\n end\n end\n end\nend\n"
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/structure/node.rb",
|
76
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n module Structure\n # Superclass for Namespace and Field classes. Represents a node in the field tree structure.\n #\n # @attr_reader [Symbol] key The node's key\n # @attr_reader [Node, nil] parent The node's parent in the tree structure\n class Node\n attr_reader :key, :parent\n\n # Initializes a new Node instance.\n #\n # @param key [Symbol, String] The key for the node\n # @param parent [Node, nil] The parent node\n def initialize(key, parent:)\n @key = :\"#{key}\"\n @parent = parent\n end\n\n def inspect\n \"<#{self.class.name} key=#{key.inspect} object=#{object.inspect} parent=#{parent.inspect} />\"\n end\n end\n end\n end\nend\n"
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/support/value.rb",
|
80
|
+
"contents": "module Phlexi\n module Field\n module Support\n module Value\n def self.from(object, key)\n return object[key] if object.is_a?(Hash)\n object.public_send(key) if object.respond_to?(key)\n end\n end\n end\n end\nend\n"
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/theme.rb",
|
84
|
+
"contents": "require \"fiber/local\"\n\nmodule Phlexi\n module Field\n class Theme\n def self.inherited(subclass)\n super\n subclass.extend Fiber::Local\n end\n\n # Retrieves the theme hash\n #\n # This method returns a hash containing theme definitions for various display components.\n # If a theme has been explicitly set in the options, it returns that. Otherwise, it\n # initializes and returns a default theme.\n #\n # The theme hash defines CSS classes or references to other theme keys for different\n # components, allowing for a flexible and inheritance-based theming system.\n #\n # @return [Hash] A hash containing theme definitions for display components\n #\n # @example Accessing the theme\n # theme[:text]\n # # => \"text-gray-700 text-sm\"\n #\n # @example Theme inheritance\n # theme[:email] # Returns :text, indicating email inherits text's theme\n def self.theme\n raise NotImplementedError, \"#{self} must implement #self.theme\"\n end\n\n def theme\n @theme ||= self.class.theme.freeze\n end\n\n # Recursively resolves the theme for a given property, handling nested symbol references\n #\n # @param property [Symbol, String] The theme property to resolve\n # @param visited [Set] Set of already visited properties to prevent infinite recursion\n # @return [String, nil] The resolved theme value or nil if not found\n #\n # @example Basic usage\n # # Assuming the theme is: { text: \"text-gray-700\", email: :text }\n # themed(:text)\n # # => \"text-gray-700 text-sm\"\n #\n # @example Cascading themes\n # # Assuming the theme is: { text: \"text-gray-700\", email: :text }\n # resolve_theme(:email)\n # # => \"text-gray-700\"\n def resolve_theme(property, visited = Set.new)\n return nil if !property.present? || visited.include?(property)\n visited.add(property)\n\n result = theme[property]\n if result.is_a?(Symbol)\n resolve_theme(result, visited)\n else\n result\n end\n end\n end\n end\nend\n"
|
85
|
+
},
|
86
|
+
{
|
87
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge/version.rb",
|
88
|
+
"contents": "# frozen_string_literal: true\n\nmodule Phlexi\n module Field\n VERSION = \"0.0.9\"\n end\nend\n"
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge.rb",
|
92
|
+
"contents": "# frozen_string_literal: true\n\nrequire \"zeitwerk\"\nrequire \"phlex\"\nrequire \"active_support/core_ext/object/blank\"\n\nmodule Phlexi\n NIL_VALUE = :__i_phlexi_i__\n\n module Field\n Loader = Zeitwerk::Loader.new.tap do |loader|\n loader.tag = File.basename(__FILE__, \".rb\")\n loader.ignore(\"#{__dir__}/field/version.rb\")\n loader.inflector.inflect(\n \"chrono_forge\" => \"Phlexi\",\n \"phlexi\" => \"Phlexi\",\n \"dom\" => \"DOM\"\n )\n loader.push_dir(File.expand_path(\"..\", __dir__))\n loader.setup\n end\n\n COMPONENT_BASE = (defined?(::ApplicationComponent) ? ::ApplicationComponent : Phlex::HTML)\n\n class Error < StandardError; end\n\n def self.object_primary_key(object)\n if object.class.respond_to?(:primary_key)\n object.send(object.class.primary_key.to_sym)\n elsif object.respond_to?(:id)\n object.id\n end\n end\n end\nend\n"
|
93
|
+
},
|
94
|
+
{
|
95
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/lib/chrono_forge.rb",
|
96
|
+
"contents": "# frozen_string_literal: true\n\nrequire_relative \"chrono_forge/version\"\nrequire_relative \"chrono_forge\"\n"
|
97
|
+
},
|
98
|
+
{
|
99
|
+
"path": "/Users/stefan/Documents/plutonium/chrono_forge/chrono_forge.gemspec",
|
100
|
+
"contents": "# frozen_string_literal: true\n\nrequire_relative \"lib/chrono_forge/version\"\n\nGem::Specification.new do |spec|\n spec.name = \"chrono_forge\"\n spec.version = ChronoForge::VERSION\n spec.authors = [\"Stefan Froelich\"]\n spec.email = [\"sfroelich01@gmail.com\"]\n\n spec.summary = \"Base fields for the Phlexi libraries\"\n spec.description = \"Base fields for the Phlexi libraries\"\n spec.homepage = \"https://github.com/radioactive-labs/chrono_forge\"\n spec.license = \"MIT\"\n spec.required_ruby_version = \">= 3.2.2\"\n\n spec.metadata[\"allowed_push_host\"] = \"https://rubygems.org\"\n\n spec.metadata[\"homepage_uri\"] = spec.homepage\n spec.metadata[\"source_code_uri\"] = spec.homepage\n spec.metadata[\"changelog_uri\"] = spec.homepage\n\n # Specify which files should be added to the gem when it is released.\n # The `git ls-files -z` loads the files in the RubyGem that have been added into git.\n gemspec = File.basename(__FILE__)\n spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|\n ls.readlines(\"\\x0\", chomp: true).reject do |f|\n (f == gemspec) ||\n f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])\n end\n end\n spec.bindir = \"exe\"\n spec.executables = spec.files.grep(%r{\\Aexe/}) { |f| File.basename(f) }\n spec.require_paths = [\"lib\"]\n\n spec.add_dependency \"phlex\", \"~> 1.11\"\n spec.add_dependency \"activesupport\"\n spec.add_dependency \"zeitwerk\"\n spec.add_dependency \"fiber-local\"\n\n spec.add_development_dependency \"rake\"\n spec.add_development_dependency \"minitest\"\n spec.add_development_dependency \"minitest-reporters\"\n spec.add_development_dependency \"standard\"\n # spec.add_development_dependency \"brakeman\"\n spec.add_development_dependency \"bundle-audit\"\n spec.add_development_dependency \"appraisal\"\n spec.add_development_dependency \"combustion\"\n spec.add_development_dependency \"phlex-testing-capybara\"\nend\n"
|
101
|
+
}
|
102
|
+
]
|
data/export.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require "json"
|
2
|
+
require "find"
|
3
|
+
|
4
|
+
def export_files_to_json(directory, extensions, output_file, exceptions = [])
|
5
|
+
# Convert extensions to lowercase for case-insensitive matching
|
6
|
+
extensions = extensions.map(&:downcase)
|
7
|
+
|
8
|
+
# Array to store file data
|
9
|
+
files_data = []
|
10
|
+
|
11
|
+
# Find all files in directory and subdirectories
|
12
|
+
Find.find(directory) do |path|
|
13
|
+
# Skip if not a file
|
14
|
+
next unless File.file?(path)
|
15
|
+
next if exceptions.any? { |exception| path.include?(exception) }
|
16
|
+
|
17
|
+
# Check if file extension matches any in our list
|
18
|
+
ext = File.extname(path).downcase[1..-1] # Remove the leading dot
|
19
|
+
next unless extensions.include?(ext)
|
20
|
+
|
21
|
+
puts path
|
22
|
+
|
23
|
+
begin
|
24
|
+
# Read file contents
|
25
|
+
contents = File.read(path)
|
26
|
+
|
27
|
+
# Add to our array
|
28
|
+
files_data << {
|
29
|
+
"path" => path,
|
30
|
+
"contents" => contents
|
31
|
+
}
|
32
|
+
rescue => e
|
33
|
+
puts "Error reading file #{path}: #{e.message}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Write to JSON file
|
38
|
+
File.write(output_file, JSON.pretty_generate(files_data))
|
39
|
+
|
40
|
+
puts "Successfully exported #{files_data.length} files to #{output_file}"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Example usage (uncomment and modify as needed):
|
44
|
+
directory = "/Users/stefan/Documents/plutonium/chrono_forge"
|
45
|
+
exceptions = ["/.github/", "/.vscode/", "gemfiles", "pkg", "test", "node_modules"]
|
46
|
+
extensions = ["rb", "md", "yml", "yaml", "gemspec"]
|
47
|
+
output_file = "export.json"
|
48
|
+
export_files_to_json(directory, extensions, output_file, exceptions)
|
@@ -0,0 +1,258 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ..
|
3
|
+
specs:
|
4
|
+
chrono_forge (0.0.1)
|
5
|
+
rails
|
6
|
+
zeitwerk
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actioncable (7.2.2)
|
12
|
+
actionpack (= 7.2.2)
|
13
|
+
activesupport (= 7.2.2)
|
14
|
+
nio4r (~> 2.0)
|
15
|
+
websocket-driver (>= 0.6.1)
|
16
|
+
zeitwerk (~> 2.6)
|
17
|
+
actionmailbox (7.2.2)
|
18
|
+
actionpack (= 7.2.2)
|
19
|
+
activejob (= 7.2.2)
|
20
|
+
activerecord (= 7.2.2)
|
21
|
+
activestorage (= 7.2.2)
|
22
|
+
activesupport (= 7.2.2)
|
23
|
+
mail (>= 2.8.0)
|
24
|
+
actionmailer (7.2.2)
|
25
|
+
actionpack (= 7.2.2)
|
26
|
+
actionview (= 7.2.2)
|
27
|
+
activejob (= 7.2.2)
|
28
|
+
activesupport (= 7.2.2)
|
29
|
+
mail (>= 2.8.0)
|
30
|
+
rails-dom-testing (~> 2.2)
|
31
|
+
actionpack (7.2.2)
|
32
|
+
actionview (= 7.2.2)
|
33
|
+
activesupport (= 7.2.2)
|
34
|
+
nokogiri (>= 1.8.5)
|
35
|
+
racc
|
36
|
+
rack (>= 2.2.4, < 3.2)
|
37
|
+
rack-session (>= 1.0.1)
|
38
|
+
rack-test (>= 0.6.3)
|
39
|
+
rails-dom-testing (~> 2.2)
|
40
|
+
rails-html-sanitizer (~> 1.6)
|
41
|
+
useragent (~> 0.16)
|
42
|
+
actiontext (7.2.2)
|
43
|
+
actionpack (= 7.2.2)
|
44
|
+
activerecord (= 7.2.2)
|
45
|
+
activestorage (= 7.2.2)
|
46
|
+
activesupport (= 7.2.2)
|
47
|
+
globalid (>= 0.6.0)
|
48
|
+
nokogiri (>= 1.8.5)
|
49
|
+
actionview (7.2.2)
|
50
|
+
activesupport (= 7.2.2)
|
51
|
+
builder (~> 3.1)
|
52
|
+
erubi (~> 1.11)
|
53
|
+
rails-dom-testing (~> 2.2)
|
54
|
+
rails-html-sanitizer (~> 1.6)
|
55
|
+
activejob (7.2.2)
|
56
|
+
activesupport (= 7.2.2)
|
57
|
+
globalid (>= 0.3.6)
|
58
|
+
activemodel (7.2.2)
|
59
|
+
activesupport (= 7.2.2)
|
60
|
+
activerecord (7.2.2)
|
61
|
+
activemodel (= 7.2.2)
|
62
|
+
activesupport (= 7.2.2)
|
63
|
+
timeout (>= 0.4.0)
|
64
|
+
activestorage (7.2.2)
|
65
|
+
actionpack (= 7.2.2)
|
66
|
+
activejob (= 7.2.2)
|
67
|
+
activerecord (= 7.2.2)
|
68
|
+
activesupport (= 7.2.2)
|
69
|
+
marcel (~> 1.0)
|
70
|
+
activesupport (7.2.2)
|
71
|
+
base64
|
72
|
+
benchmark (>= 0.3)
|
73
|
+
bigdecimal
|
74
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
75
|
+
connection_pool (>= 2.2.5)
|
76
|
+
drb
|
77
|
+
i18n (>= 1.6, < 2)
|
78
|
+
logger (>= 1.4.2)
|
79
|
+
minitest (>= 5.1)
|
80
|
+
securerandom (>= 0.3)
|
81
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
82
|
+
ansi (1.5.0)
|
83
|
+
appraisal (2.5.0)
|
84
|
+
bundler
|
85
|
+
rake
|
86
|
+
thor (>= 0.14.0)
|
87
|
+
ast (2.4.2)
|
88
|
+
base64 (0.2.0)
|
89
|
+
benchmark (0.4.0)
|
90
|
+
bigdecimal (3.1.8)
|
91
|
+
builder (3.3.0)
|
92
|
+
bundle-audit (0.1.0)
|
93
|
+
bundler-audit
|
94
|
+
bundler-audit (0.9.2)
|
95
|
+
bundler (>= 1.2.0, < 3)
|
96
|
+
thor (~> 1.0)
|
97
|
+
chaotic_job (0.3.0)
|
98
|
+
combustion (1.5.0)
|
99
|
+
activesupport (>= 3.0.0)
|
100
|
+
railties (>= 3.0.0)
|
101
|
+
thor (>= 0.14.6)
|
102
|
+
concurrent-ruby (1.3.4)
|
103
|
+
connection_pool (2.4.1)
|
104
|
+
crass (1.0.6)
|
105
|
+
date (3.4.1)
|
106
|
+
drb (2.2.1)
|
107
|
+
erubi (1.13.0)
|
108
|
+
globalid (1.2.1)
|
109
|
+
activesupport (>= 6.1)
|
110
|
+
i18n (1.14.6)
|
111
|
+
concurrent-ruby (~> 1.0)
|
112
|
+
io-console (0.8.0)
|
113
|
+
irb (1.14.3)
|
114
|
+
rdoc (>= 4.0.0)
|
115
|
+
reline (>= 0.4.2)
|
116
|
+
json (2.8.2)
|
117
|
+
language_server-protocol (3.17.0.3)
|
118
|
+
lint_roller (1.1.0)
|
119
|
+
logger (1.6.4)
|
120
|
+
loofah (2.23.1)
|
121
|
+
crass (~> 1.0.2)
|
122
|
+
nokogiri (>= 1.12.0)
|
123
|
+
mail (2.8.1)
|
124
|
+
mini_mime (>= 0.1.1)
|
125
|
+
net-imap
|
126
|
+
net-pop
|
127
|
+
net-smtp
|
128
|
+
marcel (1.0.4)
|
129
|
+
mini_mime (1.1.5)
|
130
|
+
minitest (5.25.2)
|
131
|
+
minitest-reporters (1.7.1)
|
132
|
+
ansi
|
133
|
+
builder
|
134
|
+
minitest (>= 5.0)
|
135
|
+
ruby-progressbar
|
136
|
+
net-imap (0.5.3)
|
137
|
+
date
|
138
|
+
net-protocol
|
139
|
+
net-pop (0.1.2)
|
140
|
+
net-protocol
|
141
|
+
net-protocol (0.2.2)
|
142
|
+
timeout
|
143
|
+
net-smtp (0.5.0)
|
144
|
+
net-protocol
|
145
|
+
nio4r (2.7.4)
|
146
|
+
nokogiri (1.16.7-arm64-darwin)
|
147
|
+
racc (~> 1.4)
|
148
|
+
parallel (1.26.3)
|
149
|
+
parser (3.3.6.0)
|
150
|
+
ast (~> 2.4.1)
|
151
|
+
racc
|
152
|
+
psych (5.2.2)
|
153
|
+
date
|
154
|
+
stringio
|
155
|
+
racc (1.8.1)
|
156
|
+
rack (3.1.8)
|
157
|
+
rack-session (2.0.0)
|
158
|
+
rack (>= 3.0.0)
|
159
|
+
rack-test (2.1.0)
|
160
|
+
rack (>= 1.3)
|
161
|
+
rackup (2.2.1)
|
162
|
+
rack (>= 3)
|
163
|
+
rails (7.2.2)
|
164
|
+
actioncable (= 7.2.2)
|
165
|
+
actionmailbox (= 7.2.2)
|
166
|
+
actionmailer (= 7.2.2)
|
167
|
+
actionpack (= 7.2.2)
|
168
|
+
actiontext (= 7.2.2)
|
169
|
+
actionview (= 7.2.2)
|
170
|
+
activejob (= 7.2.2)
|
171
|
+
activemodel (= 7.2.2)
|
172
|
+
activerecord (= 7.2.2)
|
173
|
+
activestorage (= 7.2.2)
|
174
|
+
activesupport (= 7.2.2)
|
175
|
+
bundler (>= 1.15.0)
|
176
|
+
railties (= 7.2.2)
|
177
|
+
rails-dom-testing (2.2.0)
|
178
|
+
activesupport (>= 5.0.0)
|
179
|
+
minitest
|
180
|
+
nokogiri (>= 1.6)
|
181
|
+
rails-html-sanitizer (1.6.0)
|
182
|
+
loofah (~> 2.21)
|
183
|
+
nokogiri (~> 1.14)
|
184
|
+
railties (7.2.2)
|
185
|
+
actionpack (= 7.2.2)
|
186
|
+
activesupport (= 7.2.2)
|
187
|
+
irb (~> 1.13)
|
188
|
+
rackup (>= 1.0.0)
|
189
|
+
rake (>= 12.2)
|
190
|
+
thor (~> 1.0, >= 1.2.2)
|
191
|
+
zeitwerk (~> 2.6)
|
192
|
+
rainbow (3.1.1)
|
193
|
+
rake (13.2.1)
|
194
|
+
rdoc (6.10.0)
|
195
|
+
psych (>= 4.0.0)
|
196
|
+
regexp_parser (2.9.3)
|
197
|
+
reline (0.6.0)
|
198
|
+
io-console (~> 0.5)
|
199
|
+
rubocop (1.68.0)
|
200
|
+
json (~> 2.3)
|
201
|
+
language_server-protocol (>= 3.17.0)
|
202
|
+
parallel (~> 1.10)
|
203
|
+
parser (>= 3.3.0.2)
|
204
|
+
rainbow (>= 2.2.2, < 4.0)
|
205
|
+
regexp_parser (>= 2.4, < 3.0)
|
206
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
207
|
+
ruby-progressbar (~> 1.7)
|
208
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
209
|
+
rubocop-ast (1.36.2)
|
210
|
+
parser (>= 3.3.1.0)
|
211
|
+
rubocop-performance (1.22.1)
|
212
|
+
rubocop (>= 1.48.1, < 2.0)
|
213
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
214
|
+
ruby-progressbar (1.13.0)
|
215
|
+
securerandom (0.4.0)
|
216
|
+
sqlite3 (1.7.3-arm64-darwin)
|
217
|
+
standard (1.42.1)
|
218
|
+
language_server-protocol (~> 3.17.0.2)
|
219
|
+
lint_roller (~> 1.0)
|
220
|
+
rubocop (~> 1.68.0)
|
221
|
+
standard-custom (~> 1.0.0)
|
222
|
+
standard-performance (~> 1.5)
|
223
|
+
standard-custom (1.0.2)
|
224
|
+
lint_roller (~> 1.0)
|
225
|
+
rubocop (~> 1.50)
|
226
|
+
standard-performance (1.5.0)
|
227
|
+
lint_roller (~> 1.1)
|
228
|
+
rubocop-performance (~> 1.22.0)
|
229
|
+
stringio (3.1.2)
|
230
|
+
thor (1.3.2)
|
231
|
+
timeout (0.4.3)
|
232
|
+
tzinfo (2.0.6)
|
233
|
+
concurrent-ruby (~> 1.0)
|
234
|
+
unicode-display_width (2.6.0)
|
235
|
+
useragent (0.16.10)
|
236
|
+
websocket-driver (0.7.6)
|
237
|
+
websocket-extensions (>= 0.1.0)
|
238
|
+
websocket-extensions (0.1.5)
|
239
|
+
zeitwerk (2.7.1)
|
240
|
+
|
241
|
+
PLATFORMS
|
242
|
+
arm64-darwin
|
243
|
+
|
244
|
+
DEPENDENCIES
|
245
|
+
appraisal
|
246
|
+
bundle-audit
|
247
|
+
chaotic_job
|
248
|
+
chrono_forge!
|
249
|
+
combustion
|
250
|
+
minitest
|
251
|
+
minitest-reporters
|
252
|
+
rails (~> 7.1, >= 7.1.3.4)
|
253
|
+
rake
|
254
|
+
sqlite3 (~> 1.4)
|
255
|
+
standard
|
256
|
+
|
257
|
+
BUNDLED WITH
|
258
|
+
2.5.16
|
data/lib/chrono_forge.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "chrono_forge/version"
|
4
|
+
|
5
|
+
require "zeitwerk"
|
6
|
+
require "active_support/core_ext/object/blank"
|
7
|
+
|
8
|
+
module Chronoforge
|
9
|
+
Loader = Zeitwerk::Loader.new.tap do |loader|
|
10
|
+
loader.tag = File.basename(__FILE__, ".rb")
|
11
|
+
loader.ignore("#{__dir__}/generators")
|
12
|
+
loader.setup
|
13
|
+
end
|
14
|
+
|
15
|
+
class Error < StandardError; end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chrono_forge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stefan Froelich
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: zeitwerk
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest-reporters
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: standard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bundle-audit
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: appraisal
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: combustion
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: chaotic_job
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: Base fields for the Phlexi libraries
|
154
|
+
email:
|
155
|
+
- sfroelich01@gmail.com
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- ".ruby-version"
|
161
|
+
- Appraisals
|
162
|
+
- CHANGELOG.md
|
163
|
+
- LICENSE.txt
|
164
|
+
- README.md
|
165
|
+
- Rakefile
|
166
|
+
- config.ru
|
167
|
+
- export.json
|
168
|
+
- export.rb
|
169
|
+
- gemfiles/rails_7.1.gemfile
|
170
|
+
- gemfiles/rails_7.1.gemfile.lock
|
171
|
+
- lib/chrono_forge.rb
|
172
|
+
- lib/chrono_forge/version.rb
|
173
|
+
- sig/chrono_forge.rbs
|
174
|
+
homepage: https://github.com/radioactive-labs/chrono_forge
|
175
|
+
licenses:
|
176
|
+
- MIT
|
177
|
+
metadata:
|
178
|
+
allowed_push_host: https://rubygems.org
|
179
|
+
homepage_uri: https://github.com/radioactive-labs/chrono_forge
|
180
|
+
source_code_uri: https://github.com/radioactive-labs/chrono_forge
|
181
|
+
changelog_uri: https://github.com/radioactive-labs/chrono_forge
|
182
|
+
post_install_message:
|
183
|
+
rdoc_options: []
|
184
|
+
require_paths:
|
185
|
+
- lib
|
186
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
187
|
+
requirements:
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: 3.2.2
|
191
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
requirements: []
|
197
|
+
rubygems_version: 3.4.10
|
198
|
+
signing_key:
|
199
|
+
specification_version: 4
|
200
|
+
summary: Base fields for the Phlexi libraries
|
201
|
+
test_files: []
|