@omnifyjp/ts 3.2.8 → 3.2.10
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.
|
@@ -16,11 +16,83 @@ export function generateFileModels(reader, config) {
|
|
|
16
16
|
files.push(generateFileBaseModel(config, defaultDisk));
|
|
17
17
|
files.push(generateFileUserModel(config));
|
|
18
18
|
files.push(generateFileStatusEnum(config));
|
|
19
|
+
files.push(generateFileResourceBase(config));
|
|
20
|
+
files.push(generateFileResourceUser(config));
|
|
19
21
|
if (locale) {
|
|
20
22
|
files.push(generateFileLocales(config, locale.locales));
|
|
21
23
|
}
|
|
22
24
|
return files;
|
|
23
25
|
}
|
|
26
|
+
function generateFileResourceBase(config) {
|
|
27
|
+
const baseNamespace = resolveModularBaseNamespace(config, 'File', 'Resources', config.resources.baseNamespace);
|
|
28
|
+
const content = `<?php
|
|
29
|
+
|
|
30
|
+
namespace ${baseNamespace};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
34
|
+
* Any changes will be overwritten on next generation.
|
|
35
|
+
*
|
|
36
|
+
* @generated by omnify
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
use Illuminate\\Http\\Request;
|
|
40
|
+
use Illuminate\\Http\\Resources\\Json\\JsonResource;
|
|
41
|
+
|
|
42
|
+
class FileResourceBase extends JsonResource
|
|
43
|
+
{
|
|
44
|
+
/**
|
|
45
|
+
* Transform the resource into an array.
|
|
46
|
+
*
|
|
47
|
+
* @return array<string, mixed>
|
|
48
|
+
*/
|
|
49
|
+
public function toArray(Request $request): array
|
|
50
|
+
{
|
|
51
|
+
return [
|
|
52
|
+
'id' => $this->id,
|
|
53
|
+
'collection' => $this->collection,
|
|
54
|
+
'disk' => $this->disk,
|
|
55
|
+
'path' => $this->path,
|
|
56
|
+
'original_name' => $this->original_name,
|
|
57
|
+
'mime_type' => $this->mime_type,
|
|
58
|
+
'size' => $this->size,
|
|
59
|
+
'status' => $this->status?->value,
|
|
60
|
+
'url' => $this->url ?? null,
|
|
61
|
+
'expires_at' => $this->expires_at?->toISOString(),
|
|
62
|
+
'sort_order' => $this->sort_order,
|
|
63
|
+
'created_at' => $this->created_at?->toISOString(),
|
|
64
|
+
'updated_at' => $this->updated_at?->toISOString(),
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
69
|
+
return baseFile(resolveModularBasePath(config, 'File', 'Resources', 'FileResourceBase.php', config.resources.basePath), content);
|
|
70
|
+
}
|
|
71
|
+
function generateFileResourceUser(config) {
|
|
72
|
+
const resourceNamespace = config.resources.namespace;
|
|
73
|
+
const baseNamespace = resolveModularBaseNamespace(config, 'File', 'Resources', config.resources.baseNamespace);
|
|
74
|
+
const content = `<?php
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* File Resource
|
|
78
|
+
*
|
|
79
|
+
* SAFE TO EDIT - This file is never overwritten by Omnify.
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
namespace ${resourceNamespace};
|
|
83
|
+
|
|
84
|
+
use ${baseNamespace}\\FileResourceBase;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* FileResource — add project-specific serialization here.
|
|
88
|
+
*/
|
|
89
|
+
class FileResource extends FileResourceBase
|
|
90
|
+
{
|
|
91
|
+
//
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
return userFile(`${config.resources.path}/FileResource.php`, content);
|
|
95
|
+
}
|
|
24
96
|
function generateFileBaseModel(config, defaultDisk) {
|
|
25
97
|
const baseNamespace = resolveModularBaseNamespace(config, 'File', 'Models', config.models.baseNamespace);
|
|
26
98
|
const localesNamespace = resolveModularBaseNamespace(config, 'File', 'Locales', config.models.baseNamespace + '\\Locales');
|
|
@@ -31,7 +31,8 @@ function generateBaseService(name, schema, reader, config) {
|
|
|
31
31
|
const modelNs = config.models.namespace;
|
|
32
32
|
const properties = schema.properties ?? {};
|
|
33
33
|
const propertyOrder = reader.getPropertyOrder(name);
|
|
34
|
-
|
|
34
|
+
const expandedProperties = reader.getExpandedProperties(name);
|
|
35
|
+
// Collect searchable, filterable, sortable fields (compound types expand to sub-columns)
|
|
35
36
|
const searchableFields = [];
|
|
36
37
|
const filterableFields = [];
|
|
37
38
|
const sortableFields = [];
|
|
@@ -41,14 +42,44 @@ function generateBaseService(name, schema, reader, config) {
|
|
|
41
42
|
continue;
|
|
42
43
|
const colName = toSnakeCase(propName);
|
|
43
44
|
const translatable = prop.translatable ?? false;
|
|
45
|
+
const expansion = expandedProperties[propName];
|
|
44
46
|
if (prop.searchable) {
|
|
45
|
-
|
|
47
|
+
if (expansion && expansion.columns.length > 0) {
|
|
48
|
+
// Compound type: search all sub-columns
|
|
49
|
+
for (const col of expansion.columns) {
|
|
50
|
+
if (col.name) {
|
|
51
|
+
searchableFields.push({ propName: col.name, colName: col.name, translatable });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
searchableFields.push({ propName, colName, translatable });
|
|
57
|
+
}
|
|
46
58
|
}
|
|
47
59
|
if (prop.filterable) {
|
|
48
|
-
|
|
60
|
+
if (expansion && expansion.columns.length > 0) {
|
|
61
|
+
// Compound type: filter on each sub-column
|
|
62
|
+
for (const col of expansion.columns) {
|
|
63
|
+
if (col.name) {
|
|
64
|
+
filterableFields.push({ propName: col.name, colName: col.name, type: col.type ?? 'String', prop, translatable });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
filterableFields.push({ propName, colName, type: prop.type, prop, translatable });
|
|
70
|
+
}
|
|
49
71
|
}
|
|
50
72
|
if (prop.sortable) {
|
|
51
|
-
|
|
73
|
+
if (expansion && expansion.columns.length > 0) {
|
|
74
|
+
// Compound type: sort by primary sub-column (first one)
|
|
75
|
+
const primaryCol = expansion.columns[0];
|
|
76
|
+
if (primaryCol?.name) {
|
|
77
|
+
sortableFields.push({ propName: colName, colName: primaryCol.name, translatable });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
sortableFields.push({ propName: colName, colName, translatable });
|
|
82
|
+
}
|
|
52
83
|
}
|
|
53
84
|
}
|
|
54
85
|
// Build search block
|
|
@@ -281,22 +312,31 @@ function buildSortBlock(sortableFields) {
|
|
|
281
312
|
$query->orderBy('created_at', 'desc');
|
|
282
313
|
`;
|
|
283
314
|
}
|
|
284
|
-
|
|
285
|
-
const
|
|
315
|
+
// allowedSorts uses logical propName (what user sends in ?sort=)
|
|
316
|
+
const allowedList = sortableFields.map(f => `'${f.propName}'`).join(', ');
|
|
317
|
+
// sortMap: logical name → actual column name (compound types map to sub-column)
|
|
318
|
+
const needsMap = sortableFields.some(f => f.propName !== f.colName);
|
|
319
|
+
const sortMapEntries = sortableFields
|
|
320
|
+
.filter(f => f.propName !== f.colName)
|
|
321
|
+
.map(f => ` '${f.propName}' => '${f.colName}',`)
|
|
322
|
+
.join('\n');
|
|
323
|
+
const sortMapDecl = needsMap ? `\n $sortMap = [\n${sortMapEntries}\n ];` : '';
|
|
324
|
+
const sortColResolve = needsMap ? `\n $sortCol = $sortMap[$sortField] ?? $sortField;` : `\n $sortCol = $sortField;`;
|
|
325
|
+
const translatableSorts = sortableFields.filter(f => f.translatable).map(f => `'${f.propName}'`);
|
|
286
326
|
const translatableCheck = translatableSorts.length > 0
|
|
287
|
-
? `\n
|
|
327
|
+
? `\n $translatableSorts = [${translatableSorts.join(', ')}];`
|
|
288
328
|
: '';
|
|
289
329
|
const orderByLine = translatableSorts.length > 0
|
|
290
330
|
? ` if (in_array($sortField, $translatableSorts ?? [], true)) {
|
|
291
|
-
$query->orderByTranslation($
|
|
331
|
+
$query->orderByTranslation($sortCol, $direction);
|
|
292
332
|
} else {
|
|
293
|
-
$query->orderBy($
|
|
333
|
+
$query->orderBy($sortCol, $direction);
|
|
294
334
|
}`
|
|
295
|
-
: ` $query->orderBy($
|
|
335
|
+
: ` $query->orderBy($sortCol, $direction);`;
|
|
296
336
|
return `
|
|
297
337
|
// Sort
|
|
298
338
|
$sortParam = $filters['sort'] ?? '-created_at';
|
|
299
|
-
$allowedSorts = [${allowedList}];${translatableCheck}
|
|
339
|
+
$allowedSorts = [${allowedList}];${sortMapDecl}${translatableCheck}
|
|
300
340
|
|
|
301
341
|
foreach (explode(',', $sortParam) as $sortField) {
|
|
302
342
|
$sortField = trim($sortField);
|
|
@@ -307,7 +347,7 @@ function buildSortBlock(sortableFields) {
|
|
|
307
347
|
$sortField = substr($sortField, 1);
|
|
308
348
|
}
|
|
309
349
|
|
|
310
|
-
if (in_array($sortField, $allowedSorts, true) || $sortField === 'created_at' || $sortField === 'updated_at') {
|
|
350
|
+
if (in_array($sortField, $allowedSorts, true) || $sortField === 'created_at' || $sortField === 'updated_at') {${sortColResolve}
|
|
311
351
|
${orderByLine}
|
|
312
352
|
}
|
|
313
353
|
}
|