@prisma/orm-family-sql 8.0.0-rc.17-dev.17 → 8.0.0-rc.17-dev.18

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.
@@ -36,10 +36,18 @@ function andList(items) {
36
36
  function fieldList(modelName, fieldNames) {
37
37
  return andList(fieldNames.map((name) => `"${modelName}.${name}"`));
38
38
  }
39
- function ignoredFieldReferenced(input) {
39
+ /** An `@ignore` field in the model's primary key: without it the model has no field that identifies a row. */
40
+ function ignoredFieldInPrimaryKey(input) {
40
41
  const fields = fieldList(input.modelName, input.fieldNames);
41
42
  const one = input.fieldNames.length === 1;
42
- return prisma7Diagnostic("PSL.PRISMA7_IGNORED_FIELD_REFERENCED", `${one ? "Field" : "Fields"} ${fields} ${one ? "is" : "are"} marked @ignore, but ${input.usedBy} uses ${one ? "it" : "them"}, and Prisma 7 still creates the ${input.constraint} that includes ${one ? "its column" : "their columns"}. Remove @ignore from ${fields}; Prisma 7's next migration is then empty, and ${one ? "the field appears" : "the fields appear"} in the Prisma 7 client again.`, input.sourceId, input.span);
43
+ return prisma7Diagnostic("PSL.PRISMA7_IGNORED_FIELD_REFERENCED", `${one ? "Field" : "Fields"} ${fields} ${one ? "is" : "are"} marked @ignore, but ${input.usedBy} uses ${one ? "it" : "them"}, and without ${one ? "it" : "them"} model "${input.modelName}" has no field that identifies a row, so Prisma 8 could not update, delete or relate its rows. Remove @ignore from ${fields}: Prisma 7's next migration is then empty, and ${one ? "the field appears" : "the fields appear"} in the Prisma 7 client again. Or replace ${one ? "it" : "them"} with @@ignore on model "${input.modelName}": Prisma 7 then requires @ignore on every relation field that points to the model, its next migration is empty, Prisma 8 keeps the model's table with its primary key, and the model disappears from both clients.`, input.sourceId, input.span);
44
+ }
45
+ /** A relation that is not `@ignore` joins on `@ignore` fields: Prisma 8 relations join on fields, and the domain has no ignored field. */
46
+ function ignoredFieldJoined(input) {
47
+ const fields = fieldList(input.modelName, input.fieldNames);
48
+ const one = input.fieldNames.length === 1;
49
+ const relation = `relation field "${input.relationField}"`;
50
+ return prisma7Diagnostic("PSL.PRISMA7_IGNORED_FIELD_REFERENCED", `${one ? "Field" : "Fields"} ${fields} ${one ? "is" : "are"} marked @ignore, but ${relation} joins on ${one ? "it" : "them"}, and Prisma 8 relations join on fields. Remove @ignore from ${fields}: Prisma 7's next migration is then empty, and ${one ? "the field appears" : "the fields appear"} in the Prisma 7 client again. Or mark ${relation} @ignore as well: Prisma 7's next migration is then empty, the relation field disappears from the Prisma 7 client, and Prisma 8 keeps its foreign key while leaving the relation out of the contract's models.`, input.sourceId, input.span);
43
51
  }
44
52
  function parseIndexAttribute(attribute, owner, sourceId, indexTypes, diagnostics) {
45
53
  const unsupported = (what, span) => {
@@ -528,10 +536,25 @@ function parseRelationAttribute(attribute, label, sourceId, diagnostics) {
528
536
  span: attribute.span
529
537
  };
530
538
  }
539
+ function storageColumn(model, fieldName) {
540
+ return model.columns.get(fieldName) ?? model.ignoredColumns.get(fieldName);
541
+ }
542
+ /** A foreign key reaches a table with a model through the model, and an `@@ignore` model's table by its name. */
543
+ function referenceTo(model, columns) {
544
+ const table = {
545
+ table: model.tableName,
546
+ columns,
547
+ namespaceId: model.namespaceId
548
+ };
549
+ return model.ignored ? table : {
550
+ model: model.modelName,
551
+ ...table
552
+ };
553
+ }
531
554
  function columnNames(model, fieldNames) {
532
555
  const columns = [];
533
556
  for (const fieldName of fieldNames) {
534
- const column = model.columns.get(fieldName);
557
+ const column = storageColumn(model, fieldName);
535
558
  if (column === void 0) return void 0;
536
559
  columns.push(column.columnName);
537
560
  }
@@ -575,7 +598,7 @@ function referentialActionRejections(input) {
575
598
  const { model, relationField, label, fieldNames, span } = input;
576
599
  const anotherAction = "choose another action, which replaces the foreign key on Prisma 7's next migration and leaves the Prisma 7 client unchanged.";
577
600
  const fieldsWhere = (predicate) => fieldNames.filter((name) => {
578
- const column = model.columns.get(name);
601
+ const column = storageColumn(model, name);
579
602
  return column !== void 0 && predicate(column);
580
603
  });
581
604
  const rejections = [];
@@ -614,6 +637,7 @@ function lowerRelations(models, naming, diagnostics) {
614
637
  const invalidFkPairings = [];
615
638
  const foreignKeys = /* @__PURE__ */ new Map();
616
639
  const junctions = /* @__PURE__ */ new Map();
640
+ const ignoredJunctions = /* @__PURE__ */ new Map();
617
641
  const reportedJunctionNames = /* @__PURE__ */ new Set();
618
642
  const junctionRequests = [];
619
643
  const addForeignKey = (modelName, node) => {
@@ -630,7 +654,7 @@ function lowerRelations(models, naming, diagnostics) {
630
654
  relationName: effectiveRelationName(relationField.attribute, model.modelName, relationField.targetModelName)
631
655
  });
632
656
  };
633
- for (const model of models.values()) for (const relationField of model.relationFields) {
657
+ for (const model of models.values()) for (const relationField of [...model.relationFields, ...model.ignoredRelationFields]) {
634
658
  const { field, targetModelName } = relationField;
635
659
  const label = `Relation field "${model.modelName}.${field.name}"`;
636
660
  const target = models.get(targetModelName);
@@ -638,23 +662,32 @@ function lowerRelations(models, naming, diagnostics) {
638
662
  if (isFkSide(relationField)) {
639
663
  const attribute = relationField.attribute;
640
664
  if (attribute === void 0 || attribute.fields === void 0) continue;
641
- const ignoredScalars = attribute.fields.filter((name) => model.ignoredFields.has(name));
642
- if (ignoredScalars.length > 0) {
643
- rejectFkSide(model, relationField, ignoredFieldReferenced({
644
- modelName: model.modelName,
645
- fieldNames: ignoredScalars,
646
- usedBy: `relation field "${model.modelName}.${field.name}"`,
647
- constraint: "foreign key",
665
+ const ignoredRelation = model.ignoredRelationFields.includes(relationField);
666
+ const joinedIgnored = ignoredRelation ? [] : [{
667
+ owner: model,
668
+ names: attribute.fields
669
+ }, {
670
+ owner: target,
671
+ names: attribute.references ?? []
672
+ }].flatMap(({ owner, names }) => {
673
+ const ignored = names.filter((name) => owner.ignoredFields.has(name));
674
+ return ignored.length === 0 ? [] : [ignoredFieldJoined({
675
+ modelName: owner.modelName,
676
+ fieldNames: ignored,
677
+ relationField: `${model.modelName}.${field.name}`,
648
678
  sourceId: model.sourceId,
649
679
  span: attribute.span
650
- }));
680
+ })];
681
+ });
682
+ if (joinedIgnored.length > 0) {
683
+ rejectFkSide(model, relationField, ...joinedIgnored);
651
684
  continue;
652
685
  }
653
686
  if (attribute.references === void 0) {
654
687
  rejectFkSide(model, relationField, unresolved(label, "declares fields without references.", model.sourceId, attribute.span));
655
688
  continue;
656
689
  }
657
- if (attribute.fields.some((name) => model.rejectedFields.has(name)) || attribute.references.some((name) => target.ignoredFields.has(name) || target.rejectedFields.has(name))) {
690
+ if (attribute.fields.some((name) => model.rejectedFields.has(name)) || attribute.references.some((name) => target.rejectedFields.has(name))) {
658
691
  rejectFkSide(model, relationField);
659
692
  continue;
660
693
  }
@@ -668,7 +701,7 @@ function lowerRelations(models, naming, diagnostics) {
668
701
  rejectFkSide(model, relationField, unresolved(label, "must list as many fields as references.", model.sourceId, attribute.span));
669
702
  continue;
670
703
  }
671
- const nullability = attribute.fields.map((name) => model.columns.get(name)?.nullable === true);
704
+ const nullability = attribute.fields.map((name) => storageColumn(model, name)?.nullable === true);
672
705
  const anyNullable = nullability.includes(true);
673
706
  if (anyNullable && !field.optional) {
674
707
  rejectFkSide(model, relationField, unresolved(label, "must be optional because one of its fields is optional.", model.sourceId, field.span));
@@ -695,16 +728,12 @@ function lowerRelations(models, naming, diagnostics) {
695
728
  addForeignKey(model.modelName, {
696
729
  ...ifDefined("name", foreignKeyName),
697
730
  columns: localColumns,
698
- references: {
699
- model: target.modelName,
700
- table: target.tableName,
701
- columns: referencedColumns,
702
- namespaceId: target.namespaceId
703
- },
731
+ references: referenceTo(target, referencedColumns),
704
732
  onDelete,
705
733
  onUpdate,
706
734
  index: false
707
735
  });
736
+ if (ignoredRelation) continue;
708
737
  fkRelationMetadata.push({
709
738
  declaringModelName: model.modelName,
710
739
  declaringFieldName: field.name,
@@ -720,8 +749,10 @@ function lowerRelations(models, naming, diagnostics) {
720
749
  });
721
750
  continue;
722
751
  }
723
- if (target.ignoredRelationFields.some((other) => other.targetModelName === model.modelName && sameName(other, relationField))) continue;
724
- if (target.relationFields.filter((other) => other.targetModelName === model.modelName && isFkSide(other) && sameName(other, relationField)).length > 0 || !field.list) {
752
+ const ignoredPair = model.ignoredRelationFields.includes(relationField) || target.ignoredRelationFields.some((other) => other.targetModelName === model.modelName && sameName(other, relationField));
753
+ const targetRelationFields = [...target.relationFields, ...target.ignoredRelationFields];
754
+ if (targetRelationFields.filter((other) => other.targetModelName === model.modelName && isFkSide(other) && sameName(other, relationField)).length > 0 || !field.list) {
755
+ if (ignoredPair) continue;
725
756
  candidates.push({
726
757
  modelName: model.modelName,
727
758
  tableName: model.tableName,
@@ -732,7 +763,7 @@ function lowerRelations(models, naming, diagnostics) {
732
763
  });
733
764
  continue;
734
765
  }
735
- const partners = target.relationFields.filter((other) => other !== relationField && other.targetModelName === model.modelName && other.field.list && !isFkSide(other) && sameName(other, relationField));
766
+ const partners = targetRelationFields.filter((other) => other !== relationField && other.targetModelName === model.modelName && other.field.list && !isFkSide(other) && sameName(other, relationField));
736
767
  const [partner] = partners;
737
768
  if (partner === void 0) {
738
769
  diagnostics.push(unresolved(label, `has no matching relation field on "${target.modelName}".`, model.sourceId, field.span));
@@ -764,7 +795,8 @@ function lowerRelations(models, naming, diagnostics) {
764
795
  junctionRequests.push({
765
796
  requester,
766
797
  partner: partnerSide,
767
- name: junctionName
798
+ name: junctionName,
799
+ ignored: ignoredPair
768
800
  });
769
801
  }
770
802
  const requestsByJunction = groupBy(junctionRequests, (request) => junctionKey(orderJunctionSides(request.requester, request.partner)[0].model.namespaceId, request.name));
@@ -795,11 +827,15 @@ function lowerRelations(models, naming, diagnostics) {
795
827
  diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_TABLE_COLLISION", message, tableOwner.sourceId, tableOwner.tableSpan), prisma7Diagnostic("PSL.PRISMA7_TABLE_COLLISION", message, first.requester.model.sourceId, first.requester.field.field.span));
796
828
  continue;
797
829
  }
798
- for (const { requester, partner } of requests) {
830
+ for (const { requester, partner, ignored } of requests) {
799
831
  const junction = synthesizeJunction(requester, partner, naming, diagnostics);
800
832
  if (junction === void 0) continue;
833
+ if (ignored) {
834
+ ignoredJunctions.set(junction.key, junction.table);
835
+ continue;
836
+ }
801
837
  if (!junctions.has(junction.key)) {
802
- junctions.set(junction.key, junction.node);
838
+ junctions.set(junction.key, junctionModel(junction.name, junction.table));
803
839
  fkRelationMetadata.push(...junction.foreignKeys);
804
840
  }
805
841
  candidates.push({
@@ -863,10 +899,23 @@ function lowerRelations(models, naming, diagnostics) {
863
899
  for (const [modelName, nodes] of modelRelations) relations.set(modelName, [...nodes].sort((left, right) => left.fieldName.localeCompare(right.fieldName)));
864
900
  return {
865
901
  junctions,
902
+ ignoredJunctions,
866
903
  foreignKeys,
867
904
  relations
868
905
  };
869
906
  }
907
+ /** The junction model over a junction table: a field for each of its columns. */
908
+ function junctionModel(name, table) {
909
+ const { columns, ...properties } = table;
910
+ return {
911
+ ...properties,
912
+ modelName: name,
913
+ fields: columns.map((column) => ({
914
+ fieldName: column.columnName,
915
+ ...column
916
+ }))
917
+ };
918
+ }
870
919
  /**
871
920
  * The id column a junction side contributes. The diagnostic names the
872
921
  * requesting relation field, so it is located at that field, whichever side's
@@ -875,7 +924,7 @@ function lowerRelations(models, naming, diagnostics) {
875
924
  function singleIdColumn(side, requester, diagnostics) {
876
925
  if (side.model.idFields.some((name) => side.model.ignoredFields.has(name) || side.model.rejectedFields.has(name))) return;
877
926
  const [idField, ...rest] = side.model.idFields;
878
- const column = idField === void 0 ? void 0 : side.model.columns.get(idField);
927
+ const column = idField === void 0 ? void 0 : storageColumn(side.model, idField);
879
928
  if (column === void 0 || rest.length > 0) {
880
929
  diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_JUNCTION_ID_UNSUPPORTED", `Relation field "${requester.model.modelName}.${requester.field.field.name}" is an implicit many-to-many relation, but "${side.model.modelName}" ${column === void 0 ? "has no single-field @id" : "has a composite id"}; Prisma 7 requires a single-field @id on both models of an implicit many-to-many relation.`, requester.model.sourceId, requester.field.field.span));
881
930
  return;
@@ -908,12 +957,7 @@ function synthesizeJunction(requester, partner, naming, diagnostics) {
908
957
  const foreignKey = (column, side, id) => ({
909
958
  ...ifDefined("name", foreignKeyName(column)),
910
959
  columns: [column],
911
- references: {
912
- model: side.model.modelName,
913
- table: side.model.tableName,
914
- columns: [id.columnName],
915
- namespaceId: side.model.namespaceId
916
- },
960
+ references: referenceTo(side.model, [id.columnName]),
917
961
  onDelete: "cascade",
918
962
  onUpdate: "cascade",
919
963
  index: false
@@ -942,18 +986,16 @@ function synthesizeJunction(requester, partner, naming, diagnostics) {
942
986
  };
943
987
  return {
944
988
  key,
945
- node: {
946
- modelName: name,
989
+ name,
990
+ table: {
947
991
  tableName,
948
992
  namespaceId,
949
- fields: [{
950
- fieldName: "A",
993
+ columns: [{
951
994
  columnName: "A",
952
995
  descriptor: idA.descriptor,
953
996
  nullable: false,
954
997
  many: false
955
998
  }, {
956
- fieldName: "B",
957
999
  columnName: "B",
958
1000
  descriptor: idB.descriptor,
959
1001
  nullable: false,
@@ -1029,7 +1071,6 @@ function interpretPrisma7Documents(input) {
1029
1071
  const datasources = [];
1030
1072
  const enumBlocks = [];
1031
1073
  const models = [];
1032
- const ignoredModels = /* @__PURE__ */ new Set();
1033
1074
  const declaredNames = /* @__PURE__ */ new Map();
1034
1075
  const claimName = (kind, name, sourceId, span) => {
1035
1076
  const previous = declaredNames.get(name);
@@ -1095,9 +1136,7 @@ function interpretPrisma7Documents(input) {
1095
1136
  for (const namedType of Object.values(symbolTable.topLevel.namedTypes)) unsupported("types", namedType.span);
1096
1137
  for (const symbol of Object.values(symbolTable.topLevel.models)) {
1097
1138
  if (!claimName("model", symbol.name, sourceId, symbol.span)) continue;
1098
- const declaration = readModelDeclaration(symbol, sourceId, sources, defaultNamespaceId, binding, diagnostics);
1099
- if (declaration === void 0) ignoredModels.add(symbol.name);
1100
- else models.push(declaration);
1139
+ models.push(readModelDeclaration(symbol, sourceId, sources, defaultNamespaceId, binding, diagnostics));
1101
1140
  }
1102
1141
  }
1103
1142
  checkDatasource(datasources, input.documents[0]?.sourceId ?? "schema.prisma", binding, diagnostics);
@@ -1108,13 +1147,15 @@ function interpretPrisma7Documents(input) {
1108
1147
  if (declaration !== void 0) enums.set(declaration.name, declaration);
1109
1148
  }
1110
1149
  const namespaceEntities = lowerNativeEnums(enums, input, diagnostics);
1111
- const modelNames = /* @__PURE__ */ new Set([...models.map((model) => model.symbol.name), ...ignoredModels]);
1150
+ const modelNames = new Set(models.map((model) => model.symbol.name));
1151
+ const ignoredModels = new Set(models.filter((model) => model.ignored).map((model) => model.symbol.name));
1112
1152
  const composedExtensions = new Set(input.composedExtensions);
1113
1153
  const builds = /* @__PURE__ */ new Map();
1114
1154
  for (const declaration of models) {
1115
1155
  const build = {
1116
1156
  declaration,
1117
1157
  columns: /* @__PURE__ */ new Map(),
1158
+ ignoredColumns: /* @__PURE__ */ new Map(),
1118
1159
  ignoredFields: /* @__PURE__ */ new Set(),
1119
1160
  ignoredRelationFields: [],
1120
1161
  rejectedFields: /* @__PURE__ */ new Set(),
@@ -1136,7 +1177,7 @@ function interpretPrisma7Documents(input) {
1136
1177
  input,
1137
1178
  diagnostics
1138
1179
  });
1139
- if (diagnostics.length > reported && !build.columns.has(field.name) && !build.ignoredFields.has(field.name)) build.rejectedFields.add(field.name);
1180
+ if (diagnostics.length > reported && !build.columns.has(field.name) && !build.ignoredColumns.has(field.name)) build.rejectedFields.add(field.name);
1140
1181
  }
1141
1182
  builds.set(declaration.symbol.name, build);
1142
1183
  }
@@ -1144,11 +1185,13 @@ function interpretPrisma7Documents(input) {
1144
1185
  for (const [modelName, build] of builds) relationModels.set(modelName, {
1145
1186
  modelName,
1146
1187
  tableName: build.declaration.tableName,
1188
+ ignored: build.declaration.ignored,
1147
1189
  tableSpan: build.declaration.symbol.attributes.find((attribute) => attribute.name === "map")?.span ?? build.declaration.symbol.span,
1148
1190
  namespaceId: build.declaration.namespaceId,
1149
1191
  sourceId: build.declaration.sourceId,
1150
1192
  sources: build.declaration.sources,
1151
1193
  columns: build.columns,
1194
+ ignoredColumns: build.ignoredColumns,
1152
1195
  ignoredFields: build.ignoredFields,
1153
1196
  ignoredRelationFields: build.ignoredRelationFields,
1154
1197
  rejectedFields: build.rejectedFields,
@@ -1158,17 +1201,17 @@ function interpretPrisma7Documents(input) {
1158
1201
  });
1159
1202
  const lowered = lowerRelations(relationModels, binding, diagnostics);
1160
1203
  const modelNodes = [];
1204
+ const tables = [];
1161
1205
  for (const [modelName, build] of builds) {
1162
1206
  const model = relationModels.get(modelName);
1163
1207
  if (model === void 0) continue;
1164
1208
  const ignoredAmong = (fieldNames) => fieldNames?.filter((name) => build.ignoredFields.has(name)) ?? [];
1165
1209
  const idAttribute = build.declaration.id;
1166
1210
  const ignoredIdFields = ignoredAmong(idAttribute?.fields);
1167
- if (idAttribute !== void 0 && ignoredIdFields.length > 0) diagnostics.push(ignoredFieldReferenced({
1211
+ if (idAttribute !== void 0 && ignoredIdFields.length > 0) diagnostics.push(ignoredFieldInPrimaryKey({
1168
1212
  modelName,
1169
1213
  fieldNames: ignoredIdFields,
1170
1214
  usedBy: `@@id on model "${modelName}"`,
1171
- constraint: "primary key",
1172
1215
  sourceId: model.sourceId,
1173
1216
  span: idAttribute.span
1174
1217
  }));
@@ -1180,18 +1223,6 @@ function interpretPrisma7Documents(input) {
1180
1223
  attribute,
1181
1224
  unique: false
1182
1225
  }))].flatMap(({ attribute, unique }) => {
1183
- const ignoredIndexFields = ignoredAmong(attribute.fields);
1184
- if (ignoredIndexFields.length > 0) {
1185
- diagnostics.push(ignoredFieldReferenced({
1186
- modelName,
1187
- fieldNames: ignoredIndexFields,
1188
- usedBy: `${unique ? "@@unique" : "@@index"} on model "${modelName}"`,
1189
- constraint: unique ? "unique index" : "index",
1190
- sourceId: model.sourceId,
1191
- span: attribute.span
1192
- }));
1193
- return [];
1194
- }
1195
1226
  if (attribute.fields?.some((name) => build.rejectedFields.has(name))) return [];
1196
1227
  const columns = attribute.fields === void 0 ? void 0 : keyColumns(model, attribute.fields);
1197
1228
  if (columns === void 0) {
@@ -1203,20 +1234,38 @@ function interpretPrisma7Documents(input) {
1203
1234
  const foreignKeys = lowered.foreignKeys.get(modelName);
1204
1235
  const relations = lowered.relations.get(modelName);
1205
1236
  const primaryKeyName = statedConstraintName(prisma7PrimaryKeyName(model.tableName, build.idMap, binding.identifierMaxBytes), binding.defaultConstraintNames.primaryKey(model.tableName));
1206
- modelNodes.push(stateServedBackingIndexes({
1207
- modelName,
1237
+ const tableProperties = stateServedBackingIndexes({
1208
1238
  tableName: model.tableName,
1209
- namespaceId: model.namespaceId,
1210
- fields: [...build.columns.values()],
1211
1239
  ...id !== void 0 && id.length > 0 ? { id: {
1212
1240
  columns: id,
1213
1241
  ...ifDefined("name", primaryKeyName)
1214
1242
  } } : {},
1215
1243
  ...indexes.length > 0 ? { indexes } : {},
1216
- ...foreignKeys !== void 0 ? { foreignKeys } : {},
1244
+ ...foreignKeys !== void 0 ? { foreignKeys } : {}
1245
+ });
1246
+ const ignoredColumns = [...build.ignoredColumns.values()];
1247
+ if (model.ignored) {
1248
+ tables.push({
1249
+ ...tableProperties,
1250
+ namespaceId: model.namespaceId,
1251
+ columns: ignoredColumns
1252
+ });
1253
+ continue;
1254
+ }
1255
+ modelNodes.push({
1256
+ ...tableProperties,
1257
+ modelName,
1258
+ namespaceId: model.namespaceId,
1259
+ fields: [...build.columns.values()],
1217
1260
  ...relations !== void 0 ? { relations } : {}
1218
- }));
1261
+ });
1262
+ if (ignoredColumns.length > 0) tables.push({
1263
+ namespaceId: model.namespaceId,
1264
+ tableName: model.tableName,
1265
+ columns: ignoredColumns
1266
+ });
1219
1267
  }
1268
+ tables.push(...[...lowered.ignoredJunctions.values()].map(stateServedBackingIndexes));
1220
1269
  for (const [key, junction] of lowered.junctions) {
1221
1270
  const relations = lowered.relations.get(key);
1222
1271
  modelNodes.push(stateServedBackingIndexes(relations === void 0 ? junction : {
@@ -1249,7 +1298,8 @@ function interpretPrisma7Documents(input) {
1249
1298
  warnings: void 0,
1250
1299
  createNamespace,
1251
1300
  ...namespaceEntities.size > 0 ? { namespaces: [...namespaceEntities.keys()] } : {},
1252
- models: modelNodes
1301
+ models: modelNodes,
1302
+ ...tables.length > 0 ? { tables } : {}
1253
1303
  }, input.codecLookup, input.dataTypes.lookup));
1254
1304
  }
1255
1305
  /**
@@ -1316,7 +1366,7 @@ function reportTableCollisions(models, diagnostics) {
1316
1366
  function keyColumns(model, fieldNames) {
1317
1367
  const columns = [];
1318
1368
  for (const fieldName of fieldNames) {
1319
- const column = model.columns.get(fieldName);
1369
+ const column = model.columns.get(fieldName) ?? model.ignoredColumns.get(fieldName);
1320
1370
  if (column === void 0) return void 0;
1321
1371
  columns.push(column.columnName);
1322
1372
  }
@@ -1324,7 +1374,7 @@ function keyColumns(model, fieldNames) {
1324
1374
  }
1325
1375
  function readModelDeclaration(symbol, sourceId, sources, defaultNamespaceId, binding, diagnostics) {
1326
1376
  const { indexTypes } = binding;
1327
- if (symbol.attributes.some((attribute) => attribute.name === "ignore")) return void 0;
1377
+ let ignored = false;
1328
1378
  let tableName = symbol.name;
1329
1379
  let namespaceId = defaultNamespaceId;
1330
1380
  let id;
@@ -1364,6 +1414,9 @@ function readModelDeclaration(symbol, sourceId, sources, defaultNamespaceId, bin
1364
1414
  if (parsed?.fields !== void 0) indexes.push(parsed);
1365
1415
  break;
1366
1416
  }
1417
+ case "ignore":
1418
+ ignored = true;
1419
+ break;
1367
1420
  default: diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_ATTRIBUTE", `Model "${symbol.name}": attribute "@@${attribute.name}" is not supported yet by the Prisma 7 contract source.`, sourceId, attribute.span));
1368
1421
  }
1369
1422
  }
@@ -1373,6 +1426,7 @@ function readModelDeclaration(symbol, sourceId, sources, defaultNamespaceId, bin
1373
1426
  sources,
1374
1427
  namespaceId,
1375
1428
  tableName,
1429
+ ignored,
1376
1430
  id,
1377
1431
  uniqueIndexes,
1378
1432
  indexes
@@ -1492,75 +1546,8 @@ function lowerNativeEnums(enums, input, diagnostics) {
1492
1546
  }
1493
1547
  return result;
1494
1548
  }
1495
- function keysUsingField(field, model) {
1496
- const modelName = model.symbol.name;
1497
- const uses = [];
1498
- for (const attribute of field.attributes) {
1499
- if (attribute.name === "id") uses.push({
1500
- usedBy: "its @id",
1501
- constraint: "primary key"
1502
- });
1503
- if (attribute.name === "unique") uses.push({
1504
- usedBy: "its @unique",
1505
- constraint: "unique index"
1506
- });
1507
- }
1508
- if (model.id?.fields?.includes(field.name)) uses.push({
1509
- usedBy: `@@id on model "${modelName}"`,
1510
- constraint: "primary key"
1511
- });
1512
- for (const unique of model.uniqueIndexes) if (unique.fields?.includes(field.name)) uses.push({
1513
- usedBy: `@@unique on model "${modelName}"`,
1514
- constraint: "unique index"
1515
- });
1516
- for (const index of model.indexes) if (index.fields?.includes(field.name)) uses.push({
1517
- usedBy: `@@index on model "${modelName}"`,
1518
- constraint: "index"
1519
- });
1520
- for (const other of Object.values(model.symbol.fields)) {
1521
- if (other.attributes.some((attribute) => attribute.name === "ignore")) continue;
1522
- const relation = other.attributes.find((attribute) => attribute.name === "relation");
1523
- if ((relation === void 0 ? void 0 : parseRelationAttribute(relation, other.name, model.sourceId, []))?.fields?.includes(field.name)) uses.push({
1524
- usedBy: `relation field "${modelName}.${other.name}"`,
1525
- constraint: "foreign key"
1526
- });
1527
- }
1528
- return uses;
1529
- }
1530
- function nativeTypeMessage(input) {
1531
- const { label, nativeType, field, model } = input;
1532
- const uses = keysUsingField(field, model);
1533
- if (uses.length > 0) {
1534
- const constraints = [...new Set(uses.map((use) => `the ${use.constraint}`))];
1535
- return `${label}: native type "@db.${nativeType}" has no Prisma 8 codec, and ${andList(uses.map((use) => use.usedBy))} ${uses.length === 1 ? "uses" : "use"} the field, so @ignore on the field does not help: Prisma 7 still creates ${andList(constraints)} over the column. Add @@ignore to model "${model.symbol.name}" to keep the model out of the contract: Prisma 7's next migration is empty, but the model disappears from the Prisma 7 client too, and every relation field in another model that points to it needs @ignore, which removes that field from the Prisma 7 client as well. Changing the field's type instead changes the column type on Prisma 7's next migration.`;
1536
- }
1537
- return `${label}: native type "@db.${nativeType}" has no Prisma 8 codec. Add @ignore to the field to keep its column out of the contract: Prisma 7's next migration is empty, and the field disappears from the Prisma 7 client too${!field.optional && !field.list && !givesColumnDefault(input.defaultAttribute) ? "; because the field is required and its column has no default, neither client can then insert rows" : ""}. Changing the field's type instead changes the column type on Prisma 7's next migration.`;
1538
- }
1539
- function readIgnoredField(field, isRelationField, args) {
1540
- const { build, diagnostics } = args;
1541
- const model = build.declaration;
1542
- if (isRelationField) {
1543
- if (args.ignoredModels.has(field.typeName)) return;
1544
- const relation = field.attributes.find((attribute) => attribute.name === "relation");
1545
- build.ignoredRelationFields.push({
1546
- field,
1547
- targetModelName: field.typeName,
1548
- attribute: relation === void 0 ? void 0 : parseRelationAttribute(relation, field.name, model.sourceId, [])
1549
- });
1550
- return;
1551
- }
1552
- for (const attribute of field.attributes) {
1553
- if (attribute.name !== "id" && attribute.name !== "unique") continue;
1554
- if (attribute.name === "id") build.idFields = [field.name];
1555
- diagnostics.push(ignoredFieldReferenced({
1556
- modelName: model.symbol.name,
1557
- fieldNames: [field.name],
1558
- usedBy: `its @${attribute.name}`,
1559
- constraint: attribute.name === "id" ? "primary key" : "unique index",
1560
- sourceId: model.sourceId,
1561
- span: attribute.span
1562
- }));
1563
- }
1549
+ function nativeTypeMessage(label, nativeType) {
1550
+ return `${label}: native type "@db.${nativeType}" has no Prisma 8 codec yet, and Prisma 8 cannot read this schema until it supports the column type. @ignore on the field or @@ignore on the model does not help: Prisma 8 keeps the columns of ignored fields and models in the contract. Changing the field's type to one Prisma 8 supports changes the column type on Prisma 7's next migration.`;
1564
1551
  }
1565
1552
  function readField(args) {
1566
1553
  const { field, build, diagnostics, input } = args;
@@ -1569,11 +1556,9 @@ function readField(args) {
1569
1556
  const sourceId = model.sourceId;
1570
1557
  const label = `Field "${model.symbol.name}.${field.name}"`;
1571
1558
  const isRelationField = args.modelNames.has(field.typeName) && field.typeConstructor === void 0;
1572
- if (field.attributes.some((attribute) => attribute.name === "ignore")) {
1573
- build.ignoredFields.add(field.name);
1574
- readIgnoredField(field, isRelationField, args);
1575
- return;
1576
- }
1559
+ const fieldIgnored = field.attributes.some((attribute) => attribute.name === "ignore") || isRelationField && args.ignoredModels.has(field.typeName);
1560
+ if (fieldIgnored) build.ignoredFields.add(field.name);
1561
+ const ignored = fieldIgnored || model.ignored;
1577
1562
  let columnName = field.name;
1578
1563
  let nativeType;
1579
1564
  let relation;
@@ -1598,6 +1583,13 @@ function readField(args) {
1598
1583
  build.idFields = [field.name];
1599
1584
  build.idMap = parsed.map;
1600
1585
  }
1586
+ if (fieldIgnored) diagnostics.push(ignoredFieldInPrimaryKey({
1587
+ modelName: model.symbol.name,
1588
+ fieldNames: [field.name],
1589
+ usedBy: "its @id",
1590
+ sourceId,
1591
+ span: attribute.span
1592
+ }));
1601
1593
  } else if (attribute.name === "unique" && !isRelationField) {
1602
1594
  const parsed = parseIndexAttribute(attribute, label, sourceId, binding.indexTypes, diagnostics);
1603
1595
  if (parsed !== void 0) build.uniqueIndexes.push({
@@ -1607,18 +1599,17 @@ function readField(args) {
1607
1599
  } else if (attribute.name === "default" && !isRelationField) defaultAttribute = attribute;
1608
1600
  else if (attribute.name === "updatedAt" && !isRelationField) updatedAt = attribute;
1609
1601
  else if (attribute.name === "relation" && isRelationField) relation = attribute;
1610
- else diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_ATTRIBUTE", `${label}: attribute "@${attribute.name}" is not supported yet by the Prisma 7 contract source.`, sourceId, attribute.span));
1602
+ else if (attribute.name === "ignore") {} else diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNKNOWN_ATTRIBUTE", `${label}: attribute "@${attribute.name}" is not supported yet by the Prisma 7 contract source.`, sourceId, attribute.span));
1611
1603
  }
1612
1604
  if (field.malformedType) return;
1613
1605
  if (field.typeConstructor !== void 0) {
1614
- diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `${label} has type "${field.typeConstructor.path.join(".")}(...)", which has no Prisma 8 codec, so model "${model.symbol.name}" cannot use this contract source while it has the field. Prisma 7 rejects @ignore on an Unsupported field, and removing the field drops its column on Prisma 7's next migration. Adding @@ignore to model "${model.symbol.name}" keeps the model out of the contract: Prisma 7's next migration is empty, but the model disappears from the Prisma 7 client too, and every relation field in another model that points to it needs @ignore, which removes that field from the Prisma 7 client as well.`, sourceId, field.typeConstructor.span));
1606
+ diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UNSUPPORTED_TYPE", `${label} has type "${field.typeConstructor.path.join(".")}(...)", which has no Prisma 8 codec yet, and Prisma 8 cannot read this schema until it supports the column type. @@ignore on model "${model.symbol.name}" does not help: Prisma 8 keeps the columns of ignored models in the contract. Removing the field drops its column on Prisma 7's next migration.`, sourceId, field.typeConstructor.span));
1615
1607
  return;
1616
1608
  }
1617
- if (args.ignoredModels.has(field.typeName)) return;
1618
1609
  if (isRelationField) {
1619
1610
  const attribute = relation === void 0 ? void 0 : parseRelationAttribute(relation, label, sourceId, diagnostics);
1620
1611
  if (relation !== void 0 && attribute === void 0) return;
1621
- build.relationFields.push({
1612
+ (ignored ? build.ignoredRelationFields : build.relationFields).push({
1622
1613
  field,
1623
1614
  targetModelName: field.typeName,
1624
1615
  attribute
@@ -1652,13 +1643,7 @@ function readField(args) {
1652
1643
  if (nativeType !== void 0) {
1653
1644
  const native = prisma7NativeTypeMapping(binding.typeMap, nativeType.name, nativeType.attribute.args.map((arg) => arg.value));
1654
1645
  if (native === void 0) {
1655
- diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_NATIVE_TYPE_UNSUPPORTED", nativeTypeMessage({
1656
- label,
1657
- nativeType: nativeType.name,
1658
- field,
1659
- model,
1660
- defaultAttribute
1661
- }), sourceId, nativeType.attribute.span));
1646
+ diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_NATIVE_TYPE_UNSUPPORTED", nativeTypeMessage(label, nativeType.name), sourceId, nativeType.attribute.span));
1662
1647
  return;
1663
1648
  }
1664
1649
  mapping = native;
@@ -1697,13 +1682,13 @@ function readField(args) {
1697
1682
  dataTypeLookup: input.dataTypes.lookup
1698
1683
  };
1699
1684
  const columnTypeName = unquotedSqlBaseNameOfCodec(resolved.descriptor.codecId, resolved.descriptor.typeParams, typeLookups);
1700
- const updatedAtGeneratorId = updatedAt === void 0 ? void 0 : binding.updatedAtGeneratorId(resolved.descriptor.codecId);
1701
- if (updatedAt !== void 0 && updatedAtGeneratorId === void 0) {
1685
+ const updatedAtGeneratorId = updatedAt === void 0 || ignored ? void 0 : binding.updatedAtGeneratorId(resolved.descriptor.codecId);
1686
+ if (updatedAt !== void 0 && !ignored && updatedAtGeneratorId === void 0) {
1702
1687
  const withoutUpdatedAt = defaultAttribute !== void 0 && givesColumnDefault(defaultAttribute) ? `. Its ${attributeText(defaultAttribute)} still sets the value on create, and neither client changes it on update.` : field.optional ? ", but neither client then fills the value, so it stays empty unless a client writes it, and updates leave it unchanged." : ", but neither client then fills the value, so both require it on create and leave it unchanged on update.";
1703
1688
  diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UPDATED_AT_TYPE_UNSUPPORTED", `${label}: @updatedAt is not supported on this column, because Prisma 8 has no generator for column type "${columnTypeName}" yet. Remove @updatedAt: Prisma 7's next migration is empty${withoutUpdatedAt}`, sourceId, updatedAt.span));
1704
1689
  return;
1705
1690
  }
1706
- if (updatedAt !== void 0 && defaultAttribute !== void 0) {
1691
+ if (updatedAt !== void 0 && !ignored && defaultAttribute !== void 0) {
1707
1692
  const written = attributeText(defaultAttribute);
1708
1693
  diagnostics.push(prisma7Diagnostic("PSL.PRISMA7_UPDATED_AT_WITH_DEFAULT_UNSUPPORTED", `${label} combines @updatedAt with ${written}, which Prisma 8 cannot express yet. Remove ${written}: @updatedAt still sets the value on create and on update, and Prisma 7's next migration removes the column default.`, sourceId, defaultAttribute.span));
1709
1694
  return;
@@ -1727,6 +1712,21 @@ function readField(args) {
1727
1712
  diagnostics
1728
1713
  });
1729
1714
  if (defaultAttribute !== void 0 && lowered === void 0) return;
1715
+ const column = {
1716
+ columnName,
1717
+ descriptor: resolved.descriptor,
1718
+ nullable: field.optional || field.list,
1719
+ many: field.list,
1720
+ ...field.list ? {
1721
+ elementNullable: false,
1722
+ noCheck: ["elementNotNull"]
1723
+ } : {},
1724
+ ...ifDefined("default", lowered?.storage)
1725
+ };
1726
+ if (ignored) {
1727
+ build.ignoredColumns.set(field.name, column);
1728
+ return;
1729
+ }
1730
1730
  const updatedAtGenerator = updatedAtGeneratorId === void 0 ? void 0 : {
1731
1731
  kind: "generator",
1732
1732
  id: updatedAtGeneratorId
@@ -1744,15 +1744,7 @@ function readField(args) {
1744
1744
  } : generator !== void 0 ? { onCreate: generator } : void 0;
1745
1745
  build.columns.set(field.name, {
1746
1746
  fieldName: field.name,
1747
- columnName,
1748
- descriptor: resolved.descriptor,
1749
- nullable: field.optional || field.list,
1750
- many: field.list,
1751
- ...field.list ? {
1752
- elementNullable: false,
1753
- noCheck: ["elementNotNull"]
1754
- } : {},
1755
- ...ifDefined("default", lowered?.storage),
1747
+ ...column,
1756
1748
  ...ifDefined("executionDefaults", executionDefaults)
1757
1749
  });
1758
1750
  }