@famgia/omnify-laravel 0.0.12 → 0.0.14
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/{chunk-2JWTIYRL.js → chunk-UVF7W2J2.js} +614 -519
- package/dist/chunk-UVF7W2J2.js.map +1 -0
- package/dist/index.cjs +613 -538
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -198
- package/dist/index.d.ts +1 -198
- package/dist/index.js +1 -41
- package/dist/plugin.cjs +613 -484
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +24 -19
- package/dist/plugin.d.ts +24 -19
- package/dist/plugin.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-2JWTIYRL.js.map +0 -1
|
@@ -266,11 +266,18 @@ function schemaToBlueprint(schema, allSchemas) {
|
|
|
266
266
|
}
|
|
267
267
|
if (schema.options?.indexes) {
|
|
268
268
|
for (const index of schema.options.indexes) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
269
|
+
if (typeof index === "string") {
|
|
270
|
+
indexes.push({
|
|
271
|
+
columns: [toColumnName(index)],
|
|
272
|
+
unique: false
|
|
273
|
+
});
|
|
274
|
+
} else {
|
|
275
|
+
indexes.push({
|
|
276
|
+
name: index.name,
|
|
277
|
+
columns: index.columns.map(toColumnName),
|
|
278
|
+
unique: index.unique ?? false
|
|
279
|
+
});
|
|
280
|
+
}
|
|
274
281
|
}
|
|
275
282
|
}
|
|
276
283
|
if (schema.options?.unique) {
|
|
@@ -988,503 +995,611 @@ function generateMigrationsFromChanges(changes, options = {}) {
|
|
|
988
995
|
return migrations;
|
|
989
996
|
}
|
|
990
997
|
|
|
991
|
-
// src/
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
Int: "number",
|
|
995
|
-
BigInt: "number",
|
|
996
|
-
Float: "number",
|
|
997
|
-
Boolean: "boolean",
|
|
998
|
-
Text: "string",
|
|
999
|
-
LongText: "string",
|
|
1000
|
-
Date: "string",
|
|
1001
|
-
Time: "string",
|
|
1002
|
-
Timestamp: "string",
|
|
1003
|
-
Json: "unknown",
|
|
1004
|
-
Email: "string",
|
|
1005
|
-
Password: "string",
|
|
1006
|
-
Enum: "string",
|
|
1007
|
-
Select: "string",
|
|
1008
|
-
Lookup: "number"
|
|
1009
|
-
};
|
|
1010
|
-
var FILE_INTERFACE_NAME = "File";
|
|
1011
|
-
var PK_TYPE_MAP = {
|
|
1012
|
-
Int: "number",
|
|
1013
|
-
BigInt: "number",
|
|
1014
|
-
Uuid: "string",
|
|
1015
|
-
String: "string"
|
|
1016
|
-
};
|
|
1017
|
-
function toPropertyName(name) {
|
|
1018
|
-
return name;
|
|
998
|
+
// src/utils.ts
|
|
999
|
+
function toSnakeCase(str) {
|
|
1000
|
+
return str.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toLowerCase();
|
|
1019
1001
|
}
|
|
1020
|
-
function
|
|
1021
|
-
return
|
|
1002
|
+
function toPascalCase(str) {
|
|
1003
|
+
return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase()).replace(/^(.)/, (_, c) => c.toUpperCase());
|
|
1022
1004
|
}
|
|
1023
|
-
function
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
return
|
|
1030
|
-
}
|
|
1031
|
-
if (property.type === "Association") {
|
|
1032
|
-
const assocProp = property;
|
|
1033
|
-
const targetName = assocProp.target ?? "unknown";
|
|
1034
|
-
switch (assocProp.relation) {
|
|
1035
|
-
// Standard relations
|
|
1036
|
-
case "OneToOne":
|
|
1037
|
-
case "ManyToOne":
|
|
1038
|
-
return targetName;
|
|
1039
|
-
case "OneToMany":
|
|
1040
|
-
case "ManyToMany":
|
|
1041
|
-
return `${targetName}[]`;
|
|
1042
|
-
// Polymorphic relations
|
|
1043
|
-
case "MorphTo":
|
|
1044
|
-
if (assocProp.targets && assocProp.targets.length > 0) {
|
|
1045
|
-
return assocProp.targets.join(" | ");
|
|
1046
|
-
}
|
|
1047
|
-
return "unknown";
|
|
1048
|
-
case "MorphOne":
|
|
1049
|
-
return targetName;
|
|
1050
|
-
case "MorphMany":
|
|
1051
|
-
case "MorphToMany":
|
|
1052
|
-
case "MorphedByMany":
|
|
1053
|
-
return `${targetName}[]`;
|
|
1054
|
-
default:
|
|
1055
|
-
return "unknown";
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
if (property.type === "Enum") {
|
|
1059
|
-
const enumProp = property;
|
|
1060
|
-
if (typeof enumProp.enum === "string") {
|
|
1061
|
-
return enumProp.enum;
|
|
1062
|
-
}
|
|
1063
|
-
if (Array.isArray(enumProp.enum)) {
|
|
1064
|
-
return enumProp.enum.map((v) => `'${v}'`).join(" | ");
|
|
1065
|
-
}
|
|
1005
|
+
function toCamelCase(str) {
|
|
1006
|
+
const pascal = toPascalCase(str);
|
|
1007
|
+
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
1008
|
+
}
|
|
1009
|
+
function pluralize(word) {
|
|
1010
|
+
if (word.endsWith("y") && !["ay", "ey", "iy", "oy", "uy"].some((v) => word.endsWith(v))) {
|
|
1011
|
+
return word.slice(0, -1) + "ies";
|
|
1066
1012
|
}
|
|
1067
|
-
if (
|
|
1068
|
-
|
|
1069
|
-
if (selectProp.options && selectProp.options.length > 0) {
|
|
1070
|
-
return selectProp.options.map((v) => `'${v}'`).join(" | ");
|
|
1071
|
-
}
|
|
1013
|
+
if (word.endsWith("s") || word.endsWith("x") || word.endsWith("z") || word.endsWith("ch") || word.endsWith("sh")) {
|
|
1014
|
+
return word + "es";
|
|
1072
1015
|
}
|
|
1073
|
-
return
|
|
1016
|
+
return word + "s";
|
|
1074
1017
|
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1018
|
+
|
|
1019
|
+
// src/model/generator.ts
|
|
1020
|
+
var DEFAULT_OPTIONS = {
|
|
1021
|
+
baseModelNamespace: "App\\Models\\OmnifyBase",
|
|
1022
|
+
modelNamespace: "App\\Models",
|
|
1023
|
+
baseModelClassName: "BaseModel",
|
|
1024
|
+
baseModelPath: "app/Models/OmnifyBase",
|
|
1025
|
+
modelPath: "app/Models"
|
|
1026
|
+
};
|
|
1027
|
+
function resolveOptions(options) {
|
|
1028
|
+
return {
|
|
1029
|
+
baseModelNamespace: options?.baseModelNamespace ?? DEFAULT_OPTIONS.baseModelNamespace,
|
|
1030
|
+
modelNamespace: options?.modelNamespace ?? DEFAULT_OPTIONS.modelNamespace,
|
|
1031
|
+
baseModelClassName: options?.baseModelClassName ?? DEFAULT_OPTIONS.baseModelClassName,
|
|
1032
|
+
baseModelPath: options?.baseModelPath ?? DEFAULT_OPTIONS.baseModelPath,
|
|
1033
|
+
modelPath: options?.modelPath ?? DEFAULT_OPTIONS.modelPath
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
function getCastType(propDef) {
|
|
1037
|
+
switch (propDef.type) {
|
|
1038
|
+
case "Boolean":
|
|
1039
|
+
return "boolean";
|
|
1040
|
+
case "Int":
|
|
1041
|
+
case "BigInt":
|
|
1042
|
+
return "integer";
|
|
1043
|
+
case "Float":
|
|
1044
|
+
return "float";
|
|
1045
|
+
case "Decimal":
|
|
1046
|
+
return "decimal:" + (propDef.scale ?? 2);
|
|
1047
|
+
case "Json":
|
|
1048
|
+
return "array";
|
|
1049
|
+
case "Date":
|
|
1050
|
+
return "date";
|
|
1051
|
+
case "Timestamp":
|
|
1052
|
+
return "datetime";
|
|
1053
|
+
case "Password":
|
|
1054
|
+
return "hashed";
|
|
1055
|
+
default:
|
|
1056
|
+
return null;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
function isNullable(propDef) {
|
|
1060
|
+
return "nullable" in propDef && propDef.nullable === true;
|
|
1061
|
+
}
|
|
1062
|
+
function getPhpDocType(propDef, schemas) {
|
|
1063
|
+
const nullable = isNullable(propDef);
|
|
1064
|
+
switch (propDef.type) {
|
|
1065
|
+
case "String":
|
|
1066
|
+
case "Text":
|
|
1067
|
+
case "LongText":
|
|
1068
|
+
case "Email":
|
|
1069
|
+
case "Password":
|
|
1070
|
+
return "string" + (nullable ? "|null" : "");
|
|
1071
|
+
case "Int":
|
|
1072
|
+
case "BigInt":
|
|
1073
|
+
return "int" + (nullable ? "|null" : "");
|
|
1074
|
+
case "Float":
|
|
1075
|
+
case "Decimal":
|
|
1076
|
+
return "float" + (nullable ? "|null" : "");
|
|
1077
|
+
case "Boolean":
|
|
1078
|
+
return "bool" + (nullable ? "|null" : "");
|
|
1079
|
+
case "Date":
|
|
1080
|
+
case "Time":
|
|
1081
|
+
case "Timestamp":
|
|
1082
|
+
return "\\Carbon\\Carbon" + (nullable ? "|null" : "");
|
|
1083
|
+
case "Json":
|
|
1084
|
+
return "array" + (nullable ? "|null" : "");
|
|
1085
|
+
case "Enum":
|
|
1086
|
+
case "EnumRef":
|
|
1087
|
+
return "string" + (nullable ? "|null" : "");
|
|
1088
|
+
case "Association": {
|
|
1089
|
+
const assoc = propDef;
|
|
1090
|
+
if (assoc.target) {
|
|
1091
|
+
const className = toPascalCase(assoc.target);
|
|
1092
|
+
switch (assoc.relation) {
|
|
1093
|
+
case "OneToMany":
|
|
1094
|
+
case "ManyToMany":
|
|
1095
|
+
case "MorphMany":
|
|
1096
|
+
case "MorphToMany":
|
|
1097
|
+
case "MorphedByMany":
|
|
1098
|
+
return `\\Illuminate\\Database\\Eloquent\\Collection<${className}>`;
|
|
1099
|
+
default:
|
|
1100
|
+
return className + "|null";
|
|
1106
1101
|
}
|
|
1107
|
-
];
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
const type = getPropertyType(property, allSchemas);
|
|
1111
|
-
return [{
|
|
1112
|
-
name: toPropertyName(propertyName),
|
|
1113
|
-
type,
|
|
1114
|
-
optional: baseProp.nullable ?? false,
|
|
1115
|
-
readonly: isReadonly,
|
|
1116
|
-
comment: baseProp.displayName
|
|
1117
|
-
}];
|
|
1118
|
-
}
|
|
1119
|
-
function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
|
|
1120
|
-
return propertyToTSProperties(propertyName, property, allSchemas, options)[0];
|
|
1121
|
-
}
|
|
1122
|
-
function schemaToInterface(schema, allSchemas, options = {}) {
|
|
1123
|
-
const properties = [];
|
|
1124
|
-
if (schema.options?.id !== false) {
|
|
1125
|
-
const pkType = schema.options?.idType ?? "BigInt";
|
|
1126
|
-
properties.push({
|
|
1127
|
-
name: "id",
|
|
1128
|
-
type: PK_TYPE_MAP[pkType] ?? "number",
|
|
1129
|
-
optional: false,
|
|
1130
|
-
readonly: options.readonly ?? true,
|
|
1131
|
-
comment: "Primary key"
|
|
1132
|
-
});
|
|
1133
|
-
}
|
|
1134
|
-
if (schema.properties) {
|
|
1135
|
-
for (const [propName, property] of Object.entries(schema.properties)) {
|
|
1136
|
-
properties.push(...propertyToTSProperties(propName, property, allSchemas, options));
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
if (schema.options?.timestamps !== false) {
|
|
1140
|
-
properties.push(
|
|
1141
|
-
{
|
|
1142
|
-
name: "createdAt",
|
|
1143
|
-
type: "string",
|
|
1144
|
-
optional: true,
|
|
1145
|
-
readonly: options.readonly ?? true,
|
|
1146
|
-
comment: "Creation timestamp"
|
|
1147
|
-
},
|
|
1148
|
-
{
|
|
1149
|
-
name: "updatedAt",
|
|
1150
|
-
type: "string",
|
|
1151
|
-
optional: true,
|
|
1152
|
-
readonly: options.readonly ?? true,
|
|
1153
|
-
comment: "Last update timestamp"
|
|
1154
1102
|
}
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
name: "deletedAt",
|
|
1160
|
-
type: "string",
|
|
1161
|
-
optional: true,
|
|
1162
|
-
readonly: options.readonly ?? true,
|
|
1163
|
-
comment: "Soft delete timestamp"
|
|
1164
|
-
});
|
|
1103
|
+
return "mixed";
|
|
1104
|
+
}
|
|
1105
|
+
default:
|
|
1106
|
+
return "mixed";
|
|
1165
1107
|
}
|
|
1108
|
+
}
|
|
1109
|
+
function generateBaseModel(schemas, options, stubContent) {
|
|
1110
|
+
const modelMap = Object.values(schemas).filter((s) => s.kind !== "enum").map((s) => {
|
|
1111
|
+
const className = toPascalCase(s.name);
|
|
1112
|
+
return ` '${s.name}' => \\${options.modelNamespace}\\${className}::class,`;
|
|
1113
|
+
}).join("\n");
|
|
1114
|
+
const content = stubContent.replace(/\{\{BASE_MODEL_NAMESPACE\}\}/g, options.baseModelNamespace).replace(/\{\{BASE_MODEL_CLASS\}\}/g, options.baseModelClassName).replace(/\{\{MODEL_MAP\}\}/g, modelMap);
|
|
1166
1115
|
return {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1116
|
+
path: `${options.baseModelPath}/${options.baseModelClassName}.php`,
|
|
1117
|
+
content,
|
|
1118
|
+
type: "base-model",
|
|
1119
|
+
overwrite: true,
|
|
1120
|
+
schemaName: "__base__"
|
|
1170
1121
|
};
|
|
1171
1122
|
}
|
|
1172
|
-
function
|
|
1173
|
-
const
|
|
1174
|
-
const
|
|
1175
|
-
const
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
const
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
const
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1123
|
+
function generateEntityBaseModel(schema, schemas, options, stubContent, authStubContent) {
|
|
1124
|
+
const className = toPascalCase(schema.name);
|
|
1125
|
+
const tableName = schema.options?.tableName ?? pluralize(toSnakeCase(schema.name));
|
|
1126
|
+
const isAuth = schema.options?.authenticatable ?? false;
|
|
1127
|
+
const primaryKey = "id";
|
|
1128
|
+
const idType = schema.options?.idType ?? "BigInt";
|
|
1129
|
+
const isUuid = idType === "Uuid";
|
|
1130
|
+
const isStringKey = idType === "Uuid" || idType === "String";
|
|
1131
|
+
const imports = [];
|
|
1132
|
+
const traits = [];
|
|
1133
|
+
const fillable = [];
|
|
1134
|
+
const hidden = [];
|
|
1135
|
+
const appends = [];
|
|
1136
|
+
const casts = [];
|
|
1137
|
+
const relations = [];
|
|
1138
|
+
const docProperties = [];
|
|
1139
|
+
if (schema.options?.softDelete) {
|
|
1140
|
+
imports.push("use Illuminate\\Database\\Eloquent\\SoftDeletes;");
|
|
1141
|
+
traits.push(" use SoftDeletes;");
|
|
1142
|
+
}
|
|
1143
|
+
const properties = schema.properties ?? {};
|
|
1144
|
+
for (const [propName, propDef] of Object.entries(properties)) {
|
|
1145
|
+
const snakeName = toSnakeCase(propName);
|
|
1146
|
+
const phpType = getPhpDocType(propDef, schemas);
|
|
1147
|
+
docProperties.push(` * @property ${phpType} $${snakeName}`);
|
|
1148
|
+
if (propDef.type === "Association") {
|
|
1149
|
+
const assoc = propDef;
|
|
1150
|
+
if (assoc.target) {
|
|
1151
|
+
imports.push(`use ${options.modelNamespace}\\${toPascalCase(assoc.target)};`);
|
|
1152
|
+
}
|
|
1153
|
+
relations.push(generateRelation(propName, assoc, options));
|
|
1154
|
+
if (assoc.relation === "ManyToOne" || assoc.relation === "OneToOne") {
|
|
1155
|
+
if (!assoc.mappedBy) {
|
|
1156
|
+
const fkName = toSnakeCase(propName) + "_id";
|
|
1157
|
+
fillable.push(` '${fkName}',`);
|
|
1158
|
+
docProperties.push(` * @property int|null $${fkName}`);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
} else if (propDef.type === "Password") {
|
|
1162
|
+
fillable.push(` '${snakeName}',`);
|
|
1163
|
+
hidden.push(` '${snakeName}',`);
|
|
1164
|
+
const cast = getCastType(propDef);
|
|
1165
|
+
if (cast) {
|
|
1166
|
+
casts.push(` '${snakeName}' => '${cast}',`);
|
|
1167
|
+
}
|
|
1168
|
+
} else if (propDef.type === "File") {
|
|
1169
|
+
const relMethod = generateFileRelation(propName, propDef);
|
|
1170
|
+
relations.push(relMethod);
|
|
1171
|
+
} else {
|
|
1172
|
+
fillable.push(` '${snakeName}',`);
|
|
1173
|
+
const cast = getCastType(propDef);
|
|
1174
|
+
if (cast) {
|
|
1175
|
+
casts.push(` '${snakeName}' => '${cast}',`);
|
|
1176
|
+
}
|
|
1195
1177
|
}
|
|
1196
|
-
interfaces.push(schemaToInterface(schema, schemas, options));
|
|
1197
1178
|
}
|
|
1198
|
-
|
|
1199
|
-
}
|
|
1179
|
+
const docComment = `/**
|
|
1180
|
+
* ${className}BaseModel
|
|
1181
|
+
*
|
|
1182
|
+
${docProperties.join("\n")}
|
|
1183
|
+
*/`;
|
|
1184
|
+
const stub = isAuth ? authStubContent : stubContent;
|
|
1185
|
+
const keyType = isStringKey ? ` /**
|
|
1186
|
+
* The "type" of the primary key ID.
|
|
1187
|
+
*/
|
|
1188
|
+
protected $keyType = 'string';
|
|
1200
1189
|
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1190
|
+
` : "";
|
|
1191
|
+
const incrementing = isUuid ? ` /**
|
|
1192
|
+
* Indicates if the IDs are auto-incrementing.
|
|
1193
|
+
*/
|
|
1194
|
+
public $incrementing = false;
|
|
1195
|
+
|
|
1196
|
+
` : "";
|
|
1197
|
+
if (isUuid) {
|
|
1198
|
+
imports.push("use Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;");
|
|
1199
|
+
traits.push(" use HasUuids;");
|
|
1211
1200
|
}
|
|
1212
|
-
const
|
|
1213
|
-
name: toEnumMemberName(value),
|
|
1214
|
-
value
|
|
1215
|
-
}));
|
|
1201
|
+
const content = stub.replace(/\{\{BASE_MODEL_NAMESPACE\}\}/g, options.baseModelNamespace).replace(/\{\{BASE_MODEL_CLASS\}\}/g, options.baseModelClassName).replace(/\{\{CLASS_NAME\}\}/g, className).replace(/\{\{TABLE_NAME\}\}/g, tableName).replace(/\{\{PRIMARY_KEY\}\}/g, primaryKey).replace(/\{\{KEY_TYPE\}\}/g, keyType).replace(/\{\{INCREMENTING\}\}/g, incrementing).replace(/\{\{TIMESTAMPS\}\}/g, schema.options?.timestamps !== false ? "true" : "false").replace(/\{\{IMPORTS\}\}/g, [...new Set(imports)].sort().join("\n")).replace(/\{\{TRAITS\}\}/g, traits.join("\n")).replace(/\{\{DOC_COMMENT\}\}/g, docComment).replace(/\{\{FILLABLE\}\}/g, fillable.join("\n")).replace(/\{\{HIDDEN\}\}/g, hidden.join("\n")).replace(/\{\{APPENDS\}\}/g, appends.join("\n")).replace(/\{\{CASTS\}\}/g, casts.join("\n")).replace(/\{\{RELATIONS\}\}/g, relations.join("\n\n"));
|
|
1216
1202
|
return {
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1203
|
+
path: `${options.baseModelPath}/${className}BaseModel.php`,
|
|
1204
|
+
content,
|
|
1205
|
+
type: "entity-base",
|
|
1206
|
+
overwrite: true,
|
|
1207
|
+
schemaName: schema.name
|
|
1220
1208
|
};
|
|
1221
1209
|
}
|
|
1222
|
-
function
|
|
1223
|
-
const
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1210
|
+
function generateRelation(propName, assoc, options) {
|
|
1211
|
+
const methodName = toCamelCase(propName);
|
|
1212
|
+
const targetClass = assoc.target ? toPascalCase(assoc.target) : "";
|
|
1213
|
+
const fkName = toSnakeCase(propName) + "_id";
|
|
1214
|
+
switch (assoc.relation) {
|
|
1215
|
+
case "ManyToOne":
|
|
1216
|
+
return ` /**
|
|
1217
|
+
* Get the ${propName} that owns this model.
|
|
1218
|
+
*/
|
|
1219
|
+
public function ${methodName}(): BelongsTo
|
|
1220
|
+
{
|
|
1221
|
+
return $this->belongsTo(${targetClass}::class, '${fkName}');
|
|
1222
|
+
}`;
|
|
1223
|
+
case "OneToOne":
|
|
1224
|
+
if (assoc.mappedBy) {
|
|
1225
|
+
return ` /**
|
|
1226
|
+
* Get the ${propName} for this model.
|
|
1227
|
+
*/
|
|
1228
|
+
public function ${methodName}(): HasOne
|
|
1229
|
+
{
|
|
1230
|
+
return $this->hasOne(${targetClass}::class, '${toSnakeCase(assoc.mappedBy)}_id');
|
|
1231
|
+
}`;
|
|
1229
1232
|
}
|
|
1233
|
+
return ` /**
|
|
1234
|
+
* Get the ${propName} that owns this model.
|
|
1235
|
+
*/
|
|
1236
|
+
public function ${methodName}(): BelongsTo
|
|
1237
|
+
{
|
|
1238
|
+
return $this->belongsTo(${targetClass}::class, '${fkName}');
|
|
1239
|
+
}`;
|
|
1240
|
+
case "OneToMany":
|
|
1241
|
+
return ` /**
|
|
1242
|
+
* Get the ${propName} for this model.
|
|
1243
|
+
*/
|
|
1244
|
+
public function ${methodName}(): HasMany
|
|
1245
|
+
{
|
|
1246
|
+
return $this->hasMany(${targetClass}::class, '${toSnakeCase(assoc.inversedBy ?? propName)}_id');
|
|
1247
|
+
}`;
|
|
1248
|
+
case "ManyToMany": {
|
|
1249
|
+
const pivotTable = assoc.joinTable ?? `${toSnakeCase(propName)}_pivot`;
|
|
1250
|
+
return ` /**
|
|
1251
|
+
* The ${propName} that belong to this model.
|
|
1252
|
+
*/
|
|
1253
|
+
public function ${methodName}(): BelongsToMany
|
|
1254
|
+
{
|
|
1255
|
+
return $this->belongsToMany(${targetClass}::class, '${pivotTable}')
|
|
1256
|
+
->withTimestamps();
|
|
1257
|
+
}`;
|
|
1230
1258
|
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
${
|
|
1242
|
-
|
|
1259
|
+
case "MorphTo":
|
|
1260
|
+
return ` /**
|
|
1261
|
+
* Get the parent ${propName} model.
|
|
1262
|
+
*/
|
|
1263
|
+
public function ${methodName}(): MorphTo
|
|
1264
|
+
{
|
|
1265
|
+
return $this->morphTo('${methodName}');
|
|
1266
|
+
}`;
|
|
1267
|
+
case "MorphOne":
|
|
1268
|
+
return ` /**
|
|
1269
|
+
* Get the ${propName} for this model.
|
|
1270
|
+
*/
|
|
1271
|
+
public function ${methodName}(): MorphOne
|
|
1272
|
+
{
|
|
1273
|
+
return $this->morphOne(${targetClass}::class, '${assoc.morphName ?? propName}');
|
|
1274
|
+
}`;
|
|
1275
|
+
case "MorphMany":
|
|
1276
|
+
return ` /**
|
|
1277
|
+
* Get the ${propName} for this model.
|
|
1278
|
+
*/
|
|
1279
|
+
public function ${methodName}(): MorphMany
|
|
1280
|
+
{
|
|
1281
|
+
return $this->morphMany(${targetClass}::class, '${assoc.morphName ?? propName}');
|
|
1282
|
+
}`;
|
|
1283
|
+
default:
|
|
1284
|
+
return ` // TODO: Implement ${assoc.relation} relation for ${propName}`;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
function generateFileRelation(propName, propDef) {
|
|
1288
|
+
const methodName = toCamelCase(propName);
|
|
1289
|
+
const relationType = propDef.multiple ? "MorphMany" : "MorphOne";
|
|
1290
|
+
const relationMethod = propDef.multiple ? "morphMany" : "morphOne";
|
|
1291
|
+
return ` /**
|
|
1292
|
+
* Get the ${propName} file(s) for this model.
|
|
1293
|
+
*/
|
|
1294
|
+
public function ${methodName}(): ${relationType}
|
|
1295
|
+
{
|
|
1296
|
+
return $this->${relationMethod}(FileUpload::class, 'uploadable')
|
|
1297
|
+
->where('attribute_name', '${propName}');
|
|
1298
|
+
}`;
|
|
1243
1299
|
}
|
|
1244
|
-
function
|
|
1245
|
-
const
|
|
1300
|
+
function generateEntityModel(schema, options, stubContent) {
|
|
1301
|
+
const className = toPascalCase(schema.name);
|
|
1302
|
+
const content = stubContent.replace(/\{\{BASE_MODEL_NAMESPACE\}\}/g, options.baseModelNamespace).replace(/\{\{MODEL_NAMESPACE\}\}/g, options.modelNamespace).replace(/\{\{CLASS_NAME\}\}/g, className);
|
|
1246
1303
|
return {
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1304
|
+
path: `${options.modelPath}/${className}.php`,
|
|
1305
|
+
content,
|
|
1306
|
+
type: "entity",
|
|
1307
|
+
overwrite: false,
|
|
1308
|
+
// Never overwrite user models
|
|
1309
|
+
schemaName: schema.name
|
|
1250
1310
|
};
|
|
1251
1311
|
}
|
|
1252
|
-
function
|
|
1253
|
-
const
|
|
1254
|
-
|
|
1312
|
+
function getStubContent(stubName) {
|
|
1313
|
+
const stubs = {
|
|
1314
|
+
"base-model": `<?php
|
|
1315
|
+
|
|
1316
|
+
namespace {{BASE_MODEL_NAMESPACE}};
|
|
1317
|
+
|
|
1318
|
+
/**
|
|
1319
|
+
* Base model class for all Omnify-generated models.
|
|
1320
|
+
* Contains model mapping for polymorphic relations.
|
|
1321
|
+
*
|
|
1322
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
1323
|
+
* Any changes will be overwritten on next generation.
|
|
1324
|
+
*
|
|
1325
|
+
* @generated by @famgia/omnify-laravel
|
|
1255
1326
|
*/
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1327
|
+
|
|
1328
|
+
use Illuminate\\Database\\Eloquent\\Model;
|
|
1329
|
+
use Illuminate\\Database\\Eloquent\\Relations\\Relation;
|
|
1330
|
+
|
|
1331
|
+
abstract class {{BASE_MODEL_CLASS}} extends Model
|
|
1332
|
+
{
|
|
1333
|
+
/**
|
|
1334
|
+
* Model class map for polymorphic relations.
|
|
1335
|
+
*/
|
|
1336
|
+
protected static array $modelMap = [
|
|
1337
|
+
{{MODEL_MAP}}
|
|
1338
|
+
];
|
|
1339
|
+
|
|
1340
|
+
/**
|
|
1341
|
+
* Boot the model and register morph map.
|
|
1342
|
+
*/
|
|
1343
|
+
protected static function boot(): void
|
|
1344
|
+
{
|
|
1345
|
+
parent::boot();
|
|
1346
|
+
|
|
1347
|
+
// Register morph map for polymorphic relations
|
|
1348
|
+
Relation::enforceMorphMap(static::$modelMap);
|
|
1264
1349
|
}
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
type: enumProp.enum.map((v) => `'${v}'`).join(" | "),
|
|
1273
|
-
comment: enumProp.displayName ?? `${schema.name} ${propName} enum`
|
|
1274
|
-
});
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
if (property.type === "Select") {
|
|
1278
|
-
const selectProp = property;
|
|
1279
|
-
if (selectProp.options && selectProp.options.length > 0) {
|
|
1280
|
-
const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;
|
|
1281
|
-
typeAliases.push({
|
|
1282
|
-
name: typeName,
|
|
1283
|
-
type: selectProp.options.map((v) => `'${v}'`).join(" | "),
|
|
1284
|
-
comment: selectProp.displayName ?? `${schema.name} ${propName} options`
|
|
1285
|
-
});
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1350
|
+
|
|
1351
|
+
/**
|
|
1352
|
+
* Get the model class for a given morph type.
|
|
1353
|
+
*/
|
|
1354
|
+
public static function getModelClass(string $morphType): ?string
|
|
1355
|
+
{
|
|
1356
|
+
return static::$modelMap[$morphType] ?? null;
|
|
1288
1357
|
}
|
|
1289
|
-
}
|
|
1290
|
-
return typeAliases;
|
|
1291
1358
|
}
|
|
1359
|
+
`,
|
|
1360
|
+
"entity-base": `<?php
|
|
1292
1361
|
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
function generateHeader() {
|
|
1301
|
-
return `/**
|
|
1302
|
-
* Auto-generated TypeScript types from Omnify schemas.
|
|
1303
|
-
* DO NOT EDIT - This file is automatically generated.
|
|
1362
|
+
namespace {{BASE_MODEL_NAMESPACE}};
|
|
1363
|
+
|
|
1364
|
+
/**
|
|
1365
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
1366
|
+
* Any changes will be overwritten on next generation.
|
|
1367
|
+
*
|
|
1368
|
+
* @generated by @famgia/omnify-laravel
|
|
1304
1369
|
*/
|
|
1305
1370
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1371
|
+
use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;
|
|
1372
|
+
use Illuminate\\Database\\Eloquent\\Relations\\HasMany;
|
|
1373
|
+
use Illuminate\\Database\\Eloquent\\Relations\\HasOne;
|
|
1374
|
+
use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;
|
|
1375
|
+
use Illuminate\\Database\\Eloquent\\Relations\\MorphTo;
|
|
1376
|
+
use Illuminate\\Database\\Eloquent\\Relations\\MorphOne;
|
|
1377
|
+
use Illuminate\\Database\\Eloquent\\Relations\\MorphMany;
|
|
1378
|
+
use Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;
|
|
1379
|
+
use Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;
|
|
1380
|
+
{{IMPORTS}}
|
|
1381
|
+
|
|
1382
|
+
{{DOC_COMMENT}}
|
|
1383
|
+
class {{CLASS_NAME}}BaseModel extends {{BASE_MODEL_CLASS}}
|
|
1384
|
+
{
|
|
1385
|
+
{{TRAITS}}
|
|
1386
|
+
/**
|
|
1387
|
+
* The table associated with the model.
|
|
1388
|
+
*/
|
|
1389
|
+
protected $table = '{{TABLE_NAME}}';
|
|
1390
|
+
|
|
1391
|
+
/**
|
|
1392
|
+
* The primary key for the model.
|
|
1393
|
+
*/
|
|
1394
|
+
protected $primaryKey = '{{PRIMARY_KEY}}';
|
|
1395
|
+
|
|
1396
|
+
{{KEY_TYPE}}
|
|
1397
|
+
{{INCREMENTING}}
|
|
1398
|
+
/**
|
|
1399
|
+
* Indicates if the model should be timestamped.
|
|
1400
|
+
*/
|
|
1401
|
+
public $timestamps = {{TIMESTAMPS}};
|
|
1402
|
+
|
|
1403
|
+
/**
|
|
1404
|
+
* The attributes that are mass assignable.
|
|
1405
|
+
*/
|
|
1406
|
+
protected $fillable = [
|
|
1407
|
+
{{FILLABLE}}
|
|
1408
|
+
];
|
|
1409
|
+
|
|
1410
|
+
/**
|
|
1411
|
+
* The attributes that should be hidden for serialization.
|
|
1412
|
+
*/
|
|
1413
|
+
protected $hidden = [
|
|
1414
|
+
{{HIDDEN}}
|
|
1415
|
+
];
|
|
1416
|
+
|
|
1417
|
+
/**
|
|
1418
|
+
* The accessors to append to the model's array form.
|
|
1419
|
+
*/
|
|
1420
|
+
protected $appends = [
|
|
1421
|
+
{{APPENDS}}
|
|
1422
|
+
];
|
|
1423
|
+
|
|
1424
|
+
/**
|
|
1425
|
+
* Get the attributes that should be cast.
|
|
1426
|
+
*/
|
|
1427
|
+
protected function casts(): array
|
|
1428
|
+
{
|
|
1429
|
+
return [
|
|
1430
|
+
{{CASTS}}
|
|
1431
|
+
];
|
|
1337
1432
|
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
fileName: opts.fileName ?? "types.ts",
|
|
1341
|
-
content: parts.join("").trim() + "\n",
|
|
1342
|
-
types
|
|
1343
|
-
};
|
|
1433
|
+
|
|
1434
|
+
{{RELATIONS}}
|
|
1344
1435
|
}
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1436
|
+
`,
|
|
1437
|
+
"entity-base-auth": `<?php
|
|
1438
|
+
|
|
1439
|
+
namespace {{BASE_MODEL_NAMESPACE}};
|
|
1440
|
+
|
|
1441
|
+
/**
|
|
1442
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
1443
|
+
* Any changes will be overwritten on next generation.
|
|
1444
|
+
*
|
|
1445
|
+
* @generated by @famgia/omnify-laravel
|
|
1446
|
+
*/
|
|
1447
|
+
|
|
1448
|
+
use Illuminate\\Foundation\\Auth\\User as Authenticatable;
|
|
1449
|
+
use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;
|
|
1450
|
+
use Illuminate\\Database\\Eloquent\\Relations\\HasMany;
|
|
1451
|
+
use Illuminate\\Database\\Eloquent\\Relations\\HasOne;
|
|
1452
|
+
use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;
|
|
1453
|
+
use Illuminate\\Database\\Eloquent\\Relations\\MorphTo;
|
|
1454
|
+
use Illuminate\\Database\\Eloquent\\Relations\\MorphOne;
|
|
1455
|
+
use Illuminate\\Database\\Eloquent\\Relations\\MorphMany;
|
|
1456
|
+
use Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;
|
|
1457
|
+
use Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;
|
|
1458
|
+
use Illuminate\\Notifications\\Notifiable;
|
|
1459
|
+
{{IMPORTS}}
|
|
1460
|
+
|
|
1461
|
+
{{DOC_COMMENT}}
|
|
1462
|
+
class {{CLASS_NAME}}BaseModel extends Authenticatable
|
|
1463
|
+
{
|
|
1464
|
+
use Notifiable;
|
|
1465
|
+
{{TRAITS}}
|
|
1466
|
+
/**
|
|
1467
|
+
* The table associated with the model.
|
|
1468
|
+
*/
|
|
1469
|
+
protected $table = '{{TABLE_NAME}}';
|
|
1470
|
+
|
|
1471
|
+
/**
|
|
1472
|
+
* The primary key for the model.
|
|
1473
|
+
*/
|
|
1474
|
+
protected $primaryKey = '{{PRIMARY_KEY}}';
|
|
1475
|
+
|
|
1476
|
+
{{KEY_TYPE}}
|
|
1477
|
+
{{INCREMENTING}}
|
|
1478
|
+
/**
|
|
1479
|
+
* Indicates if the model should be timestamped.
|
|
1480
|
+
*/
|
|
1481
|
+
public $timestamps = {{TIMESTAMPS}};
|
|
1482
|
+
|
|
1483
|
+
/**
|
|
1484
|
+
* The attributes that are mass assignable.
|
|
1485
|
+
*/
|
|
1486
|
+
protected $fillable = [
|
|
1487
|
+
{{FILLABLE}}
|
|
1488
|
+
];
|
|
1489
|
+
|
|
1490
|
+
/**
|
|
1491
|
+
* The attributes that should be hidden for serialization.
|
|
1492
|
+
*/
|
|
1493
|
+
protected $hidden = [
|
|
1494
|
+
{{HIDDEN}}
|
|
1495
|
+
];
|
|
1496
|
+
|
|
1497
|
+
/**
|
|
1498
|
+
* The accessors to append to the model's array form.
|
|
1499
|
+
*/
|
|
1500
|
+
protected $appends = [
|
|
1501
|
+
{{APPENDS}}
|
|
1502
|
+
];
|
|
1503
|
+
|
|
1504
|
+
/**
|
|
1505
|
+
* Get the attributes that should be cast.
|
|
1506
|
+
*/
|
|
1507
|
+
protected function casts(): array
|
|
1508
|
+
{
|
|
1509
|
+
return [
|
|
1510
|
+
{{CASTS}}
|
|
1511
|
+
];
|
|
1413
1512
|
}
|
|
1414
|
-
|
|
1415
|
-
|
|
1513
|
+
|
|
1514
|
+
{{RELATIONS}}
|
|
1416
1515
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1516
|
+
`,
|
|
1517
|
+
"entity": `<?php
|
|
1518
|
+
|
|
1519
|
+
namespace {{MODEL_NAMESPACE}};
|
|
1520
|
+
|
|
1521
|
+
use {{BASE_MODEL_NAMESPACE}}\\{{CLASS_NAME}}BaseModel;
|
|
1522
|
+
use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
|
|
1523
|
+
|
|
1524
|
+
/**
|
|
1525
|
+
* {{CLASS_NAME}} Model
|
|
1526
|
+
*
|
|
1527
|
+
* This file is generated once and can be customized.
|
|
1528
|
+
* Add your custom methods and logic here.
|
|
1529
|
+
*/
|
|
1530
|
+
class {{CLASS_NAME}} extends {{CLASS_NAME}}BaseModel
|
|
1531
|
+
{
|
|
1532
|
+
use HasFactory;
|
|
1533
|
+
|
|
1534
|
+
/**
|
|
1535
|
+
* Create a new model instance.
|
|
1536
|
+
*/
|
|
1537
|
+
public function __construct(array $attributes = [])
|
|
1538
|
+
{
|
|
1539
|
+
parent::__construct($attributes);
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
// Add your custom methods here
|
|
1424
1543
|
}
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
if (file.fileName === "index.ts") continue;
|
|
1429
|
-
const moduleName = file.fileName.replace(".ts", ".js");
|
|
1430
|
-
exports.push(`export * from './${moduleName}';`);
|
|
1431
|
-
}
|
|
1432
|
-
return exports.join("\n") + "\n";
|
|
1544
|
+
`
|
|
1545
|
+
};
|
|
1546
|
+
return stubs[stubName] ?? "";
|
|
1433
1547
|
}
|
|
1434
|
-
function
|
|
1435
|
-
const
|
|
1436
|
-
|
|
1437
|
-
|
|
1548
|
+
function generateModels(schemas, options) {
|
|
1549
|
+
const resolved = resolveOptions(options);
|
|
1550
|
+
const models = [];
|
|
1551
|
+
models.push(generateBaseModel(schemas, resolved, getStubContent("base-model")));
|
|
1552
|
+
for (const schema of Object.values(schemas)) {
|
|
1553
|
+
if (schema.kind === "enum") {
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
models.push(generateEntityBaseModel(
|
|
1557
|
+
schema,
|
|
1558
|
+
schemas,
|
|
1559
|
+
resolved,
|
|
1560
|
+
getStubContent("entity-base"),
|
|
1561
|
+
getStubContent("entity-base-auth")
|
|
1562
|
+
));
|
|
1563
|
+
models.push(generateEntityModel(schema, resolved, getStubContent("entity")));
|
|
1438
1564
|
}
|
|
1439
|
-
return
|
|
1565
|
+
return models;
|
|
1440
1566
|
}
|
|
1441
|
-
function
|
|
1442
|
-
return
|
|
1567
|
+
function getModelPath(model) {
|
|
1568
|
+
return model.path;
|
|
1443
1569
|
}
|
|
1444
1570
|
|
|
1445
1571
|
// src/plugin.ts
|
|
1446
1572
|
var LARAVEL_CONFIG_SCHEMA = {
|
|
1447
1573
|
fields: [
|
|
1448
|
-
// Paths group
|
|
1449
1574
|
{
|
|
1450
1575
|
key: "migrationsPath",
|
|
1451
1576
|
type: "path",
|
|
1452
1577
|
label: "Migrations Path",
|
|
1453
1578
|
description: "Directory for Laravel migration files",
|
|
1454
1579
|
default: "database/migrations",
|
|
1455
|
-
group: "
|
|
1580
|
+
group: "output"
|
|
1456
1581
|
},
|
|
1457
1582
|
{
|
|
1458
|
-
key: "
|
|
1583
|
+
key: "modelsPath",
|
|
1459
1584
|
type: "path",
|
|
1460
|
-
label: "
|
|
1461
|
-
description: "Directory for
|
|
1462
|
-
default: "
|
|
1463
|
-
group: "
|
|
1464
|
-
},
|
|
1465
|
-
// Generators group
|
|
1466
|
-
{
|
|
1467
|
-
key: "generateMigrations",
|
|
1468
|
-
type: "boolean",
|
|
1469
|
-
label: "Generate Migrations",
|
|
1470
|
-
description: "Generate Laravel migration files",
|
|
1471
|
-
default: true,
|
|
1472
|
-
group: "generators"
|
|
1585
|
+
label: "Models Path",
|
|
1586
|
+
description: "Directory for user-editable model files",
|
|
1587
|
+
default: "app/Models",
|
|
1588
|
+
group: "output"
|
|
1473
1589
|
},
|
|
1474
1590
|
{
|
|
1475
|
-
key: "
|
|
1476
|
-
type: "
|
|
1477
|
-
label: "
|
|
1478
|
-
description: "
|
|
1479
|
-
default:
|
|
1480
|
-
group: "
|
|
1591
|
+
key: "baseModelsPath",
|
|
1592
|
+
type: "path",
|
|
1593
|
+
label: "Base Models Path",
|
|
1594
|
+
description: "Directory for auto-generated base model files",
|
|
1595
|
+
default: "app/Models/OmnifyBase",
|
|
1596
|
+
group: "output"
|
|
1481
1597
|
},
|
|
1482
|
-
// Options group
|
|
1483
1598
|
{
|
|
1484
|
-
key: "
|
|
1599
|
+
key: "generateModels",
|
|
1485
1600
|
type: "boolean",
|
|
1486
|
-
label: "
|
|
1487
|
-
description: "Generate
|
|
1601
|
+
label: "Generate Models",
|
|
1602
|
+
description: "Generate Eloquent model classes",
|
|
1488
1603
|
default: true,
|
|
1489
1604
|
group: "options"
|
|
1490
1605
|
},
|
|
@@ -1498,69 +1613,69 @@ var LARAVEL_CONFIG_SCHEMA = {
|
|
|
1498
1613
|
}
|
|
1499
1614
|
]
|
|
1500
1615
|
};
|
|
1501
|
-
function
|
|
1616
|
+
function resolveOptions2(options) {
|
|
1502
1617
|
return {
|
|
1503
1618
|
migrationsPath: options?.migrationsPath ?? "database/migrations",
|
|
1504
|
-
|
|
1505
|
-
|
|
1619
|
+
modelsPath: options?.modelsPath ?? "app/Models",
|
|
1620
|
+
baseModelsPath: options?.baseModelsPath ?? "app/Models/OmnifyBase",
|
|
1621
|
+
modelNamespace: options?.modelNamespace ?? "App\\Models",
|
|
1622
|
+
baseModelNamespace: options?.baseModelNamespace ?? "App\\Models\\OmnifyBase",
|
|
1623
|
+
generateModels: options?.generateModels ?? true,
|
|
1506
1624
|
connection: options?.connection,
|
|
1507
|
-
timestamp: options?.timestamp
|
|
1508
|
-
generateTypes: options?.generateTypes ?? true,
|
|
1509
|
-
generateMigrations: options?.generateMigrations ?? true
|
|
1625
|
+
timestamp: options?.timestamp
|
|
1510
1626
|
};
|
|
1511
1627
|
}
|
|
1512
1628
|
function laravelPlugin(options) {
|
|
1513
|
-
const resolved =
|
|
1629
|
+
const resolved = resolveOptions2(options);
|
|
1630
|
+
const migrationGenerator = {
|
|
1631
|
+
name: "laravel-migrations",
|
|
1632
|
+
description: "Generate Laravel migration files",
|
|
1633
|
+
generate: async (ctx) => {
|
|
1634
|
+
const migrationOptions = {
|
|
1635
|
+
connection: resolved.connection,
|
|
1636
|
+
timestamp: resolved.timestamp
|
|
1637
|
+
};
|
|
1638
|
+
const migrations = generateMigrations(ctx.schemas, migrationOptions);
|
|
1639
|
+
return migrations.map((migration) => ({
|
|
1640
|
+
path: getMigrationPath(migration, resolved.migrationsPath),
|
|
1641
|
+
content: migration.content,
|
|
1642
|
+
type: "migration",
|
|
1643
|
+
metadata: {
|
|
1644
|
+
tableName: migration.tables[0],
|
|
1645
|
+
migrationType: migration.type
|
|
1646
|
+
}
|
|
1647
|
+
}));
|
|
1648
|
+
}
|
|
1649
|
+
};
|
|
1650
|
+
const modelGenerator = {
|
|
1651
|
+
name: "laravel-models",
|
|
1652
|
+
description: "Generate Eloquent model classes",
|
|
1653
|
+
generate: async (ctx) => {
|
|
1654
|
+
const modelOptions = {
|
|
1655
|
+
modelNamespace: resolved.modelNamespace,
|
|
1656
|
+
baseModelNamespace: resolved.baseModelNamespace,
|
|
1657
|
+
modelPath: resolved.modelsPath,
|
|
1658
|
+
baseModelPath: resolved.baseModelsPath
|
|
1659
|
+
};
|
|
1660
|
+
const models = generateModels(ctx.schemas, modelOptions);
|
|
1661
|
+
return models.map((model) => ({
|
|
1662
|
+
path: getModelPath(model),
|
|
1663
|
+
content: model.content,
|
|
1664
|
+
type: "model",
|
|
1665
|
+
// Skip writing user models if they already exist
|
|
1666
|
+
skipIfExists: !model.overwrite,
|
|
1667
|
+
metadata: {
|
|
1668
|
+
modelType: model.type,
|
|
1669
|
+
schemaName: model.schemaName
|
|
1670
|
+
}
|
|
1671
|
+
}));
|
|
1672
|
+
}
|
|
1673
|
+
};
|
|
1514
1674
|
return {
|
|
1515
1675
|
name: "@famgia/omnify-laravel",
|
|
1516
|
-
version: "0.0.
|
|
1676
|
+
version: "0.0.14",
|
|
1517
1677
|
configSchema: LARAVEL_CONFIG_SCHEMA,
|
|
1518
|
-
generators: [
|
|
1519
|
-
// Laravel Migrations Generator
|
|
1520
|
-
...resolved.generateMigrations ? [
|
|
1521
|
-
{
|
|
1522
|
-
name: "laravel-migrations",
|
|
1523
|
-
description: "Generate Laravel migration files",
|
|
1524
|
-
generate: async (ctx) => {
|
|
1525
|
-
const migrationOptions = {
|
|
1526
|
-
connection: resolved.connection,
|
|
1527
|
-
timestamp: resolved.timestamp
|
|
1528
|
-
};
|
|
1529
|
-
const migrations = generateMigrations(ctx.schemas, migrationOptions);
|
|
1530
|
-
return migrations.map((migration) => ({
|
|
1531
|
-
path: getMigrationPath(migration, resolved.migrationsPath),
|
|
1532
|
-
content: migration.content,
|
|
1533
|
-
type: "migration",
|
|
1534
|
-
metadata: {
|
|
1535
|
-
tableName: migration.tables[0],
|
|
1536
|
-
migrationType: migration.type
|
|
1537
|
-
}
|
|
1538
|
-
}));
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
] : [],
|
|
1542
|
-
// TypeScript Types Generator
|
|
1543
|
-
...resolved.generateTypes ? [
|
|
1544
|
-
{
|
|
1545
|
-
name: "typescript-types",
|
|
1546
|
-
description: "Generate TypeScript type definitions",
|
|
1547
|
-
generate: async (ctx) => {
|
|
1548
|
-
const tsOptions = {
|
|
1549
|
-
singleFile: resolved.singleFile
|
|
1550
|
-
};
|
|
1551
|
-
const files = generateTypeScript(ctx.schemas, tsOptions);
|
|
1552
|
-
return files.map((file) => ({
|
|
1553
|
-
path: `${resolved.typesPath}/${file.fileName}`,
|
|
1554
|
-
content: file.content,
|
|
1555
|
-
type: "type",
|
|
1556
|
-
metadata: {
|
|
1557
|
-
types: file.types
|
|
1558
|
-
}
|
|
1559
|
-
}));
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
] : []
|
|
1563
|
-
]
|
|
1678
|
+
generators: resolved.generateModels ? [migrationGenerator, modelGenerator] : [migrationGenerator]
|
|
1564
1679
|
};
|
|
1565
1680
|
}
|
|
1566
1681
|
|
|
@@ -1584,26 +1699,6 @@ export {
|
|
|
1584
1699
|
generateAlterMigration,
|
|
1585
1700
|
generateDropTableMigration,
|
|
1586
1701
|
generateMigrationsFromChanges,
|
|
1587
|
-
toPropertyName,
|
|
1588
|
-
toInterfaceName,
|
|
1589
|
-
getPropertyType,
|
|
1590
|
-
propertyToTSProperty,
|
|
1591
|
-
schemaToInterface,
|
|
1592
|
-
formatProperty,
|
|
1593
|
-
formatInterface,
|
|
1594
|
-
generateInterfaces,
|
|
1595
|
-
toEnumMemberName,
|
|
1596
|
-
toEnumName,
|
|
1597
|
-
schemaToEnum,
|
|
1598
|
-
generateEnums,
|
|
1599
|
-
formatEnum,
|
|
1600
|
-
enumToUnionType,
|
|
1601
|
-
formatTypeAlias,
|
|
1602
|
-
extractInlineEnums,
|
|
1603
|
-
generateTypeScriptFile,
|
|
1604
|
-
generateTypeScriptFiles,
|
|
1605
|
-
generateTypeScript,
|
|
1606
|
-
getTypeScriptPath,
|
|
1607
1702
|
laravelPlugin
|
|
1608
1703
|
};
|
|
1609
|
-
//# sourceMappingURL=chunk-
|
|
1704
|
+
//# sourceMappingURL=chunk-UVF7W2J2.js.map
|