arkormx 1.2.0 → 1.2.2
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/dist/cli.mjs +35 -25
- package/dist/index.cjs +206 -75
- package/dist/index.d.cts +128 -24
- package/dist/index.d.mts +128 -24
- package/dist/index.mjs +205 -76
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -549,7 +549,7 @@ var TableBuilder = class {
|
|
|
549
549
|
*/
|
|
550
550
|
foreign(column) {
|
|
551
551
|
const columnName = this.resolveColumn(column).name;
|
|
552
|
-
return this.foreignKey(
|
|
552
|
+
return this.foreignKey(column ?? columnName);
|
|
553
553
|
}
|
|
554
554
|
/**
|
|
555
555
|
* Returns a deep copy of the defined columns for the table.
|
|
@@ -967,24 +967,23 @@ const deriveRelationFieldName = (columnName) => {
|
|
|
967
967
|
if (trimmed.endsWith("_id") && trimmed.length > 3) return trimmed.slice(0, -3).replace(/_([a-zA-Z0-9])/g, (_, letter) => letter.toUpperCase());
|
|
968
968
|
return `${trimmed.charAt(0).toLowerCase()}${trimmed.slice(1)}`;
|
|
969
969
|
};
|
|
970
|
-
const pascalWords = (value) => {
|
|
971
|
-
return value.match(/[A-Z][a-z0-9]*/g) ?? [value];
|
|
972
|
-
};
|
|
973
970
|
/**
|
|
974
|
-
* Derive a relation name for
|
|
971
|
+
* Derive a relation name for both sides of a relation based on the
|
|
975
972
|
* source and target model names, using an explicit alias if provided or a
|
|
976
|
-
* convention of combining the
|
|
977
|
-
* the source model name.
|
|
973
|
+
* convention of combining the full source model name with the target model name.
|
|
978
974
|
*
|
|
979
975
|
* @param sourceModelName The name of the source model in the relation.
|
|
980
976
|
* @param targetModelName The name of the target model in the relation.
|
|
981
|
-
* @param explicitAlias An optional explicit alias for the
|
|
982
|
-
* @returns The derived or explicit
|
|
977
|
+
* @param explicitAlias An optional explicit alias for the relation.
|
|
978
|
+
* @returns The derived or explicit relation alias.
|
|
983
979
|
*/
|
|
984
|
-
const
|
|
980
|
+
const deriveRelationAlias = (sourceModelName, targetModelName, explicitAlias) => {
|
|
985
981
|
if (explicitAlias && explicitAlias.trim().length > 0) return explicitAlias.trim();
|
|
986
|
-
|
|
987
|
-
|
|
982
|
+
return [sourceModelName, targetModelName].sort((left, right) => left.localeCompare(right)).join("");
|
|
983
|
+
};
|
|
984
|
+
const deriveSingularFieldName = (modelName) => {
|
|
985
|
+
if (!modelName) return "item";
|
|
986
|
+
return `${modelName.charAt(0).toLowerCase()}${modelName.slice(1)}`;
|
|
988
987
|
};
|
|
989
988
|
const deriveCollectionFieldName = (modelName) => {
|
|
990
989
|
if (!modelName) return "items";
|
|
@@ -992,6 +991,12 @@ const deriveCollectionFieldName = (modelName) => {
|
|
|
992
991
|
if (camel.endsWith("s")) return `${camel}es`;
|
|
993
992
|
return `${camel}s`;
|
|
994
993
|
};
|
|
994
|
+
const resolveForeignKeyColumn = (columns, foreignKey) => {
|
|
995
|
+
return columns.find((column) => column.name === foreignKey.column);
|
|
996
|
+
};
|
|
997
|
+
const isOneToOneForeignKey = (column) => {
|
|
998
|
+
return Boolean(column?.unique || column?.primary);
|
|
999
|
+
};
|
|
995
1000
|
/**
|
|
996
1001
|
* Format a SchemaForeignKeyAction value as a Prisma onDelete action string.
|
|
997
1002
|
*
|
|
@@ -1012,15 +1017,16 @@ const formatRelationAction = (action) => {
|
|
|
1012
1017
|
* @param foreignKey The foreign key definition to convert to a relation line.
|
|
1013
1018
|
* @returns The corresponding Prisma schema line for the relation field.
|
|
1014
1019
|
*/
|
|
1015
|
-
const buildRelationLine = (foreignKey) => {
|
|
1020
|
+
const buildRelationLine = (sourceModelName, foreignKey, columns = []) => {
|
|
1016
1021
|
if (!foreignKey.referencesTable.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced table.`);
|
|
1017
1022
|
if (!foreignKey.referencesColumn.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced column.`);
|
|
1023
|
+
const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
|
|
1018
1024
|
const fieldName = foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column);
|
|
1019
1025
|
const targetModel = toModelName(foreignKey.referencesTable);
|
|
1020
|
-
const relationName = foreignKey.relationAlias?.trim();
|
|
1021
|
-
const
|
|
1026
|
+
const relationName = deriveRelationAlias(sourceModelName, targetModel, foreignKey.relationAlias?.trim());
|
|
1027
|
+
const optional = sourceColumn?.nullable ? "?" : "";
|
|
1022
1028
|
const onDelete = foreignKey.onDelete ? `, onDelete: ${formatRelationAction(foreignKey.onDelete)}` : "";
|
|
1023
|
-
return ` ${fieldName} ${targetModel} ${
|
|
1029
|
+
return ` ${fieldName} ${targetModel}${optional} @relation("${relationName.replace(/"/g, "\\\"")}", fields: [${foreignKey.column}], references: [${foreignKey.referencesColumn}]${onDelete})`;
|
|
1024
1030
|
};
|
|
1025
1031
|
/**
|
|
1026
1032
|
* Build a Prisma relation field line for the inverse side of a relation, based
|
|
@@ -1032,8 +1038,11 @@ const buildRelationLine = (foreignKey) => {
|
|
|
1032
1038
|
* @param foreignKey The foreign key definition for the relation.
|
|
1033
1039
|
* @returns The Prisma schema line for the inverse relation field.
|
|
1034
1040
|
*/
|
|
1035
|
-
const buildInverseRelationLine = (sourceModelName, targetModelName, foreignKey) => {
|
|
1036
|
-
|
|
1041
|
+
const buildInverseRelationLine = (sourceModelName, targetModelName, foreignKey, columns = []) => {
|
|
1042
|
+
const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
|
|
1043
|
+
const fieldName = isOneToOneForeignKey(sourceColumn) ? deriveSingularFieldName(sourceModelName) : deriveCollectionFieldName(sourceModelName);
|
|
1044
|
+
const relationName = deriveRelationAlias(sourceModelName, targetModelName, foreignKey.relationAlias?.trim());
|
|
1045
|
+
return ` ${fieldName} ${isOneToOneForeignKey(sourceColumn) ? `${sourceModelName}?` : `${sourceModelName}[]`} @relation("${relationName.replace(/"/g, "\\\"")}")`;
|
|
1037
1046
|
};
|
|
1038
1047
|
/**
|
|
1039
1048
|
* Inject a line into the body of a Prisma model block if it does not already
|
|
@@ -1061,14 +1070,15 @@ const injectLineIntoModelBody = (bodyLines, line, exists) => {
|
|
|
1061
1070
|
* @param foreignKeys An array of foreign key definitions to process.
|
|
1062
1071
|
* @returns The updated Prisma schema string with inverse relations applied.
|
|
1063
1072
|
*/
|
|
1064
|
-
const applyInverseRelations = (schema, sourceModelName, foreignKeys) => {
|
|
1073
|
+
const applyInverseRelations = (schema, sourceModelName, foreignKeys, columns = []) => {
|
|
1065
1074
|
let nextSchema = schema;
|
|
1066
1075
|
for (const foreignKey of foreignKeys) {
|
|
1067
1076
|
const targetModel = findModelBlock(nextSchema, foreignKey.referencesTable);
|
|
1068
1077
|
if (!targetModel) continue;
|
|
1069
|
-
const
|
|
1078
|
+
const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
|
|
1079
|
+
const inverseLine = buildInverseRelationLine(sourceModelName, targetModel.modelName, foreignKey, columns);
|
|
1070
1080
|
const targetBodyLines = targetModel.block.split("\n");
|
|
1071
|
-
const fieldName = deriveCollectionFieldName(sourceModelName);
|
|
1081
|
+
const fieldName = isOneToOneForeignKey(sourceColumn) ? deriveSingularFieldName(sourceModelName) : deriveCollectionFieldName(sourceModelName);
|
|
1072
1082
|
const fieldRegex = new RegExp(`^\\s*${escapeRegex(fieldName)}\\s+`);
|
|
1073
1083
|
injectLineIntoModelBody(targetBodyLines, inverseLine, (line) => fieldRegex.test(line));
|
|
1074
1084
|
const updatedTarget = targetBodyLines.join("\n");
|
|
@@ -1087,7 +1097,7 @@ const buildModelBlock = (operation) => {
|
|
|
1087
1097
|
const modelName = toModelName(operation.table);
|
|
1088
1098
|
const mapped = operation.table !== modelName.toLowerCase();
|
|
1089
1099
|
const fields = operation.columns.map(buildFieldLine);
|
|
1090
|
-
const relations = (operation.foreignKeys ?? []).map(buildRelationLine);
|
|
1100
|
+
const relations = (operation.foreignKeys ?? []).map((foreignKey) => buildRelationLine(modelName, foreignKey, operation.columns));
|
|
1091
1101
|
const metadata = [...(operation.indexes ?? []).map(buildIndexLine), ...mapped ? [` @@map("${str(operation.table).snake()}")`] : []];
|
|
1092
1102
|
return `model ${modelName} {\n${(metadata.length > 0 ? [
|
|
1093
1103
|
...fields,
|
|
@@ -1145,7 +1155,7 @@ const applyCreateTableOperation = (schema, operation) => {
|
|
|
1145
1155
|
if (findModelBlock(schema, operation.table)) throw new ArkormException(`Prisma model for table [${operation.table}] already exists.`);
|
|
1146
1156
|
const schemaWithEnums = ensureEnumBlocks(schema, operation.columns);
|
|
1147
1157
|
const block = buildModelBlock(operation);
|
|
1148
|
-
return applyInverseRelations(`${schemaWithEnums.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? []);
|
|
1158
|
+
return applyInverseRelations(`${schemaWithEnums.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? [], operation.columns);
|
|
1149
1159
|
};
|
|
1150
1160
|
/**
|
|
1151
1161
|
* Apply an alter table operation to a Prisma schema string, modifying the model
|
|
@@ -1186,12 +1196,12 @@ const applyAlterTableOperation = (schema, operation) => {
|
|
|
1186
1196
|
bodyLines.splice(insertIndex, 0, indexLine);
|
|
1187
1197
|
});
|
|
1188
1198
|
for (const foreignKey of operation.addForeignKeys ?? []) {
|
|
1189
|
-
const relationLine = buildRelationLine(foreignKey);
|
|
1199
|
+
const relationLine = buildRelationLine(model.modelName, foreignKey, operation.addColumns);
|
|
1190
1200
|
const relationRegex = new RegExp(`^\\s*${escapeRegex(foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column))}\\s+`);
|
|
1191
1201
|
injectLineIntoModelBody(bodyLines, relationLine, (line) => relationRegex.test(line));
|
|
1192
1202
|
}
|
|
1193
1203
|
block = bodyLines.join("\n");
|
|
1194
|
-
return applyInverseRelations(`${schemaWithEnums.slice(0, refreshedModel.start)}${block}${schemaWithEnums.slice(refreshedModel.end)}`, model.modelName, operation.addForeignKeys ?? []);
|
|
1204
|
+
return applyInverseRelations(`${schemaWithEnums.slice(0, refreshedModel.start)}${block}${schemaWithEnums.slice(refreshedModel.end)}`, model.modelName, operation.addForeignKeys ?? [], operation.addColumns);
|
|
1195
1205
|
};
|
|
1196
1206
|
/**
|
|
1197
1207
|
* Apply a drop table operation to a Prisma schema string, removing the model block
|
package/dist/index.cjs
CHANGED
|
@@ -658,7 +658,7 @@ var TableBuilder = class {
|
|
|
658
658
|
*/
|
|
659
659
|
foreign(column) {
|
|
660
660
|
const columnName = this.resolveColumn(column).name;
|
|
661
|
-
return this.foreignKey(
|
|
661
|
+
return this.foreignKey(column ?? columnName);
|
|
662
662
|
}
|
|
663
663
|
/**
|
|
664
664
|
* Returns a deep copy of the defined columns for the table.
|
|
@@ -1076,24 +1076,24 @@ const deriveRelationFieldName = (columnName) => {
|
|
|
1076
1076
|
if (trimmed.endsWith("_id") && trimmed.length > 3) return trimmed.slice(0, -3).replace(/_([a-zA-Z0-9])/g, (_, letter) => letter.toUpperCase());
|
|
1077
1077
|
return `${trimmed.charAt(0).toLowerCase()}${trimmed.slice(1)}`;
|
|
1078
1078
|
};
|
|
1079
|
-
const pascalWords = (value) => {
|
|
1080
|
-
return value.match(/[A-Z][a-z0-9]*/g) ?? [value];
|
|
1081
|
-
};
|
|
1082
1079
|
/**
|
|
1083
|
-
* Derive a relation name for
|
|
1080
|
+
* Derive a relation name for both sides of a relation based on the
|
|
1084
1081
|
* source and target model names, using an explicit alias if provided or a
|
|
1085
|
-
* convention of combining the
|
|
1086
|
-
* the source model name.
|
|
1082
|
+
* convention of combining the full source model name with the target model name.
|
|
1087
1083
|
*
|
|
1088
1084
|
* @param sourceModelName The name of the source model in the relation.
|
|
1089
1085
|
* @param targetModelName The name of the target model in the relation.
|
|
1090
|
-
* @param explicitAlias An optional explicit alias for the
|
|
1091
|
-
* @returns The derived or explicit
|
|
1086
|
+
* @param explicitAlias An optional explicit alias for the relation.
|
|
1087
|
+
* @returns The derived or explicit relation alias.
|
|
1092
1088
|
*/
|
|
1093
|
-
const
|
|
1089
|
+
const deriveRelationAlias = (sourceModelName, targetModelName, explicitAlias) => {
|
|
1094
1090
|
if (explicitAlias && explicitAlias.trim().length > 0) return explicitAlias.trim();
|
|
1095
|
-
|
|
1096
|
-
|
|
1091
|
+
return [sourceModelName, targetModelName].sort((left, right) => left.localeCompare(right)).join("");
|
|
1092
|
+
};
|
|
1093
|
+
const deriveInverseRelationAlias = deriveRelationAlias;
|
|
1094
|
+
const deriveSingularFieldName = (modelName) => {
|
|
1095
|
+
if (!modelName) return "item";
|
|
1096
|
+
return `${modelName.charAt(0).toLowerCase()}${modelName.slice(1)}`;
|
|
1097
1097
|
};
|
|
1098
1098
|
const deriveCollectionFieldName = (modelName) => {
|
|
1099
1099
|
if (!modelName) return "items";
|
|
@@ -1101,6 +1101,12 @@ const deriveCollectionFieldName = (modelName) => {
|
|
|
1101
1101
|
if (camel.endsWith("s")) return `${camel}es`;
|
|
1102
1102
|
return `${camel}s`;
|
|
1103
1103
|
};
|
|
1104
|
+
const resolveForeignKeyColumn = (columns, foreignKey) => {
|
|
1105
|
+
return columns.find((column) => column.name === foreignKey.column);
|
|
1106
|
+
};
|
|
1107
|
+
const isOneToOneForeignKey = (column) => {
|
|
1108
|
+
return Boolean(column?.unique || column?.primary);
|
|
1109
|
+
};
|
|
1104
1110
|
/**
|
|
1105
1111
|
* Format a SchemaForeignKeyAction value as a Prisma onDelete action string.
|
|
1106
1112
|
*
|
|
@@ -1121,15 +1127,16 @@ const formatRelationAction = (action) => {
|
|
|
1121
1127
|
* @param foreignKey The foreign key definition to convert to a relation line.
|
|
1122
1128
|
* @returns The corresponding Prisma schema line for the relation field.
|
|
1123
1129
|
*/
|
|
1124
|
-
const buildRelationLine = (foreignKey) => {
|
|
1130
|
+
const buildRelationLine = (sourceModelName, foreignKey, columns = []) => {
|
|
1125
1131
|
if (!foreignKey.referencesTable.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced table.`);
|
|
1126
1132
|
if (!foreignKey.referencesColumn.trim()) throw new ArkormException(`Foreign key [${foreignKey.column}] must define a referenced column.`);
|
|
1133
|
+
const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
|
|
1127
1134
|
const fieldName = foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column);
|
|
1128
1135
|
const targetModel = toModelName(foreignKey.referencesTable);
|
|
1129
|
-
const relationName = foreignKey.relationAlias?.trim();
|
|
1130
|
-
const
|
|
1136
|
+
const relationName = deriveRelationAlias(sourceModelName, targetModel, foreignKey.relationAlias?.trim());
|
|
1137
|
+
const optional = sourceColumn?.nullable ? "?" : "";
|
|
1131
1138
|
const onDelete = foreignKey.onDelete ? `, onDelete: ${formatRelationAction(foreignKey.onDelete)}` : "";
|
|
1132
|
-
return ` ${fieldName} ${targetModel} ${
|
|
1139
|
+
return ` ${fieldName} ${targetModel}${optional} @relation("${relationName.replace(/"/g, "\\\"")}", fields: [${foreignKey.column}], references: [${foreignKey.referencesColumn}]${onDelete})`;
|
|
1133
1140
|
};
|
|
1134
1141
|
/**
|
|
1135
1142
|
* Build a Prisma relation field line for the inverse side of a relation, based
|
|
@@ -1141,8 +1148,11 @@ const buildRelationLine = (foreignKey) => {
|
|
|
1141
1148
|
* @param foreignKey The foreign key definition for the relation.
|
|
1142
1149
|
* @returns The Prisma schema line for the inverse relation field.
|
|
1143
1150
|
*/
|
|
1144
|
-
const buildInverseRelationLine = (sourceModelName, targetModelName, foreignKey) => {
|
|
1145
|
-
|
|
1151
|
+
const buildInverseRelationLine = (sourceModelName, targetModelName, foreignKey, columns = []) => {
|
|
1152
|
+
const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
|
|
1153
|
+
const fieldName = isOneToOneForeignKey(sourceColumn) ? deriveSingularFieldName(sourceModelName) : deriveCollectionFieldName(sourceModelName);
|
|
1154
|
+
const relationName = deriveRelationAlias(sourceModelName, targetModelName, foreignKey.relationAlias?.trim());
|
|
1155
|
+
return ` ${fieldName} ${isOneToOneForeignKey(sourceColumn) ? `${sourceModelName}?` : `${sourceModelName}[]`} @relation("${relationName.replace(/"/g, "\\\"")}")`;
|
|
1146
1156
|
};
|
|
1147
1157
|
/**
|
|
1148
1158
|
* Inject a line into the body of a Prisma model block if it does not already
|
|
@@ -1170,14 +1180,15 @@ const injectLineIntoModelBody = (bodyLines, line, exists) => {
|
|
|
1170
1180
|
* @param foreignKeys An array of foreign key definitions to process.
|
|
1171
1181
|
* @returns The updated Prisma schema string with inverse relations applied.
|
|
1172
1182
|
*/
|
|
1173
|
-
const applyInverseRelations = (schema, sourceModelName, foreignKeys) => {
|
|
1183
|
+
const applyInverseRelations = (schema, sourceModelName, foreignKeys, columns = []) => {
|
|
1174
1184
|
let nextSchema = schema;
|
|
1175
1185
|
for (const foreignKey of foreignKeys) {
|
|
1176
1186
|
const targetModel = findModelBlock(nextSchema, foreignKey.referencesTable);
|
|
1177
1187
|
if (!targetModel) continue;
|
|
1178
|
-
const
|
|
1188
|
+
const sourceColumn = resolveForeignKeyColumn(columns, foreignKey);
|
|
1189
|
+
const inverseLine = buildInverseRelationLine(sourceModelName, targetModel.modelName, foreignKey, columns);
|
|
1179
1190
|
const targetBodyLines = targetModel.block.split("\n");
|
|
1180
|
-
const fieldName = deriveCollectionFieldName(sourceModelName);
|
|
1191
|
+
const fieldName = isOneToOneForeignKey(sourceColumn) ? deriveSingularFieldName(sourceModelName) : deriveCollectionFieldName(sourceModelName);
|
|
1181
1192
|
const fieldRegex = new RegExp(`^\\s*${escapeRegex(fieldName)}\\s+`);
|
|
1182
1193
|
injectLineIntoModelBody(targetBodyLines, inverseLine, (line) => fieldRegex.test(line));
|
|
1183
1194
|
const updatedTarget = targetBodyLines.join("\n");
|
|
@@ -1196,7 +1207,7 @@ const buildModelBlock = (operation) => {
|
|
|
1196
1207
|
const modelName = toModelName(operation.table);
|
|
1197
1208
|
const mapped = operation.table !== modelName.toLowerCase();
|
|
1198
1209
|
const fields = operation.columns.map(buildFieldLine);
|
|
1199
|
-
const relations = (operation.foreignKeys ?? []).map(buildRelationLine);
|
|
1210
|
+
const relations = (operation.foreignKeys ?? []).map((foreignKey) => buildRelationLine(modelName, foreignKey, operation.columns));
|
|
1200
1211
|
const metadata = [...(operation.indexes ?? []).map(buildIndexLine), ...mapped ? [` @@map("${(0, _h3ravel_support.str)(operation.table).snake()}")`] : []];
|
|
1201
1212
|
return `model ${modelName} {\n${(metadata.length > 0 ? [
|
|
1202
1213
|
...fields,
|
|
@@ -1254,7 +1265,7 @@ const applyCreateTableOperation = (schema, operation) => {
|
|
|
1254
1265
|
if (findModelBlock(schema, operation.table)) throw new ArkormException(`Prisma model for table [${operation.table}] already exists.`);
|
|
1255
1266
|
const schemaWithEnums = ensureEnumBlocks(schema, operation.columns);
|
|
1256
1267
|
const block = buildModelBlock(operation);
|
|
1257
|
-
return applyInverseRelations(`${schemaWithEnums.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? []);
|
|
1268
|
+
return applyInverseRelations(`${schemaWithEnums.trimEnd()}\n\n${block}\n`, toModelName(operation.table), operation.foreignKeys ?? [], operation.columns);
|
|
1258
1269
|
};
|
|
1259
1270
|
/**
|
|
1260
1271
|
* Apply an alter table operation to a Prisma schema string, modifying the model
|
|
@@ -1295,12 +1306,12 @@ const applyAlterTableOperation = (schema, operation) => {
|
|
|
1295
1306
|
bodyLines.splice(insertIndex, 0, indexLine);
|
|
1296
1307
|
});
|
|
1297
1308
|
for (const foreignKey of operation.addForeignKeys ?? []) {
|
|
1298
|
-
const relationLine = buildRelationLine(foreignKey);
|
|
1309
|
+
const relationLine = buildRelationLine(model.modelName, foreignKey, operation.addColumns);
|
|
1299
1310
|
const relationRegex = new RegExp(`^\\s*${escapeRegex(foreignKey.fieldAlias?.trim() || deriveRelationFieldName(foreignKey.column))}\\s+`);
|
|
1300
1311
|
injectLineIntoModelBody(bodyLines, relationLine, (line) => relationRegex.test(line));
|
|
1301
1312
|
}
|
|
1302
1313
|
block = bodyLines.join("\n");
|
|
1303
|
-
return applyInverseRelations(`${schemaWithEnums.slice(0, refreshedModel.start)}${block}${schemaWithEnums.slice(refreshedModel.end)}`, model.modelName, operation.addForeignKeys ?? []);
|
|
1314
|
+
return applyInverseRelations(`${schemaWithEnums.slice(0, refreshedModel.start)}${block}${schemaWithEnums.slice(refreshedModel.end)}`, model.modelName, operation.addForeignKeys ?? [], operation.addColumns);
|
|
1304
1315
|
};
|
|
1305
1316
|
/**
|
|
1306
1317
|
* Apply a drop table operation to a Prisma schema string, removing the model block
|
|
@@ -3438,6 +3449,30 @@ var Relation = class {
|
|
|
3438
3449
|
if (results instanceof ArkormCollection) return results.all()[0] ?? null;
|
|
3439
3450
|
return results;
|
|
3440
3451
|
}
|
|
3452
|
+
/**
|
|
3453
|
+
* Count records that match the relationship query.
|
|
3454
|
+
*
|
|
3455
|
+
* @returns
|
|
3456
|
+
*/
|
|
3457
|
+
async count() {
|
|
3458
|
+
return (await this.getQuery()).count();
|
|
3459
|
+
}
|
|
3460
|
+
/**
|
|
3461
|
+
* Determine whether the relationship query has any matching records.
|
|
3462
|
+
*
|
|
3463
|
+
* @returns
|
|
3464
|
+
*/
|
|
3465
|
+
async exists() {
|
|
3466
|
+
return (await this.getQuery()).exists();
|
|
3467
|
+
}
|
|
3468
|
+
/**
|
|
3469
|
+
* Determine whether the relationship query has no matching records.
|
|
3470
|
+
*
|
|
3471
|
+
* @returns
|
|
3472
|
+
*/
|
|
3473
|
+
async doesntExist() {
|
|
3474
|
+
return !await this.exists();
|
|
3475
|
+
}
|
|
3441
3476
|
};
|
|
3442
3477
|
|
|
3443
3478
|
//#endregion
|
|
@@ -3460,15 +3495,55 @@ var BelongsToManyRelation = class extends Relation {
|
|
|
3460
3495
|
this.relatedKey = relatedKey;
|
|
3461
3496
|
}
|
|
3462
3497
|
/**
|
|
3498
|
+
* Build the relationship query.
|
|
3499
|
+
*
|
|
3500
|
+
* @returns
|
|
3501
|
+
*/
|
|
3502
|
+
async getQuery() {
|
|
3503
|
+
const parentValue = this.parent.getAttribute(this.parentKey);
|
|
3504
|
+
const ids = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.foreignPivotKey]: parentValue } })).map((row) => row[this.relatedPivotKey]);
|
|
3505
|
+
return this.applyConstraint(this.related.query().where({ [this.relatedKey]: { in: ids } }));
|
|
3506
|
+
}
|
|
3507
|
+
/**
|
|
3463
3508
|
* Fetches the related models for this relationship.
|
|
3464
3509
|
*
|
|
3465
3510
|
* @returns
|
|
3466
3511
|
*/
|
|
3467
3512
|
async getResults() {
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3513
|
+
return (await this.getQuery()).get();
|
|
3514
|
+
}
|
|
3515
|
+
};
|
|
3516
|
+
|
|
3517
|
+
//#endregion
|
|
3518
|
+
//#region src/relationship/SingleResultRelation.ts
|
|
3519
|
+
/**
|
|
3520
|
+
* Base class for relationships that resolve to a single related model.
|
|
3521
|
+
*
|
|
3522
|
+
* @author Legacy (3m1n3nc3)
|
|
3523
|
+
* @since 1.3.0
|
|
3524
|
+
*/
|
|
3525
|
+
var SingleResultRelation = class extends Relation {
|
|
3526
|
+
defaultValue;
|
|
3527
|
+
constructor(parent, related) {
|
|
3528
|
+
super();
|
|
3529
|
+
this.parent = parent;
|
|
3530
|
+
this.related = related;
|
|
3531
|
+
}
|
|
3532
|
+
/**
|
|
3533
|
+
* Defines a default value to return when the relationship does not find a related model.
|
|
3534
|
+
*
|
|
3535
|
+
* @param value The default value or a callback that returns the default value.
|
|
3536
|
+
* @returns The current instance for method chaining.
|
|
3537
|
+
*/
|
|
3538
|
+
withDefault(value = {}) {
|
|
3539
|
+
this.defaultValue = value;
|
|
3540
|
+
return this;
|
|
3541
|
+
}
|
|
3542
|
+
resolveDefaultResult() {
|
|
3543
|
+
if (typeof this.defaultValue === "undefined") return null;
|
|
3544
|
+
const resolved = typeof this.defaultValue === "function" ? this.defaultValue(this.parent) : this.defaultValue;
|
|
3545
|
+
if (resolved instanceof this.related) return resolved;
|
|
3546
|
+
return this.related.hydrate(resolved);
|
|
3472
3547
|
}
|
|
3473
3548
|
};
|
|
3474
3549
|
|
|
@@ -3480,22 +3555,28 @@ var BelongsToManyRelation = class extends Relation {
|
|
|
3480
3555
|
* @author Legacy (3m1n3nc3)
|
|
3481
3556
|
* @since 0.1.0
|
|
3482
3557
|
*/
|
|
3483
|
-
var BelongsToRelation = class extends
|
|
3558
|
+
var BelongsToRelation = class extends SingleResultRelation {
|
|
3484
3559
|
constructor(parent, related, foreignKey, ownerKey) {
|
|
3485
|
-
super();
|
|
3486
|
-
this.parent = parent;
|
|
3487
|
-
this.related = related;
|
|
3560
|
+
super(parent, related);
|
|
3488
3561
|
this.foreignKey = foreignKey;
|
|
3489
3562
|
this.ownerKey = ownerKey;
|
|
3490
3563
|
}
|
|
3491
3564
|
/**
|
|
3565
|
+
* Build the relationship query.
|
|
3566
|
+
*
|
|
3567
|
+
* @returns
|
|
3568
|
+
*/
|
|
3569
|
+
async getQuery() {
|
|
3570
|
+
const foreignValue = this.parent.getAttribute(this.foreignKey);
|
|
3571
|
+
return this.applyConstraint(this.related.query().where({ [this.ownerKey]: foreignValue }));
|
|
3572
|
+
}
|
|
3573
|
+
/**
|
|
3492
3574
|
* Fetches the related models for this relationship.
|
|
3493
3575
|
*
|
|
3494
3576
|
* @returns
|
|
3495
3577
|
*/
|
|
3496
3578
|
async getResults() {
|
|
3497
|
-
|
|
3498
|
-
return this.applyConstraint(this.related.query().where({ [this.ownerKey]: foreignValue })).first();
|
|
3579
|
+
return await (await this.getQuery()).first() ?? this.resolveDefaultResult();
|
|
3499
3580
|
}
|
|
3500
3581
|
};
|
|
3501
3582
|
|
|
@@ -3516,13 +3597,21 @@ var HasManyRelation = class extends Relation {
|
|
|
3516
3597
|
this.localKey = localKey;
|
|
3517
3598
|
}
|
|
3518
3599
|
/**
|
|
3600
|
+
* Build the relationship query.
|
|
3601
|
+
*
|
|
3602
|
+
* @returns
|
|
3603
|
+
*/
|
|
3604
|
+
async getQuery() {
|
|
3605
|
+
const localValue = this.parent.getAttribute(this.localKey);
|
|
3606
|
+
return this.applyConstraint(this.related.query().where({ [this.foreignKey]: localValue }));
|
|
3607
|
+
}
|
|
3608
|
+
/**
|
|
3519
3609
|
* Fetches the related models for this relationship.
|
|
3520
3610
|
*
|
|
3521
3611
|
* @returns
|
|
3522
3612
|
*/
|
|
3523
3613
|
async getResults() {
|
|
3524
|
-
|
|
3525
|
-
return this.applyConstraint(this.related.query().where({ [this.foreignKey]: localValue })).get();
|
|
3614
|
+
return (await this.getQuery()).get();
|
|
3526
3615
|
}
|
|
3527
3616
|
};
|
|
3528
3617
|
|
|
@@ -3547,15 +3636,22 @@ var HasManyThroughRelation = class extends Relation {
|
|
|
3547
3636
|
this.secondLocalKey = secondLocalKey;
|
|
3548
3637
|
}
|
|
3549
3638
|
/**
|
|
3639
|
+
* Build the relationship query.
|
|
3640
|
+
*
|
|
3641
|
+
* @returns
|
|
3642
|
+
*/
|
|
3643
|
+
async getQuery() {
|
|
3644
|
+
const localValue = this.parent.getAttribute(this.localKey);
|
|
3645
|
+
const keys = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.firstKey]: localValue } })).map((row) => row[this.secondLocalKey]);
|
|
3646
|
+
return this.applyConstraint(this.related.query().where({ [this.secondKey]: { in: keys } }));
|
|
3647
|
+
}
|
|
3648
|
+
/**
|
|
3550
3649
|
* Fetches the related models for this relationship.
|
|
3551
3650
|
*
|
|
3552
3651
|
* @returns
|
|
3553
3652
|
*/
|
|
3554
3653
|
async getResults() {
|
|
3555
|
-
|
|
3556
|
-
const keys = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.firstKey]: localValue } })).map((row) => row[this.secondLocalKey]);
|
|
3557
|
-
if (keys.length === 0) return new ArkormCollection([]);
|
|
3558
|
-
return this.applyConstraint(this.related.query().where({ [this.secondKey]: { in: keys } })).get();
|
|
3654
|
+
return (await this.getQuery()).get();
|
|
3559
3655
|
}
|
|
3560
3656
|
};
|
|
3561
3657
|
|
|
@@ -3567,22 +3663,28 @@ var HasManyThroughRelation = class extends Relation {
|
|
|
3567
3663
|
* @author Legacy (3m1n3nc3)
|
|
3568
3664
|
* @since 0.1.0
|
|
3569
3665
|
*/
|
|
3570
|
-
var HasOneRelation = class extends
|
|
3666
|
+
var HasOneRelation = class extends SingleResultRelation {
|
|
3571
3667
|
constructor(parent, related, foreignKey, localKey) {
|
|
3572
|
-
super();
|
|
3573
|
-
this.parent = parent;
|
|
3574
|
-
this.related = related;
|
|
3668
|
+
super(parent, related);
|
|
3575
3669
|
this.foreignKey = foreignKey;
|
|
3576
3670
|
this.localKey = localKey;
|
|
3577
3671
|
}
|
|
3578
3672
|
/**
|
|
3673
|
+
* Build the relationship query.
|
|
3674
|
+
*
|
|
3675
|
+
* @returns
|
|
3676
|
+
*/
|
|
3677
|
+
async getQuery() {
|
|
3678
|
+
const localValue = this.parent.getAttribute(this.localKey);
|
|
3679
|
+
return this.applyConstraint(this.related.query().where({ [this.foreignKey]: localValue }));
|
|
3680
|
+
}
|
|
3681
|
+
/**
|
|
3579
3682
|
* Fetches the related models for this relationship.
|
|
3580
3683
|
*
|
|
3581
3684
|
* @returns
|
|
3582
3685
|
*/
|
|
3583
3686
|
async getResults() {
|
|
3584
|
-
|
|
3585
|
-
return this.applyConstraint(this.related.query().where({ [this.foreignKey]: localValue })).first();
|
|
3687
|
+
return await (await this.getQuery()).first() ?? this.resolveDefaultResult();
|
|
3586
3688
|
}
|
|
3587
3689
|
};
|
|
3588
3690
|
|
|
@@ -3595,11 +3697,9 @@ var HasOneRelation = class extends Relation {
|
|
|
3595
3697
|
* @author Legacy (3m1n3nc3)
|
|
3596
3698
|
* @since 0.1.0
|
|
3597
3699
|
*/
|
|
3598
|
-
var HasOneThroughRelation = class extends
|
|
3700
|
+
var HasOneThroughRelation = class extends SingleResultRelation {
|
|
3599
3701
|
constructor(parent, related, throughDelegate, firstKey, secondKey, localKey, secondLocalKey) {
|
|
3600
|
-
super();
|
|
3601
|
-
this.parent = parent;
|
|
3602
|
-
this.related = related;
|
|
3702
|
+
super(parent, related);
|
|
3603
3703
|
this.throughDelegate = throughDelegate;
|
|
3604
3704
|
this.firstKey = firstKey;
|
|
3605
3705
|
this.secondKey = secondKey;
|
|
@@ -3607,15 +3707,23 @@ var HasOneThroughRelation = class extends Relation {
|
|
|
3607
3707
|
this.secondLocalKey = secondLocalKey;
|
|
3608
3708
|
}
|
|
3609
3709
|
/**
|
|
3710
|
+
* Build the relationship query.
|
|
3711
|
+
*
|
|
3712
|
+
* @returns
|
|
3713
|
+
*/
|
|
3714
|
+
async getQuery() {
|
|
3715
|
+
const localValue = this.parent.getAttribute(this.localKey);
|
|
3716
|
+
const intermediate = await this.related.getDelegate(this.throughDelegate).findFirst({ where: { [this.firstKey]: localValue } });
|
|
3717
|
+
if (!intermediate) return this.applyConstraint(this.related.query().where({ [this.secondKey]: { in: [] } }));
|
|
3718
|
+
return this.applyConstraint(this.related.query().where({ [this.secondKey]: intermediate[this.secondLocalKey] }));
|
|
3719
|
+
}
|
|
3720
|
+
/**
|
|
3610
3721
|
* Fetches the related models for this relationship.
|
|
3611
3722
|
*
|
|
3612
3723
|
* @returns
|
|
3613
3724
|
*/
|
|
3614
3725
|
async getResults() {
|
|
3615
|
-
|
|
3616
|
-
const intermediate = await this.related.getDelegate(this.throughDelegate).findFirst({ where: { [this.firstKey]: localValue } });
|
|
3617
|
-
if (!intermediate) return null;
|
|
3618
|
-
return this.applyConstraint(this.related.query().where({ [this.secondKey]: intermediate[this.secondLocalKey] })).first();
|
|
3726
|
+
return await (await this.getQuery()).first() ?? this.resolveDefaultResult();
|
|
3619
3727
|
}
|
|
3620
3728
|
};
|
|
3621
3729
|
|
|
@@ -3636,17 +3744,25 @@ var MorphManyRelation = class extends Relation {
|
|
|
3636
3744
|
this.localKey = localKey;
|
|
3637
3745
|
}
|
|
3638
3746
|
/**
|
|
3639
|
-
*
|
|
3640
|
-
*
|
|
3641
|
-
* @returns
|
|
3747
|
+
* Build the relationship query.
|
|
3748
|
+
*
|
|
3749
|
+
* @returns
|
|
3642
3750
|
*/
|
|
3643
|
-
async
|
|
3751
|
+
async getQuery() {
|
|
3644
3752
|
const id = this.parent.getAttribute(this.localKey);
|
|
3645
3753
|
const type = this.parent.constructor.name;
|
|
3646
3754
|
return this.applyConstraint(this.related.query().where({
|
|
3647
3755
|
[`${this.morphName}Id`]: id,
|
|
3648
3756
|
[`${this.morphName}Type`]: type
|
|
3649
|
-
}))
|
|
3757
|
+
}));
|
|
3758
|
+
}
|
|
3759
|
+
/**
|
|
3760
|
+
* Fetches the related models for this relationship.
|
|
3761
|
+
*
|
|
3762
|
+
* @returns
|
|
3763
|
+
*/
|
|
3764
|
+
async getResults() {
|
|
3765
|
+
return (await this.getQuery()).get();
|
|
3650
3766
|
}
|
|
3651
3767
|
};
|
|
3652
3768
|
|
|
@@ -3658,26 +3774,32 @@ var MorphManyRelation = class extends Relation {
|
|
|
3658
3774
|
* @author Legacy (3m1n3nc3)
|
|
3659
3775
|
* @since 0.1.0
|
|
3660
3776
|
*/
|
|
3661
|
-
var MorphOneRelation = class extends
|
|
3777
|
+
var MorphOneRelation = class extends SingleResultRelation {
|
|
3662
3778
|
constructor(parent, related, morphName, localKey) {
|
|
3663
|
-
super();
|
|
3664
|
-
this.parent = parent;
|
|
3665
|
-
this.related = related;
|
|
3779
|
+
super(parent, related);
|
|
3666
3780
|
this.morphName = morphName;
|
|
3667
3781
|
this.localKey = localKey;
|
|
3668
3782
|
}
|
|
3669
3783
|
/**
|
|
3670
|
-
*
|
|
3671
|
-
*
|
|
3672
|
-
* @returns
|
|
3784
|
+
* Build the relationship query.
|
|
3785
|
+
*
|
|
3786
|
+
* @returns
|
|
3673
3787
|
*/
|
|
3674
|
-
async
|
|
3788
|
+
async getQuery() {
|
|
3675
3789
|
const id = this.parent.getAttribute(this.localKey);
|
|
3676
3790
|
const type = this.parent.constructor.name;
|
|
3677
3791
|
return this.applyConstraint(this.related.query().where({
|
|
3678
3792
|
[`${this.morphName}Id`]: id,
|
|
3679
3793
|
[`${this.morphName}Type`]: type
|
|
3680
|
-
}))
|
|
3794
|
+
}));
|
|
3795
|
+
}
|
|
3796
|
+
/**
|
|
3797
|
+
* Fetches the related models for this relationship.
|
|
3798
|
+
*
|
|
3799
|
+
* @returns
|
|
3800
|
+
*/
|
|
3801
|
+
async getResults() {
|
|
3802
|
+
return await (await this.getQuery()).first() ?? this.resolveDefaultResult();
|
|
3681
3803
|
}
|
|
3682
3804
|
};
|
|
3683
3805
|
|
|
@@ -3701,19 +3823,26 @@ var MorphToManyRelation = class extends Relation {
|
|
|
3701
3823
|
this.relatedKey = relatedKey;
|
|
3702
3824
|
}
|
|
3703
3825
|
/**
|
|
3704
|
-
*
|
|
3705
|
-
*
|
|
3706
|
-
* @returns
|
|
3826
|
+
* Build the relationship query.
|
|
3827
|
+
*
|
|
3828
|
+
* @returns
|
|
3707
3829
|
*/
|
|
3708
|
-
async
|
|
3830
|
+
async getQuery() {
|
|
3709
3831
|
const parentValue = this.parent.getAttribute(this.parentKey);
|
|
3710
3832
|
const morphType = this.parent.constructor.name;
|
|
3711
3833
|
const ids = (await this.related.getDelegate(this.throughDelegate).findMany({ where: {
|
|
3712
3834
|
[`${this.morphName}Id`]: parentValue,
|
|
3713
3835
|
[`${this.morphName}Type`]: morphType
|
|
3714
3836
|
} })).map((row) => row[this.relatedPivotKey]);
|
|
3715
|
-
|
|
3716
|
-
|
|
3837
|
+
return this.applyConstraint(this.related.query().where({ [this.relatedKey]: { in: ids } }));
|
|
3838
|
+
}
|
|
3839
|
+
/**
|
|
3840
|
+
* Fetches the related models for this relationship.
|
|
3841
|
+
*
|
|
3842
|
+
* @returns
|
|
3843
|
+
*/
|
|
3844
|
+
async getResults() {
|
|
3845
|
+
return (await this.getQuery()).get();
|
|
3717
3846
|
}
|
|
3718
3847
|
};
|
|
3719
3848
|
|
|
@@ -6468,7 +6597,9 @@ exports.defineConfig = defineConfig;
|
|
|
6468
6597
|
exports.defineFactory = defineFactory;
|
|
6469
6598
|
exports.deriveCollectionFieldName = deriveCollectionFieldName;
|
|
6470
6599
|
exports.deriveInverseRelationAlias = deriveInverseRelationAlias;
|
|
6600
|
+
exports.deriveRelationAlias = deriveRelationAlias;
|
|
6471
6601
|
exports.deriveRelationFieldName = deriveRelationFieldName;
|
|
6602
|
+
exports.deriveSingularFieldName = deriveSingularFieldName;
|
|
6472
6603
|
exports.ensureArkormConfigLoading = ensureArkormConfigLoading;
|
|
6473
6604
|
exports.escapeRegex = escapeRegex;
|
|
6474
6605
|
exports.findAppliedMigration = findAppliedMigration;
|