+22
-10
packages/emitter/src/emitter.ts
+22
-10
packages/emitter/src/emitter.ts
···
48
LexCidLink,
49
LexRefVariant,
50
LexToken,
51
} from "./types.js";
52
53
import {
···
415
// Apply @default decorator if present
416
const rawDefault = getDefault(this.program, scalar);
417
const defaultValue = this.processDefaultValue(rawDefault);
418
-
let defWithDefault: any = { ...scalarDef };
419
420
if (defaultValue !== undefined) {
421
// Check if it's a Type (model reference for tokens)
···
431
} else {
432
// Validate that the default value matches the type
433
this.assertValidValueForType(scalarDef.type, defaultValue, scalar);
434
-
defWithDefault = { ...defWithDefault, default: defaultValue };
435
}
436
}
437
···
439
if (scalarDef.type === "integer") {
440
const minValue = getMinValue(this.program, scalar);
441
if (minValue !== undefined) {
442
-
(defWithDefault as any).minimum = minValue;
443
}
444
const maxValue = getMaxValue(this.program, scalar);
445
if (maxValue !== undefined) {
446
-
(defWithDefault as any).maximum = maxValue;
447
}
448
}
449
···
474
// Apply @default decorator if present
475
const rawDefault = getDefault(this.program, union);
476
const defaultValue = this.processDefaultValue(rawDefault);
477
-
let defWithDefault: any = { ...unionDef };
478
479
if (defaultValue !== undefined) {
480
// Check if it's a Type (model reference for tokens)
···
517
`Use @inline to inline them at usage sites, use @token models for known values, or use string literals.`,
518
target: union,
519
});
520
-
} else if (unionDef.type === "integer" && (unionDef as any).enum) {
521
// Integer enums can also be defs
522
const defName = name.charAt(0).toLowerCase() + name.slice(1);
523
const description = getDoc(this.program, union);
···
525
// Apply @default decorator if present
526
const rawDefault = getDefault(this.program, union);
527
const defaultValue = this.processDefaultValue(rawDefault);
528
-
let defWithDefault = { ...unionDef };
529
530
if (defaultValue !== undefined) {
531
if (typeof defaultValue === "number") {
···
645
// Check for default value: property default takes precedence, then union's @default
646
let defaultValue: string | number | boolean | undefined;
647
if (prop?.defaultValue !== undefined) {
648
-
defaultValue = serializeValueAsJson(this.program, prop.defaultValue, prop) as any;
649
} else {
650
// If no property default, check union's @default decorator
651
const rawUnionDefault = getDefault(this.program, unionType);
···
681
// Check for default value: property default takes precedence, then union's @default
682
let defaultValue: string | number | boolean | undefined;
683
if (prop?.defaultValue !== undefined) {
684
-
defaultValue = serializeValueAsJson(this.program, prop.defaultValue, prop) as any;
685
} else {
686
// If no property default, check union's @default decorator
687
const rawUnionDefault = getDefault(this.program, unionType);
···
1452
const propDefault = serializeValueAsJson(this.program, prop.defaultValue, prop);
1453
1454
// For union defaults that are model references, we need to resolve them for comparison
1455
-
let resolvedUnionDefault: string | number | boolean | undefined = unionDefault as any;
1456
if (unionDefault && typeof unionDefault === 'object' && 'kind' in unionDefault && unionDefault.kind === 'Model') {
1457
const ref = this.getModelReference(unionDefault as Model, true);
1458
resolvedUnionDefault = ref || undefined;
1459
}
1460
1461
// If the union has a different default, or if the property has a default but the union doesn't, error
···
48
LexCidLink,
49
LexRefVariant,
50
LexToken,
51
+
LexBoolean,
52
+
LexInteger,
53
+
LexString,
54
} from "./types.js";
55
56
import {
···
418
// Apply @default decorator if present
419
const rawDefault = getDefault(this.program, scalar);
420
const defaultValue = this.processDefaultValue(rawDefault);
421
+
let defWithDefault: LexObjectProperty = { ...scalarDef };
422
423
if (defaultValue !== undefined) {
424
// Check if it's a Type (model reference for tokens)
···
434
} else {
435
// Validate that the default value matches the type
436
this.assertValidValueForType(scalarDef.type, defaultValue, scalar);
437
+
// Type-safe narrowing based on both the type discriminator and value type
438
+
if (scalarDef.type === "boolean" && typeof defaultValue === "boolean") {
439
+
(defWithDefault as LexBoolean).default = defaultValue;
440
+
} else if (scalarDef.type === "integer" && typeof defaultValue === "number") {
441
+
(defWithDefault as LexInteger).default = defaultValue;
442
+
} else if (scalarDef.type === "string" && typeof defaultValue === "string") {
443
+
(defWithDefault as LexString).default = defaultValue;
444
+
}
445
}
446
}
447
···
449
if (scalarDef.type === "integer") {
450
const minValue = getMinValue(this.program, scalar);
451
if (minValue !== undefined) {
452
+
(defWithDefault as LexInteger).minimum = minValue;
453
}
454
const maxValue = getMaxValue(this.program, scalar);
455
if (maxValue !== undefined) {
456
+
(defWithDefault as LexInteger).maximum = maxValue;
457
}
458
}
459
···
484
// Apply @default decorator if present
485
const rawDefault = getDefault(this.program, union);
486
const defaultValue = this.processDefaultValue(rawDefault);
487
+
let defWithDefault: LexString = { ...unionDef as LexString };
488
489
if (defaultValue !== undefined) {
490
// Check if it's a Type (model reference for tokens)
···
527
`Use @inline to inline them at usage sites, use @token models for known values, or use string literals.`,
528
target: union,
529
});
530
+
} else if (unionDef.type === "integer" && (unionDef as LexInteger).enum) {
531
// Integer enums can also be defs
532
const defName = name.charAt(0).toLowerCase() + name.slice(1);
533
const description = getDoc(this.program, union);
···
535
// Apply @default decorator if present
536
const rawDefault = getDefault(this.program, union);
537
const defaultValue = this.processDefaultValue(rawDefault);
538
+
let defWithDefault: LexInteger = { ...unionDef as LexInteger };
539
540
if (defaultValue !== undefined) {
541
if (typeof defaultValue === "number") {
···
655
// Check for default value: property default takes precedence, then union's @default
656
let defaultValue: string | number | boolean | undefined;
657
if (prop?.defaultValue !== undefined) {
658
+
defaultValue = serializeValueAsJson(this.program, prop.defaultValue, prop) as string | number | boolean;
659
} else {
660
// If no property default, check union's @default decorator
661
const rawUnionDefault = getDefault(this.program, unionType);
···
691
// Check for default value: property default takes precedence, then union's @default
692
let defaultValue: string | number | boolean | undefined;
693
if (prop?.defaultValue !== undefined) {
694
+
defaultValue = serializeValueAsJson(this.program, prop.defaultValue, prop) as string | number | boolean;
695
} else {
696
// If no property default, check union's @default decorator
697
const rawUnionDefault = getDefault(this.program, unionType);
···
1462
const propDefault = serializeValueAsJson(this.program, prop.defaultValue, prop);
1463
1464
// For union defaults that are model references, we need to resolve them for comparison
1465
+
let resolvedUnionDefault: string | number | boolean | undefined;
1466
if (unionDefault && typeof unionDefault === 'object' && 'kind' in unionDefault && unionDefault.kind === 'Model') {
1467
const ref = this.getModelReference(unionDefault as Model, true);
1468
resolvedUnionDefault = ref || undefined;
1469
+
} else {
1470
+
resolvedUnionDefault = unionDefault as string | number | boolean;
1471
}
1472
1473
// If the union has a different default, or if the property has a default but the union doesn't, error