@omnifyjp/ts 5.8.36 → 5.8.39
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.
|
@@ -18,7 +18,15 @@ export declare function getPropertyType(property: PropertyDefinition, allSchemas
|
|
|
18
18
|
export declare function propertyToTSProperties(propertyName: string, property: PropertyDefinition, schema: SchemaDefinition, allSchemas: Record<string, SchemaDefinition>, options: GeneratorOptions): TSProperty[];
|
|
19
19
|
/** Generate a TSInterface from a schema definition. */
|
|
20
20
|
export declare function schemaToInterface(schema: SchemaDefinition, allSchemas: Record<string, SchemaDefinition>, options: GeneratorOptions): TSInterface;
|
|
21
|
-
/** Format a TypeScript property line.
|
|
21
|
+
/** Format a TypeScript property line.
|
|
22
|
+
*
|
|
23
|
+
* Nullable fields (DB column allows NULL) emit `field?: T | null` so
|
|
24
|
+
* consumers can accept the actual JSON value the backend serializes
|
|
25
|
+
* (`null`), not just an absent key. Mirrors the Go target's `*T`
|
|
26
|
+
* pointer convention — `*string` in Go ↔ `string | null` in TS.
|
|
27
|
+
* Pure-optional fields (e.g. payload DTOs that allow omitting) keep
|
|
28
|
+
* the `field?: T` shape. Issue #103 Phase 2 TS-Go nullability sync.
|
|
29
|
+
*/
|
|
22
30
|
export declare function formatProperty(property: TSProperty): string;
|
|
23
31
|
/** Format a TypeScript interface. */
|
|
24
32
|
export declare function formatInterface(iface: TSInterface): string;
|
|
@@ -129,6 +129,7 @@ export function propertyToTSProperties(propertyName, property, schema, allSchema
|
|
|
129
129
|
name: col.name,
|
|
130
130
|
type: tsType,
|
|
131
131
|
optional: col.nullable ?? false,
|
|
132
|
+
nullable: col.nullable ?? false,
|
|
132
133
|
readonly: isReadonly,
|
|
133
134
|
});
|
|
134
135
|
}
|
|
@@ -142,6 +143,7 @@ export function propertyToTSProperties(propertyName, property, schema, allSchema
|
|
|
142
143
|
name: propertyName,
|
|
143
144
|
type: tsType,
|
|
144
145
|
optional: isNullable,
|
|
146
|
+
nullable: isNullable,
|
|
145
147
|
readonly: isReadonly,
|
|
146
148
|
}];
|
|
147
149
|
}
|
|
@@ -185,10 +187,13 @@ export function propertyToTSProperties(propertyName, property, schema, allSchema
|
|
|
185
187
|
name: `${propertyName}_id`,
|
|
186
188
|
type: fkType,
|
|
187
189
|
optional: isNullable,
|
|
190
|
+
nullable: isNullable,
|
|
188
191
|
readonly: isReadonly,
|
|
189
192
|
},
|
|
190
193
|
{
|
|
191
194
|
name: propertyName,
|
|
195
|
+
// Type already carries `| null` when nullable — don't double up
|
|
196
|
+
// by also setting nullable: true on the property.
|
|
192
197
|
type: isNullable ? `${targetName} | null` : targetName,
|
|
193
198
|
optional: true,
|
|
194
199
|
readonly: isReadonly,
|
|
@@ -211,6 +216,7 @@ export function propertyToTSProperties(propertyName, property, schema, allSchema
|
|
|
211
216
|
name: propertyName,
|
|
212
217
|
type,
|
|
213
218
|
optional: isNullable,
|
|
219
|
+
nullable: isNullable,
|
|
214
220
|
readonly: isReadonly,
|
|
215
221
|
}];
|
|
216
222
|
}
|
|
@@ -252,13 +258,17 @@ export function schemaToInterface(schema, allSchemas, options) {
|
|
|
252
258
|
properties.push(...propertyToTSProperties(propName, property, schema, allSchemas, options));
|
|
253
259
|
}
|
|
254
260
|
}
|
|
255
|
-
// Timestamps
|
|
261
|
+
// Timestamps. created_at + updated_at are NOT NULL with DEFAULT
|
|
262
|
+
// CURRENT_TIMESTAMP — every persisted row has them. Mark optional in
|
|
263
|
+
// Create-DTO contexts (caller can omit, DB fills) but always present
|
|
264
|
+
// and never NULL on the read shape, so no `| null`.
|
|
256
265
|
if (schema.options?.timestamps !== false) {
|
|
257
266
|
properties.push({ name: 'created_at', type: 'DateTimeString', optional: true, readonly: false }, { name: 'updated_at', type: 'DateTimeString', optional: true, readonly: false });
|
|
258
267
|
}
|
|
259
|
-
// Soft delete
|
|
268
|
+
// Soft delete. deleted_at IS nullable (NULL until soft-deleted) — match
|
|
269
|
+
// Go's `*time.Time` pointer with TS `?: DateTimeString | null`.
|
|
260
270
|
if (schema.options?.softDelete) {
|
|
261
|
-
properties.push({ name: 'deleted_at', type: 'DateTimeString', optional: true, readonly: false });
|
|
271
|
+
properties.push({ name: 'deleted_at', type: 'DateTimeString', optional: true, nullable: true, readonly: false });
|
|
262
272
|
}
|
|
263
273
|
// Collect dependencies
|
|
264
274
|
const dependencySet = new Set();
|
|
@@ -304,10 +314,24 @@ export function schemaToInterface(schema, allSchemas, options) {
|
|
|
304
314
|
enumDependencies: enumDependencySet.size > 0 ? Array.from(enumDependencySet).sort() : undefined,
|
|
305
315
|
};
|
|
306
316
|
}
|
|
307
|
-
/** Format a TypeScript property line.
|
|
317
|
+
/** Format a TypeScript property line.
|
|
318
|
+
*
|
|
319
|
+
* Nullable fields (DB column allows NULL) emit `field?: T | null` so
|
|
320
|
+
* consumers can accept the actual JSON value the backend serializes
|
|
321
|
+
* (`null`), not just an absent key. Mirrors the Go target's `*T`
|
|
322
|
+
* pointer convention — `*string` in Go ↔ `string | null` in TS.
|
|
323
|
+
* Pure-optional fields (e.g. payload DTOs that allow omitting) keep
|
|
324
|
+
* the `field?: T` shape. Issue #103 Phase 2 TS-Go nullability sync.
|
|
325
|
+
*/
|
|
308
326
|
export function formatProperty(property) {
|
|
309
327
|
const optional = property.optional ? '?' : '';
|
|
310
|
-
|
|
328
|
+
// Already-nullable type strings (e.g. someone hand-wrote `T | null`
|
|
329
|
+
// upstream) are passed through unchanged so we don't end up with
|
|
330
|
+
// `T | null | null`.
|
|
331
|
+
const typeStr = property.nullable && !/\| null\b/.test(property.type)
|
|
332
|
+
? `${property.type} | null`
|
|
333
|
+
: property.type;
|
|
334
|
+
return ` ${property.name}${optional}: ${typeStr};`;
|
|
311
335
|
}
|
|
312
336
|
/** Format a TypeScript interface. */
|
|
313
337
|
export function formatInterface(iface) {
|
|
@@ -20,9 +20,34 @@ namespace ${ns};
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
use Illuminate\\Database\\Eloquent\\Model;
|
|
23
|
+
use Illuminate\\Database\\Eloquent\\Relations\\Relation;
|
|
23
24
|
|
|
24
25
|
class BaseModel extends Model
|
|
25
26
|
{
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the polymorphic alias from the morph map, walking up the class
|
|
29
|
+
* hierarchy so application subclasses of a generated model still resolve.
|
|
30
|
+
*
|
|
31
|
+
* Omnify registers the morph map against the generated model classes. A
|
|
32
|
+
* project that subclasses one and instantiates the subclass would otherwise
|
|
33
|
+
* throw ClassMorphViolationException under an enforced morph map, because the
|
|
34
|
+
* subclass itself is absent from the map. Returning the nearest mapped
|
|
35
|
+
* ancestor's alias keeps stored type values stable across both layers.
|
|
36
|
+
*/
|
|
37
|
+
public function getMorphClass(): string
|
|
38
|
+
{
|
|
39
|
+
$morphMap = Relation::morphMap();
|
|
40
|
+
|
|
41
|
+
for ($class = static::class; $class !== false; $class = get_parent_class($class)) {
|
|
42
|
+
$alias = array_search($class, $morphMap, true);
|
|
43
|
+
|
|
44
|
+
if ($alias !== false) {
|
|
45
|
+
return $alias;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return parent::getMorphClass();
|
|
50
|
+
}
|
|
26
51
|
}
|
|
27
52
|
`;
|
|
28
53
|
const path = resolveSharedBasePath(config, 'Models', 'BaseModel.php', config.models.basePath);
|
package/dist/types.d.ts
CHANGED
|
@@ -392,6 +392,14 @@ export interface TSProperty {
|
|
|
392
392
|
readonly optional: boolean;
|
|
393
393
|
readonly readonly: boolean;
|
|
394
394
|
readonly comment?: string;
|
|
395
|
+
/**
|
|
396
|
+
* The underlying schema column is `nullable: true` (DB allows NULL),
|
|
397
|
+
* NOT just "optional in some payload shape". When set, formatProperty
|
|
398
|
+
* emits `field?: T | null` so consumers can accept the actual JSON
|
|
399
|
+
* value the backend serializes (`null`, not `undefined`). Mirrors the
|
|
400
|
+
* Go target's `*T` pointer convention. Phase 2 of issue #103.
|
|
401
|
+
*/
|
|
402
|
+
readonly nullable?: boolean;
|
|
395
403
|
}
|
|
396
404
|
/** TypeScript interface definition. */
|
|
397
405
|
export interface TSInterface {
|