@omnifyjp/omnify 3.2.12 → 3.4.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omnifyjp/omnify",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Schema-driven code generation for Laravel, TypeScript, and SQL",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"zod": "^3.24.0"
|
|
37
37
|
},
|
|
38
38
|
"optionalDependencies": {
|
|
39
|
-
"@omnifyjp/omnify-darwin-arm64": "3.
|
|
40
|
-
"@omnifyjp/omnify-darwin-x64": "3.
|
|
41
|
-
"@omnifyjp/omnify-linux-x64": "3.
|
|
42
|
-
"@omnifyjp/omnify-linux-arm64": "3.
|
|
43
|
-
"@omnifyjp/omnify-win32-x64": "3.
|
|
39
|
+
"@omnifyjp/omnify-darwin-arm64": "3.4.0",
|
|
40
|
+
"@omnifyjp/omnify-darwin-x64": "3.4.0",
|
|
41
|
+
"@omnifyjp/omnify-linux-x64": "3.4.0",
|
|
42
|
+
"@omnifyjp/omnify-linux-arm64": "3.4.0",
|
|
43
|
+
"@omnifyjp/omnify-win32-x64": "3.4.0"
|
|
44
44
|
}
|
|
45
45
|
}
|
package/ts-dist/cli.js
CHANGED
|
@@ -47,6 +47,7 @@ function resolveFromConfig(configPath) {
|
|
|
47
47
|
const laravelConfig = config.codegen?.laravel;
|
|
48
48
|
const laravelEnabled = laravelConfig?.enable === true;
|
|
49
49
|
const laravelOverrides = laravelEnabled ? {
|
|
50
|
+
rootPath: laravelConfig?.rootPath,
|
|
50
51
|
structure: laravelConfig?.structure,
|
|
51
52
|
model: laravelConfig?.model,
|
|
52
53
|
request: laravelConfig?.request,
|
|
@@ -57,6 +58,7 @@ function resolveFromConfig(configPath) {
|
|
|
57
58
|
controller: laravelConfig?.controller,
|
|
58
59
|
service: laravelConfig?.service,
|
|
59
60
|
route: laravelConfig?.route,
|
|
61
|
+
config: laravelConfig?.config,
|
|
60
62
|
nestedset: laravelConfig?.nestedset,
|
|
61
63
|
} : undefined;
|
|
62
64
|
return {
|
|
@@ -13,7 +13,7 @@ export function generateFileCleanup(reader, config) {
|
|
|
13
13
|
return [];
|
|
14
14
|
const modelNamespace = config.models.namespace;
|
|
15
15
|
const purgeHours = parseDurationHours(fileConfig.purgeAfter ?? '72h');
|
|
16
|
-
return [generateCommand(modelNamespace, purgeHours)];
|
|
16
|
+
return [generateCommand(modelNamespace, purgeHours, config)];
|
|
17
17
|
}
|
|
18
18
|
/** Parse a duration string like "72h" or "3d" to hours. */
|
|
19
19
|
function parseDurationHours(duration) {
|
|
@@ -24,7 +24,7 @@ function parseDurationHours(duration) {
|
|
|
24
24
|
const unit = match[2];
|
|
25
25
|
return unit === 'd' ? value * 24 : value;
|
|
26
26
|
}
|
|
27
|
-
function generateCommand(modelNamespace, purgeHours) {
|
|
27
|
+
function generateCommand(modelNamespace, purgeHours, config) {
|
|
28
28
|
const content = `<?php
|
|
29
29
|
|
|
30
30
|
namespace App\\Console\\Commands;
|
|
@@ -153,5 +153,8 @@ class CleanupFiles extends Command
|
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
`;
|
|
156
|
-
|
|
156
|
+
const path = config.rootPath
|
|
157
|
+
? `${config.rootPath}/app/Console/Commands/CleanupFiles.php`
|
|
158
|
+
: 'app/Console/Commands/CleanupFiles.php';
|
|
159
|
+
return baseFile(path, content);
|
|
157
160
|
}
|
|
@@ -22,7 +22,7 @@ export function generateSchemaConfig(reader, config) {
|
|
|
22
22
|
return [
|
|
23
23
|
${entries.join('\n')}];
|
|
24
24
|
`;
|
|
25
|
-
return [baseFile(
|
|
25
|
+
return [baseFile(config.configFile.path, content)];
|
|
26
26
|
}
|
|
27
27
|
function generateSchemaEntry(name, schema, reader, config) {
|
|
28
28
|
const modelName = toPascalCase(name);
|
package/ts-dist/php/types.d.ts
CHANGED
|
@@ -49,6 +49,13 @@ export interface NestedSetOverride {
|
|
|
49
49
|
}
|
|
50
50
|
/** Overrides from codegen.laravel YAML config (all optional). */
|
|
51
51
|
export interface LaravelCodegenOverrides {
|
|
52
|
+
/**
|
|
53
|
+
* Filesystem prefix applied to ALL generated paths (defaults + explicit overrides
|
|
54
|
+
* that are not already absolute). Use this for monorepo setups where the Laravel
|
|
55
|
+
* project lives in a subdirectory, e.g. `rootPath: backend` makes everything
|
|
56
|
+
* write under `backend/app/...`, `backend/config/...`, etc.
|
|
57
|
+
*/
|
|
58
|
+
rootPath?: string;
|
|
52
59
|
structure?: 'legacy' | 'modular';
|
|
53
60
|
model?: LaravelPathOverride;
|
|
54
61
|
request?: LaravelPathOverride;
|
|
@@ -59,10 +66,13 @@ export interface LaravelCodegenOverrides {
|
|
|
59
66
|
controller?: LaravelPathOverride;
|
|
60
67
|
service?: LaravelPathOverride;
|
|
61
68
|
route?: LaravelPathOverride;
|
|
69
|
+
config?: LaravelPathOverride;
|
|
62
70
|
nestedset?: NestedSetOverride;
|
|
63
71
|
}
|
|
64
72
|
/** PHP codegen configuration (resolved with defaults). */
|
|
65
73
|
export interface PhpConfig {
|
|
74
|
+
/** Filesystem prefix applied to all generated paths. Empty when not set. */
|
|
75
|
+
rootPath: string;
|
|
66
76
|
structure: 'legacy' | 'modular';
|
|
67
77
|
modulesPath: string;
|
|
68
78
|
models: {
|
|
@@ -112,6 +122,10 @@ export interface PhpConfig {
|
|
|
112
122
|
routes: {
|
|
113
123
|
path: string;
|
|
114
124
|
};
|
|
125
|
+
/** Path to the omnify-schemas.php config file (full path including filename). */
|
|
126
|
+
configFile: {
|
|
127
|
+
path: string;
|
|
128
|
+
};
|
|
115
129
|
nestedset: {
|
|
116
130
|
namespace: string;
|
|
117
131
|
};
|
package/ts-dist/php/types.js
CHANGED
|
@@ -27,7 +27,7 @@ export function resolveModularBasePath(config, schemaName, category, fileName, l
|
|
|
27
27
|
*/
|
|
28
28
|
export function resolveModularBaseNamespace(config, schemaName, category, legacyNamespace) {
|
|
29
29
|
if (config.structure === 'modular') {
|
|
30
|
-
return pathToNamespace(`${config.modulesPath}/${schemaName}/${category}`);
|
|
30
|
+
return pathToNamespace(`${stripRootPath(config, config.modulesPath)}/${schemaName}/${category}`);
|
|
31
31
|
}
|
|
32
32
|
return legacyNamespace;
|
|
33
33
|
}
|
|
@@ -49,10 +49,20 @@ export function resolveSharedBasePath(config, category, fileName, legacyPath) {
|
|
|
49
49
|
*/
|
|
50
50
|
export function resolveSharedBaseNamespace(config, category, legacyNamespace) {
|
|
51
51
|
if (config.structure === 'modular') {
|
|
52
|
-
return pathToNamespace(`${config.modulesPath}/Shared/${category}`);
|
|
52
|
+
return pathToNamespace(`${stripRootPath(config, config.modulesPath)}/Shared/${category}`);
|
|
53
53
|
}
|
|
54
54
|
return legacyNamespace;
|
|
55
55
|
}
|
|
56
|
+
/** Strip the configured rootPath prefix from a filesystem path. */
|
|
57
|
+
function stripRootPath(config, p) {
|
|
58
|
+
if (!config.rootPath)
|
|
59
|
+
return p;
|
|
60
|
+
if (p === config.rootPath)
|
|
61
|
+
return '';
|
|
62
|
+
if (p.startsWith(`${config.rootPath}/`))
|
|
63
|
+
return p.slice(config.rootPath.length + 1);
|
|
64
|
+
return p;
|
|
65
|
+
}
|
|
56
66
|
/** Convert a file path to a PHP namespace (e.g., app/Models/Omnify → App\Models\Omnify). */
|
|
57
67
|
function pathToNamespace(p) {
|
|
58
68
|
return p
|
|
@@ -60,42 +70,109 @@ function pathToNamespace(p) {
|
|
|
60
70
|
.map(s => s.charAt(0).toUpperCase() + s.slice(1))
|
|
61
71
|
.join('\\');
|
|
62
72
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Convert a PHP namespace to a Laravel filesystem path
|
|
75
|
+
* (e.g., App\Models → app/Models, App\Models\Omnify → app/Models/Omnify).
|
|
76
|
+
*
|
|
77
|
+
* Lowercases the leading "App" segment to match Laravel's autoload convention.
|
|
78
|
+
*/
|
|
79
|
+
function namespaceToPath(ns) {
|
|
80
|
+
const parts = ns.split('\\').filter(Boolean);
|
|
81
|
+
if (parts.length === 0)
|
|
82
|
+
return '';
|
|
83
|
+
if (parts[0] === 'App')
|
|
84
|
+
parts[0] = 'app';
|
|
85
|
+
return parts.join('/');
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Resolve the path/namespace pair for a target (model, policy, etc.) so they
|
|
89
|
+
* always stay in sync. Either side can be overridden independently:
|
|
90
|
+
* - both unset → use defaults
|
|
91
|
+
* - only path set → derive namespace from path
|
|
92
|
+
* - only namespace set → derive path from namespace (prevents autoload
|
|
93
|
+
* mismatches like generating App\Foo into app/Foo/Bar/)
|
|
94
|
+
* - both set → use as-is (caller is responsible for keeping them aligned)
|
|
95
|
+
*/
|
|
96
|
+
function resolvePathAndNamespace(rootPath, override, defaultPath, nsFromPath) {
|
|
97
|
+
const hasPath = override?.path !== undefined;
|
|
98
|
+
const hasNs = override?.namespace !== undefined;
|
|
99
|
+
if (hasNs && !hasPath) {
|
|
100
|
+
const namespace = override.namespace;
|
|
101
|
+
const path = withRoot(rootPath, namespaceToPath(namespace));
|
|
102
|
+
return { path, namespace };
|
|
103
|
+
}
|
|
104
|
+
const path = withRoot(rootPath, override?.path ?? defaultPath);
|
|
105
|
+
const namespace = hasNs ? override.namespace : nsFromPath(path);
|
|
106
|
+
return { path, namespace };
|
|
107
|
+
}
|
|
108
|
+
// Default paths.
|
|
109
|
+
//
|
|
110
|
+
// Hybrid projects (manual team code + Omnify codegen) need Omnify-generated
|
|
111
|
+
// files to live in their own `Omnify/` subfolder so they don't collide with
|
|
112
|
+
// hand-written controllers/services/requests/resources of the same name.
|
|
113
|
+
// See issue #32. Models keep the standard `app/Models` location because
|
|
114
|
+
// editable models are first-class entities the team owns directly; the
|
|
115
|
+
// regenerated base classes already live under `app/Modules/{Schema}/Models/`
|
|
116
|
+
// in modular structure.
|
|
117
|
+
const DEFAULT_MODEL_PATH = 'app/Models';
|
|
118
|
+
const DEFAULT_REQUEST_PATH = 'app/Http/Requests/Omnify';
|
|
119
|
+
const DEFAULT_RESOURCE_PATH = 'app/Http/Resources/Omnify';
|
|
67
120
|
const DEFAULT_FACTORY_PATH = 'database/factories';
|
|
68
121
|
const DEFAULT_PROVIDER_PATH = 'app/Providers';
|
|
69
122
|
const DEFAULT_POLICY_PATH = 'app/Policies/Omnify';
|
|
70
|
-
const DEFAULT_CONTROLLER_PATH = 'app/Http/Controllers';
|
|
71
|
-
const DEFAULT_SERVICE_PATH = 'app/Services';
|
|
123
|
+
const DEFAULT_CONTROLLER_PATH = 'app/Http/Controllers/Omnify';
|
|
124
|
+
const DEFAULT_SERVICE_PATH = 'app/Services/Omnify';
|
|
72
125
|
const DEFAULT_ROUTE_PATH = 'routes/api/omnify';
|
|
126
|
+
const DEFAULT_CONFIG_FILE_PATH = 'config/omnify-schemas.php';
|
|
127
|
+
const DEFAULT_MODULES_PATH = 'app/Modules';
|
|
128
|
+
/**
|
|
129
|
+
* Apply a rootPath prefix to a path. Absolute paths and paths that already
|
|
130
|
+
* begin with `${rootPath}/` are returned as-is, so users can mix and match
|
|
131
|
+
* if needed.
|
|
132
|
+
*/
|
|
133
|
+
function withRoot(rootPath, p) {
|
|
134
|
+
if (!rootPath)
|
|
135
|
+
return p;
|
|
136
|
+
if (p.startsWith('/'))
|
|
137
|
+
return p;
|
|
138
|
+
if (p === rootPath || p.startsWith(`${rootPath}/`))
|
|
139
|
+
return p;
|
|
140
|
+
return `${rootPath}/${p}`;
|
|
141
|
+
}
|
|
73
142
|
/**
|
|
74
143
|
* Derive full PHP config from optional overrides.
|
|
75
144
|
* All paths and namespaces fall back to sensible defaults.
|
|
76
145
|
*/
|
|
77
146
|
export function derivePhpConfig(overrides) {
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
const
|
|
147
|
+
// Strip trailing slash for stable join behavior.
|
|
148
|
+
const rootPath = (overrides?.rootPath ?? '').replace(/\/+$/, '');
|
|
149
|
+
// Namespace generation should NOT include the rootPath prefix — it's a
|
|
150
|
+
// filesystem location, not a PHP namespace component.
|
|
151
|
+
const stripRoot = (p) => {
|
|
152
|
+
if (!rootPath)
|
|
153
|
+
return p;
|
|
154
|
+
if (p === rootPath)
|
|
155
|
+
return '';
|
|
156
|
+
if (p.startsWith(`${rootPath}/`))
|
|
157
|
+
return p.slice(rootPath.length + 1);
|
|
158
|
+
return p;
|
|
159
|
+
};
|
|
160
|
+
const nsFromPath = (p) => pathToNamespace(stripRoot(p));
|
|
161
|
+
const { path: modelPath, namespace: modelNs } = resolvePathAndNamespace(rootPath, overrides?.model, DEFAULT_MODEL_PATH, nsFromPath);
|
|
162
|
+
const { path: requestPath, namespace: requestNs } = resolvePathAndNamespace(rootPath, overrides?.request, DEFAULT_REQUEST_PATH, nsFromPath);
|
|
163
|
+
const { path: resourcePath, namespace: resourceNs } = resolvePathAndNamespace(rootPath, overrides?.resource, DEFAULT_RESOURCE_PATH, nsFromPath);
|
|
164
|
+
const { path: factoryPath, namespace: factoryNs } = resolvePathAndNamespace(rootPath, overrides?.factory, DEFAULT_FACTORY_PATH, nsFromPath);
|
|
165
|
+
const { path: providerPath, namespace: providerNs } = resolvePathAndNamespace(rootPath, overrides?.provider, DEFAULT_PROVIDER_PATH, nsFromPath);
|
|
166
|
+
const { path: policyPath, namespace: policyNs } = resolvePathAndNamespace(rootPath, overrides?.policy, DEFAULT_POLICY_PATH, nsFromPath);
|
|
167
|
+
const { path: controllerPath, namespace: controllerNs } = resolvePathAndNamespace(rootPath, overrides?.controller, DEFAULT_CONTROLLER_PATH, nsFromPath);
|
|
168
|
+
const { path: servicePath, namespace: serviceNs } = resolvePathAndNamespace(rootPath, overrides?.service, DEFAULT_SERVICE_PATH, nsFromPath);
|
|
169
|
+
const routePath = withRoot(rootPath, overrides?.route?.path ?? DEFAULT_ROUTE_PATH);
|
|
170
|
+
const configFilePath = withRoot(rootPath, overrides?.config?.path ?? DEFAULT_CONFIG_FILE_PATH);
|
|
95
171
|
const nestedsetNs = overrides?.nestedset?.namespace ?? 'Aimeos\\Nestedset';
|
|
96
172
|
const structure = overrides?.structure ?? 'legacy';
|
|
97
|
-
const modulesPath =
|
|
173
|
+
const modulesPath = withRoot(rootPath, DEFAULT_MODULES_PATH);
|
|
98
174
|
return {
|
|
175
|
+
rootPath,
|
|
99
176
|
structure,
|
|
100
177
|
modulesPath,
|
|
101
178
|
models: {
|
|
@@ -145,6 +222,9 @@ export function derivePhpConfig(overrides) {
|
|
|
145
222
|
routes: {
|
|
146
223
|
path: routePath,
|
|
147
224
|
},
|
|
225
|
+
configFile: {
|
|
226
|
+
path: configFilePath,
|
|
227
|
+
},
|
|
148
228
|
nestedset: {
|
|
149
229
|
namespace: nestedsetNs,
|
|
150
230
|
},
|
package/types/config.d.ts
CHANGED
|
@@ -53,6 +53,14 @@ export interface CodegenNestedSetConfig {
|
|
|
53
53
|
export interface CodegenLaravelConfig {
|
|
54
54
|
/** Enable Laravel codegen. Defaults to false. */
|
|
55
55
|
enable: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Filesystem prefix applied to all generated paths. Use this for monorepo
|
|
58
|
+
* setups where the Laravel project lives in a subdirectory, e.g. `backend`
|
|
59
|
+
* makes everything write under `backend/app/...`, `backend/config/...`, etc.
|
|
60
|
+
*/
|
|
61
|
+
rootPath?: string;
|
|
62
|
+
/** Directory layout: "legacy" (default) or "modular". */
|
|
63
|
+
structure?: "legacy" | "modular";
|
|
56
64
|
/** Model output configuration. */
|
|
57
65
|
model?: CodegenLaravelPathConfig;
|
|
58
66
|
/** Request output configuration. */
|
|
@@ -65,6 +73,14 @@ export interface CodegenLaravelConfig {
|
|
|
65
73
|
provider?: CodegenLaravelPathConfig;
|
|
66
74
|
/** Policy output configuration (default: app/Policies/Omnify). */
|
|
67
75
|
policy?: CodegenLaravelPathConfig;
|
|
76
|
+
/** Controller output configuration (default: app/Http/Controllers). */
|
|
77
|
+
controller?: CodegenLaravelPathConfig;
|
|
78
|
+
/** Service output configuration (default: app/Services). */
|
|
79
|
+
service?: CodegenLaravelPathConfig;
|
|
80
|
+
/** Route file output configuration (default: routes/api/omnify). */
|
|
81
|
+
route?: CodegenLaravelPathConfig;
|
|
82
|
+
/** Path for the omnify-schemas.php config file (default: config/omnify-schemas.php). */
|
|
83
|
+
config?: CodegenLaravelPathConfig;
|
|
68
84
|
/** Nested set package configuration. Only applies to schemas with nestedSet: true. */
|
|
69
85
|
nestedset?: CodegenNestedSetConfig;
|
|
70
86
|
}
|