({
model,
relation,
services,
options,
selfRelation,
similarRelations,
}: {
model: Model;
relation: Relation;
services: ZModelServices;
options: PullOptions;
//self included
similarRelations: number;
selfRelation: boolean;
})
| 386 | } |
| 387 | |
| 388 | export function syncRelation({ |
| 389 | model, |
| 390 | relation, |
| 391 | services, |
| 392 | options, |
| 393 | selfRelation, |
| 394 | similarRelations, |
| 395 | }: { |
| 396 | model: Model; |
| 397 | relation: Relation; |
| 398 | services: ZModelServices; |
| 399 | options: PullOptions; |
| 400 | //self included |
| 401 | similarRelations: number; |
| 402 | selfRelation: boolean; |
| 403 | }) { |
| 404 | const idAttribute = getAttributeRef('@id', services); |
| 405 | const uniqueAttribute = getAttributeRef('@unique', services); |
| 406 | const relationAttribute = getAttributeRef('@relation', services); |
| 407 | const fieldMapAttribute = getAttributeRef('@map', services); |
| 408 | const tableMapAttribute = getAttributeRef('@@map', services); |
| 409 | |
| 410 | const includeRelationName = selfRelation || similarRelations > 0; |
| 411 | |
| 412 | if (!idAttribute || !uniqueAttribute || !relationAttribute || !fieldMapAttribute || !tableMapAttribute) { |
| 413 | throw new CliError('Cannot find required attributes in the model.'); |
| 414 | } |
| 415 | |
| 416 | const sourceModel = model.declarations.find((d) => d.$type === 'DataModel' && getDbName(d) === relation.table) as |
| 417 | | DataModel |
| 418 | | undefined; |
| 419 | if (!sourceModel) return; |
| 420 | |
| 421 | // Resolve all source and target fields for the relation (supports composite FKs) |
| 422 | const sourceFields: { field: DataField; index: number }[] = []; |
| 423 | for (const colName of relation.columns) { |
| 424 | const idx = sourceModel.fields.findIndex((f) => getDbName(f) === colName); |
| 425 | const field = sourceModel.fields[idx] as DataField | undefined; |
| 426 | if (!field) return; |
| 427 | sourceFields.push({ field, index: idx }); |
| 428 | } |
| 429 | |
| 430 | const targetModel = model.declarations.find( |
| 431 | (d) => d.$type === 'DataModel' && getDbName(d) === relation.references.table, |
| 432 | ) as DataModel | undefined; |
| 433 | if (!targetModel) return; |
| 434 | |
| 435 | const targetFields: DataField[] = []; |
| 436 | for (const colName of relation.references.columns) { |
| 437 | const field = targetModel.fields.find((f) => getDbName(f) === colName); |
| 438 | if (!field) return; |
| 439 | targetFields.push(field); |
| 440 | } |
| 441 | |
| 442 | // Use the first source field for naming heuristics |
| 443 | const firstSourceField = sourceFields[0]!.field; |
| 444 | const firstSourceFieldId = sourceFields[0]!.index; |
| 445 | const firstColumn = relation.columns[0]!; |
no test coverage detected