svelte-reflector 2.5.0 → 2.5.1

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.
@@ -0,0 +1,35 @@
1
+ import type { ArrayProp } from "../../props/array.property.js";
2
+ import type { EnumProp } from "../../props/enum.property.js";
3
+ import type { ObjectProp } from "../../props/object.property.js";
4
+ import type { PrimitiveProp } from "../../props/primitive.property.js";
5
+ import type { UnionProp } from "../../props/union.property.js";
6
+ /**
7
+ * Renders a schema's `Interface` as a *discriminated union* type alias when one
8
+ * of its properties is a `oneOf` carrying a `discriminator` whose `propertyName`
9
+ * points at a sibling enum property (e.g. `NotificationData.actionMeta` keyed by
10
+ * `action`). Each `discriminator.mapping` entry (action value → variant schema)
11
+ * becomes a union member that pins `action` to its literal(s) and `actionMeta`
12
+ * to the matching variant `Interface`:
13
+ *
14
+ * ```ts
15
+ * export type NotificationDataInterface =
16
+ * | { ...commons; action: "STOCK_LOW" | "STOCK_OUT"; actionMeta: ProductStockMetaInterface }
17
+ * | { ...commons; action: "ANNOUNCEMENT"; actionMeta: UrlMetaInterface };
18
+ * ```
19
+ *
20
+ * This is what makes `if (n.action === "STOCK_LOW") n.actionMeta.productId`
21
+ * narrow on plain `Interface`-typed values (raw response data, `.bundle()`,
22
+ * `.discriminated()`). It never narrows on the live `$state` class instance —
23
+ * TS can't correlate two independent mutable fields.
24
+ */
25
+ export declare class DiscriminatedInterfaceRenderer {
26
+ static render(params: {
27
+ name: string;
28
+ union: UnionProp;
29
+ primitiveProps: PrimitiveProp[];
30
+ arrayProps: ArrayProp[];
31
+ objectProps: ObjectProp[];
32
+ enumProps: EnumProp[];
33
+ otherUnionProps: UnionProp[];
34
+ }): string;
35
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Renders a schema's `Interface` as a *discriminated union* type alias when one
3
+ * of its properties is a `oneOf` carrying a `discriminator` whose `propertyName`
4
+ * points at a sibling enum property (e.g. `NotificationData.actionMeta` keyed by
5
+ * `action`). Each `discriminator.mapping` entry (action value → variant schema)
6
+ * becomes a union member that pins `action` to its literal(s) and `actionMeta`
7
+ * to the matching variant `Interface`:
8
+ *
9
+ * ```ts
10
+ * export type NotificationDataInterface =
11
+ * | { ...commons; action: "STOCK_LOW" | "STOCK_OUT"; actionMeta: ProductStockMetaInterface }
12
+ * | { ...commons; action: "ANNOUNCEMENT"; actionMeta: UrlMetaInterface };
13
+ * ```
14
+ *
15
+ * This is what makes `if (n.action === "STOCK_LOW") n.actionMeta.productId`
16
+ * narrow on plain `Interface`-typed values (raw response data, `.bundle()`,
17
+ * `.discriminated()`). It never narrows on the live `$state` class instance —
18
+ * TS can't correlate two independent mutable fields.
19
+ */
20
+ export class DiscriminatedInterfaceRenderer {
21
+ static render(params) {
22
+ const { name, union, primitiveProps, arrayProps, objectProps, enumProps, otherUnionProps } = params;
23
+ const discProp = union.discriminator.propertyName;
24
+ const mapping = union.discriminator.mapping ?? {};
25
+ // Commons = every property except the discriminant and the discriminated union itself.
26
+ const allProps = [
27
+ ...primitiveProps,
28
+ ...arrayProps,
29
+ ...objectProps,
30
+ ...enumProps,
31
+ ...otherUnionProps,
32
+ ];
33
+ const commons = allProps
34
+ .filter((p) => p.name !== discProp && p.name !== union.name)
35
+ .map((p) => p.interfaceBuild());
36
+ // Invert the mapping: variant schema name → the action literals that select it,
37
+ // preserving first-seen order so output stays deterministic.
38
+ const byVariant = new Map();
39
+ for (const [actionValue, ref] of Object.entries(mapping)) {
40
+ const variant = ref.split("/").at(-1) ?? "";
41
+ if (!variant)
42
+ continue;
43
+ const list = byVariant.get(variant) ?? [];
44
+ list.push(actionValue);
45
+ byVariant.set(variant, list);
46
+ }
47
+ // The discriminated part: only the discriminant + the union field vary per variant.
48
+ // Commons are factored into a single object type and intersected with the union —
49
+ // narrowing on `action` still works through the intersection.
50
+ const members = [...byVariant.entries()].map(([variant, actions]) => {
51
+ const literals = actions.map((a) => `"${a}"`).join(" | ");
52
+ return `{ ${discProp}: ${literals}; ${union.name}: ${variant}Interface }`;
53
+ });
54
+ const variantUnion = members.map((m) => `| ${m}`).join("\n");
55
+ // No commons → emit the bare union (avoid a pointless `{} & (...)`).
56
+ if (commons.length === 0) {
57
+ return `
58
+ export type ${name}Interface =
59
+ ${variantUnion};
60
+ `;
61
+ }
62
+ return `
63
+ export type ${name}Interface = {
64
+ ${commons.join(";\n")}
65
+ } & (
66
+ ${variantUnion}
67
+ );
68
+ `;
69
+ }
70
+ }
@@ -2,6 +2,7 @@ import type { ArrayProp } from "../../props/array.property.js";
2
2
  import type { EnumProp } from "../../props/enum.property.js";
3
3
  import type { ObjectProp } from "../../props/object.property.js";
4
4
  import type { PrimitiveProp } from "../../props/primitive.property.js";
5
+ import type { UnionProp } from "../../props/union.property.js";
5
6
  export declare class ReflectorInterface {
6
7
  builded: string;
7
8
  constructor(params: {
@@ -10,5 +11,6 @@ export declare class ReflectorInterface {
10
11
  name: string;
11
12
  objectProps: ObjectProp[];
12
13
  enumProps: EnumProp[];
14
+ unionProps: UnionProp[];
13
15
  });
14
16
  }
@@ -1,7 +1,7 @@
1
1
  export class ReflectorInterface {
2
2
  builded;
3
3
  constructor(params) {
4
- const { name, arrayProps, primitiveProps, objectProps, enumProps } = params;
4
+ const { name, arrayProps, primitiveProps, objectProps, enumProps, unionProps } = params;
5
5
  const buildedProps = [];
6
6
  primitiveProps.forEach((prop) => {
7
7
  buildedProps.push(prop.interfaceBuild());
@@ -15,6 +15,9 @@ export class ReflectorInterface {
15
15
  enumProps.forEach((prop) => {
16
16
  buildedProps.push(prop.interfaceBuild());
17
17
  });
18
+ unionProps.forEach((prop) => {
19
+ buildedProps.push(prop.interfaceBuild());
20
+ });
18
21
  this.builded = `
19
22
  export interface ${name}Interface {
20
23
  ${buildedProps}
@@ -2,6 +2,7 @@ import { ArrayProp } from "../../props/array.property.js";
2
2
  import { EnumProp } from "../../props/enum.property.js";
3
3
  import { ObjectProp } from "../../props/object.property.js";
4
4
  import { PrimitiveProp } from "../../props/primitive.property.js";
5
+ import { UnionProp } from "../../props/union.property.js";
5
6
  import type { SchemaObject, ReferenceObject } from "../../types/open-api-spec.interface.js";
6
7
  import type { FieldConfigs } from "../../types/types.js";
7
8
  import type { CodegenContext } from "../CodegenContext.js";
@@ -11,6 +12,7 @@ export declare class Schema {
11
12
  arrayProps: ArrayProp[];
12
13
  objectProps: ObjectProp[];
13
14
  enumProps: EnumProp[];
15
+ unionProps: UnionProp[];
14
16
  /** Other schema class names this schema depends on (via ObjectProp/$ref arrays) */
15
17
  readonly schemaDeps: string[];
16
18
  /** Enum type names used by this schema */
@@ -2,6 +2,7 @@ import { ArrayProp } from "../../props/array.property.js";
2
2
  import { EnumProp } from "../../props/enum.property.js";
3
3
  import { ObjectProp } from "../../props/object.property.js";
4
4
  import { PrimitiveProp } from "../../props/primitive.property.js";
5
+ import { UnionProp } from "../../props/union.property.js";
5
6
  import { isReferenceObject } from "../../helpers/helpers.js";
6
7
  import { SchemaPropertyClassifier } from "./SchemaPropertyClassifier.js";
7
8
  import { SchemaDependencyCollector } from "./SchemaDependencyCollector.js";
@@ -13,6 +14,7 @@ export class Schema {
13
14
  arrayProps = [];
14
15
  objectProps = [];
15
16
  enumProps = [];
17
+ unionProps = [];
16
18
  /** Other schema class names this schema depends on (via ObjectProp/$ref arrays) */
17
19
  schemaDeps;
18
20
  /** Enum type names used by this schema */
@@ -45,6 +47,7 @@ export class Schema {
45
47
  schema.arrayProps = [];
46
48
  schema.objectProps = [];
47
49
  schema.enumProps = [];
50
+ schema.unionProps = [];
48
51
  schema.schemaDeps = element.kind === "ref" ? [element.type] : [];
49
52
  schema.enumDeps = element.kind === "enum" ? [element.type] : [];
50
53
  schema.customTypeDeps = [];
@@ -110,12 +113,15 @@ export class Schema {
110
113
  this.objectProps.push(prop);
111
114
  else if (prop instanceof EnumProp)
112
115
  this.enumProps.push(prop);
116
+ else if (prop instanceof UnionProp)
117
+ this.unionProps.push(prop);
113
118
  }
114
119
  const deps = SchemaDependencyCollector.collect({
115
120
  primitiveProps: this.primitiveProps,
116
121
  arrayProps: this.arrayProps,
117
122
  objectProps: this.objectProps,
118
123
  enumProps: this.enumProps,
124
+ unionProps: this.unionProps,
119
125
  });
120
126
  this.schemaDeps = deps.schemaDeps;
121
127
  this.enumDeps = deps.enumDeps;
@@ -127,6 +133,7 @@ export class Schema {
127
133
  arrayProps: this.arrayProps,
128
134
  objectProps: this.objectProps,
129
135
  enumProps: this.enumProps,
136
+ unionProps: this.unionProps,
130
137
  });
131
138
  this.interface = rendered.interface;
132
139
  this.schema = rendered.schema;
@@ -148,6 +155,7 @@ export class Schema {
148
155
  arrayProps: this.arrayProps,
149
156
  objectProps: this.objectProps,
150
157
  enumProps: this.enumProps,
158
+ unionProps: this.unionProps,
151
159
  mode: "request",
152
160
  });
153
161
  this.schema = rendered.schema;
@@ -2,6 +2,7 @@ import type { ArrayProp } from "../../props/array.property.js";
2
2
  import type { EnumProp } from "../../props/enum.property.js";
3
3
  import type { ObjectProp } from "../../props/object.property.js";
4
4
  import type { PrimitiveProp } from "../../props/primitive.property.js";
5
+ import type { UnionProp } from "../../props/union.property.js";
5
6
  export declare class SchemaClassRenderer {
6
7
  static render(params: {
7
8
  name: string;
@@ -9,6 +10,7 @@ export declare class SchemaClassRenderer {
9
10
  arrayProps: ArrayProp[];
10
11
  objectProps: ObjectProp[];
11
12
  enumProps: EnumProp[];
13
+ unionProps: UnionProp[];
12
14
  mode?: "request" | "response";
13
15
  }): {
14
16
  interface: string;
@@ -1,15 +1,23 @@
1
+ import { DiscriminatedInterfaceRenderer } from "./DiscriminatedInterfaceRenderer.js";
1
2
  import { ReflectorInterface } from "./ReflectorInterface.js";
2
3
  export class SchemaClassRenderer {
3
4
  static render(params) {
4
- const { name, primitiveProps, arrayProps, objectProps, enumProps } = params;
5
+ const { name, primitiveProps, arrayProps, objectProps, enumProps, unionProps } = params;
5
6
  const mode = params.mode ?? "response";
6
- const reflectorInterface = new ReflectorInterface({
7
- name,
8
- arrayProps,
9
- primitiveProps,
10
- objectProps,
11
- enumProps,
12
- });
7
+ // A `oneOf` with a usable discriminator turns the Interface into a discriminated
8
+ // union type alias; the matching `discriminated()` accessor is emitted below.
9
+ const discriminatedUnion = unionProps.find((u) => u.hasDiscriminator);
10
+ const interfaceStr = discriminatedUnion
11
+ ? DiscriminatedInterfaceRenderer.render({
12
+ name,
13
+ union: discriminatedUnion,
14
+ primitiveProps,
15
+ arrayProps,
16
+ objectProps,
17
+ enumProps,
18
+ otherUnionProps: unionProps.filter((u) => u !== discriminatedUnion),
19
+ })
20
+ : new ReflectorInterface({ name, arrayProps, primitiveProps, objectProps, enumProps, unionProps }).builded;
13
21
  const constructorThis = [];
14
22
  const keys = [];
15
23
  const bundleParams = [];
@@ -35,6 +43,11 @@ export class SchemaClassRenderer {
35
43
  keys.push(prop.classBuild());
36
44
  bundleParams.push(prop.bundleBuild());
37
45
  });
46
+ unionProps.forEach((prop) => {
47
+ constructorThis.push(prop.constructorBuild());
48
+ keys.push(prop.classBuild());
49
+ bundleParams.push(prop.bundleBuild());
50
+ });
38
51
  const constructorCode = `constructor(params?: { data?: ${name}Interface | undefined, empty?: boolean }) {
39
52
  ${constructorThis.join(";\n")}
40
53
  }`;
@@ -43,6 +56,7 @@ export class SchemaClassRenderer {
43
56
  arrayProps.forEach((p) => hydrateLines.push(p.hydrateBuild()));
44
57
  objectProps.forEach((p) => hydrateLines.push(p.hydrateBuild()));
45
58
  enumProps.forEach((p) => hydrateLines.push(p.hydrateBuild()));
59
+ unionProps.forEach((p) => hydrateLines.push(p.hydrateBuild()));
46
60
  const hydrateCode = `
47
61
  hydrate(data: Partial<${name}Interface>): void {
48
62
  ${hydrateLines.join(";\n")}
@@ -52,15 +66,31 @@ export class SchemaClassRenderer {
52
66
  this.hydrate(new ${name}({ empty: true }).bundle() as Partial<${name}Interface>);
53
67
  }
54
68
  `;
69
+ // Live class instances can't narrow `actionMeta` by `action` (independent
70
+ // `$state` fields), so expose a plain discriminated snapshot for consumers
71
+ // that want the narrowing. `bundle()` already returns the discriminated type
72
+ // (see below), so this is just an ergonomic, cast-free alias.
73
+ const discriminatedAccessor = discriminatedUnion
74
+ ? `discriminated(): ${name}Interface { return this.bundle(); }`
75
+ : "";
55
76
  // Request DTO serializa a partir das instâncias `BuildedInput` (carregam os flags
56
77
  // required/nullable), não do `.value` pré-extraído — bundleInputs faz a coerção
57
78
  // nullable ''→null e cobre array/aninhado. Response fica em bundleStrict (inalterado).
79
+ //
80
+ // Para um schema com união discriminada, `bundleStrict` infere a forma plana (action
81
+ // = enum inteiro), que NÃO é atribuível a nenhum membro da união — o array-root wrapper
82
+ // (`item.bundle()` tipado como `Interface[]` discriminada) quebraria. O único `as` do
83
+ // feature mora aqui, fazendo `bundle()` devolver a própria união; `discriminated()` e
84
+ // `reset()` ficam cast-free por consequência.
58
85
  const bundleHelper = mode === "request" ? "inputs" : "strict";
86
+ const responseBundle = discriminatedUnion
87
+ ? `return bundleStrict({ ${bundleParams.join(",")} }) as ${name}Interface`
88
+ : `return bundleStrict({ ${bundleParams.join(",")} })`;
59
89
  const bundleBody = mode === "request"
60
- ? `return bundleInputs({ ${[...primitiveProps, ...arrayProps, ...objectProps, ...enumProps]
90
+ ? `return bundleInputs({ ${[...primitiveProps, ...arrayProps, ...objectProps, ...enumProps, ...unionProps]
61
91
  .map((p) => `${p.name}: this.${p.name}`)
62
92
  .join(",")} })`
63
- : `return bundleStrict({ ${bundleParams.join(",")} })`;
93
+ : responseBundle;
64
94
  const schema = `
65
95
  export class ${name} {
66
96
  ${keys.join(";")}
@@ -74,7 +104,9 @@ export class SchemaClassRenderer {
74
104
  bundle(){
75
105
  ${bundleBody}
76
106
  }
107
+
108
+ ${discriminatedAccessor}
77
109
  };`;
78
- return { interface: reflectorInterface.builded, schema, bundleHelper };
110
+ return { interface: interfaceStr, schema, bundleHelper };
79
111
  }
80
112
  }
@@ -2,6 +2,7 @@ import type { ArrayProp } from "../../props/array.property.js";
2
2
  import type { EnumProp } from "../../props/enum.property.js";
3
3
  import type { ObjectProp } from "../../props/object.property.js";
4
4
  import type { PrimitiveProp } from "../../props/primitive.property.js";
5
+ import type { UnionProp } from "../../props/union.property.js";
5
6
  export interface SchemaDependencies {
6
7
  schemaDeps: string[];
7
8
  enumDeps: string[];
@@ -14,5 +15,6 @@ export declare class SchemaDependencyCollector {
14
15
  arrayProps: ArrayProp[];
15
16
  objectProps: ObjectProp[];
16
17
  enumProps: EnumProp[];
18
+ unionProps: UnionProp[];
17
19
  }): SchemaDependencies;
18
20
  }
@@ -1,6 +1,6 @@
1
1
  export class SchemaDependencyCollector {
2
2
  static collect(props) {
3
- const { primitiveProps, arrayProps, objectProps, enumProps } = props;
3
+ const { primitiveProps, arrayProps, objectProps, enumProps, unionProps } = props;
4
4
  const schemaDepsSet = new Set();
5
5
  for (const prop of objectProps) {
6
6
  schemaDepsSet.add(prop.type);
@@ -10,6 +10,11 @@ export class SchemaDependencyCollector {
10
10
  schemaDepsSet.add(prop.type);
11
11
  }
12
12
  }
13
+ for (const prop of unionProps) {
14
+ for (const variant of prop.variantTypes) {
15
+ schemaDepsSet.add(variant);
16
+ }
17
+ }
13
18
  const enumDepsSet = new Set();
14
19
  for (const prop of enumProps) {
15
20
  if (prop.enumName)
@@ -2,10 +2,11 @@ import { ArrayProp } from "../../props/array.property.js";
2
2
  import { EnumProp } from "../../props/enum.property.js";
3
3
  import { ObjectProp } from "../../props/object.property.js";
4
4
  import { PrimitiveProp } from "../../props/primitive.property.js";
5
+ import { UnionProp } from "../../props/union.property.js";
5
6
  import type { SchemaObject, ReferenceObject } from "../../types/open-api-spec.interface.js";
6
7
  import type { FieldConfigs } from "../../types/types.js";
7
8
  import type { CodegenContext } from "../CodegenContext.js";
8
- export type ClassifiedProp = PrimitiveProp | ArrayProp | ObjectProp | EnumProp;
9
+ export type ClassifiedProp = PrimitiveProp | ArrayProp | ObjectProp | EnumProp | UnionProp;
9
10
  export declare class SchemaPropertyClassifier {
10
11
  static classify(params: {
11
12
  key: string;
@@ -2,11 +2,21 @@ import { ArrayProp } from "../../props/array.property.js";
2
2
  import { EnumProp } from "../../props/enum.property.js";
3
3
  import { ObjectProp } from "../../props/object.property.js";
4
4
  import { PrimitiveProp } from "../../props/primitive.property.js";
5
+ import { UnionProp } from "../../props/union.property.js";
5
6
  import { isReferenceObject, isPrimitiveEnumValues } from "../../helpers/helpers.js";
6
7
  export class SchemaPropertyClassifier {
7
8
  static classify(params) {
8
9
  const { key, value, requireds, fieldConfigs, schemaName, context } = params;
9
10
  if (isReferenceObject(value) || !value?.type) {
11
+ if (!isReferenceObject(value) && value.oneOf) {
12
+ return new UnionProp({
13
+ name: key,
14
+ oneOf: value.oneOf,
15
+ discriminator: value.discriminator,
16
+ isRequired: requireds.includes(key),
17
+ isNullable: value.nullable,
18
+ });
19
+ }
10
20
  if (!isReferenceObject(value) && value.additionalProperties) {
11
21
  const fakeStringSchema = { ...value, type: "string" };
12
22
  const config = fieldConfigs.get(key);
@@ -0,0 +1,37 @@
1
+ import type { DiscriminatorObject, ReferenceObject, SchemaObject } from "../types/open-api-spec.interface.js";
2
+ /**
3
+ * Property whose OpenAPI schema is a `oneOf` — a union of `$ref`ed component
4
+ * schemas, optionally carrying a `discriminator`. Only `$ref` variants are
5
+ * supported (inline `oneOf` members aren't promoted today).
6
+ *
7
+ * Runtime model is intentionally flat/passthrough: the class field stores the
8
+ * raw incoming object typed as the union of the variants' `Interface`s — there
9
+ * is no `new` (you can't instantiate a union) and no `.bundle()` on it
10
+ * (`bundleStrict`/`bundleInputs` pass plain objects through unchanged). The
11
+ * elegant discriminated narrowing lives in the schema's `Interface` type alias
12
+ * (see `DiscriminatedInterfaceRenderer`), not on the live class instance.
13
+ */
14
+ export declare class UnionProp {
15
+ name: string;
16
+ /** Variant component names extracted from each `oneOf` `$ref` (deduped, order-preserving). */
17
+ readonly variantTypes: string[];
18
+ readonly discriminator: DiscriminatorObject | undefined;
19
+ private readonly required;
20
+ private readonly isNullable;
21
+ constructor(params: {
22
+ name: string;
23
+ oneOf: (SchemaObject | ReferenceObject)[];
24
+ discriminator?: DiscriminatorObject | undefined;
25
+ isRequired?: boolean;
26
+ isNullable?: boolean | undefined;
27
+ });
28
+ /** `AInterface | BInterface | ...` — the flat union used for the class field type. */
29
+ flatUnion(): string;
30
+ /** True when this union can render as a discriminated `Interface` (needs a mapping). */
31
+ get hasDiscriminator(): boolean;
32
+ classBuild(): string;
33
+ constructorBuild(): string;
34
+ bundleBuild(): string;
35
+ interfaceBuild(): string;
36
+ hydrateBuild(): string;
37
+ }
@@ -0,0 +1,62 @@
1
+ import { isReferenceObject } from "../helpers/helpers.js";
2
+ /**
3
+ * Property whose OpenAPI schema is a `oneOf` — a union of `$ref`ed component
4
+ * schemas, optionally carrying a `discriminator`. Only `$ref` variants are
5
+ * supported (inline `oneOf` members aren't promoted today).
6
+ *
7
+ * Runtime model is intentionally flat/passthrough: the class field stores the
8
+ * raw incoming object typed as the union of the variants' `Interface`s — there
9
+ * is no `new` (you can't instantiate a union) and no `.bundle()` on it
10
+ * (`bundleStrict`/`bundleInputs` pass plain objects through unchanged). The
11
+ * elegant discriminated narrowing lives in the schema's `Interface` type alias
12
+ * (see `DiscriminatedInterfaceRenderer`), not on the live class instance.
13
+ */
14
+ export class UnionProp {
15
+ name;
16
+ /** Variant component names extracted from each `oneOf` `$ref` (deduped, order-preserving). */
17
+ variantTypes;
18
+ discriminator;
19
+ required;
20
+ isNullable;
21
+ constructor(params) {
22
+ const { name, oneOf, discriminator, isRequired, isNullable } = params;
23
+ this.name = name;
24
+ this.discriminator = discriminator;
25
+ this.required = isRequired ?? true;
26
+ this.isNullable = !!isNullable;
27
+ const refs = oneOf
28
+ .filter(isReferenceObject)
29
+ .map((ref) => ref.$ref.split("/").at(-1) ?? "")
30
+ .filter(Boolean);
31
+ this.variantTypes = [...new Set(refs)];
32
+ }
33
+ /** `AInterface | BInterface | ...` — the flat union used for the class field type. */
34
+ flatUnion() {
35
+ return this.variantTypes.map((t) => `${t}Interface`).join(" | ");
36
+ }
37
+ /** True when this union can render as a discriminated `Interface` (needs a mapping). */
38
+ get hasDiscriminator() {
39
+ return !!this.discriminator?.mapping && Object.keys(this.discriminator.mapping).length > 0;
40
+ }
41
+ classBuild() {
42
+ const req = this.required ? "" : "?";
43
+ const nullable = this.isNullable ? " | null" : "";
44
+ // No `new` for a union — `$state<T>()` (no arg) yields `T | undefined`,
45
+ // populated by the constructor from the incoming data.
46
+ return `${this.name}${req} = $state<${this.flatUnion()}${nullable}>()`;
47
+ }
48
+ constructorBuild() {
49
+ return `this.${this.name} = params?.data?.${this.name}`;
50
+ }
51
+ bundleBuild() {
52
+ return `${this.name}: this.${this.name}`;
53
+ }
54
+ interfaceBuild() {
55
+ const req = this.required ? "" : "?";
56
+ const nullable = this.isNullable ? " | null" : "";
57
+ return `${this.name}${req}: ${this.flatUnion()}${nullable}`;
58
+ }
59
+ hydrateBuild() {
60
+ return `if (data.${this.name} !== undefined) this.${this.name} = data.${this.name}`;
61
+ }
62
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-reflector",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "Reflects types from openAPI schemas",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",