@omnifyjp/ts 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +13 -0
- package/dist/cli.js +180 -0
- package/dist/enum-generator.d.ts +28 -0
- package/dist/enum-generator.js +253 -0
- package/dist/generator.d.ts +19 -0
- package/dist/generator.js +330 -0
- package/dist/i18n-generator.d.ts +10 -0
- package/dist/i18n-generator.js +143 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +9 -0
- package/dist/interface-generator.d.ts +31 -0
- package/dist/interface-generator.js +341 -0
- package/dist/php/base-model-generator.d.ts +7 -0
- package/dist/php/base-model-generator.js +70 -0
- package/dist/php/factory-generator.d.ts +7 -0
- package/dist/php/factory-generator.js +95 -0
- package/dist/php/faker-mapper.d.ts +12 -0
- package/dist/php/faker-mapper.js +206 -0
- package/dist/php/index.d.ts +18 -0
- package/dist/php/index.js +40 -0
- package/dist/php/locales-generator.d.ts +7 -0
- package/dist/php/locales-generator.js +135 -0
- package/dist/php/model-generator.d.ts +7 -0
- package/dist/php/model-generator.js +396 -0
- package/dist/php/naming-helper.d.ts +22 -0
- package/dist/php/naming-helper.js +61 -0
- package/dist/php/relation-builder.d.ts +12 -0
- package/dist/php/relation-builder.js +147 -0
- package/dist/php/request-generator.d.ts +7 -0
- package/dist/php/request-generator.js +221 -0
- package/dist/php/resource-generator.d.ts +7 -0
- package/dist/php/resource-generator.js +178 -0
- package/dist/php/schema-reader.d.ts +28 -0
- package/dist/php/schema-reader.js +79 -0
- package/dist/php/service-provider-generator.d.ts +7 -0
- package/dist/php/service-provider-generator.js +64 -0
- package/dist/php/trait-generator.d.ts +6 -0
- package/dist/php/trait-generator.js +104 -0
- package/dist/php/type-mapper.d.ts +25 -0
- package/dist/php/type-mapper.js +217 -0
- package/dist/php/types.d.ts +61 -0
- package/dist/php/types.js +68 -0
- package/dist/types.d.ts +196 -0
- package/dist/types.js +6 -0
- package/dist/zod-generator.d.ts +32 -0
- package/dist/zod-generator.js +428 -0
- package/package.json +31 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of RequestGenerator.php — generates Store/Update request classes.
|
|
3
|
+
*/
|
|
4
|
+
import { toPascalCase, toSnakeCase, toCamelCase } from './naming-helper.js';
|
|
5
|
+
import { toStoreRules, toUpdateRules, formatRules, hasRuleObject } from './type-mapper.js';
|
|
6
|
+
import { baseFile, userFile } from './types.js';
|
|
7
|
+
/** Generate Store/Update request classes for all visible object schemas. */
|
|
8
|
+
export function generateRequests(reader, config) {
|
|
9
|
+
const files = [];
|
|
10
|
+
for (const [name, schema] of Object.entries(reader.getVisibleObjectSchemas())) {
|
|
11
|
+
files.push(...generateForSchema(name, schema, reader, config));
|
|
12
|
+
}
|
|
13
|
+
return files;
|
|
14
|
+
}
|
|
15
|
+
function generateForSchema(name, schema, reader, config) {
|
|
16
|
+
return [
|
|
17
|
+
generateBaseRequest(name, schema, reader, config, 'Store'),
|
|
18
|
+
generateBaseRequest(name, schema, reader, config, 'Update'),
|
|
19
|
+
generateUserRequest(name, config, 'Store'),
|
|
20
|
+
generateUserRequest(name, config, 'Update'),
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
function generateBaseRequest(name, schema, reader, config, action) {
|
|
24
|
+
const modelName = toPascalCase(name);
|
|
25
|
+
const baseNamespace = config.requests.baseNamespace;
|
|
26
|
+
const modelBaseNamespace = config.models.baseNamespace;
|
|
27
|
+
const properties = (schema.properties ?? {});
|
|
28
|
+
const expandedProperties = reader.getExpandedProperties(name);
|
|
29
|
+
const propertyOrder = reader.getPropertyOrder(name);
|
|
30
|
+
const tableName = reader.getTableName(name);
|
|
31
|
+
const modelRouteParam = toCamelCase(name);
|
|
32
|
+
const isUpdate = action === 'Update';
|
|
33
|
+
let needsRuleImport = false;
|
|
34
|
+
const rulesLines = [];
|
|
35
|
+
const attributeKeys = [];
|
|
36
|
+
for (const propName of propertyOrder) {
|
|
37
|
+
const prop = properties[propName];
|
|
38
|
+
if (!prop)
|
|
39
|
+
continue;
|
|
40
|
+
const type = prop['type'] ?? 'String';
|
|
41
|
+
// Compound type: generate rules for expanded columns
|
|
42
|
+
if (expandedProperties[propName]) {
|
|
43
|
+
const expansion = expandedProperties[propName];
|
|
44
|
+
for (const col of expansion.columns ?? []) {
|
|
45
|
+
const colAny = col;
|
|
46
|
+
const colName = col.name ?? '';
|
|
47
|
+
const colProp = {
|
|
48
|
+
type: col.type ?? 'String',
|
|
49
|
+
nullable: col.nullable ?? false,
|
|
50
|
+
length: colAny['length'] ?? null,
|
|
51
|
+
unique: false,
|
|
52
|
+
};
|
|
53
|
+
// Handle enum in expanded columns
|
|
54
|
+
const colEnum = colAny['enum'];
|
|
55
|
+
if (colEnum) {
|
|
56
|
+
if (typeof colEnum === 'object' && colEnum !== null && 'values' in colEnum) {
|
|
57
|
+
colProp['type'] = 'Enum';
|
|
58
|
+
colProp['enum'] = colEnum['values'];
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
colProp['enum'] = colEnum;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const rules = isUpdate
|
|
65
|
+
? toUpdateRules(colProp, tableName, modelRouteParam)
|
|
66
|
+
: toStoreRules(colProp, tableName);
|
|
67
|
+
if (hasRuleObject(rules))
|
|
68
|
+
needsRuleImport = true;
|
|
69
|
+
rulesLines.push(` '${colName}' => ${formatRules(rules)},`);
|
|
70
|
+
attributeKeys.push(colName);
|
|
71
|
+
}
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
// Skip non-fillable associations except ManyToOne
|
|
75
|
+
if (type === 'Association') {
|
|
76
|
+
const relation = prop['relation'] ?? '';
|
|
77
|
+
if (relation !== 'ManyToOne')
|
|
78
|
+
continue;
|
|
79
|
+
const snakeName = toSnakeCase(propName) + '_id';
|
|
80
|
+
const rules = isUpdate
|
|
81
|
+
? toUpdateRules(prop, tableName, modelRouteParam)
|
|
82
|
+
: toStoreRules(prop, tableName);
|
|
83
|
+
rulesLines.push(` '${snakeName}' => ${formatRules(rules)},`);
|
|
84
|
+
attributeKeys.push(snakeName);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const snakeName = toSnakeCase(propName);
|
|
88
|
+
const rules = isUpdate
|
|
89
|
+
? toUpdateRules(prop, tableName, modelRouteParam)
|
|
90
|
+
: toStoreRules(prop, tableName);
|
|
91
|
+
if (hasRuleObject(rules))
|
|
92
|
+
needsRuleImport = true;
|
|
93
|
+
rulesLines.push(` '${snakeName}' => ${formatRules(rules)},`);
|
|
94
|
+
attributeKeys.push(snakeName);
|
|
95
|
+
}
|
|
96
|
+
const rulesContent = rulesLines.join('\n');
|
|
97
|
+
const localesClass = `${modelBaseNamespace}\\Locales\\${modelName}Locales`;
|
|
98
|
+
const attributeKeysList = attributeKeys.map(k => ` '${k}',`).join('\n');
|
|
99
|
+
const ruleImport = needsRuleImport ? '\nuse Illuminate\\Validation\\Rule;' : '';
|
|
100
|
+
const content = `<?php
|
|
101
|
+
|
|
102
|
+
namespace ${baseNamespace};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
106
|
+
* Any changes will be overwritten on next generation.
|
|
107
|
+
*
|
|
108
|
+
* @generated by omnify
|
|
109
|
+
*/
|
|
110
|
+
|
|
111
|
+
use Illuminate\\Foundation\\Http\\FormRequest;${ruleImport}
|
|
112
|
+
use ${localesClass};
|
|
113
|
+
|
|
114
|
+
abstract class ${modelName}${action}RequestBase extends FormRequest
|
|
115
|
+
{
|
|
116
|
+
/**
|
|
117
|
+
* Get the schema-defined validation rules.
|
|
118
|
+
*
|
|
119
|
+
* @return array<string, array>
|
|
120
|
+
*/
|
|
121
|
+
protected function schemaRules(): array
|
|
122
|
+
{
|
|
123
|
+
return [
|
|
124
|
+
${rulesContent}
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Get custom attributes for validator errors.
|
|
130
|
+
* Resolves display names from Locales using the current app locale.
|
|
131
|
+
*
|
|
132
|
+
* @return array<string, string>
|
|
133
|
+
*/
|
|
134
|
+
protected function schemaAttributes(): array
|
|
135
|
+
{
|
|
136
|
+
$locale = app()->getLocale();
|
|
137
|
+
$fallback = config('app.fallback_locale', 'en');
|
|
138
|
+
$propertyNames = ${modelName}Locales::PROPERTY_DISPLAY_NAMES;
|
|
139
|
+
$attributes = [];
|
|
140
|
+
|
|
141
|
+
$keys = [
|
|
142
|
+
${attributeKeysList}
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
foreach ($keys as $key) {
|
|
146
|
+
$names = $propertyNames[$key] ?? [];
|
|
147
|
+
$attributes[$key] = $names[$locale] ?? $names[$fallback] ?? $names[array_key_first($names) ?? 'en'] ?? $key;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return $attributes;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
`;
|
|
154
|
+
return baseFile(`${config.requests.basePath}/${modelName}${action}RequestBase.php`, content);
|
|
155
|
+
}
|
|
156
|
+
function generateUserRequest(name, config, action) {
|
|
157
|
+
const modelName = toPascalCase(name);
|
|
158
|
+
const requestNamespace = config.requests.namespace;
|
|
159
|
+
const baseNamespace = config.requests.baseNamespace;
|
|
160
|
+
const content = `<?php
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* ${modelName} ${action} Request
|
|
164
|
+
*
|
|
165
|
+
* SAFE TO EDIT - This file is never overwritten by Omnify.
|
|
166
|
+
*/
|
|
167
|
+
|
|
168
|
+
namespace ${requestNamespace};
|
|
169
|
+
|
|
170
|
+
use Illuminate\\Http\\Request;
|
|
171
|
+
use ${baseNamespace}\\${modelName}${action}RequestBase;
|
|
172
|
+
|
|
173
|
+
class ${modelName}${action}Request extends ${modelName}${action}RequestBase
|
|
174
|
+
{
|
|
175
|
+
/**
|
|
176
|
+
* Determine if the user is authorized to make this request.
|
|
177
|
+
*/
|
|
178
|
+
public function authorize(): bool
|
|
179
|
+
{
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get the validation rules that apply to the request.
|
|
185
|
+
*
|
|
186
|
+
* @return array<string, \\Illuminate\\Contracts\\Validation\\ValidationRule|array<mixed>|string>
|
|
187
|
+
*/
|
|
188
|
+
public function rules(): array
|
|
189
|
+
{
|
|
190
|
+
return array_merge($this->schemaRules(), [
|
|
191
|
+
// Custom rules here
|
|
192
|
+
]);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get custom attributes for validator errors.
|
|
197
|
+
*
|
|
198
|
+
* @return array<string, string>
|
|
199
|
+
*/
|
|
200
|
+
public function attributes(): array
|
|
201
|
+
{
|
|
202
|
+
return array_merge($this->schemaAttributes(), [
|
|
203
|
+
// Custom attributes here
|
|
204
|
+
]);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Get the error messages for the defined validation rules.
|
|
209
|
+
*
|
|
210
|
+
* @return array<string, string>
|
|
211
|
+
*/
|
|
212
|
+
public function messages(): array
|
|
213
|
+
{
|
|
214
|
+
return [
|
|
215
|
+
// Custom messages here
|
|
216
|
+
];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
`;
|
|
220
|
+
return userFile(`${config.requests.path}/${modelName}${action}Request.php`, content);
|
|
221
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of ResourceGenerator.php — generates API Resource classes.
|
|
3
|
+
*/
|
|
4
|
+
import { SchemaReader } from './schema-reader.js';
|
|
5
|
+
import type { GeneratedFile, PhpConfig } from './types.js';
|
|
6
|
+
/** Generate Resource classes for all visible object schemas. */
|
|
7
|
+
export declare function generateResources(reader: SchemaReader, config: PhpConfig): GeneratedFile[];
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of ResourceGenerator.php — generates API Resource classes.
|
|
3
|
+
*/
|
|
4
|
+
import { toPascalCase, toSnakeCase, toCamelCase } from './naming-helper.js';
|
|
5
|
+
import { isHiddenByDefault, toResourceExpression } from './type-mapper.js';
|
|
6
|
+
import { baseFile, userFile } from './types.js';
|
|
7
|
+
/** Generate Resource classes for all visible object schemas. */
|
|
8
|
+
export function generateResources(reader, config) {
|
|
9
|
+
const files = [];
|
|
10
|
+
for (const [name, schema] of Object.entries(reader.getVisibleObjectSchemas())) {
|
|
11
|
+
files.push(generateBaseResource(name, schema, reader, config));
|
|
12
|
+
files.push(generateUserResource(name, config));
|
|
13
|
+
}
|
|
14
|
+
return files;
|
|
15
|
+
}
|
|
16
|
+
function generateBaseResource(name, schema, reader, config) {
|
|
17
|
+
const modelName = toPascalCase(name);
|
|
18
|
+
const baseNamespace = config.resources.baseNamespace;
|
|
19
|
+
const resourceNamespace = config.resources.namespace;
|
|
20
|
+
const modelNamespace = config.models.namespace;
|
|
21
|
+
const properties = (schema.properties ?? {});
|
|
22
|
+
const expandedProperties = reader.getExpandedProperties(name);
|
|
23
|
+
const propertyOrder = reader.getPropertyOrder(name);
|
|
24
|
+
const options = schema.options ?? {};
|
|
25
|
+
const hasTimestamps = options.timestamps ?? false;
|
|
26
|
+
const hasSoftDelete = options.softDelete ?? false;
|
|
27
|
+
const hasId = options.id ?? true;
|
|
28
|
+
const fields = [];
|
|
29
|
+
if (hasId) {
|
|
30
|
+
fields.push(" 'id' => $this->id,");
|
|
31
|
+
}
|
|
32
|
+
for (const propName of propertyOrder) {
|
|
33
|
+
const prop = properties[propName];
|
|
34
|
+
if (!prop)
|
|
35
|
+
continue;
|
|
36
|
+
const type = prop['type'] ?? 'String';
|
|
37
|
+
const hidden = prop['hidden'] ?? false;
|
|
38
|
+
if (isHiddenByDefault(type) || hidden)
|
|
39
|
+
continue;
|
|
40
|
+
if (type === 'Association') {
|
|
41
|
+
addAssociationFields(propName, prop, fields, resourceNamespace, modelNamespace);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (expandedProperties[propName]) {
|
|
45
|
+
for (const col of expandedProperties[propName].columns ?? []) {
|
|
46
|
+
const colName = col.name ?? '';
|
|
47
|
+
const colType = col.type ?? 'String';
|
|
48
|
+
const expr = toResourceExpression(colName, colType);
|
|
49
|
+
fields.push(` '${colName}' => ${expr},`);
|
|
50
|
+
}
|
|
51
|
+
const sourceType = expandedProperties[propName].sourceType ?? '';
|
|
52
|
+
const snakeName = toSnakeCase(propName);
|
|
53
|
+
switch (sourceType) {
|
|
54
|
+
case 'JapaneseName':
|
|
55
|
+
fields.push(` '${snakeName}_full_name' => $this->${snakeName}_full_name,`);
|
|
56
|
+
fields.push(` '${snakeName}_full_name_kana' => $this->${snakeName}_full_name_kana,`);
|
|
57
|
+
break;
|
|
58
|
+
case 'JapaneseAddress':
|
|
59
|
+
fields.push(` '${snakeName}_full_address' => $this->${snakeName}_full_address,`);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const snakeName = toSnakeCase(propName);
|
|
65
|
+
const expr = toResourceExpression(snakeName, type);
|
|
66
|
+
fields.push(` '${snakeName}' => ${expr},`);
|
|
67
|
+
}
|
|
68
|
+
if (hasTimestamps) {
|
|
69
|
+
fields.push(" 'created_at' => $this->created_at?->toISOString(),");
|
|
70
|
+
fields.push(" 'updated_at' => $this->updated_at?->toISOString(),");
|
|
71
|
+
}
|
|
72
|
+
if (hasSoftDelete) {
|
|
73
|
+
fields.push(" 'deleted_at' => $this->deleted_at?->toISOString(),");
|
|
74
|
+
}
|
|
75
|
+
const fieldsContent = fields.join('\n');
|
|
76
|
+
const content = `<?php
|
|
77
|
+
|
|
78
|
+
namespace ${baseNamespace};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
82
|
+
* Any changes will be overwritten on next generation.
|
|
83
|
+
*
|
|
84
|
+
* @generated by omnify
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
use Illuminate\\Http\\Request;
|
|
88
|
+
use Illuminate\\Http\\Resources\\Json\\JsonResource;
|
|
89
|
+
|
|
90
|
+
class ${modelName}ResourceBase extends JsonResource
|
|
91
|
+
{
|
|
92
|
+
/**
|
|
93
|
+
* Transform the schema-defined fields into an array.
|
|
94
|
+
*
|
|
95
|
+
* @return array<string, mixed>
|
|
96
|
+
*/
|
|
97
|
+
protected function schemaArray(Request $request): array
|
|
98
|
+
{
|
|
99
|
+
return [
|
|
100
|
+
${fieldsContent}
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
return baseFile(`${config.resources.basePath}/${modelName}ResourceBase.php`, content);
|
|
106
|
+
}
|
|
107
|
+
function generateUserResource(name, config) {
|
|
108
|
+
const modelName = toPascalCase(name);
|
|
109
|
+
const resourceNamespace = config.resources.namespace;
|
|
110
|
+
const baseNamespace = config.resources.baseNamespace;
|
|
111
|
+
const content = `<?php
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* ${modelName} Resource
|
|
115
|
+
*
|
|
116
|
+
* SAFE TO EDIT - This file is never overwritten by Omnify.
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
namespace ${resourceNamespace};
|
|
120
|
+
|
|
121
|
+
use Illuminate\\Http\\Request;
|
|
122
|
+
use ${baseNamespace}\\${modelName}ResourceBase;
|
|
123
|
+
|
|
124
|
+
class ${modelName}Resource extends ${modelName}ResourceBase
|
|
125
|
+
{
|
|
126
|
+
/**
|
|
127
|
+
* Transform the resource into an array.
|
|
128
|
+
*
|
|
129
|
+
* @return array<string, mixed>
|
|
130
|
+
*/
|
|
131
|
+
public function toArray(Request $request): array
|
|
132
|
+
{
|
|
133
|
+
return array_merge($this->schemaArray($request), [
|
|
134
|
+
// Custom fields here
|
|
135
|
+
]);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get additional data that should be returned with the resource array.
|
|
140
|
+
*
|
|
141
|
+
* @return array<string, mixed>
|
|
142
|
+
*/
|
|
143
|
+
public function with(Request $request): array
|
|
144
|
+
{
|
|
145
|
+
return [
|
|
146
|
+
// Additional metadata here
|
|
147
|
+
];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
return userFile(`${config.resources.path}/${modelName}Resource.php`, content);
|
|
152
|
+
}
|
|
153
|
+
function addAssociationFields(propName, prop, fields, resourceNamespace, modelNamespace) {
|
|
154
|
+
const relation = prop['relation'] ?? '';
|
|
155
|
+
const target = prop['target'] ?? '';
|
|
156
|
+
const methodName = toCamelCase(propName);
|
|
157
|
+
const targetResource = toPascalCase(target) + 'Resource';
|
|
158
|
+
switch (relation) {
|
|
159
|
+
case 'ManyToOne': {
|
|
160
|
+
const snakeName = toSnakeCase(propName) + '_id';
|
|
161
|
+
fields.push(` '${snakeName}' => $this->${snakeName},`);
|
|
162
|
+
fields.push(` '${methodName}' => $this->whenLoaded('${methodName}', fn() => new \\${resourceNamespace}\\${targetResource}($this->${methodName})),`);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
case 'OneToMany':
|
|
166
|
+
case 'ManyToMany':
|
|
167
|
+
case 'MorphMany':
|
|
168
|
+
fields.push(` '${methodName}' => $this->whenLoaded('${methodName}', fn() => \\${resourceNamespace}\\${targetResource}::collection($this->${methodName})),`);
|
|
169
|
+
break;
|
|
170
|
+
case 'OneToOne':
|
|
171
|
+
case 'MorphOne':
|
|
172
|
+
fields.push(` '${methodName}' => $this->whenLoaded('${methodName}', fn() => new \\${resourceNamespace}\\${targetResource}($this->${methodName})),`);
|
|
173
|
+
break;
|
|
174
|
+
case 'MorphTo':
|
|
175
|
+
fields.push(` '${methodName}' => $this->whenLoaded('${methodName}'),`);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of SchemaReader.php — reads schemas.json data.
|
|
3
|
+
*/
|
|
4
|
+
import type { SchemasJson, SchemaDefinition, ExpandedProperty } from '../types.js';
|
|
5
|
+
export declare class SchemaReader {
|
|
6
|
+
private data;
|
|
7
|
+
constructor(data: SchemasJson);
|
|
8
|
+
static fromData(data: SchemasJson): SchemaReader;
|
|
9
|
+
getSchemas(): Record<string, SchemaDefinition>;
|
|
10
|
+
getSchema(name: string): SchemaDefinition | undefined;
|
|
11
|
+
getObjectSchemas(): Record<string, SchemaDefinition>;
|
|
12
|
+
getVisibleObjectSchemas(): Record<string, SchemaDefinition>;
|
|
13
|
+
getEnumSchemas(): Record<string, SchemaDefinition>;
|
|
14
|
+
getCompoundTypes(): Record<string, unknown>;
|
|
15
|
+
getSimpleTypes(): Record<string, unknown>;
|
|
16
|
+
getCustomEnums(): Record<string, string[]>;
|
|
17
|
+
getDatabaseDriver(): string;
|
|
18
|
+
getLocale(): {
|
|
19
|
+
readonly locales: string[];
|
|
20
|
+
readonly defaultLocale: string;
|
|
21
|
+
readonly fallbackLocale: string;
|
|
22
|
+
};
|
|
23
|
+
getLocales(): string[];
|
|
24
|
+
getDefaultLocale(): string;
|
|
25
|
+
getExpandedProperties(schemaName: string): Record<string, ExpandedProperty>;
|
|
26
|
+
getPropertyOrder(schemaName: string): string[];
|
|
27
|
+
getTableName(schemaName: string): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of SchemaReader.php — reads schemas.json data.
|
|
3
|
+
*/
|
|
4
|
+
export class SchemaReader {
|
|
5
|
+
data;
|
|
6
|
+
constructor(data) {
|
|
7
|
+
this.data = data;
|
|
8
|
+
}
|
|
9
|
+
static fromData(data) {
|
|
10
|
+
return new SchemaReader(data);
|
|
11
|
+
}
|
|
12
|
+
getSchemas() {
|
|
13
|
+
return this.data.schemas ?? {};
|
|
14
|
+
}
|
|
15
|
+
getSchema(name) {
|
|
16
|
+
return this.data.schemas?.[name];
|
|
17
|
+
}
|
|
18
|
+
getObjectSchemas() {
|
|
19
|
+
const result = {};
|
|
20
|
+
for (const [name, schema] of Object.entries(this.getSchemas())) {
|
|
21
|
+
const kind = schema.kind ?? 'object';
|
|
22
|
+
if (kind !== 'enum' && kind !== 'partial') {
|
|
23
|
+
result[name] = schema;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
getVisibleObjectSchemas() {
|
|
29
|
+
const result = {};
|
|
30
|
+
for (const [name, schema] of Object.entries(this.getObjectSchemas())) {
|
|
31
|
+
if (!schema.options?.hidden) {
|
|
32
|
+
result[name] = schema;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
getEnumSchemas() {
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const [name, schema] of Object.entries(this.getSchemas())) {
|
|
40
|
+
if (schema.kind === 'enum') {
|
|
41
|
+
result[name] = schema;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
getCompoundTypes() {
|
|
47
|
+
return this.data.customTypes?.compound ?? {};
|
|
48
|
+
}
|
|
49
|
+
getSimpleTypes() {
|
|
50
|
+
return this.data.customTypes?.simple ?? {};
|
|
51
|
+
}
|
|
52
|
+
getCustomEnums() {
|
|
53
|
+
return this.data.customTypes?.enums ?? {};
|
|
54
|
+
}
|
|
55
|
+
getDatabaseDriver() {
|
|
56
|
+
return this.data.database?.driver ?? 'mysql';
|
|
57
|
+
}
|
|
58
|
+
getLocale() {
|
|
59
|
+
return this.data.locale ?? null;
|
|
60
|
+
}
|
|
61
|
+
getLocales() {
|
|
62
|
+
return this.data.locale?.locales ?? [];
|
|
63
|
+
}
|
|
64
|
+
getDefaultLocale() {
|
|
65
|
+
return this.data.locale?.defaultLocale ?? 'en';
|
|
66
|
+
}
|
|
67
|
+
getExpandedProperties(schemaName) {
|
|
68
|
+
const schema = this.getSchema(schemaName);
|
|
69
|
+
return (schema?.expandedProperties ?? {});
|
|
70
|
+
}
|
|
71
|
+
getPropertyOrder(schemaName) {
|
|
72
|
+
const schema = this.getSchema(schemaName);
|
|
73
|
+
return [...(schema?.propertyOrder ?? Object.keys(schema?.properties ?? {}))];
|
|
74
|
+
}
|
|
75
|
+
getTableName(schemaName) {
|
|
76
|
+
const schema = this.getSchema(schemaName);
|
|
77
|
+
return schema?.tableName ?? '';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of AppServiceProviderGenerator.php — generates OmnifyServiceProvider.
|
|
3
|
+
*/
|
|
4
|
+
import { SchemaReader } from './schema-reader.js';
|
|
5
|
+
import type { GeneratedFile, PhpConfig } from './types.js';
|
|
6
|
+
/** Generate the OmnifyServiceProvider for the application. */
|
|
7
|
+
export declare function generateServiceProvider(reader: SchemaReader, config: PhpConfig): GeneratedFile[];
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of AppServiceProviderGenerator.php — generates OmnifyServiceProvider.
|
|
3
|
+
*/
|
|
4
|
+
import { toPascalCase } from './naming-helper.js';
|
|
5
|
+
import { baseFile } from './types.js';
|
|
6
|
+
/** Generate the OmnifyServiceProvider for the application. */
|
|
7
|
+
export function generateServiceProvider(reader, config) {
|
|
8
|
+
const modelNamespace = config.models.namespace;
|
|
9
|
+
// Build morph map entries
|
|
10
|
+
const morphEntries = [];
|
|
11
|
+
for (const name of Object.keys(reader.getVisibleObjectSchemas())) {
|
|
12
|
+
const modelName = toPascalCase(name);
|
|
13
|
+
morphEntries.push(` '${modelName}' => \\${modelNamespace}\\${modelName}::class,`);
|
|
14
|
+
}
|
|
15
|
+
morphEntries.sort();
|
|
16
|
+
const morphMapContent = morphEntries.join('\n');
|
|
17
|
+
const providerNamespace = config.providers.namespace;
|
|
18
|
+
const content = `<?php
|
|
19
|
+
|
|
20
|
+
namespace ${providerNamespace};
|
|
21
|
+
|
|
22
|
+
use Illuminate\\Database\\Eloquent\\Relations\\Relation;
|
|
23
|
+
use Illuminate\\Support\\ServiceProvider;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Omnify Service Provider
|
|
27
|
+
*
|
|
28
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
29
|
+
* Any changes will be overwritten on next generation.
|
|
30
|
+
*
|
|
31
|
+
* - Loads Omnify migrations from database/migrations/omnify
|
|
32
|
+
* - Registers morph map for polymorphic relationships
|
|
33
|
+
*
|
|
34
|
+
* @generated by omnify
|
|
35
|
+
*/
|
|
36
|
+
class OmnifyServiceProvider extends ServiceProvider
|
|
37
|
+
{
|
|
38
|
+
/**
|
|
39
|
+
* Register any application services.
|
|
40
|
+
*/
|
|
41
|
+
public function register(): void
|
|
42
|
+
{
|
|
43
|
+
//
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Bootstrap any application services.
|
|
48
|
+
*/
|
|
49
|
+
public function boot(): void
|
|
50
|
+
{
|
|
51
|
+
// Load Omnify migrations from custom directory
|
|
52
|
+
$this->loadMigrationsFrom(database_path('migrations/omnify'));
|
|
53
|
+
|
|
54
|
+
// Register morph map for polymorphic relationships
|
|
55
|
+
Relation::enforceMorphMap([
|
|
56
|
+
${morphMapContent}
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
return [
|
|
62
|
+
baseFile(`${config.providers.path}/OmnifyServiceProvider.php`, content),
|
|
63
|
+
];
|
|
64
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port of TraitGenerator.php — generates HasLocalizedDisplayName trait.
|
|
3
|
+
*/
|
|
4
|
+
import type { GeneratedFile, PhpConfig } from './types.js';
|
|
5
|
+
/** Generate the HasLocalizedDisplayName trait. */
|
|
6
|
+
export declare function generateTrait(config: PhpConfig): GeneratedFile[];
|