@typespec/html-program-viewer 0.65.0 → 0.66.0-dev.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,6 @@
1
+ const manifest = {
2
+ "version": "0.65.1",
3
+ "commit": "ba241e8e5561e3b99d4a7b6195aa193c35cbae63"
4
+ };
5
+
6
+ export { manifest as default };
@@ -18110,7 +18110,7 @@ let manifest;
18110
18110
  try {
18111
18111
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
18112
18112
  // @ts-ignore
18113
- manifest = (await import('../manifest-BNuBm9Cd.js')).default;
18113
+ manifest = (await import('../manifest-oMDJJFgr.js')).default;
18114
18114
  }
18115
18115
  catch {
18116
18116
  const name = "../dist/manifest.js";
@@ -28630,6 +28630,64 @@ const stateKeys = {
28630
28630
  errorsDocs: createStateSymbol("errorDocs"),
28631
28631
  discriminator: createStateSymbol("discriminator"),
28632
28632
  };
28633
+ function getMinValueAsNumeric(program, target) {
28634
+ return program.stateMap(stateKeys.minValues).get(target);
28635
+ }
28636
+ function getMinValue(program, target) {
28637
+ return getMinValueAsNumeric(program, target)?.asNumber() ?? undefined;
28638
+ }
28639
+ function getMaxValueAsNumeric(program, target) {
28640
+ return program.stateMap(stateKeys.maxValues).get(target);
28641
+ }
28642
+ function getMaxValue(program, target) {
28643
+ return getMaxValueAsNumeric(program, target)?.asNumber() ?? undefined;
28644
+ }
28645
+ function getMinValueExclusiveAsNumeric(program, target) {
28646
+ return program.stateMap(stateKeys.minValueExclusive).get(target);
28647
+ }
28648
+ function getMinValueExclusive(program, target) {
28649
+ return getMinValueExclusiveAsNumeric(program, target)?.asNumber() ?? undefined;
28650
+ }
28651
+ function getMaxValueExclusiveAsNumeric(program, target) {
28652
+ return program.stateMap(stateKeys.maxValueExclusive).get(target);
28653
+ }
28654
+ function getMaxValueExclusive(program, target) {
28655
+ return getMaxValueExclusiveAsNumeric(program, target)?.asNumber() ?? undefined;
28656
+ }
28657
+ /**
28658
+ * Get the minimum length of a string type as a {@link Numeric} value.
28659
+ * @param program Current program
28660
+ * @param target Type with the `@minLength` decorator
28661
+ */
28662
+ function getMinLengthAsNumeric(program, target) {
28663
+ return program.stateMap(stateKeys.minLength).get(target);
28664
+ }
28665
+ function getMinLength(program, target) {
28666
+ return getMinLengthAsNumeric(program, target)?.asNumber() ?? undefined;
28667
+ }
28668
+ /**
28669
+ * Get the minimum length of a string type as a {@link Numeric} value.
28670
+ * @param program Current program
28671
+ * @param target Type with the `@maxLength` decorator
28672
+ */
28673
+ function getMaxLengthAsNumeric(program, target) {
28674
+ return program.stateMap(stateKeys.maxLength).get(target);
28675
+ }
28676
+ function getMaxLength(program, target) {
28677
+ return getMaxLengthAsNumeric(program, target)?.asNumber() ?? undefined;
28678
+ }
28679
+ function getMinItemsAsNumeric(program, target) {
28680
+ return program.stateMap(stateKeys.minItems).get(target);
28681
+ }
28682
+ function getMinItems(program, target) {
28683
+ return getMinItemsAsNumeric(program, target)?.asNumber() ?? undefined;
28684
+ }
28685
+ function getMaxItemsAsNumeric(program, target) {
28686
+ return program.stateMap(stateKeys.maxItems).get(target);
28687
+ }
28688
+ function getMaxItems(program, target) {
28689
+ return getMaxItemsAsNumeric(program, target)?.asNumber() ?? undefined;
28690
+ }
28633
28691
  function getDocKey(target) {
28634
28692
  switch (target) {
28635
28693
  case "self":
@@ -28650,8 +28708,50 @@ function getDocKey(target) {
28650
28708
  function getDocDataInternal(program, target, key) {
28651
28709
  return program.stateMap(getDocKey(key)).get(target);
28652
28710
  }
28711
+ function getDiscriminator(program, entity) {
28712
+ return program.stateMap(stateKeys.discriminator).get(entity);
28713
+ }
28653
28714
  // #endregion
28654
28715
 
28716
+ /**
28717
+ * Helper class to track duplicate instance
28718
+ */
28719
+ class DuplicateTracker {
28720
+ #entries = new Map();
28721
+ /**
28722
+ * Track usage of K.
28723
+ * @param k key that is being checked for duplicate.
28724
+ * @param v value that map to the key
28725
+ */
28726
+ track(k, v) {
28727
+ const existing = this.#entries.get(k);
28728
+ if (existing === undefined) {
28729
+ this.#entries.set(k, [v]);
28730
+ }
28731
+ else {
28732
+ existing.push(v);
28733
+ }
28734
+ }
28735
+ /**
28736
+ * Return iterator of all the duplicate entries.
28737
+ */
28738
+ *entries() {
28739
+ for (const [k, v] of this.#entries.entries()) {
28740
+ if (v.length > 1) {
28741
+ yield [k, v];
28742
+ }
28743
+ }
28744
+ }
28745
+ }
28746
+
28747
+ function getLocationContext(program, type) {
28748
+ const sourceLocation = getSourceLocation(type);
28749
+ if (sourceLocation.isSynthetic) {
28750
+ return { type: "synthetic" };
28751
+ }
28752
+ return program.getSourceFileLocationContext(sourceLocation.file);
28753
+ }
28754
+
28655
28755
  //
28656
28756
  // Generated by scripts/regen-nonascii-map.js
28657
28757
  // on node v18.16.0 with unicode 15.0.
@@ -29422,6 +29522,49 @@ function lookupInNonAsciiMap(codePoint, map) {
29422
29522
  return false;
29423
29523
  }
29424
29524
 
29525
+ /**
29526
+ * Print a string as a TypeSpec identifier. If the string is a valid identifier, return it as is otherwise wrap it into backticks.
29527
+ * @param sv Identifier string value.
29528
+ * @returns Identifier string as it would be represented in a TypeSpec file.
29529
+ *
29530
+ * @example
29531
+ * ```ts
29532
+ * printIdentifier("foo") // foo
29533
+ * printIdentifier("foo bar") // `foo bar`
29534
+ * ```
29535
+ */
29536
+ function printIdentifier(sv) {
29537
+ if (needBacktick(sv)) {
29538
+ const escapedString = sv
29539
+ .replace(/\\/g, "\\\\")
29540
+ .replace(/\n/g, "\\n")
29541
+ .replace(/\r/g, "\\r")
29542
+ .replace(/\t/g, "\\t")
29543
+ .replace(/`/g, "\\`");
29544
+ return `\`${escapedString}\``;
29545
+ }
29546
+ else {
29547
+ return sv;
29548
+ }
29549
+ }
29550
+ function needBacktick(sv) {
29551
+ if (sv.length === 0) {
29552
+ return false;
29553
+ }
29554
+ if (Keywords.has(sv)) {
29555
+ return true;
29556
+ }
29557
+ let cp = sv.codePointAt(0);
29558
+ if (!isIdentifierStart(cp)) {
29559
+ return true;
29560
+ }
29561
+ let pos = 0;
29562
+ do {
29563
+ pos += utf16CodeUnits(cp);
29564
+ } while (pos < sv.length && isIdentifierContinue((cp = sv.codePointAt(pos))));
29565
+ return pos < sv.length;
29566
+ }
29567
+
29425
29568
  var Token;
29426
29569
  (function (Token) {
29427
29570
  Token[Token["None"] = 0] = "None";
@@ -29838,12 +29981,28 @@ function getDeprecationDetails(program, typeOrNode) {
29838
29981
  function isErrorType(type) {
29839
29982
  return "kind" in type && type.kind === "Intrinsic" && type.name === "ErrorType";
29840
29983
  }
29984
+ function isNeverType(type) {
29985
+ return "kind" in type && type.kind === "Intrinsic" && type.name === "never";
29986
+ }
29841
29987
  function isType(entity) {
29842
29988
  return entity.entityKind === "Type";
29843
29989
  }
29844
29990
  function isValue(entity) {
29845
29991
  return entity.entityKind === "Value";
29846
29992
  }
29993
+ /**
29994
+ * @param type Model type
29995
+ */
29996
+ function isArrayModelType(program, type) {
29997
+ return Boolean(type.indexer && type.indexer.key.name === "integer");
29998
+ }
29999
+ /**
30000
+ * Check if a model is an array type.
30001
+ * @param type Model type
30002
+ */
30003
+ function isRecordModelType(program, type) {
30004
+ return Boolean(type.indexer && type.indexer.key.name === "string");
30005
+ }
29847
30006
  /**
29848
30007
  * Check the given type is a finished template instance.
29849
30008
  */
@@ -29853,48 +30012,167 @@ function isTemplateInstance(type) {
29853
30012
  !maybeTemplateType.templateMapper.partial &&
29854
30013
  maybeTemplateType.isFinished);
29855
30014
  }
29856
-
29857
30015
  /**
29858
- * Print a string as a TypeSpec identifier. If the string is a valid identifier, return it as is otherwise wrap it into backticks.
29859
- * @param sv Identifier string value.
29860
- * @returns Identifier string as it would be represented in a TypeSpec file.
29861
- *
29862
- * @example
29863
- * ```ts
29864
- * printIdentifier("foo") // foo
29865
- * printIdentifier("foo bar") // `foo bar`
29866
- * ```
30016
+ * Resolve if the type was created from a template type or is a template type declaration.
29867
30017
  */
29868
- function printIdentifier(sv) {
29869
- if (needBacktick(sv)) {
29870
- const escapedString = sv
29871
- .replace(/\\/g, "\\\\")
29872
- .replace(/\n/g, "\\n")
29873
- .replace(/\r/g, "\\r")
29874
- .replace(/\t/g, "\\t")
29875
- .replace(/`/g, "\\`");
29876
- return `\`${escapedString}\``;
30018
+ function isTemplateDeclarationOrInstance(type) {
30019
+ if (type.node === undefined) {
30020
+ return false;
29877
30021
  }
29878
- else {
29879
- return sv;
30022
+ const node = type.node;
30023
+ return node.templateParameters && node.templateParameters.length > 0;
30024
+ }
30025
+
30026
+ function getDiscriminatedUnion(type, discriminator) {
30027
+ switch (type.kind) {
30028
+ case "Model":
30029
+ return getDiscriminatedUnionForModel(type, discriminator);
30030
+ case "Union":
30031
+ return getDiscriminatedUnionForUnion(type, discriminator);
30032
+ }
30033
+ }
30034
+ function getDiscriminatedUnionForUnion(type, discriminator) {
30035
+ const variants = new Map();
30036
+ const diagnostics = [];
30037
+ const duplicates = new DuplicateTracker();
30038
+ for (const variant of type.variants.values()) {
30039
+ if (variant.type.kind !== "Model") {
30040
+ diagnostics.push(createDiagnostic({
30041
+ code: "invalid-discriminated-union-variant",
30042
+ format: { name: variant.name.toString() },
30043
+ target: variant,
30044
+ }));
30045
+ continue;
30046
+ }
30047
+ const prop = getDiscriminatorProperty(variant.type, discriminator, diagnostics);
30048
+ if (prop === undefined) {
30049
+ diagnostics.push(createDiagnostic({
30050
+ code: "invalid-discriminated-union-variant",
30051
+ messageId: "noDiscriminant",
30052
+ format: { name: variant.name.toString(), discriminant: discriminator.propertyName },
30053
+ target: variant,
30054
+ }));
30055
+ continue;
30056
+ }
30057
+ const key = getStringValue(prop.type);
30058
+ if (key) {
30059
+ duplicates.track(key, variant.type);
30060
+ variants.set(key, variant.type);
30061
+ }
30062
+ else {
30063
+ diagnostics.push(createDiagnostic({
30064
+ code: "invalid-discriminated-union-variant",
30065
+ messageId: "wrongDiscriminantType",
30066
+ format: { name: variant.name.toString(), discriminant: discriminator.propertyName },
30067
+ target: variant.type,
30068
+ }));
30069
+ }
30070
+ }
30071
+ reportDuplicateDiscriminatorValues(duplicates, diagnostics);
30072
+ const discriminatedUnion = {
30073
+ propertyName: discriminator.propertyName,
30074
+ variants,
30075
+ };
30076
+ return [discriminatedUnion, diagnostics];
30077
+ }
30078
+ function getDiscriminatedUnionForModel(type, discriminator) {
30079
+ const variants = new Map();
30080
+ const diagnostics = [];
30081
+ const duplicates = new DuplicateTracker();
30082
+ function checkForVariantsIn(current) {
30083
+ for (const derivedModel of current.derivedModels) {
30084
+ if (isTemplateDeclarationOrInstance(derivedModel)) {
30085
+ continue; // Skip template instances as they should be used with `model is`
30086
+ }
30087
+ const keys = getDiscriminatorValues(derivedModel, discriminator, diagnostics);
30088
+ if (keys === undefined) {
30089
+ if (derivedModel.derivedModels.length === 0) {
30090
+ diagnostics.push(createDiagnostic({
30091
+ code: "missing-discriminator-property",
30092
+ format: { discriminator: discriminator.propertyName },
30093
+ target: derivedModel,
30094
+ }));
30095
+ }
30096
+ else {
30097
+ checkForVariantsIn(derivedModel);
30098
+ }
30099
+ }
30100
+ else {
30101
+ for (const key of keys) {
30102
+ duplicates.track(key, derivedModel);
30103
+ variants.set(key, derivedModel);
30104
+ }
30105
+ }
30106
+ }
30107
+ }
30108
+ checkForVariantsIn(type);
30109
+ reportDuplicateDiscriminatorValues(duplicates, diagnostics);
30110
+ const discriminatedUnion = {
30111
+ propertyName: discriminator.propertyName,
30112
+ variants,
30113
+ };
30114
+ return [discriminatedUnion, diagnostics];
30115
+ }
30116
+ function reportDuplicateDiscriminatorValues(duplicates, diagnostics) {
30117
+ for (const [duplicateKey, models] of duplicates.entries()) {
30118
+ for (const model of models) {
30119
+ diagnostics.push(createDiagnostic({
30120
+ code: "invalid-discriminator-value",
30121
+ messageId: "duplicate",
30122
+ format: { discriminator: duplicateKey },
30123
+ target: model,
30124
+ }));
30125
+ }
29880
30126
  }
29881
30127
  }
29882
- function needBacktick(sv) {
29883
- if (sv.length === 0) {
29884
- return false;
30128
+ function getDiscriminatorProperty(model, discriminator, diagnostics) {
30129
+ const prop = model.properties.get(discriminator.propertyName);
30130
+ if (prop && prop.optional) {
30131
+ diagnostics.push(createDiagnostic({
30132
+ code: "invalid-discriminator-value",
30133
+ messageId: "required",
30134
+ target: prop,
30135
+ }));
29885
30136
  }
29886
- if (Keywords.has(sv)) {
29887
- return true;
30137
+ return prop;
30138
+ }
30139
+ function getDiscriminatorValues(model, discriminator, diagnostics) {
30140
+ const prop = getDiscriminatorProperty(model, discriminator, diagnostics);
30141
+ if (!prop)
30142
+ return undefined;
30143
+ const keys = getStringValues(prop.type);
30144
+ if (keys.length === 0) {
30145
+ diagnostics.push(createDiagnostic({
30146
+ code: "invalid-discriminator-value",
30147
+ format: { kind: prop.type.kind },
30148
+ target: prop,
30149
+ }));
29888
30150
  }
29889
- let cp = sv.codePointAt(0);
29890
- if (!isIdentifierStart(cp)) {
29891
- return true;
30151
+ return keys;
30152
+ }
30153
+ function getStringValues(type) {
30154
+ switch (type.kind) {
30155
+ case "String":
30156
+ return [type.value];
30157
+ case "Union":
30158
+ return [...type.variants.values()].flatMap((x) => getStringValues(x.type)).filter(isDefined);
30159
+ case "EnumMember":
30160
+ return typeof type.value !== "number" ? [type.value ?? type.name] : [];
30161
+ case "UnionVariant":
30162
+ return getStringValues(type.type);
30163
+ default:
30164
+ return [];
30165
+ }
30166
+ }
30167
+ function getStringValue(type) {
30168
+ switch (type.kind) {
30169
+ case "String":
30170
+ return type.value;
30171
+ case "EnumMember":
30172
+ return typeof type.value !== "number" ? (type.value ?? type.name) : undefined;
30173
+ default:
30174
+ return undefined;
29892
30175
  }
29893
- let pos = 0;
29894
- do {
29895
- pos += utf16CodeUnits(cp);
29896
- } while (pos < sv.length && isIdentifierContinue((cp = sv.codePointAt(pos))));
29897
- return pos < sv.length;
29898
30176
  }
29899
30177
 
29900
30178
  function getTypeName(type, options) {
@@ -32040,6 +32318,7 @@ _a = Realm;
32040
32318
  * @internal
32041
32319
  */
32042
32320
  const TypekitPrototype = {};
32321
+ const TypekitNamespaceSymbol = Symbol.for("TypekitNamespace");
32043
32322
  /**
32044
32323
  * Defines an extension to the Typekit interface.
32045
32324
  *
@@ -32049,10 +32328,228 @@ const TypekitPrototype = {};
32049
32328
  */
32050
32329
  function defineKit(source) {
32051
32330
  for (const [name, fnOrNs] of Object.entries(source)) {
32052
- TypekitPrototype[name] = fnOrNs;
32331
+ let kits = fnOrNs;
32332
+ if (TypekitPrototype[name] !== undefined) {
32333
+ kits = { ...TypekitPrototype[name], ...fnOrNs };
32334
+ }
32335
+ // Tag top-level namespace objects with the symbol
32336
+ if (typeof kits === "object" && kits !== null) {
32337
+ Object.defineProperty(kits, TypekitNamespaceSymbol, {
32338
+ value: true,
32339
+ enumerable: false, // Keep the symbol non-enumerable
32340
+ configurable: false,
32341
+ });
32342
+ }
32343
+ TypekitPrototype[name] = kits;
32053
32344
  }
32054
32345
  }
32055
32346
 
32347
+ defineKit({
32348
+ array: {
32349
+ is(type) {
32350
+ return (type.kind === "Model" && isArrayModelType(this.program, type) && type.properties.size === 0);
32351
+ },
32352
+ getElementType(type) {
32353
+ if (!this.array.is(type)) {
32354
+ throw new Error("Type is not an array.");
32355
+ }
32356
+ return type.indexer.value;
32357
+ },
32358
+ create(elementType) {
32359
+ return this.model.create({
32360
+ name: "Array",
32361
+ properties: {},
32362
+ indexer: {
32363
+ key: this.builtin.integer,
32364
+ value: elementType,
32365
+ },
32366
+ });
32367
+ },
32368
+ },
32369
+ });
32370
+
32371
+ defineKit({
32372
+ builtin: {
32373
+ get string() {
32374
+ return this.program.checker.getStdType("string");
32375
+ },
32376
+ get boolean() {
32377
+ return this.program.checker.getStdType("boolean");
32378
+ },
32379
+ get bytes() {
32380
+ return this.program.checker.getStdType("bytes");
32381
+ },
32382
+ get decimal() {
32383
+ return this.program.checker.getStdType("decimal");
32384
+ },
32385
+ get decimal128() {
32386
+ return this.program.checker.getStdType("decimal128");
32387
+ },
32388
+ get duration() {
32389
+ return this.program.checker.getStdType("duration");
32390
+ },
32391
+ get float() {
32392
+ return this.program.checker.getStdType("float");
32393
+ },
32394
+ get float32() {
32395
+ return this.program.checker.getStdType("float32");
32396
+ },
32397
+ get float64() {
32398
+ return this.program.checker.getStdType("float64");
32399
+ },
32400
+ get int8() {
32401
+ return this.program.checker.getStdType("int8");
32402
+ },
32403
+ get int16() {
32404
+ return this.program.checker.getStdType("int16");
32405
+ },
32406
+ get int32() {
32407
+ return this.program.checker.getStdType("int32");
32408
+ },
32409
+ get int64() {
32410
+ return this.program.checker.getStdType("int64");
32411
+ },
32412
+ get integer() {
32413
+ return this.program.checker.getStdType("integer");
32414
+ },
32415
+ get offsetDateTime() {
32416
+ return this.program.checker.getStdType("offsetDateTime");
32417
+ },
32418
+ get plainDate() {
32419
+ return this.program.checker.getStdType("plainDate");
32420
+ },
32421
+ get plainTime() {
32422
+ return this.program.checker.getStdType("plainTime");
32423
+ },
32424
+ get safeInt() {
32425
+ return this.program.checker.getStdType("safeint");
32426
+ },
32427
+ get uint8() {
32428
+ return this.program.checker.getStdType("uint8");
32429
+ },
32430
+ get uint16() {
32431
+ return this.program.checker.getStdType("uint16");
32432
+ },
32433
+ get uint32() {
32434
+ return this.program.checker.getStdType("uint32");
32435
+ },
32436
+ get uint64() {
32437
+ return this.program.checker.getStdType("uint64");
32438
+ },
32439
+ get url() {
32440
+ return this.program.checker.getStdType("url");
32441
+ },
32442
+ get utcDateTime() {
32443
+ return this.program.checker.getStdType("utcDateTime");
32444
+ },
32445
+ get numeric() {
32446
+ return this.program.checker.getStdType("numeric");
32447
+ },
32448
+ },
32449
+ });
32450
+
32451
+ /**
32452
+ * Creates a shallow copy of a rekeyable map.
32453
+ *
32454
+ * @experimental
32455
+ */
32456
+ function copyMap(map) {
32457
+ return createRekeyableMap(map.entries());
32458
+ }
32459
+ /**
32460
+ * Utility function for converting a list of decorators and arguments into structure decorator applications that are
32461
+ * compatible with the TypeSpec type graph.
32462
+ *
32463
+ * Note: Not all JavaScript values can be converted faithfully to TypeSpec values. This function will attempt to convert
32464
+ * the value to a literal TypeSpec value if it is a primitive value, otherwise it will be left as a JavaScript value.
32465
+ * The `jsValue` property of the argument will always contain the original JavaScript value passed to the decorator.
32466
+ *
32467
+ * @param typekit - The Typekit instance to use for creating types and values.
32468
+ * @param decorators - The list of decorators and arguments to apply.
32469
+ *
32470
+ * @see {@link DecoratorArgs}
32471
+ *
32472
+ * @experimental
32473
+ */
32474
+ function decoratorApplication(typekit, decorators) {
32475
+ return (decorators?.map((arg) => {
32476
+ const [decorator, args] = Array.isArray(arg) ? [arg[0], arg.slice(1)] : [arg, []];
32477
+ return {
32478
+ decorator,
32479
+ args: args.map((rawValue) => ({
32480
+ value: typeof rawValue === "object" && rawValue !== null
32481
+ ? rawValue
32482
+ : typekit.literal.create(rawValue),
32483
+ jsValue: rawValue,
32484
+ })),
32485
+ };
32486
+ }) ?? []);
32487
+ }
32488
+
32489
+ defineKit({
32490
+ enumMember: {
32491
+ create(desc) {
32492
+ const member = this.program.checker.createType({
32493
+ kind: "EnumMember",
32494
+ name: desc.name,
32495
+ value: desc.value,
32496
+ decorators: decoratorApplication(this, desc.decorators),
32497
+ node: undefined,
32498
+ enum: desc.enum, // initialized in enum.build if not provided here
32499
+ });
32500
+ this.program.checker.finishType(member);
32501
+ return member;
32502
+ },
32503
+ is(type) {
32504
+ return type.kind === "EnumMember";
32505
+ },
32506
+ },
32507
+ });
32508
+
32509
+ defineKit({
32510
+ enum: {
32511
+ create(desc) {
32512
+ const en = this.program.checker.createType({
32513
+ kind: "Enum",
32514
+ name: desc.name,
32515
+ decorators: decoratorApplication(this, desc.decorators),
32516
+ members: createRekeyableMap(),
32517
+ node: undefined,
32518
+ });
32519
+ if (Array.isArray(desc.members)) {
32520
+ for (const member of desc.members) {
32521
+ member.enum = en;
32522
+ en.members.set(member.name, member);
32523
+ }
32524
+ }
32525
+ else {
32526
+ for (const [name, member] of Object.entries(desc.members ?? {})) {
32527
+ en.members.set(name, this.enumMember.create({ name, value: member, enum: en }));
32528
+ }
32529
+ }
32530
+ this.program.checker.finishType(en);
32531
+ return en;
32532
+ },
32533
+ is(type) {
32534
+ return type.kind === "Enum";
32535
+ },
32536
+ createFromUnion(type) {
32537
+ if (!type.name) {
32538
+ throw new Error("Cannot create an enum from an anonymous union.");
32539
+ }
32540
+ const enumMembers = [];
32541
+ for (const variant of type.variants.values()) {
32542
+ if ((variant.name && typeof variant.name === "symbol") ||
32543
+ (!this.literal.isString(variant.type) && !this.literal.isNumeric(variant.type))) {
32544
+ continue;
32545
+ }
32546
+ enumMembers.push(this.enumMember.create({ name: variant.name, value: variant.type.value }));
32547
+ }
32548
+ return this.enum.create({ name: type.name, members: enumMembers });
32549
+ },
32550
+ },
32551
+ });
32552
+
32056
32553
  defineKit({
32057
32554
  literal: {
32058
32555
  create(value) {
@@ -32172,6 +32669,63 @@ function getVisibilityForClass(program, property, visibilityClass) {
32172
32669
  }
32173
32670
  // #endregion
32174
32671
 
32672
+ const regex = /^(application|audio|font|example|image|message|model|multipart|text|video|x-(?:[0-9A-Za-z!#$%&'*+.^_`|~-]+))\/([0-9A-Za-z!#$%&'*+.^_`|~-]+)$/;
32673
+ function parseMimeType(mimeType) {
32674
+ const match = mimeType.match(regex);
32675
+ if (match == null) {
32676
+ return undefined;
32677
+ }
32678
+ const type = {
32679
+ type: match[1],
32680
+ ...parseSubType(match[2]),
32681
+ };
32682
+ return type;
32683
+ }
32684
+ function parseSubType(value) {
32685
+ if (!value.includes("+"))
32686
+ return { subtype: value };
32687
+ const [subtype, suffix] = value.split("+", 2);
32688
+ return { subtype, suffix };
32689
+ }
32690
+
32691
+ const [getEncodedNamesMap, setEncodedNamesMap, getEncodedNamesStateMap] = useStateMap(createStateSymbol("encodedName"));
32692
+ function getEncodedName(program, target, mimeType) {
32693
+ const mimeTypeObj = parseMimeType(mimeType);
32694
+ if (mimeTypeObj === undefined) {
32695
+ return undefined;
32696
+ }
32697
+ const resolvedMimeType = mimeTypeObj?.suffix
32698
+ ? `${mimeTypeObj.type}/${mimeTypeObj.suffix}`
32699
+ : mimeType;
32700
+ return getEncodedNamesMap(program, target)?.get(resolvedMimeType);
32701
+ }
32702
+ /**
32703
+ * Resolve the encoded name for the given type when serialized to the given mime type.
32704
+ * If a specific value was provided by `@encodedName` decorator for that mime type it will return that otherwise it will return the name of the type.
32705
+ *
32706
+ * @example
32707
+ *
32708
+ * For the given
32709
+ * ```tsp
32710
+ * model Certificate {
32711
+ * @encodedName("application/json", "exp")
32712
+ * @encodedName("application/xml", "expiry")
32713
+ * expireAt: utcDateTime;
32714
+ *
32715
+ * }
32716
+ * ```
32717
+ *
32718
+ * ```ts
32719
+ * resolveEncodedName(program, type, "application/json") // exp
32720
+ * resolveEncodedName(program, type, "application/merge-patch+json") // exp
32721
+ * resolveEncodedName(program, type, "application/xml") // expireAt
32722
+ * resolveEncodedName(program, type, "application/yaml") // expiry
32723
+ * ```
32724
+ */
32725
+ function resolveEncodedName(program, target, mimeType) {
32726
+ return getEncodedName(program, target, mimeType) ?? target.name;
32727
+ }
32728
+
32175
32729
  /**
32176
32730
  * Flow control for mutators.
32177
32731
  *
@@ -32199,6 +32753,7 @@ var MutatorFlow;
32199
32753
  })(MutatorFlow || (MutatorFlow = {}));
32200
32754
  // #endregion
32201
32755
 
32756
+ const [getSummary, setSummary] = useStateMap(createStateSymbol("summary"));
32202
32757
  /**
32203
32758
  * Get the documentation string for the given type.
32204
32759
  * @param program Program
@@ -32226,47 +32781,21 @@ defineKit({
32226
32781
  getVisibilityForClass(property, visibilityClass) {
32227
32782
  return getVisibilityForClass(this.program, property, visibilityClass);
32228
32783
  },
32784
+ create(desc) {
32785
+ return this.program.checker.createType({
32786
+ kind: "ModelProperty",
32787
+ name: desc.name,
32788
+ node: undefined,
32789
+ type: desc.type,
32790
+ optional: desc.optional ?? false,
32791
+ decorators: [],
32792
+ defaultValue: desc.defaultValue,
32793
+ });
32794
+ },
32229
32795
  },
32230
32796
  });
32231
32797
 
32232
- /**
32233
- * Creates a shallow copy of a rekeyable map.
32234
- *
32235
- * @experimental
32236
- */
32237
- function copyMap(map) {
32238
- return createRekeyableMap(map.entries());
32239
- }
32240
- /**
32241
- * Utility function for converting a list of decorators and arguments into structure decorator applications that are
32242
- * compatible with the TypeSpec type graph.
32243
- *
32244
- * Note: Not all JavaScript values can be converted faithfully to TypeSpec values. This function will attempt to convert
32245
- * the value to a literal TypeSpec value if it is a primitive value, otherwise it will be left as a JavaScript value.
32246
- * The `jsValue` property of the argument will always contain the original JavaScript value passed to the decorator.
32247
- *
32248
- * @param typekit - The Typekit instance to use for creating types and values.
32249
- * @param decorators - The list of decorators and arguments to apply.
32250
- *
32251
- * @see {@link DecoratorArgs}
32252
- *
32253
- * @experimental
32254
- */
32255
- function decoratorApplication(typekit, decorators) {
32256
- return (decorators?.map((arg) => {
32257
- const [decorator, args] = Array.isArray(arg) ? [arg[0], arg.slice(1)] : [arg, []];
32258
- return {
32259
- decorator,
32260
- args: args.map((rawValue) => ({
32261
- value: typeof rawValue === "object" && rawValue !== null
32262
- ? rawValue
32263
- : typekit.literal.create(rawValue),
32264
- jsValue: rawValue,
32265
- })),
32266
- };
32267
- }) ?? []);
32268
- }
32269
-
32798
+ const spreadCache = new Map();
32270
32799
  defineKit({
32271
32800
  model: {
32272
32801
  create(desc) {
@@ -32280,6 +32809,7 @@ defineKit({
32280
32809
  node: undefined,
32281
32810
  derivedModels: desc.derivedModels ?? [],
32282
32811
  sourceModels: desc.sourceModels ?? [],
32812
+ indexer: desc.indexer,
32283
32813
  });
32284
32814
  this.program.checker.finishType(model);
32285
32815
  return model;
@@ -32287,9 +32817,105 @@ defineKit({
32287
32817
  is(type) {
32288
32818
  return type.kind === "Model";
32289
32819
  },
32820
+ isExpresion(type) {
32821
+ return type.name === "";
32822
+ },
32290
32823
  getEffectiveModel(model, filter) {
32291
32824
  return getEffectiveModelType(this.program, model, filter);
32292
32825
  },
32826
+ getSpreadType(model) {
32827
+ if (spreadCache.has(model)) {
32828
+ return spreadCache.get(model);
32829
+ }
32830
+ if (!model.indexer) {
32831
+ return undefined;
32832
+ }
32833
+ if (model.indexer.key.name === "string") {
32834
+ const record = this.record.create(model.indexer.value);
32835
+ spreadCache.set(model, record);
32836
+ return record;
32837
+ }
32838
+ if (model.indexer.key.name === "integer") {
32839
+ const array = this.array.create(model.indexer.value);
32840
+ spreadCache.set(model, array);
32841
+ return array;
32842
+ }
32843
+ return model.indexer.value;
32844
+ },
32845
+ getProperties(model, options = {}) {
32846
+ // Add explicitly defined properties
32847
+ const properties = copyMap(model.properties);
32848
+ // Add discriminator property if it exists
32849
+ const discriminator = this.type.getDiscriminator(model);
32850
+ if (discriminator) {
32851
+ const discriminatorName = discriminator.propertyName;
32852
+ properties.set(discriminatorName, this.modelProperty.create({ name: discriminatorName, type: this.builtin.string }));
32853
+ }
32854
+ if (options.includeExtended) {
32855
+ let base = model.baseModel;
32856
+ while (base) {
32857
+ for (const [key, value] of base.properties) {
32858
+ if (!properties.has(key)) {
32859
+ properties.set(key, value);
32860
+ }
32861
+ }
32862
+ base = base.baseModel;
32863
+ }
32864
+ }
32865
+ // TODO: Add Spread?
32866
+ return properties;
32867
+ },
32868
+ },
32869
+ });
32870
+
32871
+ defineKit({
32872
+ operation: {
32873
+ is(type) {
32874
+ return type.kind === "Operation";
32875
+ },
32876
+ create(desc) {
32877
+ const parametersModel = this.model.create({
32878
+ name: `${desc.name}Parameters`,
32879
+ properties: desc.parameters.reduce((acc, property) => {
32880
+ acc[property.name] = property;
32881
+ return acc;
32882
+ }, {}),
32883
+ });
32884
+ const operation = this.program.checker.createType({
32885
+ kind: "Operation",
32886
+ name: desc.name,
32887
+ decorators: [],
32888
+ parameters: parametersModel,
32889
+ returnType: desc.returnType,
32890
+ node: undefined,
32891
+ });
32892
+ this.program.checker.finishType(operation);
32893
+ return operation;
32894
+ },
32895
+ },
32896
+ });
32897
+
32898
+ defineKit({
32899
+ record: {
32900
+ is(type) {
32901
+ return (type.kind === "Model" && isRecordModelType(this.program, type) && type.properties.size === 0);
32902
+ },
32903
+ getElementType(type) {
32904
+ if (!this.record.is(type)) {
32905
+ throw new Error("Type is not a record.");
32906
+ }
32907
+ return type.indexer.value;
32908
+ },
32909
+ create(elementType) {
32910
+ return this.model.create({
32911
+ name: "Record",
32912
+ properties: {},
32913
+ indexer: {
32914
+ key: this.builtin.string,
32915
+ value: elementType,
32916
+ },
32917
+ });
32918
+ },
32293
32919
  },
32294
32920
  });
32295
32921
 
@@ -32381,6 +33007,22 @@ function extendsStdType(typeName) {
32381
33007
  };
32382
33008
  }
32383
33009
 
33010
+ /**
33011
+ * Get a plausible name for the given type.
33012
+ * @experimental
33013
+ */
33014
+ function getPlausibleName(type) {
33015
+ let name = type.name;
33016
+ if (!name) {
33017
+ name = "TypeExpression"; // TODO: Implement automatic name generation based on the type context
33018
+ }
33019
+ if (isTemplateInstance(type)) {
33020
+ const namePrefix = type.templateMapper.args.map((a) => ("name" in a && a.name) || "").join("_");
33021
+ name = `${namePrefix}${name}`;
33022
+ }
33023
+ return name;
33024
+ }
33025
+
32384
33026
  defineKit({
32385
33027
  type: {
32386
33028
  finishType(type) {
@@ -32460,6 +33102,66 @@ defineKit({
32460
33102
  this.realm.addType(clone);
32461
33103
  return clone;
32462
33104
  },
33105
+ isError(type) {
33106
+ return isErrorType(type);
33107
+ },
33108
+ getEncodedName(type, encoding) {
33109
+ return resolveEncodedName(this.program, type, encoding);
33110
+ },
33111
+ getSummary(type) {
33112
+ return getSummary(this.program, type);
33113
+ },
33114
+ getDoc(type) {
33115
+ return getDoc(this.program, type);
33116
+ },
33117
+ getPlausibleName(type) {
33118
+ return getPlausibleName(type);
33119
+ },
33120
+ getDiscriminator(type) {
33121
+ return getDiscriminator(this.program, type);
33122
+ },
33123
+ getDiscriminatedUnion(type) {
33124
+ const discriminator = getDiscriminator(this.program, type);
33125
+ if (!discriminator) {
33126
+ return undefined;
33127
+ }
33128
+ const [union] = getDiscriminatedUnion(type, discriminator);
33129
+ const variants = Array.from(union.variants.entries()).map(([k, v]) => this.unionVariant.create({ name: k, type: v }));
33130
+ return this.union.create({
33131
+ name: union.propertyName,
33132
+ variants,
33133
+ });
33134
+ },
33135
+ maxValue(type) {
33136
+ return getMaxValue(this.program, type);
33137
+ },
33138
+ minValue(type) {
33139
+ return getMinValue(this.program, type);
33140
+ },
33141
+ maxLength(type) {
33142
+ return getMaxLength(this.program, type);
33143
+ },
33144
+ minLength(type) {
33145
+ return getMinLength(this.program, type);
33146
+ },
33147
+ maxItems(type) {
33148
+ return getMaxItems(this.program, type);
33149
+ },
33150
+ maxValueExclusive(type) {
33151
+ return getMaxValueExclusive(this.program, type);
33152
+ },
33153
+ minValueExclusive(type) {
33154
+ return getMinValueExclusive(this.program, type);
33155
+ },
33156
+ minItems(type) {
33157
+ return getMinItems(this.program, type);
33158
+ },
33159
+ isNever(type) {
33160
+ return isNeverType(type);
33161
+ },
33162
+ isUserDefined(type) {
33163
+ return getLocationContext(this.program, type).type === "project";
33164
+ },
32463
33165
  },
32464
33166
  });
32465
33167
 
@@ -32485,6 +33187,10 @@ defineKit({
32485
33187
 
32486
33188
  defineKit({
32487
33189
  union: {
33190
+ filter(union, filterFn) {
33191
+ const variants = Array.from(union.variants.values()).filter(filterFn);
33192
+ return this.union.create({ variants });
33193
+ },
32488
33194
  create(desc) {
32489
33195
  const union = this.program.checker.createType({
32490
33196
  kind: "Union",
@@ -32545,6 +33251,88 @@ defineKit({
32545
33251
  }
32546
33252
  return false;
32547
33253
  },
33254
+ isExpression(type) {
33255
+ return type.name === undefined || type.name === "";
33256
+ },
33257
+ },
33258
+ });
33259
+
33260
+ defineKit({
33261
+ value: {
33262
+ is(value) {
33263
+ const type = value;
33264
+ return (this.value.isString(type) ||
33265
+ this.value.isNumeric(type) ||
33266
+ this.value.isBoolean(type) ||
33267
+ this.value.isArray(type) ||
33268
+ this.value.isObject(type) ||
33269
+ this.value.isEnum(type) ||
33270
+ this.value.isNull(type) ||
33271
+ this.value.isScalar(type));
33272
+ },
33273
+ create(value) {
33274
+ if (typeof value === "string") {
33275
+ return this.value.createString(value);
33276
+ }
33277
+ else if (typeof value === "number") {
33278
+ return this.value.createNumeric(value);
33279
+ }
33280
+ else {
33281
+ return this.value.createBoolean(value);
33282
+ }
33283
+ },
33284
+ createString(value) {
33285
+ return {
33286
+ entityKind: "Value",
33287
+ value: value,
33288
+ valueKind: "StringValue",
33289
+ type: this.literal.createString(value),
33290
+ scalar: undefined,
33291
+ };
33292
+ },
33293
+ createNumeric(value) {
33294
+ const valueAsString = String(value);
33295
+ return {
33296
+ entityKind: "Value",
33297
+ value: Numeric(valueAsString),
33298
+ valueKind: "NumericValue",
33299
+ type: this.literal.createNumeric(value),
33300
+ scalar: undefined,
33301
+ };
33302
+ },
33303
+ createBoolean(value) {
33304
+ return {
33305
+ entityKind: "Value",
33306
+ value: value,
33307
+ valueKind: "BooleanValue",
33308
+ type: this.literal.createBoolean(value),
33309
+ scalar: undefined,
33310
+ };
33311
+ },
33312
+ isBoolean(type) {
33313
+ return type.valueKind === "BooleanValue";
33314
+ },
33315
+ isString(type) {
33316
+ return type.valueKind === "StringValue";
33317
+ },
33318
+ isNumeric(type) {
33319
+ return type.valueKind === "NumericValue";
33320
+ },
33321
+ isArray(type) {
33322
+ return type.valueKind === "ArrayValue";
33323
+ },
33324
+ isObject(type) {
33325
+ return type.valueKind === "ObjectValue";
33326
+ },
33327
+ isEnum(type) {
33328
+ return type.valueKind === "EnumValue";
33329
+ },
33330
+ isNull(type) {
33331
+ return type.valueKind === "NullValue";
33332
+ },
33333
+ isScalar(type) {
33334
+ return type.valueKind === "ScalarValue";
33335
+ },
32548
33336
  },
32549
33337
  });
32550
33338
 
@@ -32571,13 +33359,15 @@ function createTypekit(realm) {
32571
33359
  return realm;
32572
33360
  }
32573
33361
  const value = Reflect.get(target, prop, receiver);
33362
+ // Wrap functions to set `this` correctly
32574
33363
  if (typeof value === "function") {
32575
33364
  return function (...args) {
32576
33365
  return value.apply(proxy, args);
32577
33366
  };
32578
33367
  }
32579
- if (typeof value === "object" && value !== null) {
32580
- return new Proxy(value, handler);
33368
+ // Only wrap objects marked as Typekit namespaces
33369
+ if (typeof value === "object" && value !== null && isTypekitNamespace(value)) {
33370
+ return new Proxy(value, handler); // Wrap namespace objects
32581
33371
  }
32582
33372
  return value;
32583
33373
  },
@@ -32585,6 +33375,10 @@ function createTypekit(realm) {
32585
33375
  const proxy = new Proxy(tk, handler);
32586
33376
  return proxy;
32587
33377
  }
33378
+ // Helper function to check if an object is a Typekit namespace
33379
+ function isTypekitNamespace(obj) {
33380
+ return obj && !!obj[TypekitNamespaceSymbol];
33381
+ }
32588
33382
  // #region Default Typekit
32589
33383
  const CURRENT_PROGRAM = Symbol.for("TypeSpec.Typekit.CURRENT_PROGRAM");
32590
33384
  const DEFAULT_REALM = Symbol.for("TypeSpec.Typekit.DEFAULT_TYPEKIT_REALM");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typespec/html-program-viewer",
3
- "version": "0.65.0",
3
+ "version": "0.66.0-dev.1",
4
4
  "author": "Microsoft Corporation",
5
5
  "description": "TypeSpec library for emitting an html view of the program.",
6
6
  "homepage": "https://typespec.io",
@@ -36,7 +36,7 @@
36
36
  "!dist/test/**"
37
37
  ],
38
38
  "peerDependencies": {
39
- "@typespec/compiler": "~0.65.0"
39
+ "@typespec/compiler": "~0.65.1 || >=0.66.0-dev <0.66.0"
40
40
  },
41
41
  "dependencies": {
42
42
  "@fluentui/react-components": "~9.57.0",
@@ -54,6 +54,7 @@
54
54
  "@types/node": "~22.10.10",
55
55
  "@types/react": "~18.3.11",
56
56
  "@types/react-dom": "~18.3.0",
57
+ "@typespec/compiler": "~0.65.1 || >=0.66.0-dev <0.66.0",
57
58
  "@vitejs/plugin-react": "~4.3.4",
58
59
  "@vitest/coverage-v8": "^3.0.4",
59
60
  "@vitest/ui": "^3.0.3",
@@ -64,7 +65,7 @@
64
65
  "vite-plugin-checker": "^0.8.0",
65
66
  "vite-plugin-dts": "4.5.0",
66
67
  "vitest": "^3.0.5",
67
- "@typespec/compiler": "~0.65.0",
68
+ "vite-plugin-node-polyfills": "^0.23.0",
68
69
  "@typespec/react-components": "~0.57.0"
69
70
  },
70
71
  "scripts": {
@@ -1,6 +0,0 @@
1
- const manifest = {
2
- "version": "0.65.0",
3
- "commit": "ef04080e69155401e5047cff69e5b50c1844d5dc"
4
- };
5
-
6
- export { manifest as default };