@stonyx/orm 0.2.1-beta.41 → 0.2.1-beta.42

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
@@ -4,7 +4,7 @@
4
4
  "stonyx-async",
5
5
  "stonyx-module"
6
6
  ],
7
- "version": "0.2.1-beta.41",
7
+ "version": "0.2.1-beta.42",
8
8
  "description": "",
9
9
  "main": "src/main.js",
10
10
  "type": "module",
package/src/belongs-to.js CHANGED
@@ -11,7 +11,7 @@ export default function belongsTo(modelName) {
11
11
  const pendingHasManyQueue = relationships.get('pending');
12
12
  const pendingBelongsToQueue = relationships.get('pendingBelongsTo');
13
13
 
14
- return (sourceRecord, rawData, options) => {
14
+ const fn = (sourceRecord, rawData, options) => {
15
15
  if (!rawData) return null;
16
16
 
17
17
  const { __name: sourceModelName } = sourceRecord.__model;
@@ -60,4 +60,7 @@ export default function belongsTo(modelName) {
60
60
 
61
61
  return output;
62
62
  }
63
+
64
+ Object.defineProperty(fn, '__relatedModelName', { value: modelName });
65
+ return fn;
63
66
  }
package/src/has-many.js CHANGED
@@ -16,7 +16,7 @@ export default function hasMany(modelName) {
16
16
  const globalRelationships = relationships.get('global');
17
17
  const pendingRelationships = relationships.get('pending');
18
18
 
19
- return (sourceRecord, rawData, options) => {
19
+ const fn = (sourceRecord, rawData, options) => {
20
20
  const { __name: sourceModelName } = sourceRecord.__model;
21
21
  const relationshipId = sourceRecord.id;
22
22
  const relationship = getRelationships('hasMany', sourceModelName, modelName, relationshipId);
@@ -58,4 +58,7 @@ export default function hasMany(modelName) {
58
58
 
59
59
  return output;
60
60
  }
61
+
62
+ Object.defineProperty(fn, '__relatedModelName', { value: modelName });
63
+ return fn;
61
64
  }
@@ -8,13 +8,18 @@ import { AggregateProperty } from '../aggregates.js';
8
8
  function getRelationshipInfo(property) {
9
9
  if (typeof property !== 'function') return null;
10
10
  const fnStr = property.toString();
11
+ const modelName = property.__relatedModelName || null;
11
12
 
12
- if (fnStr.includes(`getRelationships('belongsTo',`)) return 'belongsTo';
13
- if (fnStr.includes(`getRelationships('hasMany',`)) return 'hasMany';
13
+ if (fnStr.includes(`getRelationships('belongsTo',`)) return { type: 'belongsTo', modelName };
14
+ if (fnStr.includes(`getRelationships('hasMany',`)) return { type: 'hasMany', modelName };
14
15
 
15
16
  return null;
16
17
  }
17
18
 
19
+ function sanitizeTableName(name) {
20
+ return name.replace(/[-/]/g, '_');
21
+ }
22
+
18
23
  export function introspectModels() {
19
24
  const { models } = Orm.instance;
20
25
  const schemas = {};
@@ -35,12 +40,12 @@ export function introspectModels() {
35
40
  for (const [key, property] of Object.entries(model)) {
36
41
  if (key.startsWith('__')) continue;
37
42
 
38
- const relType = getRelationshipInfo(property);
43
+ const relInfo = getRelationshipInfo(property);
39
44
 
40
- if (relType === 'belongsTo') {
41
- relationships.belongsTo[key] = true;
42
- } else if (relType === 'hasMany') {
43
- relationships.hasMany[key] = true;
45
+ if (relInfo?.type === 'belongsTo') {
46
+ relationships.belongsTo[key] = relInfo.modelName;
47
+ } else if (relInfo?.type === 'hasMany') {
48
+ relationships.hasMany[key] = relInfo.modelName;
44
49
  } else if (property?.constructor?.name === 'ModelProperty') {
45
50
  if (key === 'id') {
46
51
  idType = property.type;
@@ -51,17 +56,16 @@ export function introspectModels() {
51
56
  }
52
57
 
53
58
  // Build foreign keys from belongsTo relationships
54
- for (const relName of Object.keys(relationships.belongsTo)) {
55
- const modelName = camelCaseToKebabCase(relName);
59
+ for (const [relName, targetModelName] of Object.entries(relationships.belongsTo)) {
56
60
  const fkColumn = `${relName}_id`;
57
61
  foreignKeys[fkColumn] = {
58
- references: getPluralName(modelName),
62
+ references: sanitizeTableName(getPluralName(targetModelName)),
59
63
  column: 'id',
60
64
  };
61
65
  }
62
66
 
63
67
  schemas[name] = {
64
- table: getPluralName(name),
68
+ table: sanitizeTableName(getPluralName(name)),
65
69
  idType,
66
70
  columns,
67
71
  foreignKeys,
@@ -74,7 +78,8 @@ export function introspectModels() {
74
78
  }
75
79
 
76
80
  export function buildTableDDL(name, schema, allSchemas = {}) {
77
- const { table, idType, columns, foreignKeys } = schema;
81
+ const { idType, columns, foreignKeys } = schema;
82
+ const table = sanitizeTableName(schema.table);
78
83
  const lines = [];
79
84
 
80
85
  // Primary key
@@ -101,7 +106,8 @@ export function buildTableDDL(name, schema, allSchemas = {}) {
101
106
 
102
107
  // Foreign key constraints
103
108
  for (const [fkCol, fkDef] of Object.entries(foreignKeys)) {
104
- lines.push(` FOREIGN KEY (\`${fkCol}\`) REFERENCES \`${fkDef.references}\`(\`${fkDef.column}\`) ON DELETE SET NULL`);
109
+ const refTable = sanitizeTableName(fkDef.references);
110
+ lines.push(` FOREIGN KEY (\`${fkCol}\`) REFERENCES \`${refTable}\`(\`${fkDef.column}\`) ON DELETE SET NULL`);
105
111
  }
106
112
 
107
113
  return `CREATE TABLE IF NOT EXISTS \`${table}\` (\n${lines.join(',\n')}\n)`;
@@ -131,8 +137,8 @@ export function getTopologicalOrder(schemas) {
131
137
  if (!schema) return;
132
138
 
133
139
  // Visit dependencies (belongsTo targets) first
134
- for (const relName of Object.keys(schema.relationships.belongsTo)) {
135
- visit(camelCaseToKebabCase(relName));
140
+ for (const targetModelName of Object.values(schema.relationships.belongsTo)) {
141
+ visit(targetModelName);
136
142
  }
137
143
 
138
144
  order.push(name);
@@ -172,18 +178,17 @@ export function introspectViews() {
172
178
  continue;
173
179
  }
174
180
 
175
- const relType = getRelationshipInfo(property);
181
+ const relInfo = getRelationshipInfo(property);
176
182
 
177
- if (relType === 'belongsTo') {
178
- relationships.belongsTo[key] = true;
179
- const modelName = camelCaseToKebabCase(key);
183
+ if (relInfo?.type === 'belongsTo') {
184
+ relationships.belongsTo[key] = relInfo.modelName;
180
185
  const fkColumn = `${key}_id`;
181
186
  foreignKeys[fkColumn] = {
182
- references: getPluralName(modelName),
187
+ references: sanitizeTableName(getPluralName(relInfo.modelName)),
183
188
  column: 'id',
184
189
  };
185
- } else if (relType === 'hasMany') {
186
- relationships.hasMany[key] = true;
190
+ } else if (relInfo?.type === 'hasMany') {
191
+ relationships.hasMany[key] = relInfo.modelName;
187
192
  } else if (property?.constructor?.name === 'ModelProperty') {
188
193
  const transforms = Orm.instance.transforms;
189
194
  columns[key] = getMysqlType(property.type, transforms[property.type]);
@@ -191,7 +196,7 @@ export function introspectViews() {
191
196
  }
192
197
 
193
198
  schemas[name] = {
194
- viewName: getPluralName(name),
199
+ viewName: sanitizeTableName(getPluralName(name)),
195
200
  source,
196
201
  groupBy: viewClass.groupBy || undefined,
197
202
  columns,
@@ -213,9 +218,9 @@ export function buildViewDDL(name, viewSchema, modelSchemas = {}) {
213
218
 
214
219
  const sourceModelName = viewSchema.source;
215
220
  const sourceSchema = modelSchemas[sourceModelName];
216
- const sourceTable = sourceSchema
221
+ const sourceTable = sanitizeTableName(sourceSchema
217
222
  ? sourceSchema.table
218
- : getPluralName(sourceModelName);
223
+ : getPluralName(sourceModelName));
219
224
 
220
225
  const selectColumns = [];
221
226
  const joins = [];
@@ -241,8 +246,7 @@ export function buildViewDDL(name, viewSchema, modelSchemas = {}) {
241
246
  } else {
242
247
  // Relationship aggregate
243
248
  const relName = aggProp.relationship;
244
- const relModelName = camelCaseToKebabCase(relName);
245
- const relTable = getPluralName(relModelName);
249
+ const relTable = sanitizeTableName(getPluralName(relName));
246
250
 
247
251
  if (aggProp.aggregateType === 'count') {
248
252
  selectColumns.push(`${aggProp.mysqlFunction}(\`${relTable}\`.\`id\`) AS \`${key}\``);
@@ -281,7 +285,7 @@ export function buildViewDDL(name, viewSchema, modelSchemas = {}) {
281
285
  groupBy = `\nGROUP BY \`${sourceTable}\`.\`id\``;
282
286
  }
283
287
 
284
- const viewName = viewSchema.viewName;
288
+ const viewName = sanitizeTableName(viewSchema.viewName);
285
289
  const sql = `CREATE OR REPLACE VIEW \`${viewName}\` AS\nSELECT\n ${selectColumns.join(',\n ')}\nFROM \`${sourceTable}\`${joinClauses ? '\n ' + joinClauses : ''}${groupBy}`;
286
290
 
287
291
  return sql;