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