@omnifyjp/ts 5.9.1 → 5.9.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.
package/dist/cli.js CHANGED
@@ -29,7 +29,7 @@ import { Command } from 'commander';
29
29
  import { parse as parseYaml } from 'yaml';
30
30
  import { generateTypeScript } from './generator.js';
31
31
  import { generatePhp, derivePhpConfig } from './php/index.js';
32
- import { pruneOrphanServiceFiles } from './php/orphan-cleanup.js';
32
+ import { pruneOrphanServiceFilesIfEnabled } from './php/orphan-cleanup.js';
33
33
  import { findSiblingWithSameBasename, findAppRootAncestor } from './php/sibling-skip.js';
34
34
  import { runPintFormat } from './php/pint-format.js';
35
35
  import { resolveInput, sniffInputKind } from './input-resolver.js';
@@ -315,7 +315,7 @@ program
315
315
  // pollutes Composer autoload. Prune base files automatically; warn
316
316
  // about editable `*Service.php` (may contain user code).
317
317
  const phpConfig = derivePhpConfig(laravelOverrides);
318
- const cleanup = pruneOrphanServiceFiles(configDir, phpConfig, phpFiles);
318
+ const cleanup = pruneOrphanServiceFilesIfEnabled(configDir, phpConfig, phpFiles);
319
319
  if (cleanup.prunedBases.length > 0) {
320
320
  console.log(` ${cleanup.prunedBases.length} orphan ServiceBase pruned (schema removed/renamed/opted-out)`);
321
321
  for (const p of cleanup.prunedBases) {
@@ -115,7 +115,7 @@ function generateBaseModel(name, schema, reader, config) {
115
115
  // the generated base model.
116
116
  const hasAuditLog = reader.isAuditLogEnabled(name);
117
117
  const imports = buildImports(baseNamespace, modelName, hasSoftDelete, isAuthenticatable, hasTranslatable, properties, needsUuidTrait, needsUlidTrait, hasNestedSet, config.nestedset.namespace, hasFiles, modelNamespace, localesNamespace, traitsNamespace, sharedModelsNamespace, config, hasAuditLog);
118
- const docProperties = buildDocProperties(properties, expandedProperties, propertyOrder);
118
+ const docProperties = buildDocProperties(properties, expandedProperties, propertyOrder, reader, config);
119
119
  const baseClass = isAuthenticatable ? 'Authenticatable' : 'BaseModel';
120
120
  const implementsClause = hasTranslatable ? ' implements TranslatableContract' : '';
121
121
  const traits = buildTraits(hasSoftDelete, isAuthenticatable, hasTranslatable, needsUuidTrait, needsUlidTrait, hasNestedSet, hasFiles, hasAuditLog);
@@ -409,8 +409,14 @@ function buildImports(baseNamespace, modelName, hasSoftDelete, isAuthenticatable
409
409
  }
410
410
  return lines.join('\n') + '\n';
411
411
  }
412
- function buildDocProperties(properties, expandedProperties, propertyOrder) {
412
+ function buildDocProperties(properties, expandedProperties, propertyOrder, reader, config) {
413
413
  const lines = [];
414
+ // Mirror buildCasts: EnumRef columns are cast to their generated enum class,
415
+ // so document them with that class (not `string`) — otherwise static analysis
416
+ // sees a string and rejects `$model->col->value` / enum comparisons.
417
+ const globalEnumNs = config
418
+ ? resolveGlobalEnumNamespace(config, config.models.namespace)
419
+ : '';
414
420
  for (const propName of propertyOrder) {
415
421
  const prop = properties[propName];
416
422
  if (!prop)
@@ -445,6 +451,16 @@ function buildDocProperties(properties, expandedProperties, propertyOrder) {
445
451
  }
446
452
  const nullable = prop['nullable'] ?? false;
447
453
  const snakeName = toSnakeCase(propName);
454
+ // EnumRef → document the generated enum class (fully-qualified, matching the
455
+ // cast) only when the referenced enum schema exists; else fall through.
456
+ if (type === 'EnumRef') {
457
+ const enumName = prop['enum'];
458
+ if (typeof enumName === 'string' && reader.getSchema(enumName)?.kind === 'enum' && globalEnumNs) {
459
+ const enumType = `\\${globalEnumNs}\\${enumClassName(enumName)}`;
460
+ lines.push(` * @property ${nullable ? `${enumType}|null` : enumType} $${snakeName}`);
461
+ continue;
462
+ }
463
+ }
448
464
  const phpDocType = toPhpDocType(type, nullable);
449
465
  lines.push(` * @property ${phpDocType} $${snakeName}`);
450
466
  }
@@ -26,6 +26,12 @@ export interface ServiceCleanupResult {
26
26
  * preserved (may contain user code). Caller should print a warning. */
27
27
  warnedEditables: string[];
28
28
  }
29
+ /**
30
+ * Apply service cleanup only while this target is managed by Omnify.
31
+ * A globally disabled service layer is a migration boundary: existing bases
32
+ * must remain available until the host application removes its inheritance.
33
+ */
34
+ export declare function pruneOrphanServiceFilesIfEnabled(configDir: string, config: PhpConfig, generated: readonly GeneratedFile[]): ServiceCleanupResult;
29
35
  /**
30
36
  * Delete orphan `*ServiceBase.php` files; flag orphan editable services
31
37
  * for warning. Pure-ish: takes the generated file list (= source of
@@ -20,6 +20,17 @@
20
20
  */
21
21
  import { existsSync, readdirSync, statSync, unlinkSync } from 'node:fs';
22
22
  import { join, resolve, basename } from 'node:path';
23
+ /**
24
+ * Apply service cleanup only while this target is managed by Omnify.
25
+ * A globally disabled service layer is a migration boundary: existing bases
26
+ * must remain available until the host application removes its inheritance.
27
+ */
28
+ export function pruneOrphanServiceFilesIfEnabled(configDir, config, generated) {
29
+ if (!config.services.enabled) {
30
+ return { prunedBases: [], warnedEditables: [] };
31
+ }
32
+ return pruneOrphanServiceFiles(configDir, config, generated);
33
+ }
23
34
  /**
24
35
  * Delete orphan `*ServiceBase.php` files; flag orphan editable services
25
36
  * for warning. Pure-ish: takes the generated file list (= source of
@@ -30,6 +30,8 @@ import { baseFile, userFile, resolveModularBasePath, resolveModularBaseNamespace
30
30
  * - package-owned schemas (those get services in their owning package)
31
31
  */
32
32
  export function generateServices(reader, config) {
33
+ if (!config.services.enabled)
34
+ return [];
33
35
  const files = [];
34
36
  const candidates = collectServiceCandidates(reader);
35
37
  // Emit deprecation warnings once per schema for legacy service-block keys
@@ -99,8 +99,9 @@ class OmnifyServiceProvider extends ServiceProvider
99
99
  $this->loadMigrationsFrom($connectionDir);
100
100
  }
101
101
  ${packageMigrationsBlock}
102
- // Register morph map for polymorphic relationships
103
- Relation::enforceMorphMap([
102
+ // Merge Omnify aliases without requiring every host-application model
103
+ // (Sanctum tokenables, media, notifications, etc.) to be listed here.
104
+ Relation::morphMap([
104
105
  ${morphMapContent}
105
106
  ]);
106
107
  }
@@ -87,6 +87,8 @@ export declare function resolveGlobalTraitNamespace(config: PhpConfig, legacyNam
87
87
  * working.
88
88
  */
89
89
  export interface LaravelPathOverride {
90
+ /** Disable generation for layers that support it (currently `service`). */
91
+ enable?: boolean;
90
92
  /** Path for BASE (auto-generated, regenerated) classes. */
91
93
  path?: string;
92
94
  /** Namespace for BASE (auto-generated) classes. */
@@ -303,7 +305,10 @@ export interface PhpConfig {
303
305
  };
304
306
  policies: BaseEditableLayer;
305
307
  controllers: BaseEditableLayer;
306
- services: BaseEditableLayer;
308
+ services: BaseEditableLayer & {
309
+ /** False disables Laravel service emission and cleanup for this target. */
310
+ enabled: boolean;
311
+ };
307
312
  routes: {
308
313
  path: string;
309
314
  };
package/dist/php/types.js CHANGED
@@ -359,7 +359,10 @@ export function derivePhpConfig(overrides) {
359
359
  },
360
360
  policies: policiesLayer,
361
361
  controllers: controllersLayer,
362
- services: servicesLayer,
362
+ services: {
363
+ ...servicesLayer,
364
+ enabled: overrides?.service?.enable ?? true,
365
+ },
363
366
  routes: {
364
367
  path: routePath,
365
368
  },
@@ -603,7 +603,7 @@ export function formatZodModelFile(schemaName) {
603
603
  * This file will NOT be overwritten by the generator.
604
604
  */
605
605
 
606
- import { z } from 'zod';
606
+ import type { z } from 'zod';
607
607
  import type { ${schemaName} as ${schemaName}Base } from './base/${schemaName}';
608
608
  import {
609
609
  base${schemaName}Schemas,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnifyjp/ts",
3
- "version": "5.9.1",
3
+ "version": "5.9.3",
4
4
  "description": "TypeScript model type generator from Omnify schemas.json",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",