mbeditor 0.7.2 → 0.7.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c88d7e8236553061b81b5f828261a5fdfdbf77992b8c1b46c662e49d187b3bac
4
- data.tar.gz: 5b7ae20d67ed9e1e3b63f393252dc94b001331fcc8a7073add6e767ec440ef06
3
+ metadata.gz: 720ab9c5f06c65a444d4e7a4d9204926a91e31941ed5d21df9a8cb234c322124
4
+ data.tar.gz: 3c31e3387d38ba23e997dd71051328678bd225ea6ec2078c7d8cae72b44b09c6
5
5
  SHA512:
6
- metadata.gz: 0e0841e9552fb15f688ca19f54767283ec338eb26b2a2476eadfc69986c62a940738538120eb3fe9ed3687ed21178710f45976747fcfcb5480694541b09f597f
7
- data.tar.gz: 96577d3f9f1293a66ec5b70fc81a322eddf11a5e50cdaef3d7965fb8d69a02411dbe0cbb6782c144f87f42aee66fd21fb731ebafd154de9155d3a24ac2e6b19b
6
+ metadata.gz: aa5177a8fb2e8511a4452dc33d3965c5838001991883360e2767ad598edefcb0b3f4feeeb54cd9692b0d7e7527cdf87463faeef2713edcb48cdd672aadfc961b
7
+ data.tar.gz: 1634701e852db9e3273f0217e5268c6298f3443fdfc5b598d53cfff6a462771a754c7f4ed187cbc247429e0d19ba27913d188715e3846856c034f3382facab5b
data/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.7.3] - 2026-06-03
9
+
10
+ ### Fixed
11
+ - **Custom path reverse lookup** — moved the custom-path check in `extract_resource_names` before the `case` statement so paths under `app/assets/`, `app/javascript/`, etc. are handled. Stripped `_controller`/`_model`/`_helper`/`_service` suffixes from custom-path filenames in both backend and frontend for consistent label/grouping.
12
+ - **Schema modal `self.table_name` support** — reads `self.table_name` from the model file before falling back to `ActiveSupport::Inflector.tableize`, enabling custom table names.
13
+ - **Structure.sql broader schema-prefix regex** — handles quoted schemas, non-public schemas, and no prefix.
14
+ - **PostgreSQL type coverage** — expanded `sql_type_to_rails` with full PostgreSQL type coverage (timestamptz, double precision, citext, hstore, geometric types, etc.).
15
+ - **Schema read error handling** — broadened rescue in `try_schema_rb`/`try_structure_sql` to catch encoding errors.
16
+
17
+ ---
18
+
8
19
  ## [0.7.2] - 2026-06-03
9
20
 
10
21
  ### Changed
@@ -1631,13 +1631,12 @@ var MbeditorApp = function MbeditorApp() {
1631
1631
  if (p.startsWith(base + '/')) {
1632
1632
  var rest = p.slice(base.length + 1);
1633
1633
  var resource = rest.split('/')[0].replace(/\.[^.]+$/, '');
1634
- if (resource) {
1635
- var seg = resource.replace(/_/g, ' ').replace(/\b\w/g, function(c) { return c.toUpperCase(); });
1636
- return seg;
1637
- }
1634
+ // Strip Rails-style suffixes so custom-path files group with their controller/model
1635
+ resource = resource.replace(/_(controller|model|helper|service)$/, '');
1636
+ if (resource) { name = resource; break; }
1638
1637
  }
1639
1638
  }
1640
- return null;
1639
+ if (!name) return null;
1641
1640
  }
1642
1641
  var seg = (name || '').split('/').pop() || name || '';
1643
1642
  // Normalize plural→singular so views/users and models/user share one group
@@ -124,6 +124,20 @@ module Mbeditor
124
124
  parts = relative_path.to_s.split("/")
125
125
  return nil unless parts.length >= 2
126
126
 
