metal-orm 1.0.101 → 1.0.103

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metal-orm",
3
- "version": "1.0.101",
3
+ "version": "1.0.103",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "engines": {
@@ -188,7 +188,7 @@ Flags:
188
188
  --include=tbl1,tbl2 Only include these tables
189
189
  --exclude=tbl3,tbl4 Exclude these tables
190
190
  --locale=pt-BR Naming locale for class/relation names (default: en)
191
- --naming-overrides Path to JSON map of irregular plurals { "singular": "plural" }
191
+ --naming-overrides Path to JSON config for naming customizations (see docs)
192
192
  --dry-run Print to stdout instead of writing a file
193
193
  --out=<file> Override the generated file (defaults to generated-entities.ts or the index inside --out-dir)
194
194
  --out-dir=<dir> Emit one file per entity inside this directory plus the shared index
@@ -5,7 +5,7 @@ import { loadDriver } from './drivers.mjs';
5
5
  import { renderEntityFile, renderSplitEntityFiles, renderSplitIndexFile } from './render.mjs';
6
6
  import { printDryRun, writeSingleFile, writeSplitFiles } from './emit.mjs';
7
7
 
8
- const loadIrregulars = async (filePath, fsPromises) => {
8
+ const loadNamingOverrides = async (filePath, fsPromises) => {
9
9
  const raw = await fsPromises.readFile(filePath, 'utf8');
10
10
  let parsed;
11
11
  try {
@@ -13,22 +13,31 @@ const loadIrregulars = async (filePath, fsPromises) => {
13
13
  } catch (err) {
14
14
  throw new Error(`Failed to parse naming overrides at ${filePath}: ${err.message || err}`);
15
15
  }
16
- const irregulars =
17
- parsed && typeof parsed === 'object' && !Array.isArray(parsed)
18
- ? parsed.irregulars && typeof parsed.irregulars === 'object' && !Array.isArray(parsed.irregulars)
19
- ? parsed.irregulars
20
- : parsed
21
- : undefined;
22
- if (!irregulars) {
23
- throw new Error(`Naming overrides at ${filePath} must be an object or { "irregulars": { ... } }`);
16
+
17
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
18
+ throw new Error(`Naming overrides at ${filePath} must be an object`);
24
19
  }
25
- return irregulars;
20
+
21
+ // Support both flat format { "singular": "plural" } and structured { irregulars: {...}, relationOverrides: {...} }
22
+ const hasStructuredFormat = parsed.irregulars || parsed.relationOverrides;
23
+
24
+ const irregulars = hasStructuredFormat
25
+ ? (parsed.irregulars && typeof parsed.irregulars === 'object' ? parsed.irregulars : {})
26
+ : parsed;
27
+
28
+ const relationOverrides = hasStructuredFormat && parsed.relationOverrides && typeof parsed.relationOverrides === 'object'
29
+ ? parsed.relationOverrides
30
+ : {};
31
+
32
+ return { irregulars, relationOverrides };
26
33
  };
27
34
 
28
35
  export const generateEntities = async (opts, context = {}) => {
29
36
  const { fs: fsPromises = fs, logger = console } = context;
30
- const irregulars = opts.namingOverrides ? await loadIrregulars(opts.namingOverrides, fsPromises) : undefined;
31
- const naming = createNamingStrategy(opts.locale, irregulars);
37
+ const { irregulars, relationOverrides } = opts.namingOverrides
38
+ ? await loadNamingOverrides(opts.namingOverrides, fsPromises)
39
+ : { irregulars: undefined, relationOverrides: {} };
40
+ const naming = createNamingStrategy(opts.locale, irregulars, relationOverrides);
32
41
 
33
42
  const { executor, cleanup } = await loadDriver(opts.dialect, opts.url, opts.dbPath);
34
43
  let schema;
@@ -259,26 +259,27 @@ const renderEntityClassLines = ({ table, className, naming, relations, resolveCl
259
259
  for (const rel of relations) {
260
260
  const targetClass = resolveClassName(rel.target);
261
261
  if (!targetClass) continue;
262
+ const propName = naming.applyRelationOverride(className, rel.property);
262
263
  switch (rel.kind) {
263
264
  case 'belongsTo':
264
265
  lines.push(
265
266
  ` @BelongsTo({ target: () => ${targetClass}, foreignKey: '${escapeJsString(rel.foreignKey)}' })`
266
267
  );
267
- lines.push(` ${rel.property}!: BelongsToReference<${targetClass}>;`);
268
+ lines.push(` ${propName}!: BelongsToReference<${targetClass}>;`);
268
269
  lines.push('');
269
270
  break;
270
271
  case 'hasMany':
271
272
  lines.push(
272
273
  ` @HasMany({ target: () => ${targetClass}, foreignKey: '${escapeJsString(rel.foreignKey)}' })`
273
274
  );
274
- lines.push(` ${rel.property}!: HasManyCollection<${targetClass}>;`);
275
+ lines.push(` ${propName}!: HasManyCollection<${targetClass}>;`);
275
276
  lines.push('');
276
277
  break;
277
278
  case 'hasOne':
278
279
  lines.push(
279
280
  ` @HasOne({ target: () => ${targetClass}, foreignKey: '${escapeJsString(rel.foreignKey)}' })`
280
281
  );
281
- lines.push(` ${rel.property}!: HasOneReference<${targetClass}>;`);
282
+ lines.push(` ${propName}!: HasOneReference<${targetClass}>;`);
282
283
  lines.push('');
283
284
  break;
284
285
  case 'belongsToMany': {
@@ -289,7 +290,7 @@ const renderEntityClassLines = ({ table, className, naming, relations, resolveCl
289
290
  rel.pivotForeignKeyToRoot
290
291
  )}', pivotForeignKeyToTarget: '${escapeJsString(rel.pivotForeignKeyToTarget)}' })`
291
292
  );
292
- lines.push(` ${rel.property}!: ManyToManyCollection<${targetClass}>;`);
293
+ lines.push(` ${propName}!: ManyToManyCollection<${targetClass}>;`);
293
294
  lines.push('');
294
295
  break;
295
296
  }