@reinteractive/rails-insight 1.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.
Files changed (90) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +210 -0
  3. package/bin/railsinsight.js +128 -0
  4. package/package.json +62 -0
  5. package/src/core/blast-radius.js +496 -0
  6. package/src/core/constants.js +39 -0
  7. package/src/core/context-loader.js +227 -0
  8. package/src/core/drift-detector.js +168 -0
  9. package/src/core/formatter.js +197 -0
  10. package/src/core/graph.js +510 -0
  11. package/src/core/indexer.js +595 -0
  12. package/src/core/patterns/api.js +27 -0
  13. package/src/core/patterns/auth.js +25 -0
  14. package/src/core/patterns/authorization.js +24 -0
  15. package/src/core/patterns/caching.js +19 -0
  16. package/src/core/patterns/component.js +18 -0
  17. package/src/core/patterns/config.js +15 -0
  18. package/src/core/patterns/controller.js +42 -0
  19. package/src/core/patterns/email.js +20 -0
  20. package/src/core/patterns/factory.js +31 -0
  21. package/src/core/patterns/gemfile.js +9 -0
  22. package/src/core/patterns/helper.js +10 -0
  23. package/src/core/patterns/job.js +12 -0
  24. package/src/core/patterns/model.js +123 -0
  25. package/src/core/patterns/realtime.js +17 -0
  26. package/src/core/patterns/route.js +27 -0
  27. package/src/core/patterns/schema.js +25 -0
  28. package/src/core/patterns/stimulus.js +13 -0
  29. package/src/core/patterns/storage.js +16 -0
  30. package/src/core/patterns/uploader.js +16 -0
  31. package/src/core/patterns/view.js +20 -0
  32. package/src/core/patterns/worker.js +12 -0
  33. package/src/core/patterns.js +27 -0
  34. package/src/core/scanner.js +394 -0
  35. package/src/core/version-detector.js +295 -0
  36. package/src/extractors/api.js +284 -0
  37. package/src/extractors/auth.js +853 -0
  38. package/src/extractors/authorization.js +785 -0
  39. package/src/extractors/caching.js +84 -0
  40. package/src/extractors/component.js +221 -0
  41. package/src/extractors/config.js +81 -0
  42. package/src/extractors/controller.js +273 -0
  43. package/src/extractors/coverage-snapshot.js +296 -0
  44. package/src/extractors/email.js +123 -0
  45. package/src/extractors/factory-registry.js +225 -0
  46. package/src/extractors/gemfile.js +440 -0
  47. package/src/extractors/helper.js +55 -0
  48. package/src/extractors/jobs.js +122 -0
  49. package/src/extractors/model.js +506 -0
  50. package/src/extractors/realtime.js +102 -0
  51. package/src/extractors/routes.js +251 -0
  52. package/src/extractors/schema.js +178 -0
  53. package/src/extractors/stimulus.js +149 -0
  54. package/src/extractors/storage.js +100 -0
  55. package/src/extractors/test-conventions.js +340 -0
  56. package/src/extractors/tier2.js +417 -0
  57. package/src/extractors/tier3.js +84 -0
  58. package/src/extractors/uploader.js +138 -0
  59. package/src/extractors/views.js +131 -0
  60. package/src/extractors/worker.js +62 -0
  61. package/src/git/diff-parser.js +132 -0
  62. package/src/providers/interface.js +12 -0
  63. package/src/providers/local-fs.js +318 -0
  64. package/src/server.js +71 -0
  65. package/src/tools/blast-radius-tools.js +129 -0
  66. package/src/tools/free-tools.js +44 -0
  67. package/src/tools/handlers/get-controller.js +93 -0
  68. package/src/tools/handlers/get-coverage-gaps.js +100 -0
  69. package/src/tools/handlers/get-deep-analysis.js +294 -0
  70. package/src/tools/handlers/get-domain-clusters.js +113 -0
  71. package/src/tools/handlers/get-factory-registry.js +43 -0
  72. package/src/tools/handlers/get-full-index.js +28 -0
  73. package/src/tools/handlers/get-model.js +108 -0
  74. package/src/tools/handlers/get-overview.js +153 -0
  75. package/src/tools/handlers/get-routes.js +18 -0
  76. package/src/tools/handlers/get-schema.js +40 -0
  77. package/src/tools/handlers/get-subgraph.js +82 -0
  78. package/src/tools/handlers/get-test-conventions.js +18 -0
  79. package/src/tools/handlers/get-well-tested-examples.js +51 -0
  80. package/src/tools/handlers/helpers.js +115 -0
  81. package/src/tools/handlers/index-project.js +36 -0
  82. package/src/tools/handlers/search-patterns.js +104 -0
  83. package/src/tools/index.js +34 -0
  84. package/src/tools/pro-tools.js +13 -0
  85. package/src/utils/file-reader.js +20 -0
  86. package/src/utils/inflector.js +223 -0
  87. package/src/utils/ruby-parser.js +115 -0
  88. package/src/utils/spec-style-detector.js +26 -0
  89. package/src/utils/token-counter.js +46 -0
  90. package/src/utils/yaml-parser.js +135 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Regex patterns for ViewComponent extraction.