127
+ # Custom paths are checked first so they work regardless of top-level prefix.
128
+ # Paths under app/assets/, app/javascript/, etc. never reach the standard
129
+ # "app" branch, so the check must happen before the case statement.
130
+ Array(custom_paths).each do |base|
131
+ base = base.to_s.strip
132
+ next if base.empty?
133
+ next unless relative_path.start_with?("#{base}/")
134
+ rest = relative_path.delete_prefix("#{base}/")
135
+ resource = rest.split('/').first.to_s.sub(/\.[^.]+$/, '') # first segment, no extension
136
+ resource = resource.sub(/_(controller|model|helper|service)$/, '') # strip Rails suffixes
137
+ next if resource.empty?
138
+ return [pluralize(resource), singularize(resource)]
139
+ end
140
+
127
141
  case parts[0]
128
142
  when "app"
129
143
  case parts[1]
@@ -230,16 +244,6 @@ module Mbeditor
230
244
  end
231
245
 
232
246
  else
233
- # Custom path fallback — must be last
234
- Array(custom_paths).each do |base|
235
- base = base.to_s.strip
236
- next if base.empty?
237
- next unless relative_path.start_with?("#{base}/")
238
- rest = relative_path.delete_prefix("#{base}/")
239
- resource = rest.split('/').first.to_s.sub(/\.[^.]+$/, '') # first path segment, no extension
240
- next if resource.empty?
241
- return [pluralize(resource), singularize(resource)]
242
- end
243
247
  nil
244
248
  end
245
249
  end
@@ -40,8 +40,25 @@ module Mbeditor
40
40
  private
41
41
 
42
42
  # "User" → "users", "OrderItem" → "order_items", "Order Item" → "order_items"
43
+ # Also checks the model file for an explicit `self.table_name = "..."` declaration.
43
44
  def derive_table_name(model_name)
44
45
  normalized = model_name.delete(" ")
46
+
47
+ # Check model file for an explicit table_name override
48
+ singular = ActiveSupport::Inflector.underscore(normalized)
49
+ model_file = File.join(@workspace_root, "app", "models", "#{singular}.rb")
50
+ if File.exist?(model_file)
51
+ begin
52
+ source = File.read(model_file, encoding: "utf-8")
53
+ # Matches: self.table_name = "name" or = :name or = 'name'
54
+ if (m = source.match(/self\.table_name\s*=\s*[:"']([^"'\s]+)["']?/))
55
+ return m[1]
56
+ end
57
+ rescue StandardError
58
+ # fall through to default derivation
59
+ end
60
+ end
61
+
45
62
  ActiveSupport::Inflector.tableize(normalized)
46
63
  end
47
64
 
@@ -53,7 +70,7 @@ module Mbeditor
53
70
  begin
54
71
  content = File.read(schema_path, encoding: "utf-8")
55
72
  parse_schema_rb(content, table_name)
56
- rescue Errno::ENOENT, Errno::EACCES => e
73
+ rescue StandardError => e
57
74
  Rails.logger.debug("SchemaService: failed to read #{schema_path}: #{e.message}")
58
75
  nil
59
76
  end
@@ -67,7 +84,7 @@ module Mbeditor
67
84
  begin
68
85
  content = File.read(schema_path, encoding: "utf-8")
69
86
  parse_structure_sql(content, table_name)
70
- rescue Errno::ENOENT, Errno::EACCES => e
87
+ rescue StandardError => e
71
88
  Rails.logger.debug("SchemaService: failed to read #{schema_path}: #{e.message}")
72
89
  nil
73
90
  end
@@ -145,11 +162,13 @@ module Mbeditor
145
162
  # Handles: PostgreSQL, MySQL, SQLite with quoted/unquoted names
146
163
  # Ends with different delimiters: ); ENGINE...; or just );
147
164
  quoted_name = Regexp.escape(table_name)
