Class: Herb::Embedded::CustomRuleLoader
- Inherits:
-
Object
- Object
- Herb::Embedded::CustomRuleLoader
- Defined in:
- lib/herb/embedded/custom_rule_loader.rb
Overview
Loads project-local rules from .herb/rules/**/*.mjs. Upstream's own loader uses pathToFileURL, tinyglobby, and dynamic import() — none of which exist in an embedded engine. Ruby replaces the loader entirely: it globs and reads the files, rewrites their one supported import (@herb-tools/linter) into a destructure from the already-loaded bundle, and hands the result to the engine for registration.
Defined Under Namespace
Classes: InvalidRuleError, UnsupportedImportError
Constant Summary collapse
- RULES_GLOB =
File.join(".herb", "rules", "**", "*.mjs")
- ALLOWED_SPECIFIER =
"@herb-tools/linter"- IMPORT_LINE =
/^import\b.*$/- NAMED_IMPORT_LINE =
/^import\s*\{([^}]*)\}\s*from\s*["']([^"']+)["'];?\s*$/- EXPORT_DEFAULT_CLASS =
/export\s+default\s+class\s+(\w+)/
Class Method Summary collapse
-
.rewrite(source, path) ⇒ Object
Only a single supported specifier is rewritten: named imports from "@herb-tools/linter" become a destructure from the bundle-global HerbLinter.
Instance Method Summary collapse
-
#initialize(root:, bridge:) ⇒ CustomRuleLoader
constructor
A new instance of CustomRuleLoader.
- #load_all ⇒ Object
Constructor Details
#initialize(root:, bridge:) ⇒ CustomRuleLoader
Returns a new instance of CustomRuleLoader.
21 22 23 24 |
# File 'lib/herb/embedded/custom_rule_loader.rb', line 21 def initialize(root:, bridge:) @root = root @bridge = bridge end |
Class Method Details
.rewrite(source, path) ⇒ Object
Only a single supported specifier is rewritten: named imports from "@herb-tools/linter" become a destructure from the bundle-global HerbLinter. Anything else — a different specifier, or an import form other than named braces — fails loudly rather than producing a mysterious ReferenceError at rule-execution time.
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/herb/embedded/custom_rule_loader.rb', line 44 def self.rewrite(source, path) named_imports = extract_named_imports(source, path) body = strip_import_lines(source) body = rewrite_default_export(body, path) destructure = named_imports.empty? ? "" : "const { #{named_imports.join(", ")} } = HerbLinter;\n" <<~JS (function () { #{destructure}#{body} return __herbCustomRule; })() JS end |
Instance Method Details
#load_all ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/herb/embedded/custom_rule_loader.rb', line 26 def load_all Dir.glob(File.join(@root, RULES_GLOB)).map do |path| rewritten = self.class.rewrite(File.read(path), path) result = @bridge.register_custom_rule(rewritten, path) if result["overrode"] warn("Custom rule '#{result["ruleName"]}' at #{path} overrides a built-in rule of the same name") end result["ruleName"] end end |