@omnifyjp/ts 5.8.1 → 5.8.3

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.
@@ -42,7 +42,11 @@ function generateForSchema(name, schema, reader, config) {
42
42
  }
43
43
  function generateBaseRequest(name, schema, reader, config, action) {
44
44
  const modelName = toPascalCase(name);
45
- const baseNamespace = resolveModularBaseNamespace(config, name, 'Requests', config.requests.baseNamespace);
45
+ // Issue #98 v5.8.2: nest namespace by group in legacy structure so the
46
+ // file's `namespace App\Omnify\Requests\Cms;` matches its grouped path.
47
+ const baseNamespace = config.structure === 'modular'
48
+ ? resolveModularBaseNamespace(config, name, 'Requests', config.requests.baseNamespace)
49
+ : nestByGroup({ path: '', namespace: config.requests.baseNamespace }, schema.group).namespace;
46
50
  const modelLocalesNamespace = resolveModularBaseNamespace(config, name, 'Locales', config.models.baseNamespace + '\\Locales');
47
51
  const properties = (schema.properties ?? {});
48
52
  const expandedProperties = reader.getExpandedProperties(name);
@@ -17,7 +17,13 @@ export function generateResources(reader, config) {
17
17
  }
18
18
  function generateBaseResource(name, schema, reader, config) {
19
19
  const modelName = toPascalCase(name);
20
- const baseNamespace = resolveModularBaseNamespace(config, name, 'Resources', config.resources.baseNamespace);
20
+ // Issue #98 v5.8.2: nest namespace by group in legacy structure so the
21
+ // file's `namespace App\Omnify\Resources\Cms;` matches its grouped path.
22
+ // (Models layer was already correct in v5.8.0; the other 3 base+editable
23
+ // layers shipped with path nested but namespace ungrouped — broken PSR-4.)
24
+ const baseNamespace = config.structure === 'modular'
25
+ ? resolveModularBaseNamespace(config, name, 'Resources', config.resources.baseNamespace)
26
+ : nestByGroup({ path: '', namespace: config.resources.baseNamespace }, schema.group).namespace;
21
27
  const resourceNamespace = config.resources.namespace;
22
28
  const modelNamespace = config.models.namespace;
23
29
  const properties = (schema.properties ?? {});
@@ -500,7 +500,16 @@ function generateBaseService(name, schema, reader, config) {
500
500
  const defaults = resolveDefaults(schema, reader, name);
501
501
  // Locales (for translatable)
502
502
  const locales = reader.getLocales();
503
- const baseNs = resolveModularBaseNamespace(config, name, 'Services', config.services.baseNamespace);
503
+ // Issue #98 v5.8.2: legacy structure must nest by group so the file's
504
+ // `namespace App\Omnify\Services\Cms;` declaration matches its
505
+ // grouped path (`app/Omnify/Services/Cms/BannerServiceBase.php`).
506
+ // Without this, PSR-4 autoload silently breaks: composer dump-autoload
507
+ // succeeds (it doesn't read the file body) but `App\Omnify\Services\Cms\BannerService`
508
+ // resolves to nothing at runtime → "Class not found" for every consumer.
509
+ // Modular structure handled separately below.
510
+ const baseNs = config.structure === 'modular'
511
+ ? resolveModularBaseNamespace(config, name, 'Services', config.services.baseNamespace)
512
+ : nestByGroup({ path: '', namespace: config.services.baseNamespace }, schema.group).namespace;
504
513
  const modelNs = config.models.namespace;
505
514
  // Build imports
506
515
  const imports = [
@@ -56,7 +56,23 @@ function castFor(type) {
56
56
  function generateTranslationBaseModel(name, translatableFields, enforceLanguageFk, config) {
57
57
  const modelName = toPascalCase(name);
58
58
  const modelSnake = toSnakeCase(name);
59
- const baseNamespace = resolveModularBaseNamespace(config, name, 'Models', config.models.baseNamespace);
59
+ // Issue #98 v5.8.2: consolidate every Translation model under one
60
+ // dedicated `Translation/` subfolder + sub-namespace. Reporter's
61
+ // rationale: 39 translation models flat at the top of `Models/`
62
+ // (next to the grouped main models) is the worst-of-both-worlds
63
+ // layout. One consolidated `Translation/` folder lets a project set
64
+ // Astrotomic's `translation_model_namespace` once globally instead
65
+ // of per-model `$translationModel` overrides. Modular structure
66
+ // already isolates per-Schema so this nesting only applies to legacy.
67
+ // Issue #98 v5.8.3: when `flatBase: true`, the model layer drops
68
+ // the `Base/` subfolder + `BaseModel` suffix everywhere else; the
69
+ // translation base must follow the same convention so naming
70
+ // stays consistent across layers (a class extending `Model` named
71
+ // `CategoryTranslationBaseModel` while siblings drop the suffix is
72
+ // the bug the reporter flagged).
73
+ const baseNamespace = config.structure === 'modular'
74
+ ? resolveModularBaseNamespace(config, name, 'Models', config.models.baseNamespace)
75
+ : `${config.models.baseNamespace}\\Translation`;
60
76
  const tableName = `${modelSnake}_translations`;
61
77
  // Fillable: every translatable column + the optional `language_id`
62
78
  // FK column (added by the migration when locale.enforceLanguageFk is
@@ -83,6 +99,12 @@ function generateTranslationBaseModel(name, translatableFields, enforceLanguageF
83
99
  protected $casts = [
84
100
  ${castEntries.join('\n')}
85
101
  ];`;
102
+ // Issue #98 v5.8.3: honor flatBase. With flatBase=true the base
103
+ // class drops the `BaseModel` suffix and lives at the bare name,
104
+ // matching how every other Models-layer base behaves under flatBase.
105
+ // Modular structure ignores flatBase (per-Schema isolation already).
106
+ const flatBase = config.structure !== 'modular' && config.models.flatBase === true;
107
+ const baseClassName = flatBase ? `${modelName}Translation` : `${modelName}TranslationBaseModel`;
86
108
  const content = `<?php
87
109
 
88
110
  namespace ${baseNamespace};
@@ -97,9 +119,9 @@ namespace ${baseNamespace};
97
119
  use Illuminate\\Database\\Eloquent\\Model;
98
120
 
99
121
  /**
100
- * ${modelName}TranslationBaseModel
122
+ * ${baseClassName}
101
123
  */
102
- class ${modelName}TranslationBaseModel extends Model
124
+ class ${baseClassName} extends Model
103
125
  {
104
126
  /**
105
127
  * The table associated with the model.
@@ -119,28 +141,64 @@ ${fillableLines}
119
141
  ];${castsBlock}
120
142
  }
121
143
  `;
122
- return baseFile(resolveModularBasePath(config, name, 'Models', `${modelName}TranslationBaseModel.php`, config.models.basePath), content);
144
+ // Issue #98 v5.8.2: legacy structure routes translation bases to
145
+ // `<modelsBasePath>/Translation/<Name>TranslationBaseModel.php`
146
+ // (or `${modelName}Translation.php` when flatBase drops the suffix).
147
+ const filePath = config.structure === 'modular'
148
+ ? resolveModularBasePath(config, name, 'Models', `${baseClassName}.php`, config.models.basePath)
149
+ : `${config.models.basePath}/Translation/${baseClassName}.php`;
150
+ return baseFile(filePath, content);
123
151
  }
124
152
  function generateTranslationUserModel(name, config) {
125
153
  const modelName = toPascalCase(name);
126
- const modelNamespace = config.models.namespace;
127
- const baseNamespace = resolveModularBaseNamespace(config, name, 'Models', config.models.baseNamespace);
154
+ // Issue #98 v5.8.2: editable translation stub also lives under
155
+ // `Translation/` to mirror the base layout. Astrotomic finds it via
156
+ // the project-set `translation_model_namespace`.
157
+ // Issue #98 v5.8.3 (Bug 1): when `userEditablePath` points elsewhere
158
+ // (e.g. canonical Laravel `app/Models/`), the namespace must match
159
+ // the FILE LOCATION, not the base namespace — otherwise PSR-4 fails
160
+ // at runtime. Use `userEditableNamespace` (resolved from the config
161
+ // override) instead of the base `models.namespace`.
162
+ const modelNamespace = config.structure === 'modular'
163
+ ? config.models.namespace
164
+ : `${config.models.userEditableNamespace}\\Translation`;
165
+ const baseNamespace = config.structure === 'modular'
166
+ ? resolveModularBaseNamespace(config, name, 'Models', config.models.baseNamespace)
167
+ : `${config.models.baseNamespace}\\Translation`;
168
+ // Issue #98 v5.8.3 (Bug 2): honor flatBase + alias on class-name
169
+ // collision. With flatBase the base class is also named
170
+ // `<Model>Translation` (no suffix); the editable stub then needs
171
+ // an alias to avoid a self-collision when extending. Mirrors the
172
+ // pattern used by resource / service / request user generators.
173
+ const flatBase = config.structure !== 'modular' && config.models.flatBase === true;
174
+ const baseClassName = flatBase ? `${modelName}Translation` : `${modelName}TranslationBaseModel`;
175
+ const editableClassName = `${modelName}Translation`;
176
+ const baseAlias = baseClassName === editableClassName
177
+ ? `${editableClassName}Base`
178
+ : baseClassName;
179
+ const baseImport = baseAlias === baseClassName
180
+ ? `use ${baseNamespace}\\${baseClassName};`
181
+ : `use ${baseNamespace}\\${baseClassName} as ${baseAlias};`;
128
182
  const content = `<?php
129
183
 
130
184
  namespace ${modelNamespace};
131
185
 
132
- use ${baseNamespace}\\${modelName}TranslationBaseModel;
186
+ ${baseImport}
133
187
 
134
188
  /**
135
- * ${modelName}Translation Model
189
+ * ${editableClassName} Model
136
190
  *
137
191
  * This file is generated once and can be customized.
138
192
  * Add your custom methods and logic here.
139
193
  */
140
- class ${modelName}Translation extends ${modelName}TranslationBaseModel
194
+ class ${editableClassName} extends ${baseAlias}
141
195
  {
142
196
  // Add your custom methods here
143
197
  }
144
198
  `;
145
- return userFile(`${config.models.path}/${modelName}Translation.php`, content);
199
+ // Editable file path mirrors the namespace nesting.
200
+ const filePath = config.structure === 'modular'
201
+ ? `${config.models.path}/${editableClassName}.php`
202
+ : `${config.models.userEditablePath}/Translation/${editableClassName}.php`;
203
+ return userFile(filePath, content);
146
204
  }
package/dist/php/types.js CHANGED
@@ -184,10 +184,19 @@ nsFromPath) {
184
184
  const baseNamespace = flatBase ? namespace : `${namespace}\\${baseSubfolder}`;
185
185
  // User-editable: defaults to the same dir as base (legacy behavior),
186
186
  // overridable to e.g. canonical Laravel paths (`app/Models/`).
187
+ // Issue #98 v5.8.3: when only `userEditablePath` is overridden,
188
+ // derive the namespace from the editable PATH (not the base
189
+ // namespace) so the file's `namespace ...;` declaration matches
190
+ // its physical location and PSR-4 autoload doesn't break at
191
+ // runtime. Reporter hit this with `userEditablePath: app/Models`
192
+ // and the base path defaulting to `app/Omnify/Models/`: the
193
+ // editable stub claimed the base namespace and Laravel couldn't
194
+ // load it.
187
195
  const userEditablePath = override?.userEditablePath
188
196
  ? withRoot(rootPath, override.userEditablePath)
189
197
  : path;
190
- const userEditableNamespace = override?.userEditableNamespace ?? namespace;
198
+ const userEditableNamespace = override?.userEditableNamespace
199
+ ?? (override?.userEditablePath ? nsFromPath(userEditablePath) : namespace);
191
200
  return { namespace, baseNamespace, path, basePath, userEditablePath, userEditableNamespace, flatBase };
192
201
  }
193
202
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnifyjp/ts",
3
- "version": "5.8.1",
3
+ "version": "5.8.3",
4
4
  "description": "TypeScript model type generator from Omnify schemas.json",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",