165
+ # Schema prefix pattern: matches public., "public"., myschema., "myschema". or nothing.
166
+ schema_prefix = /(?:(?:"[^"]+"|`[^`]+`|\w+)\.)?/
148
167
  patterns = [
149
- # PostgreSQL with public schema: CREATE TABLE public."users" ( ... );
150
- /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:public\.)?["`]?#{quoted_name}["`]?\s*\(([\s\S]*?)\)\s*;/mi,
151
- # MySQL with ENGINE: CREATE TABLE `users` ( ... ) ENGINE=...;
152
- /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["`]?#{quoted_name}["`]?\s*\(([\s\S]*?)\)\s*(?:ENGINE|DEFAULT)/mi
168
+ # PostgreSQL: CREATE TABLE [schema.]table ( ... );
169
+ /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?#{schema_prefix}["`]?#{quoted_name}["`]?\s*\(([\s\S]*?)\)\s*;/mi,
170
+ # MySQL: CREATE TABLE [schema.]`table` ( ... ) ENGINE=...;
171
+ /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?#{schema_prefix}["`]?#{quoted_name}["`]?\s*\(([\s\S]*?)\)\s*(?:ENGINE|DEFAULT)/mi
153
172
  ]
154
173
 
155
174
  table_def = nil
@@ -240,6 +259,9 @@ module Mbeditor
240
259
  type_map = {
241
260
  'integer' => 'integer',
242
261
  'int' => 'integer',
262
+ 'int4' => 'integer',
263
+ 'int2' => 'integer',
264
+ 'int8' => 'bigint',
243
265
  'bigint' => 'bigint',
244
266
  'smallint' => 'integer',
245
267
  'bigserial' => 'bigint',
@@ -247,21 +269,50 @@ module Mbeditor
247
269
  'varchar' => 'string',
248
270
  'character varying' => 'string',
249
271
  'character' => 'string',
272
+ 'char' => 'string',
250
273
  'text' => 'text',
274
+ 'citext' => 'string',
251
275
  'boolean' => 'boolean',
252
276
  'bool' => 'boolean',
253
277
  'decimal' => 'decimal',
254
278
  'numeric' => 'decimal',
279
+ 'real' => 'float',
255
280
  'float' => 'float',
281
+ 'float4' => 'float',
282
+ 'float8' => 'float',
283
+ 'double precision' => 'float',
256
284
  'double' => 'float',
285
+ 'money' => 'decimal',
257
286
  'timestamp' => 'datetime',
287
+ 'timestamp without time zone' => 'datetime',
288
+ 'timestamp with time zone' => 'datetime',
289
+ 'timestamptz' => 'datetime',
258
290
  'datetime' => 'datetime',
259
291
  'date' => 'date',
260
292
  'time' => 'time',
293
+ 'time without time zone' => 'time',
294
+ 'time with time zone' => 'time',
295
+ 'interval' => 'string',
261
296
  'json' => 'json',
262
297
  'jsonb' => 'jsonb',
263
298
  'uuid' => 'uuid',
264
- 'bytea' => 'binary'
299
+ 'bytea' => 'binary',
300
+ 'bit' => 'string',
301
+ 'bit varying' => 'string',
302
+ 'inet' => 'string',
303
+ 'cidr' => 'string',
304
+ 'macaddr' => 'string',
305
+ 'xml' => 'string',
306
+ 'hstore' => 'hstore',
307
+ 'tsvector' => 'string',
308
+ 'ltree' => 'string',
309
+ 'point' => 'string',
310
+ 'line' => 'string',
311
+ 'lseg' => 'string',
312
+ 'box' => 'string',
313
+ 'path' => 'string',
314
+ 'polygon' => 'string',
315
+ 'circle' => 'string'
265
316
  }
266
317
 
267
318
  type_map[sql_type.downcase] || sql_type
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mbeditor
4
- VERSION = "0.7.2"
4
+ VERSION = "0.7.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mbeditor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Noonan