metal-orm 1.0.47 → 1.0.49
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 +1 -1
- package/scripts/generate-entities/cli.mjs +97 -0
- package/scripts/generate-entities/drivers.mjs +183 -0
- package/scripts/generate-entities/emit.mjs +24 -0
- package/scripts/generate-entities/generate.mjs +68 -0
- package/scripts/generate-entities/render.mjs +442 -0
- package/scripts/generate-entities/schema.mjs +178 -0
- package/scripts/generate-entities.mjs +19 -738
- package/scripts/naming-strategy.mjs +152 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
export class BaseNamingStrategy {
|
|
2
|
+
constructor(irregulars = {}) {
|
|
3
|
+
this.irregulars = new Map();
|
|
4
|
+
this.inverseIrregulars = new Map();
|
|
5
|
+
for (const [singular, plural] of Object.entries(irregulars)) {
|
|
6
|
+
if (!singular || !plural) continue;
|
|
7
|
+
const singularKey = singular.toLowerCase();
|
|
8
|
+
const pluralValue = plural.toLowerCase();
|
|
9
|
+
this.irregulars.set(singularKey, pluralValue);
|
|
10
|
+
this.inverseIrregulars.set(pluralValue, singularKey);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
applyIrregular(word, direction) {
|
|
15
|
+
const lower = word.toLowerCase();
|
|
16
|
+
if (direction === 'plural' && this.irregulars.has(lower)) {
|
|
17
|
+
return this.irregulars.get(lower);
|
|
18
|
+
}
|
|
19
|
+
if (direction === 'singular' && this.inverseIrregulars.has(lower)) {
|
|
20
|
+
return this.inverseIrregulars.get(lower);
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
toPascalCase(value) {
|
|
26
|
+
return (
|
|
27
|
+
value
|
|
28
|
+
.split(/[^a-zA-Z0-9]+/)
|
|
29
|
+
.filter(Boolean)
|
|
30
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
31
|
+
.join('') || 'Entity'
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
toCamelCase(value) {
|
|
36
|
+
const pascal = this.toPascalCase(value);
|
|
37
|
+
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
toSnakeCase(value) {
|
|
41
|
+
return value
|
|
42
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
43
|
+
.replace(/[^a-z0-9_]+/gi, '_')
|
|
44
|
+
.replace(/__+/g, '_')
|
|
45
|
+
.replace(/^_|_$/g, '')
|
|
46
|
+
.toLowerCase();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pluralize(word) {
|
|
50
|
+
const irregular = this.applyIrregular(word, 'plural');
|
|
51
|
+
if (irregular) return irregular;
|
|
52
|
+
const lower = word.toLowerCase();
|
|
53
|
+
if (lower.endsWith('y')) return `${lower.slice(0, -1)}ies`;
|
|
54
|
+
if (lower.endsWith('s')) return `${lower}es`;
|
|
55
|
+
return `${lower}s`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
singularize(word) {
|
|
59
|
+
const irregular = this.applyIrregular(word, 'singular');
|
|
60
|
+
if (irregular) return irregular;
|
|
61
|
+
const lower = word.toLowerCase();
|
|
62
|
+
if (lower.endsWith('ies')) return `${lower.slice(0, -3)}y`;
|
|
63
|
+
if (lower.endsWith('ses')) return lower.slice(0, -2);
|
|
64
|
+
if (lower.endsWith('s')) return lower.slice(0, -1);
|
|
65
|
+
return lower;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
classNameFromTable(tableName) {
|
|
69
|
+
return this.toPascalCase(this.singularize(tableName));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
belongsToProperty(foreignKeyName, targetTable) {
|
|
73
|
+
const trimmed = foreignKeyName.replace(/_?id$/i, '');
|
|
74
|
+
const base = trimmed && trimmed !== foreignKeyName ? trimmed : this.singularize(targetTable);
|
|
75
|
+
return this.toCamelCase(base);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
hasManyProperty(targetTable) {
|
|
79
|
+
return this.toCamelCase(this.pluralize(this.singularize(targetTable)));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
hasOneProperty(targetTable) {
|
|
83
|
+
return this.toCamelCase(this.singularize(targetTable));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
belongsToManyProperty(targetTable) {
|
|
87
|
+
return this.toCamelCase(this.pluralize(this.singularize(targetTable)));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
defaultTableNameFromClass(className) {
|
|
91
|
+
const normalized = this.toSnakeCase(className);
|
|
92
|
+
if (!normalized) return 'unknown';
|
|
93
|
+
return this.pluralize(normalized);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export class EnglishNamingStrategy extends BaseNamingStrategy {}
|
|
98
|
+
|
|
99
|
+
const DEFAULT_PT_IRREGULARS = {
|
|
100
|
+
mao: 'maos',
|
|
101
|
+
pao: 'paes',
|
|
102
|
+
cao: 'caes',
|
|
103
|
+
mal: 'males',
|
|
104
|
+
consul: 'consules'
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export class PortugueseNamingStrategy extends BaseNamingStrategy {
|
|
108
|
+
constructor(irregulars = {}) {
|
|
109
|
+
super({ ...DEFAULT_PT_IRREGULARS, ...irregulars });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
pluralize(word) {
|
|
113
|
+
const irregular = this.applyIrregular(word, 'plural');
|
|
114
|
+
if (irregular) return irregular;
|
|
115
|
+
const lower = word.toLowerCase();
|
|
116
|
+
if (lower.endsWith('cao')) return `${lower.slice(0, -3)}coes`;
|
|
117
|
+
if (lower.endsWith('ao')) return `${lower.slice(0, -2)}oes`;
|
|
118
|
+
if (lower.endsWith('m')) return `${lower.slice(0, -1)}ns`;
|
|
119
|
+
if (lower.endsWith('al')) return `${lower.slice(0, -2)}ais`;
|
|
120
|
+
if (lower.endsWith('el')) return `${lower.slice(0, -2)}eis`;
|
|
121
|
+
if (lower.endsWith('ol')) return `${lower.slice(0, -2)}ois`;
|
|
122
|
+
if (lower.endsWith('ul')) return `${lower.slice(0, -2)}uis`;
|
|
123
|
+
if (lower.endsWith('il')) return `${lower.slice(0, -2)}is`;
|
|
124
|
+
if (/[rznsx]$/.test(lower)) return `${lower}es`;
|
|
125
|
+
if (lower.endsWith('s')) return lower;
|
|
126
|
+
return `${lower}s`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
singularize(word) {
|
|
130
|
+
const irregular = this.applyIrregular(word, 'singular');
|
|
131
|
+
if (irregular) return irregular;
|
|
132
|
+
const lower = word.toLowerCase();
|
|
133
|
+
if (lower.endsWith('coes')) return `${lower.slice(0, -4)}cao`;
|
|
134
|
+
if (lower.endsWith('oes')) return `${lower.slice(0, -3)}ao`;
|
|
135
|
+
if (lower.endsWith('ns')) return `${lower.slice(0, -2)}m`;
|
|
136
|
+
if (lower.endsWith('ais')) return `${lower.slice(0, -3)}al`;
|
|
137
|
+
if (lower.endsWith('eis')) return `${lower.slice(0, -3)}el`;
|
|
138
|
+
if (lower.endsWith('ois')) return `${lower.slice(0, -3)}ol`;
|
|
139
|
+
if (lower.endsWith('uis')) return `${lower.slice(0, -3)}ul`;
|
|
140
|
+
if (lower.endsWith('is')) return `${lower.slice(0, -2)}il`;
|
|
141
|
+
if (/[rznsx]es$/.test(lower)) return lower.replace(/es$/, '');
|
|
142
|
+
if (lower.endsWith('s')) return lower.slice(0, -1);
|
|
143
|
+
return lower;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export const createNamingStrategy = (locale = 'en', irregulars) => {
|
|
148
|
+
const normalized = (locale || 'en').toLowerCase();
|
|
149
|
+
if (normalized.startsWith('pt')) return new PortugueseNamingStrategy(irregulars);
|
|
150
|
+
if (normalized.startsWith('en')) return new EnglishNamingStrategy(irregulars);
|
|
151
|
+
return new EnglishNamingStrategy(irregulars);
|
|
152
|
+
};
|