3
+ */
4
+ export const COMPONENT_PATTERNS = {
5
+ classDeclaration: /class\s+(\w+(?:::\w+)*Component)\s*<\s*(\w+(?:::\w+)*)/,
6
+ initialize: /def\s+initialize\(([^)]+)\)/,
7
+ rendersOne: /^\s*renders_one\s+:(\w+)(?:,\s*(.+))?/m,
8
+ rendersMany: /^\s*renders_many\s+:(\w+)(?:,\s*(.+))?/m,
9
+ collectionParam: /^\s*with_collection_parameter\s+:(\w+)/m,
10
+ contentAreas: /^\s*with_content_areas?\s+(.+)/m,
11
+ // Template patterns
12
+ stimulusController: /data-controller=['"]([^'"]+)['"]/g,
13
+ stimulusAction: /data-action=['"]([^'"]+)['"]/g,
14
+ turboFrame: /<turbo-frame\s+id=['"]([^'"]+)['"]/g,
15
+ turboStream: /<turbo-stream\s/g,
16
+ componentRender: /render\s+(\w+(?:::\w+)*Component)/g,
17
+ partialRender: /render\s+partial:/g,
18
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Regex patterns for Rails configuration extraction (Section 7.2).
3
+ */
4
+ export const CONFIG_PATTERNS = {
5
+ loadDefaults: /config\.load_defaults\s+(\d+\.\d+)/,
6
+ apiOnly: /config\.api_only\s*=\s*true/,
7
+ timeZone: /config\.time_zone\s*=\s*['"]([^'"]+)['"]/,
8
+ queueAdapter: /config\.active_job\.queue_adapter\s*=\s*:(\w+)/,
9
+ cacheStore: /config\.cache_store\s*=\s*:(\w+)/,
10
+ forceSSL: /config\.force_ssl\s*=\s*true/,
11
+ filterParameters: /config\.filter_parameters\s*\+=\s*\[([^\]]+)\]/,
12
+ railsConfigure: /Rails\.application\.configure\s+do/,
13
+ configSetting: /config\.\w+(?:\.\w+)*\s*=/g,
14
+ initializer: /initializer\s+['"]([^'"]+)['"]/g,
15
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Regex patterns for Rails controller extraction.
3
+ */
4
+ export const CONTROLLER_PATTERNS = {
5
+ classDeclaration: /class\s+(\w+(?:::\w+)*Controller)\s*<\s*(\w+(?:::\w+)*)/,
6
+ include: /^\s*include\s+(\w+(?:::\w+)*)/m,
7
+
8
+ // Filters
9
+ filter:
10
+ /^\s*(?:before|after|around|skip_before|skip_after|skip_around)_action\s+:?(\w+)(?:,\s*(.+))?$/m,
11
+ filterType:
12
+ /^\s*((?:before|after|around|skip_before|skip_after|skip_around)_action)\s+:?(\w+!?)(?:,\s*(.+))?$/m,
13
+
14
+ // Visibility boundaries
15
+ visibility: /^\s*(private|protected)\s*$/m,
16
+
17
+ // Method/action
18
+ method: /^\s*def\s+(\w+)/m,
19
+
20
+ // Strong params
21
+ strongParamsMethod: /^\s*def\s+(\w+_params)/m,
22
+ paramsRequire: /params\.require\(:(\w+)\)\.permit\(([^)]+)\)/,
23
+
24
+ // Respond to
25
+ respondTo: /respond_to\s+(?:do\s*\|(\w+)\||:(\w+))/,
26
+
27
+ // Rescue from
28
+ rescueFrom: /^\s*rescue_from\s+(\w+(?:::\w+)*)(?:,\s*with:\s*:(\w+))?/m,
29
+
30
+ // Layout
31
+ layout: /^\s*layout\s+['"](\w+)['"]/m,
32
+
33
+ // Forgery protection
34
+ protectFromForgery: /protect_from_forgery\s*(.*)/,
35
+ skipForgeryProtection: /skip_forgery_protection/,
36
+
37
+ // HTTP auth
38
+ httpBasicAuth: /http_basic_authenticate_with/,
39
+
40
+ // Streaming
41
+ actionControllerLive: /include\s+ActionController::Live/,
42
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Regex patterns for Rails mailer extraction.
3
+ */
4
+ export const EMAIL_PATTERNS = {
5
+ mailerClass: /class\s+(\w+Mailer)\s*<\s*(\w+)/,
6
+ mailerMethod: /^\s*def\s+(\w+)/m,
7
+ defaultFrom: /default\s+from:\s*['"]([^'"]+)['"]/,
8
+ mailerLayout: /^\s*layout\s+['"](\w+)['"]/m,
9
+ deliveryMethod: /config\.action_mailer\.delivery_method\s*=\s*:(\w+)/,
10
+ smtpSettings: /config\.action_mailer\.smtp_settings/,
11
+ mailerConfig: /config\.action_mailer\.(\w+)\s*=\s*(.+)/g,
12
+ interceptor: /ActionMailer::Base\.register_interceptor\s*\((\w+)\)/,
13
+ observer: /ActionMailer::Base\.register_observer\s*\((\w+)\)/,
14
+ mailboxClass: /class\s+(\w+Mailbox)\s*<\s*(\w+)/,
15
+ mailboxRouting: /routing\s+(.+)/g,
16
+ mailCall: /mail\s*\(/g,
17
+ deliverNow: /\.deliver_now/g,
18
+ deliverLater: /\.deliver_later/g,
19
+ attachments: /attachments\[/g,
20
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Regex patterns for FactoryBot extraction.
3
+ */
4
+ export const FACTORY_PATTERNS = {
5
+ // Factory definition: factory :name or factory :name, class: "ClassName"
6
+ factoryDef:
7
+ /^\s*factory\s+:(\w+)(?:,\s*class:\s*['"]?:?(\w+(?:::\w+)*)['"]?)?\s*do/m,
8
+
9
+ // Trait definition
10
+ trait: /^\s*trait\s+:(\w+)\s*do/m,
11
+
12
+ // Sequence definition
13
+ sequence: /^\s*sequence\s*\(:(\w+)\)/m,
14
+ sequenceBlock: /^\s*sequence\s+:(\w+)\s/m,
15
+
16
+ // Association reference inside factory
17
+ association: /^\s*association\s+:(\w+)(?:,\s*(.+))?/m,
18
+
19
+ // Transient block
20
+ transient: /^\s*transient\s+do/m,
21
+
22
+ // After callbacks
23
+ afterCreate: /^\s*after\s*\(:create\)/m,
24
+ afterBuild: /^\s*after\s*\(:build\)/m,
25
+
26
+ // Attribute with block: name { value }
27
+ attributeBlock: /^\s*(\w+)\s*\{([^}]*)\}/m,
28
+
29
+ // Attribute with static value (less common)
30
+ attributeStatic: /^\s*(\w+)\s+['"]([^'"]+)['"]/m,
31
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Regex patterns for Gemfile extraction.
3
+ */
4
+ export const GEMFILE_PATTERNS = {
5
+ gem: /^\s*gem\s+['"]([^'"]+)['"](?:,\s*['"]([^'"]+)['"])?(?:,\s*(.+))?$/m,
6
+ group: /^\s*group\s+(.+)\s+do/m,
7
+ source: /^\s*source\s+['"]([^'"]+)['"]/m,
8
+ ruby: /^\s*ruby\s+['"]([^'"]+)['"]/m,
9
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Regex patterns for Rails helper extraction.
3
+ */
4
+ export const HELPER_PATTERNS = {
5
+ moduleDeclaration: /module\s+(\w+(?:::\w+)*Helper)/,
6
+ methodDefinition: /^\s*def\s+(\w+[?!]?)(?:\(([^)]*)\))?/gm,
7
+ helperMethod: /helper_method\s+:(\w+)/g,
8
+ includeHelper: /include\s+(\w+(?:::\w+)*Helper)/g,
9
+ privateKeyword: /^\s*private\s*$/m,
10
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Regex patterns for Rails job extraction.
3
+ */
4
+ export const JOB_PATTERNS = {
5
+ classDeclaration: /class\s+(\w+(?:::\w+)*)\s*<\s*(\w+)/,
6
+ queueAs: /^\s*queue_as\s+:?['"]?(\w+)['"]?/m,
7
+ retryOn: /^\s*retry_on\s+(\w+(?:::\w+)*)(?:,\s*(.+))?/m,
8
+ discardOn: /^\s*discard_on\s+(\w+(?:::\w+)*)(?:,\s*(.+))?/m,
9
+ queueAdapter: /self\.queue_adapter\s*=\s*:(\w+)/,
10
+ sidekiqOptions: /^\s*sidekiq_options\s+(.+)/m,
11
+ performLater: /(\w+)\.perform_later/g,
12
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Regex patterns for Rails model extraction.
3
+ */
4
+ export const MODEL_PATTERNS = {
5
+ // Class declaration + inheritance
6
+ classDeclaration: /class\s+(\w+(?:::\w+)*)\s*<\s*(\w+(?:::\w+)*)/,
7
+
8
+ // Concern inclusions
9
+ include: /^\s*include\s+(\w+(?:::\w+)*)/m,
10
+ extend: /^\s*extend\s+(\w+(?:::\w+)*)/m,
11
+
12
+ // === ASSOCIATIONS ===
13
+ belongsTo: /^\s*belongs_to\s+:(\w+)(?:,\s*(.+))?$/m,
14
+ hasMany: /^\s*has_many\s+:(\w+)(?:,\s*(.+))?$/m,
15
+ hasOne: /^\s*has_one\s+:(\w+)(?:,\s*(.+))?$/m,
16
+ habtm: /^\s*has_and_belongs_to_many\s+:(\w+)(?:,\s*(.+))?$/m,
17
+ through: /through:\s*:(\w+)/,
18
+ polymorphic: /polymorphic:\s*true/,
19
+ asPolymorphic: /as:\s*:(\w+)/,
20
+
21
+ // === VALIDATIONS ===
22
+ validates: /^\s*validates?\s+:?(\w+(?:,\s*:\w+)*)(?:,\s*(.+))?$/m,
23
+ validate: /^\s*validate\s+:(\w+)/m,
24
+
25
+ // === SCOPES ===
26
+ scope: /^\s*scope\s+:(\w+),\s*(?:->|lambda|proc)/m,
27
+
28
+ // === ENUMS ===
29
+ enumPositional: /^\s*enum\s+:(\w+),\s*\{([^}]+)\}/m,
30
+ enumPositionalArray: /^\s*enum\s+:(\w+),\s*\[([^\]]+)\]/m,
31
+ enumLegacy: /^\s*enum\s+(\w+):\s*\{([^}]+)\}/m,
32
+ enumLegacyArray: /^\s*enum\s+(\w+):\s*\[([^\]]+)\]/m,
33
+
34
+ // === CALLBACKS ===
35
+ callback:
36
+ /^\s*(?:before|after|around)_(?:save|create|update|destroy|validation|commit|rollback|initialize|find|touch)\s+:?(\w+)(?:,\s*(.+))?$/m,
37
+ callbackType:
38
+ /^\s*((?:before|after|around)_(?:save|create|update|destroy|validation|commit|rollback|initialize|find|touch))\s+:?(\w+)(?:,\s*(.+))?$/m,
39
+
40
+ // === DELEGATIONS ===
41
+ delegate: /^\s*delegate\s+(.+),\s*to:\s*:(\w+)/m,
42
+
43
+ // === ENCRYPTION (Rails 7+) ===
44
+ encrypts: /^\s*encrypts\s+(.+)/m,
45
+
46
+ // === NORMALIZES (Rails 7.1+) ===
47
+ normalizes: /^\s*normalizes\s+(.+)/m,
48
+
49
+ // === TOKEN GENERATION (Rails 7.2+) ===
50
+ generatesTokenFor: /^\s*generates_token_for\s+:(\w+)/m,
51
+
52
+ // === SECURE PASSWORD ===
53
+ hasSecurePassword: /^\s*has_secure_password/m,
54
+
55
+ // === SECURE TOKEN ===
56
+ hasSecureToken: /^\s*has_secure_token\s*(?::(\w+))?/m,
57
+
58
+ // === ACTIVE STORAGE ===
59
+ hasOneAttached: /^\s*has_one_attached\s+:(\w+)(?:,\s*(.+))?/m,
60
+ hasManyAttached: /^\s*has_many_attached\s+:(\w+)(?:,\s*(.+))?/m,
61
+
62
+ // === ACTION TEXT ===
63
+ hasRichText: /^\s*has_rich_text\s+:(\w+)/m,
64
+
65
+ // === STORE ===
66
+ store: /^\s*store\s+:(\w+),\s*accessors:\s*\[([^\]]+)\]/m,
67
+ storeAccessor: /^\s*store_accessor\s+:(\w+),\s*(.+)/m,
68
+
69
+ // === TABLE/KEY OVERRIDES ===
70
+ tableName: /self\.table_name\s*=\s*['"](\w+)['"]/,
71
+ primaryKey: /self\.primary_key\s*=\s*(.+)/,
72
+
73
+ // === DEFAULT SCOPE ===
74
+ defaultScope: /^\s*default_scope\s/m,
75
+
76
+ // === COUNTER CACHE ===
77
+ counterCache: /counter_cache:\s*(?:true|['"](\w+)['"])/,
78
+
79
+ // === STI ===
80
+ inheritanceColumn: /self\.inheritance_column\s*=\s*['"](\w+)['"]/,
81
+
82
+ // === ABSTRACT CLASS ===
83
+ abstractClass: /self\.abstract_class\s*=\s*true/,
84
+
85
+ // === ACTS AS / PLUGIN PATTERNS ===
86
+ actsAs: /^\s*acts_as_(\w+)/m,
87
+
88
+ // === BROADCASTS (Turbo Streams) ===
89
+ broadcastsTo: /^\s*broadcasts_to\s+(.+)/m,
90
+ broadcasts: /^\s*broadcasts\b/m,
91
+
92
+ // === STRICT LOADING ===
93
+ strictLoading: /^\s*self\.strict_loading_by_default\s*=\s*true/m,
94
+ strictLoadingAssoc: /strict_loading:\s*true/,
95
+
96
+ // === TURBO 8 MORPHING ===
97
+ turboRefreshes: /^\s*turbo_refreshes_with\s+:(\w+)/m,
98
+
99
+ // === SOFT DELETE ===
100
+ discardModel: /include\s+Discard::Model/,
101
+ paranoid: /acts_as_paranoid/,
102
+
103
+ // === STATE MACHINE ===
104
+ includeAASM: /include\s+AASM/,
105
+ aasm: /^\s*aasm\s/m,
106
+ stateMachine: /^\s*state_machine\s/m,
107
+
108
+ // === FRIENDLY ID ===
109
+ extendFriendlyId: /extend\s+FriendlyId/,
110
+ friendlyId: /^\s*friendly_id\s+:(\w+)/m,
111
+
112
+ // === PAPER TRAIL / AUDITING ===
113
+ hasPaperTrail: /^\s*has_paper_trail/m,
114
+ audited: /^\s*audited/m,
115
+
116
+ // === DEVISE MODULES ===
117
+ devise: /^\s*devise\s+(.+)/m,
118
+
119
+ // === SEARCHABLE ===
120
+ searchkick: /^\s*searchkick/m,
121
+ pgSearchModel: /include\s+PgSearch::Model/,
122
+ pgSearchScope: /^\s*pg_search_scope\s+:(\w+)/m,
123
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Regex patterns for ActionCable and realtime extraction.
3
+ */
4
+ export const REALTIME_PATTERNS = {
5
+ channelClass: /class\s+(\w+Channel)\s*<\s*(\w+)/,
6
+ subscribed: /def\s+subscribed/,
7
+ streamFrom: /stream_from\s+['"]?([^'"]+)['"]?/g,
8
+ streamFor: /stream_for\s+(.+)/g,
9
+ turboStreamFrom: /turbo_stream_from\s+(.+)/g,
10
+ connectionConnect: /def\s+connect/,
11
+ findVerifiedUser: /find_verified_user/,
12
+ rejectUnauthorized: /reject_unauthorized_connection/,
13
+ cableAdapter: /adapter:\s*(\w+)/,
14
+ broadcast: /\.broadcast\s*\(/g,
15
+ turboStream: /Turbo::StreamsChannel\.broadcast/g,
16
+ broadcastsTo: /broadcasts_to\s+:(\w+)/g,
17
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Regex patterns for Rails route extraction.
3
+ */
4
+ export const ROUTE_PATTERNS = {
5
+ resources: /^\s*resources?\s+:(\w+)(?:,\s*(.+))?\s*(?:do)?\s*$/m,
6
+ resource: /^\s*resource\s+:(\w+)(?:,\s*(.+))?\s*(?:do)?\s*$/m,
7
+ namespace: /^\s*namespace\s+:(\w+)(?:,\s*(.+))?\s*do/m,
8
+ scope: /^\s*scope\s+(?:['"]([^'"]+)['"]|:(\w+))(?:,\s*(.+))?\s*do/m,
9
+ scopeModule: /^\s*scope\s+module:\s*['"]?:?(\w+)['"]?/m,
10
+ constraints: /^\s*constraints\s*(?:\((.+)\))?\s*do/m,
11
+ httpVerb:
12
+ /^\s*(?:get|post|put|patch|delete)\s+['"]([^'"]+)['"](?:.*?(?:to:|=>)\s*['"]([^'"#]+)#?([^'"]*)['"'])?/m,
13
+ root: /^\s*root\s+(?:to:\s*)?['"]([^'"#]+)#?([^'"]*)['"']/m,
14
+ mount:
15
+ /^\s*mount\s+(\w+(?:(?:::|\.)\w+)*)\s*(?:=>|,\s*at:)\s*['"]([^'"]+)['"]/m,
16
+ concern: /^\s*concern\s+:(\w+)\s+do/m,
17
+ concerns: /^\s*concerns\s+:(\w+)/m,
18
+ member: /^\s*member\s+do/m,
19
+ collection: /^\s*collection\s+do/m,
20
+ draw: /^\s*draw\s*\(?:?(\w+)\)?/m,
21
+ only: /only:\s*\[([^\]]+)\]/,
22
+ except: /except:\s*\[([^\]]+)\]/,
23
+ defaults: /defaults:\s*\{([^}]+)\}/,
24
+ healthCheck: /^\s*get\s+['"]up['"]/m,
25
+ direct: /^\s*direct\s*\(:(\w+)\)/m,
26
+ resolve: /^\s*resolve\s*\((.+)\)/m,
27
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Regex patterns for Rails schema extraction.
3
+ */
4
+ export const SCHEMA_PATTERNS = {
5
+ schemaVersion: /ActiveRecord::Schema\[[\d.]+\]\.define\(version:\s*([\d_]+)/,
6
+ schemaVersionAlt: /ActiveRecord::Schema\.define\(version:\s*([\d_]+)/,
7
+ createTable: /^\s*create_table\s+['"](\w+)['"](?:,\s*(.+))?\s*do/m,
8
+ column: /^\s*t\.(\w+)\s+['":]+(\w+)['"]?(?:,\s*(.+))?/m,
9
+ references:
10
+ /^\s*t\.(?:references|belongs_to)\s+['"]?:?(\w+)['"]?(?:,\s*(.+))?/m,
11
+ timestamps: /^\s*t\.timestamps/m,
12
+ index:
13
+ /^\s*(?:t\.index|add_index)\s+(?:\[([^\]]+)\]|['"](\w+)['"]),?\s*(.+)?/m,
14
+ foreignKey:
15
+ /^\s*add_foreign_key\s+['"](\w+)['"],\s*['"](\w+)['"](?:,\s*(.+))?/m,
16
+ checkConstraint:
17
+ /^\s*add_check_constraint\s+['"](\w+)['"],\s*['"](.+)['"](?:,\s*(.+))?/m,
18
+ createEnum: /^\s*create_enum\s+['"](\w+)['"],\s*\[([^\]]+)\]/m,
19
+ enableExtension: /^\s*enable_extension\s+['"](\w+)['"]/m,
20
+ idType: /id:\s*:(\w+)/,
21
+ idUuid: /id:\s*:uuid/,
22
+ idFalse: /id:\s*false/,
23
+ compositePrimaryKey: /primary_key:\s*\[([^\]]+)\]/,
24
+ comment: /comment:\s*['"]([^'"]+)['"]/,
25
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Regex patterns for Stimulus controller extraction.
3
+ */
4
+ export const STIMULUS_PATTERNS = {
5
+ classDeclaration:
6
+ /export\s+default\s+class\s+(?:(\w+)\s+)?extends\s+Controller/,
7
+ targets: /static\s+targets\s*=\s*\[([^\]]+)\]/,
8
+ values: /static\s+values\s*=\s*\{([^}]+)\}/,
9
+ classes: /static\s+classes\s*=\s*\[([^\]]+)\]/,
10
+ outlets: /static\s+outlets\s*=\s*\[([^\]]+)\]/,
11
+ actionMethod: /^\s+(\w+)\s*\(.*?\)\s*\{/gm,
12
+ imports: /import\s+(?:\{([^}]+)\}|(\w+))\s+from\s+['"]([^'"]+)['"]/g,
13
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Regex patterns for Active Storage extraction.
3
+ */
4
+ export const STORAGE_PATTERNS = {
5
+ storageService: /(\w+):\s*\n\s*service:\s*(\w+)/g,
6
+ variant: /variant\s*\(([^)]+)\)/g,
7
+ namedVariant: /variant\s+:(\w+),\s*(.+)/g,
8
+ directUpload: /direct_upload:\s*true/,
9
+ contentTypeValidation: /content_type:\s*\[([^\]]+)\]/,
10
+ fileSizeValidation: /byte_size:\s*\{[^}]*less_than:\s*(\d+)/,
11
+ variantProcessor: /config\.active_storage\.variant_processor\s*=\s*:(\w+)/,
12
+ mirrorService: /service:\s*Mirror/,
13
+ hasOneAttached: /^\s*has_one_attached\s+:(\w+)/m,
14
+ hasManyAttached: /^\s*has_many_attached\s+:(\w+)/m,
15
+ purge: /\.purge(?:_later)?/g,
16
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Regex patterns for CarrierWave / Shrine uploader extraction.
3
+ */
4
+ export const UPLOADER_PATTERNS = {
5
+ // CarrierWave
6
+ carrierWaveClass: /class\s+(\w+(?:::\w+)*)\s*<\s*CarrierWave::Uploader::Base/,
7
+ storageType: /^\s*storage\s+:(\w+)/m,
8
+ extensionAllowlist: /def\s+extension_allowlist\s*\n\s*%w\[([^\]]+)\]/m,
9
+ contentTypeAllowlist: /def\s+content_type_allowlist\s*\n\s*%w\[([^\]]+)\]/m,
10
+ versionBlock: /version\s+:(\w+)/g,
11
+ storeDir: /def\s+store_dir\s*\n\s*['"]([^'"]+)['"]/m,
12
+ mountUploader: /mount_uploader\s+:(\w+),\s*(\w+(?:::\w+)*)/g,
13
+ // Shrine
14
+ shrineClass: /class\s+(\w+(?:::\w+)*)\s*<\s*Shrine/,
15
+ shrinePlugin: /plugin\s+:(\w+)/g,
16
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Regex patterns for view and template extraction.
3
+ */
4
+ export const VIEW_PATTERNS = {
5
+ turboFrame:
6
+ /(?:<turbo-frame\s+id=['"]([^'"]+)['"]|turbo_frame_tag\s+['"]([^'"]+)['"])/g,
7
+ componentRender: /render\s+(\w+(?:::\w+)*Component)/g,
8
+ partialRender: /render\s+(?:partial:\s*)?['"]([^'"]+)['"]/g,
9
+ contentFor: /content_for\s*[:(]\s*:?(\w+)/g,
10
+ formWith: /form_with\s/g,
11
+ formFor: /form_for\s/g,
12
+ formTag: /form_tag\s/g,
13
+ stimulusController: /data-controller=['"]([^'"]+)['"]/g,
14
+ stimulusAction: /data-action=['"]([^'"]+)['"]/g,
15
+ jbuilderField: /json\.(\w+)/g,
16
+ jbuilderArray: /json\.array!/g,
17
+ yieldContent: /yield\s*[:(]?\s*:?(\w+)/g,
18
+ helperMethod: /helper_method\s+:(\w+)/g,
19
+ turboStreamTag: /turbo_stream\.\w+/g,
20
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Regex patterns for Sidekiq native worker extraction.
3
+ */
4
+ export const WORKER_PATTERNS = {
5
+ classDeclaration: /class\s+(\w+(?:::\w+)*)\s*(?:<\s*(\w+(?:::\w+)*))?/,
6
+ includeSidekiq: /include\s+Sidekiq::(Job|Worker)/,
7
+ sidekiqOptions: /^\s*sidekiq_options\s+(.+)/m,
8
+ queueOption: /queue:\s*[:'"]*(\w+)['"']*/,
9
+ retryOption: /retry:\s*(false|\d+)/,
10
+ performSignature: /^\s*def\s+perform\(([^)]*)\)/m,
11
+ uniqueOption: /unique:\s*:(\w+)/,
12
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared regex patterns for all extractors.
3
+ * Organized by domain — each pattern set lives in its own file under ./patterns/.
4
+ * This barrel re-exports every named constant so existing imports keep working.
5
+ */
6
+
7
+ export { MODEL_PATTERNS } from './patterns/model.js'
8
+ export { CONTROLLER_PATTERNS } from './patterns/controller.js'
9
+ export { ROUTE_PATTERNS } from './patterns/route.js'
10
+ export { SCHEMA_PATTERNS } from './patterns/schema.js'
11
+ export { COMPONENT_PATTERNS } from './patterns/component.js'
12
+ export { STIMULUS_PATTERNS } from './patterns/stimulus.js'
13
+ export { AUTH_PATTERNS } from './patterns/auth.js'
14
+ export { AUTHORIZATION_PATTERNS } from './patterns/authorization.js'
15
+ export { JOB_PATTERNS } from './patterns/job.js'
16
+ export { EMAIL_PATTERNS } from './patterns/email.js'
17
+ export { STORAGE_PATTERNS } from './patterns/storage.js'
18
+ export { CACHING_PATTERNS } from './patterns/caching.js'
19
+ export { REALTIME_PATTERNS } from './patterns/realtime.js'
20
+ export { API_PATTERNS } from './patterns/api.js'
21
+ export { VIEW_PATTERNS } from './patterns/view.js'
22
+ export { GEMFILE_PATTERNS } from './patterns/gemfile.js'
23
+ export { CONFIG_PATTERNS } from './patterns/config.js'
24
+ export { FACTORY_PATTERNS } from './patterns/factory.js'
25
+ export { HELPER_PATTERNS } from './patterns/helper.js'
26
+ export { WORKER_PATTERNS } from './patterns/worker.js'
27
+ export { UPLOADER_PATTERNS } from './patterns/uploader.js'