@typespec/html-program-viewer 0.68.0 → 0.69.0
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/manifest-DR_CKuUi.js +6 -0
- package/dist/react/index.js +957 -568
- package/package.json +4 -4
- package/dist/manifest-Cmvvh_kl.js +0 -6
package/dist/react/index.js
CHANGED
|
@@ -19096,7 +19096,7 @@ const diagnostics = {
|
|
|
19096
19096
|
},
|
|
19097
19097
|
// #endregion CLI
|
|
19098
19098
|
};
|
|
19099
|
-
const { createDiagnostic} = createDiagnosticCreator(diagnostics);
|
|
19099
|
+
const { createDiagnostic, reportDiagnostic } = createDiagnosticCreator(diagnostics);
|
|
19100
19100
|
|
|
19101
19101
|
var ajv = {exports: {}};
|
|
19102
19102
|
|
|
@@ -28331,6 +28331,39 @@ function compilerAssert(condition, message, target) {
|
|
|
28331
28331
|
}
|
|
28332
28332
|
throw new Error(message);
|
|
28333
28333
|
}
|
|
28334
|
+
/**
|
|
28335
|
+
* Create a new instance of the @see DiagnosticCollector.
|
|
28336
|
+
*/
|
|
28337
|
+
function createDiagnosticCollector() {
|
|
28338
|
+
const diagnostics = [];
|
|
28339
|
+
return {
|
|
28340
|
+
diagnostics,
|
|
28341
|
+
add,
|
|
28342
|
+
pipe,
|
|
28343
|
+
wrap,
|
|
28344
|
+
join,
|
|
28345
|
+
};
|
|
28346
|
+
function add(diagnostic) {
|
|
28347
|
+
diagnostics.push(diagnostic);
|
|
28348
|
+
}
|
|
28349
|
+
function pipe(result) {
|
|
28350
|
+
const [value, diags] = result;
|
|
28351
|
+
for (const diag of diags) {
|
|
28352
|
+
diagnostics.push(diag);
|
|
28353
|
+
}
|
|
28354
|
+
return value;
|
|
28355
|
+
}
|
|
28356
|
+
function wrap(value) {
|
|
28357
|
+
return [value, diagnostics];
|
|
28358
|
+
}
|
|
28359
|
+
function join(result) {
|
|
28360
|
+
const [value, diags] = result;
|
|
28361
|
+
for (const diag of diags) {
|
|
28362
|
+
diagnostics.push(diag);
|
|
28363
|
+
}
|
|
28364
|
+
return [value, diagnostics];
|
|
28365
|
+
}
|
|
28366
|
+
}
|
|
28334
28367
|
/**
|
|
28335
28368
|
* Ignore the diagnostics emitted by the diagnostic accessor pattern and just return the actual result.
|
|
28336
28369
|
* @param result Accessor pattern tuple result including the actual result and the list of diagnostics.
|
|
@@ -28593,6 +28626,25 @@ function defineKit(source) {
|
|
|
28593
28626
|
}
|
|
28594
28627
|
}
|
|
28595
28628
|
|
|
28629
|
+
/**
|
|
28630
|
+
* Creates a diagnosable function wrapper.
|
|
28631
|
+
*
|
|
28632
|
+
* The returned function will ignore diagnostics by default.
|
|
28633
|
+
* A `withDiagnostics` property is attached to the returned function,
|
|
28634
|
+
* allowing access to the original function's return value including diagnostics.
|
|
28635
|
+
*
|
|
28636
|
+
* @param fn The function to wrap, which must return a tuple `[Result, readonly Diagnostic[]]`.
|
|
28637
|
+
* @returns A function that ignores diagnostics by default, with a `withDiagnostics` method.
|
|
28638
|
+
* @experimental
|
|
28639
|
+
*/
|
|
28640
|
+
function createDiagnosable(fn) {
|
|
28641
|
+
function wrapper(...args) {
|
|
28642
|
+
return ignoreDiagnostics(fn.apply(this, args));
|
|
28643
|
+
}
|
|
28644
|
+
wrapper.withDiagnostics = fn;
|
|
28645
|
+
return wrapper;
|
|
28646
|
+
}
|
|
28647
|
+
|
|
28596
28648
|
function isErrorType(type) {
|
|
28597
28649
|
return "kind" in type && type.kind === "Intrinsic" && type.name === "ErrorType";
|
|
28598
28650
|
}
|
|
@@ -28788,7 +28840,6 @@ defineKit({
|
|
|
28788
28840
|
name: desc.name,
|
|
28789
28841
|
value: desc.value,
|
|
28790
28842
|
decorators: decoratorApplication(this, desc.decorators),
|
|
28791
|
-
node: undefined,
|
|
28792
28843
|
enum: desc.enum, // initialized in enum.build if not provided here
|
|
28793
28844
|
});
|
|
28794
28845
|
this.program.checker.finishType(member);
|
|
@@ -28800,424 +28851,107 @@ defineKit({
|
|
|
28800
28851
|
},
|
|
28801
28852
|
});
|
|
28802
28853
|
|
|
28803
|
-
|
|
28804
|
-
|
|
28805
|
-
create(desc) {
|
|
28806
|
-
const en = this.program.checker.createType({
|
|
28807
|
-
kind: "Enum",
|
|
28808
|
-
name: desc.name,
|
|
28809
|
-
decorators: decoratorApplication(this, desc.decorators),
|
|
28810
|
-
members: createRekeyableMap(),
|
|
28811
|
-
node: undefined,
|
|
28812
|
-
});
|
|
28813
|
-
if (Array.isArray(desc.members)) {
|
|
28814
|
-
for (const member of desc.members) {
|
|
28815
|
-
member.enum = en;
|
|
28816
|
-
en.members.set(member.name, member);
|
|
28817
|
-
}
|
|
28818
|
-
}
|
|
28819
|
-
else {
|
|
28820
|
-
for (const [name, member] of Object.entries(desc.members ?? {})) {
|
|
28821
|
-
en.members.set(name, this.enumMember.create({ name, value: member, enum: en }));
|
|
28822
|
-
}
|
|
28823
|
-
}
|
|
28824
|
-
this.program.checker.finishType(en);
|
|
28825
|
-
return en;
|
|
28826
|
-
},
|
|
28827
|
-
is(type) {
|
|
28828
|
-
return type.kind === "Enum";
|
|
28829
|
-
},
|
|
28830
|
-
createFromUnion(type) {
|
|
28831
|
-
if (!type.name) {
|
|
28832
|
-
throw new Error("Cannot create an enum from an anonymous union.");
|
|
28833
|
-
}
|
|
28834
|
-
const enumMembers = [];
|
|
28835
|
-
for (const variant of type.variants.values()) {
|
|
28836
|
-
if ((variant.name && typeof variant.name === "symbol") ||
|
|
28837
|
-
(!this.literal.isString(variant.type) && !this.literal.isNumeric(variant.type))) {
|
|
28838
|
-
continue;
|
|
28839
|
-
}
|
|
28840
|
-
enumMembers.push(this.enumMember.create({ name: variant.name, value: variant.type.value }));
|
|
28841
|
-
}
|
|
28842
|
-
return this.enum.create({ name: type.name, members: enumMembers });
|
|
28843
|
-
},
|
|
28844
|
-
},
|
|
28845
|
-
});
|
|
28846
|
-
|
|
28847
|
-
class InvalidNumericError extends Error {
|
|
28848
|
-
code = "InvalidNumeric";
|
|
28854
|
+
function isIntrinsicType(program, type, kind) {
|
|
28855
|
+
return ignoreDiagnostics(program.checker.isTypeAssignableTo(type, program.checker.getStdType(kind), type));
|
|
28849
28856
|
}
|
|
28850
|
-
|
|
28851
|
-
|
|
28852
|
-
|
|
28853
|
-
|
|
28854
|
-
|
|
28855
|
-
|
|
28856
|
-
|
|
28857
|
-
|
|
28857
|
+
function validateDecoratorUniqueOnNode(context, type, decorator) {
|
|
28858
|
+
compilerAssert("decorators" in type, "Type should have decorators");
|
|
28859
|
+
const sameDecorators = type.decorators.filter((x) => x.decorator === decorator &&
|
|
28860
|
+
x.node?.kind === SyntaxKind.DecoratorExpression &&
|
|
28861
|
+
x.node?.parent === type.node);
|
|
28862
|
+
if (sameDecorators.length > 1) {
|
|
28863
|
+
reportDiagnostic(context.program, {
|
|
28864
|
+
code: "duplicate-decorator",
|
|
28865
|
+
format: { decoratorName: "@" + decorator.name.slice(1) },
|
|
28866
|
+
target: context.decoratorTarget,
|
|
28867
|
+
});
|
|
28868
|
+
return false;
|
|
28858
28869
|
}
|
|
28859
|
-
|
|
28860
|
-
const isInteger = data.d === 0;
|
|
28861
|
-
const obj = {
|
|
28862
|
-
[InternalDataSym]: data,
|
|
28863
|
-
isInteger,
|
|
28864
|
-
};
|
|
28865
|
-
// We are explicitly not using a class here due to version mismatch between the compiler and the runtime that could happen and break instanceof checks.
|
|
28866
|
-
const numeric = setTypedProptotype(obj, NumericPrototype);
|
|
28867
|
-
return Object.freeze(numeric);
|
|
28870
|
+
return true;
|
|
28868
28871
|
}
|
|
28869
|
-
|
|
28870
|
-
|
|
28871
|
-
|
|
28872
|
+
|
|
28873
|
+
/**
|
|
28874
|
+
* Filters the properties of a model by removing them from the model instance if
|
|
28875
|
+
* a given `filter` predicate is not satisfied.
|
|
28876
|
+
*
|
|
28877
|
+
* @param model - the model to filter properties on
|
|
28878
|
+
* @param filter - the predicate to filter properties with
|
|
28879
|
+
*/
|
|
28880
|
+
/**
|
|
28881
|
+
* Creates a unique symbol for storing state on objects
|
|
28882
|
+
* @param name The name/description of the state
|
|
28883
|
+
*/
|
|
28884
|
+
function createStateSymbol(name) {
|
|
28885
|
+
return Symbol.for(`TypeSpec.${name}`);
|
|
28872
28886
|
}
|
|
28873
|
-
|
|
28874
|
-
|
|
28875
|
-
|
|
28876
|
-
|
|
28877
|
-
|
|
28878
|
-
|
|
28879
|
-
|
|
28880
|
-
|
|
28881
|
-
|
|
28882
|
-
|
|
28887
|
+
|
|
28888
|
+
const deprecatedKey = createStateSymbol("deprecated");
|
|
28889
|
+
/**
|
|
28890
|
+
* Returns complete deprecation details for the given type or node
|
|
28891
|
+
* @param program Program
|
|
28892
|
+
* @param typeOrNode A Type or Node to check for deprecation
|
|
28893
|
+
*/
|
|
28894
|
+
function getDeprecationDetails(program, typeOrNode) {
|
|
28895
|
+
function isType(maybeType) {
|
|
28896
|
+
return typeof maybeType.kind === "string";
|
|
28883
28897
|
}
|
|
28884
|
-
|
|
28885
|
-
if (
|
|
28886
|
-
|
|
28887
|
-
n = BigInt(stringValue.slice(start));
|
|
28888
|
-
exp = n.toString().length;
|
|
28889
|
-
decimal = 0;
|
|
28890
|
-
}
|
|
28891
|
-
catch {
|
|
28892
|
-
throw new InvalidNumericError(`Invalid numeric value: ${original}`);
|
|
28893
|
-
}
|
|
28898
|
+
// If we're looking at a type, pull the deprecation details from the state map
|
|
28899
|
+
if (isType(typeOrNode)) {
|
|
28900
|
+
return program.stateMap(deprecatedKey).get(typeOrNode);
|
|
28894
28901
|
}
|
|
28895
28902
|
else {
|
|
28896
|
-
//
|
|
28897
|
-
|
|
28898
|
-
|
|
28899
|
-
|
|
28900
|
-
|
|
28901
|
-
|
|
28902
|
-
// Decimal point?
|
|
28903
|
-
if (decimalPointIndex !== -1) {
|
|
28904
|
-
exp = adjustedPointIndex;
|
|
28905
|
-
stringValue = stringValue.replace(".", "");
|
|
28906
|
-
}
|
|
28907
|
-
let i;
|
|
28908
|
-
if ((i = stringValue.search(/e/i)) > 0) {
|
|
28909
|
-
// Determine exponent.
|
|
28910
|
-
if (exp === undefined) {
|
|
28911
|
-
exp = i - start;
|
|
28912
|
-
}
|
|
28913
|
-
exp += Number(stringValue.slice(i + 1));
|
|
28914
|
-
stringValue = stringValue.slice(start, i);
|
|
28915
|
-
decimal = Math.max(stringValue.length - exp, 0);
|
|
28903
|
+
// Look at the node for a deprecation directive
|
|
28904
|
+
const deprecatedDirective = (typeOrNode.directives ?? []).find((directive) => directive.target.sv === "deprecated");
|
|
28905
|
+
if (deprecatedDirective?.arguments[0].kind === SyntaxKind.StringLiteral) {
|
|
28906
|
+
return {
|
|
28907
|
+
message: deprecatedDirective.arguments[0].value,
|
|
28908
|
+
};
|
|
28916
28909
|
}
|
|
28917
|
-
|
|
28918
|
-
|
|
28919
|
-
|
|
28920
|
-
|
|
28910
|
+
}
|
|
28911
|
+
return undefined;
|
|
28912
|
+
}
|
|
28913
|
+
|
|
28914
|
+
/**
|
|
28915
|
+
* Helper class to track duplicate instance
|
|
28916
|
+
*/
|
|
28917
|
+
class DuplicateTracker {
|
|
28918
|
+
#entries = new Map();
|
|
28919
|
+
/**
|
|
28920
|
+
* Track usage of K.
|
|
28921
|
+
* @param k key that is being checked for duplicate.
|
|
28922
|
+
* @param v value that map to the key
|
|
28923
|
+
*/
|
|
28924
|
+
track(k, v) {
|
|
28925
|
+
const existing = this.#entries.get(k);
|
|
28926
|
+
if (existing === undefined) {
|
|
28927
|
+
this.#entries.set(k, [v]);
|
|
28921
28928
|
}
|
|
28922
28929
|
else {
|
|
28923
|
-
|
|
28924
|
-
}
|
|
28925
|
-
let end = stringValue.length;
|
|
28926
|
-
while (stringValue[end - 1] === "0" && end > adjustedPointIndex) {
|
|
28927
|
-
end--;
|
|
28928
|
-
}
|
|
28929
|
-
// Only if there is 0 before the decimal point, keeps checking how many 0 there is after it and update the exponent accordingly.
|
|
28930
|
-
if (start === adjustedPointIndex + 1) {
|
|
28931
|
-
let cur = adjustedPointIndex;
|
|
28932
|
-
while (stringValue[cur] === "0" && cur < end) {
|
|
28933
|
-
cur++;
|
|
28934
|
-
exp--;
|
|
28935
|
-
}
|
|
28930
|
+
existing.push(v);
|
|
28936
28931
|
}
|
|
28937
|
-
|
|
28938
|
-
|
|
28939
|
-
|
|
28940
|
-
|
|
28941
|
-
|
|
28942
|
-
|
|
28943
|
-
|
|
28944
|
-
|
|
28945
|
-
decimal = Math.max(stringValue.length - Math.max(exp, 0), 0);
|
|
28932
|
+
}
|
|
28933
|
+
/**
|
|
28934
|
+
* Return iterator of all the duplicate entries.
|
|
28935
|
+
*/
|
|
28936
|
+
*entries() {
|
|
28937
|
+
for (const [k, v] of this.#entries.entries()) {
|
|
28938
|
+
if (v.length > 1) {
|
|
28939
|
+
yield [k, v];
|
|
28946
28940
|
}
|
|
28947
28941
|
}
|
|
28948
|
-
catch {
|
|
28949
|
-
throw new InvalidNumericError(`Invalid numeric value: ${original}`);
|
|
28950
|
-
}
|
|
28951
28942
|
}
|
|
28952
|
-
return { n, e: exp, s: sign, d: decimal };
|
|
28953
28943
|
}
|
|
28954
|
-
|
|
28955
|
-
|
|
28956
|
-
|
|
28957
|
-
const
|
|
28958
|
-
const
|
|
28959
|
-
|
|
28960
|
-
const decimal = value.e < n.length ? "." + n.slice(-value.d).padStart(value.d, "0") : "";
|
|
28961
|
-
return sign + int + decimal;
|
|
28944
|
+
|
|
28945
|
+
function useStateMap(key) {
|
|
28946
|
+
const getter = (program, target) => program.stateMap(key).get(target);
|
|
28947
|
+
const setter = (program, target, value) => program.stateMap(key).set(target, value);
|
|
28948
|
+
const mapGetter = (program) => program.stateMap(key);
|
|
28949
|
+
return [getter, setter, mapGetter];
|
|
28962
28950
|
}
|
|
28963
|
-
|
|
28964
|
-
const
|
|
28965
|
-
|
|
28966
|
-
|
|
28967
|
-
}
|
|
28968
|
-
else if (a.s > b.s) {
|
|
28969
|
-
return 1;
|
|
28970
|
-
}
|
|
28971
|
-
const neg = a.s;
|
|
28972
|
-
if (a.e < b.e) {
|
|
28973
|
-
return (-1 * neg);
|
|
28974
|
-
}
|
|
28975
|
-
else if (a.e > b.e) {
|
|
28976
|
-
return (1 * neg);
|
|
28977
|
-
}
|
|
28978
|
-
let aN = a.n;
|
|
28979
|
-
let bN = b.n;
|
|
28980
|
-
if (a.d < b.d) {
|
|
28981
|
-
aN *= 10n ** BigInt(b.d - a.d);
|
|
28982
|
-
}
|
|
28983
|
-
else {
|
|
28984
|
-
bN *= 10n ** BigInt(a.d - b.d);
|
|
28985
|
-
}
|
|
28986
|
-
if (aN < bN)
|
|
28987
|
-
return (-1 * neg);
|
|
28988
|
-
if (aN > bN)
|
|
28989
|
-
return (1 * neg);
|
|
28990
|
-
return 0;
|
|
28991
|
-
};
|
|
28992
|
-
const NumericPrototype = {
|
|
28993
|
-
toString: function () {
|
|
28994
|
-
return stringify(this[InternalDataSym]);
|
|
28995
|
-
},
|
|
28996
|
-
asNumber: function () {
|
|
28997
|
-
const num = Number(stringify(this[InternalDataSym]));
|
|
28998
|
-
return equals(this[InternalDataSym], Numeric(num.toString())[InternalDataSym]) ? num : null;
|
|
28999
|
-
},
|
|
29000
|
-
asBigInt: function () {
|
|
29001
|
-
if (!this.isInteger) {
|
|
29002
|
-
return null;
|
|
29003
|
-
}
|
|
29004
|
-
const { s, n } = this[InternalDataSym];
|
|
29005
|
-
return BigInt(s) * n;
|
|
29006
|
-
},
|
|
29007
|
-
equals: function (other) {
|
|
29008
|
-
return equals(this[InternalDataSym], other[InternalDataSym]);
|
|
29009
|
-
},
|
|
29010
|
-
lt: function (other) {
|
|
29011
|
-
return compare(this[InternalDataSym], other[InternalDataSym]) === -1;
|
|
29012
|
-
},
|
|
29013
|
-
lte: function (other) {
|
|
29014
|
-
return compare(this[InternalDataSym], other[InternalDataSym]) <= 0;
|
|
29015
|
-
},
|
|
29016
|
-
gt: function (other) {
|
|
29017
|
-
return compare(this[InternalDataSym], other[InternalDataSym]) === 1;
|
|
29018
|
-
},
|
|
29019
|
-
gte: function (other) {
|
|
29020
|
-
return compare(this[InternalDataSym], other[InternalDataSym]) >= 0;
|
|
29021
|
-
},
|
|
29022
|
-
};
|
|
29023
|
-
NumericPrototype.toString = function () {
|
|
29024
|
-
return stringify(this[InternalDataSym]);
|
|
29025
|
-
};
|
|
29026
|
-
|
|
29027
|
-
defineKit({
|
|
29028
|
-
literal: {
|
|
29029
|
-
create(value) {
|
|
29030
|
-
if (typeof value === "string") {
|
|
29031
|
-
return this.literal.createString(value);
|
|
29032
|
-
}
|
|
29033
|
-
else if (typeof value === "number") {
|
|
29034
|
-
return this.literal.createNumeric(value);
|
|
29035
|
-
}
|
|
29036
|
-
else {
|
|
29037
|
-
return this.literal.createBoolean(value);
|
|
29038
|
-
}
|
|
29039
|
-
},
|
|
29040
|
-
createString(value) {
|
|
29041
|
-
return this.program.checker.createType({
|
|
29042
|
-
kind: "String",
|
|
29043
|
-
value,
|
|
29044
|
-
});
|
|
29045
|
-
},
|
|
29046
|
-
createNumeric(value) {
|
|
29047
|
-
const valueAsString = String(value);
|
|
29048
|
-
return this.program.checker.createType({
|
|
29049
|
-
kind: "Number",
|
|
29050
|
-
value,
|
|
29051
|
-
valueAsString,
|
|
29052
|
-
numericValue: Numeric(valueAsString),
|
|
29053
|
-
});
|
|
29054
|
-
},
|
|
29055
|
-
createBoolean(value) {
|
|
29056
|
-
return this.program.checker.createType({
|
|
29057
|
-
kind: "Boolean",
|
|
29058
|
-
value,
|
|
29059
|
-
});
|
|
29060
|
-
},
|
|
29061
|
-
isBoolean(type) {
|
|
29062
|
-
return type.kind === "Boolean";
|
|
29063
|
-
},
|
|
29064
|
-
isString(type) {
|
|
29065
|
-
return type.kind === "String";
|
|
29066
|
-
},
|
|
29067
|
-
isNumeric(type) {
|
|
29068
|
-
return type.kind === "Number";
|
|
29069
|
-
},
|
|
29070
|
-
is(type) {
|
|
29071
|
-
return (this.literal.isBoolean(type) || this.literal.isNumeric(type) || this.literal.isString(type));
|
|
29072
|
-
},
|
|
29073
|
-
},
|
|
29074
|
-
});
|
|
29075
|
-
|
|
29076
|
-
/**
|
|
29077
|
-
* Filters the properties of a model by removing them from the model instance if
|
|
29078
|
-
* a given `filter` predicate is not satisfied.
|
|
29079
|
-
*
|
|
29080
|
-
* @param model - the model to filter properties on
|
|
29081
|
-
* @param filter - the predicate to filter properties with
|
|
29082
|
-
*/
|
|
29083
|
-
/**
|
|
29084
|
-
* Creates a unique symbol for storing state on objects
|
|
29085
|
-
* @param name The name/description of the state
|
|
29086
|
-
*/
|
|
29087
|
-
function createStateSymbol(name) {
|
|
29088
|
-
return Symbol.for(`TypeSpec.${name}`);
|
|
29089
|
-
}
|
|
29090
|
-
|
|
29091
|
-
/**
|
|
29092
|
-
* Helper class to track duplicate instance
|
|
29093
|
-
*/
|
|
29094
|
-
class DuplicateTracker {
|
|
29095
|
-
#entries = new Map();
|
|
29096
|
-
/**
|
|
29097
|
-
* Track usage of K.
|
|
29098
|
-
* @param k key that is being checked for duplicate.
|
|
29099
|
-
* @param v value that map to the key
|
|
29100
|
-
*/
|
|
29101
|
-
track(k, v) {
|
|
29102
|
-
const existing = this.#entries.get(k);
|
|
29103
|
-
if (existing === undefined) {
|
|
29104
|
-
this.#entries.set(k, [v]);
|
|
29105
|
-
}
|
|
29106
|
-
else {
|
|
29107
|
-
existing.push(v);
|
|
29108
|
-
}
|
|
29109
|
-
}
|
|
29110
|
-
/**
|
|
29111
|
-
* Return iterator of all the duplicate entries.
|
|
29112
|
-
*/
|
|
29113
|
-
*entries() {
|
|
29114
|
-
for (const [k, v] of this.#entries.entries()) {
|
|
29115
|
-
if (v.length > 1) {
|
|
29116
|
-
yield [k, v];
|
|
29117
|
-
}
|
|
29118
|
-
}
|
|
29119
|
-
}
|
|
29120
|
-
}
|
|
29121
|
-
|
|
29122
|
-
function useStateMap(key) {
|
|
29123
|
-
const getter = (program, target) => program.stateMap(key).get(target);
|
|
29124
|
-
const setter = (program, target, value) => program.stateMap(key).set(target, value);
|
|
29125
|
-
const mapGetter = (program) => program.stateMap(key);
|
|
29126
|
-
return [getter, setter, mapGetter];
|
|
29127
|
-
}
|
|
29128
|
-
|
|
29129
|
-
// Copyright (c) Microsoft Corporation
|
|
29130
|
-
// Licensed under the MIT license.
|
|
29131
|
-
// TypeSpec Visibility System
|
|
29132
|
-
// --------------------------
|
|
29133
|
-
// This module defines the core visibility system of the TypeSpec language. The
|
|
29134
|
-
// visibility system is used to decide when properties of a _conceptual resource_
|
|
29135
|
-
// are present. The system is based on the concept of _visibility classes_,
|
|
29136
|
-
// represented by TypeSpec enums. Each visibility class has a set of _visibility
|
|
29137
|
-
// modifiers_ that can be applied to a model property, each modifier represented
|
|
29138
|
-
// by a member of the visibility class enum.
|
|
29139
|
-
//
|
|
29140
|
-
// Each visibility class has a _default modifier set_ that is used when no
|
|
29141
|
-
// modifiers are specified for a property, and each property has an _active
|
|
29142
|
-
// modifier set_ that is used when analyzing the visibility of the property.
|
|
29143
|
-
//
|
|
29144
|
-
// Visibility can be _sealed_ for a program, property, or visibility class
|
|
29145
|
-
// within a property. Once visibility is sealed, it cannot be unsealed, and any
|
|
29146
|
-
// attempts to modify a sealed visibility will fail.
|
|
29147
|
-
/**
|
|
29148
|
-
* The global visibility store.
|
|
29149
|
-
*
|
|
29150
|
-
* This store is used to track the visibility modifiers
|
|
29151
|
-
*/
|
|
29152
|
-
const [getVisibilityStore, setVisibilityStore] = useStateMap(createStateSymbol("visibilityStore"));
|
|
29153
|
-
/**
|
|
29154
|
-
* Stores the default modifier set for a given visibility class.
|
|
29155
|
-
*/
|
|
29156
|
-
const [getDefaultModifiers, setDefaultModifiers] = useStateMap(createStateSymbol("defaultVisibilityModifiers"));
|
|
29157
|
-
/**
|
|
29158
|
-
* Gets the default modifier set for a visibility class. If no default modifier set has been set, this function will
|
|
29159
|
-
* initialize the default modifier set to ALL the visibility class's members.
|
|
29160
|
-
*
|
|
29161
|
-
* @param program - the program in which the visibility class occurs
|
|
29162
|
-
* @param visibilityClass - the visibility class to get the default modifier set for
|
|
29163
|
-
* @returns the default modifier set for the visibility class
|
|
29164
|
-
*/
|
|
29165
|
-
function getDefaultModifierSetForClass(program, visibilityClass) {
|
|
29166
|
-
const cached = getDefaultModifiers(program, visibilityClass);
|
|
29167
|
-
if (cached)
|
|
29168
|
-
return new Set(cached);
|
|
29169
|
-
const defaultModifierSet = new Set(visibilityClass.members.values());
|
|
29170
|
-
setDefaultModifiers(program, visibilityClass, defaultModifierSet);
|
|
29171
|
-
// Explicitly clone the set again to prevent accidental modification of the default set.
|
|
29172
|
-
return new Set(defaultModifierSet);
|
|
29173
|
-
}
|
|
29174
|
-
// #endregion
|
|
29175
|
-
// #region Visibility Analysis API
|
|
29176
|
-
/**
|
|
29177
|
-
* Returns the active visibility modifiers for a property in a given visibility class.
|
|
29178
|
-
*
|
|
29179
|
-
* This function is infallible. If the visibility modifiers for the given class have not been set explicitly, it will
|
|
29180
|
-
* return the default visibility modifiers for the class.
|
|
29181
|
-
*
|
|
29182
|
-
* @param program - the program in which the property occurs
|
|
29183
|
-
* @param property - the property to get visibility modifiers for
|
|
29184
|
-
* @param visibilityClass - the visibility class to get visibility modifiers for
|
|
29185
|
-
* @returns the set of active modifiers (enum members) for the property and visibility class
|
|
29186
|
-
*/
|
|
29187
|
-
function getVisibilityForClass(program, property, visibilityClass) {
|
|
29188
|
-
const store = getVisibilityStore(program, property);
|
|
29189
|
-
return store?.get(visibilityClass) ?? getDefaultModifierSetForClass(program, visibilityClass);
|
|
29190
|
-
}
|
|
29191
|
-
// #endregion
|
|
29192
|
-
|
|
29193
|
-
function isIntrinsicType(program, type, kind) {
|
|
29194
|
-
return ignoreDiagnostics(program.checker.isTypeAssignableTo(type, program.checker.getStdType(kind), type));
|
|
29195
|
-
}
|
|
29196
|
-
|
|
29197
|
-
const deprecatedKey = createStateSymbol("deprecated");
|
|
29198
|
-
/**
|
|
29199
|
-
* Returns complete deprecation details for the given type or node
|
|
29200
|
-
* @param program Program
|
|
29201
|
-
* @param typeOrNode A Type or Node to check for deprecation
|
|
29202
|
-
*/
|
|
29203
|
-
function getDeprecationDetails(program, typeOrNode) {
|
|
29204
|
-
function isType(maybeType) {
|
|
29205
|
-
return typeof maybeType.kind === "string";
|
|
29206
|
-
}
|
|
29207
|
-
// If we're looking at a type, pull the deprecation details from the state map
|
|
29208
|
-
if (isType(typeOrNode)) {
|
|
29209
|
-
return program.stateMap(deprecatedKey).get(typeOrNode);
|
|
29210
|
-
}
|
|
29211
|
-
else {
|
|
29212
|
-
// Look at the node for a deprecation directive
|
|
29213
|
-
const deprecatedDirective = (typeOrNode.directives ?? []).find((directive) => directive.target.sv === "deprecated");
|
|
29214
|
-
if (deprecatedDirective?.arguments[0].kind === SyntaxKind.StringLiteral) {
|
|
29215
|
-
return {
|
|
29216
|
-
message: deprecatedDirective.arguments[0].value,
|
|
29217
|
-
};
|
|
29218
|
-
}
|
|
29219
|
-
}
|
|
29220
|
-
return undefined;
|
|
28951
|
+
function useStateSet(key) {
|
|
28952
|
+
const getter = (program, target) => program.stateSet(key).has(target);
|
|
28953
|
+
const setter = (program, target) => program.stateSet(key).add(target);
|
|
28954
|
+
return [getter, setter];
|
|
29221
28955
|
}
|
|
29222
28956
|
|
|
29223
28957
|
// Contains all intrinsic data setter or getter
|
|
@@ -29294,6 +29028,10 @@ function getMaxItemsAsNumeric(program, target) {
|
|
|
29294
29028
|
function getMaxItems(program, target) {
|
|
29295
29029
|
return getMaxItemsAsNumeric(program, target)?.asNumber() ?? undefined;
|
|
29296
29030
|
}
|
|
29031
|
+
/** @internal */
|
|
29032
|
+
function setDocData(program, target, key, data) {
|
|
29033
|
+
program.stateMap(getDocKey(key)).set(target, data);
|
|
29034
|
+
}
|
|
29297
29035
|
function getDocKey(target) {
|
|
29298
29036
|
switch (target) {
|
|
29299
29037
|
case "self":
|
|
@@ -30901,7 +30639,7 @@ function getInterfaceName(iface, options) {
|
|
|
30901
30639
|
}
|
|
30902
30640
|
function getOperationName(op, options) {
|
|
30903
30641
|
let opName = getIdentifierName(op.name, options);
|
|
30904
|
-
if (op.node.templateParameters.length > 0) {
|
|
30642
|
+
if (op.node && op.node.templateParameters.length > 0) {
|
|
30905
30643
|
// template
|
|
30906
30644
|
const params = op.node.templateParameters.map((t) => getIdentifierName(t.id.sv, options));
|
|
30907
30645
|
opName += `<${params.join(", ")}>`;
|
|
@@ -30911,121 +30649,750 @@ function getOperationName(op, options) {
|
|
|
30911
30649
|
: getNamespacePrefix(op.namespace, options);
|
|
30912
30650
|
return `${prefix}${opName}`;
|
|
30913
30651
|
}
|
|
30914
|
-
function getIdentifierName(name, options) {
|
|
30915
|
-
return options?.printable ? printIdentifier(name) : name;
|
|
30652
|
+
function getIdentifierName(name, options) {
|
|
30653
|
+
return options?.printable ? printIdentifier(name) : name;
|
|
30654
|
+
}
|
|
30655
|
+
function getStringTemplateName(type) {
|
|
30656
|
+
if (type.stringValue) {
|
|
30657
|
+
return `"${type.stringValue}"`;
|
|
30658
|
+
}
|
|
30659
|
+
return "string";
|
|
30660
|
+
}
|
|
30661
|
+
|
|
30662
|
+
const regex = /^(application|audio|font|example|image|message|model|multipart|text|video|x-(?:[0-9A-Za-z!#$%&'*+.^_`|~-]+))\/([0-9A-Za-z!#$%&'*+.^_`|~-]+)$/;
|
|
30663
|
+
function parseMimeType(mimeType) {
|
|
30664
|
+
const match = mimeType.match(regex);
|
|
30665
|
+
if (match == null) {
|
|
30666
|
+
return undefined;
|
|
30667
|
+
}
|
|
30668
|
+
const type = {
|
|
30669
|
+
type: match[1],
|
|
30670
|
+
...parseSubType(match[2]),
|
|
30671
|
+
};
|
|
30672
|
+
return type;
|
|
30673
|
+
}
|
|
30674
|
+
function parseSubType(value) {
|
|
30675
|
+
if (!value.includes("+"))
|
|
30676
|
+
return { subtype: value };
|
|
30677
|
+
const [subtype, suffix] = value.split("+", 2);
|
|
30678
|
+
return { subtype, suffix };
|
|
30679
|
+
}
|
|
30680
|
+
|
|
30681
|
+
const [getEncodedNamesMap, setEncodedNamesMap, getEncodedNamesStateMap] = useStateMap(createStateSymbol("encodedName"));
|
|
30682
|
+
function getEncodedName(program, target, mimeType) {
|
|
30683
|
+
const mimeTypeObj = parseMimeType(mimeType);
|
|
30684
|
+
if (mimeTypeObj === undefined) {
|
|
30685
|
+
return undefined;
|
|
30686
|
+
}
|
|
30687
|
+
const resolvedMimeType = mimeTypeObj?.suffix
|
|
30688
|
+
? `${mimeTypeObj.type}/${mimeTypeObj.suffix}`
|
|
30689
|
+
: mimeType;
|
|
30690
|
+
return getEncodedNamesMap(program, target)?.get(resolvedMimeType);
|
|
30691
|
+
}
|
|
30692
|
+
/**
|
|
30693
|
+
* Resolve the encoded name for the given type when serialized to the given mime type.
|
|
30694
|
+
* 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.
|
|
30695
|
+
*
|
|
30696
|
+
* @example
|
|
30697
|
+
*
|
|
30698
|
+
* For the given
|
|
30699
|
+
* ```tsp
|
|
30700
|
+
* model Certificate {
|
|
30701
|
+
* @encodedName("application/json", "exp")
|
|
30702
|
+
* @encodedName("application/xml", "expiry")
|
|
30703
|
+
* expireAt: utcDateTime;
|
|
30704
|
+
*
|
|
30705
|
+
* }
|
|
30706
|
+
* ```
|
|
30707
|
+
*
|
|
30708
|
+
* ```ts
|
|
30709
|
+
* resolveEncodedName(program, type, "application/json") // exp
|
|
30710
|
+
* resolveEncodedName(program, type, "application/merge-patch+json") // exp
|
|
30711
|
+
* resolveEncodedName(program, type, "application/xml") // expireAt
|
|
30712
|
+
* resolveEncodedName(program, type, "application/yaml") // expiry
|
|
30713
|
+
* ```
|
|
30714
|
+
*/
|
|
30715
|
+
function resolveEncodedName(program, target, mimeType) {
|
|
30716
|
+
return getEncodedName(program, target, mimeType) ?? target.name;
|
|
30717
|
+
}
|
|
30718
|
+
|
|
30719
|
+
const [
|
|
30720
|
+
/**
|
|
30721
|
+
* Check if the given property is the `@offset` property for a paging operation.
|
|
30722
|
+
* @param program Program
|
|
30723
|
+
* @param target Model Property
|
|
30724
|
+
*/
|
|
30725
|
+
isOffsetProperty, markOffset,
|
|
30726
|
+
/** {@inheritdoc OffsetDecorator} */
|
|
30727
|
+
offsetDecorator,] = createMarkerDecorator("offset", createNumericValidation("offset"));
|
|
30728
|
+
const [
|
|
30729
|
+
/**
|
|
30730
|
+
* Check if the given property is the `@pageIndex` property for a paging operation.
|
|
30731
|
+
* @param program Program
|
|
30732
|
+
* @param target Model Property
|
|
30733
|
+
*/
|
|
30734
|
+
isPageIndexProperty, markPageIndexProperty,
|
|
30735
|
+
/** {@inheritdoc PageIndexDecorator} */
|
|
30736
|
+
pageIndexDecorator,] = createMarkerDecorator("pageIndex", createNumericValidation("pageIndex"));
|
|
30737
|
+
const [
|
|
30738
|
+
/**
|
|
30739
|
+
* Check if the given property is the `@pageIndex` property for a paging operation.
|
|
30740
|
+
* @param program Program
|
|
30741
|
+
* @param target Model Property
|
|
30742
|
+
*/
|
|
30743
|
+
isPageSizeProperty, markPageSizeProperty,
|
|
30744
|
+
/** {@inheritdoc PageSizeDecorator} */
|
|
30745
|
+
pageSizeDecorator,] = createMarkerDecorator("pageSize", createNumericValidation("pageSize"));
|
|
30746
|
+
const [
|
|
30747
|
+
/**
|
|
30748
|
+
* Check if the given property is the `@pageIndex` property for a paging operation.
|
|
30749
|
+
* @param program Program
|
|
30750
|
+
* @param target Model Property
|
|
30751
|
+
*/
|
|
30752
|
+
isPageItemsProperty, markPageItemsProperty,
|
|
30753
|
+
/** {@inheritdoc PageItemsDecorator} */
|
|
30754
|
+
pageItemsDecorator,] = createMarkerDecorator("pageItems", (context, target) => {
|
|
30755
|
+
if (target.type.kind !== "Model" || !isArrayModelType(context.program, target.type)) {
|
|
30756
|
+
reportDiagnostic(context.program, {
|
|
30757
|
+
code: "decorator-wrong-target",
|
|
30758
|
+
messageId: "withExpected",
|
|
30759
|
+
format: { decorator: "continuationToken", expected: "Array", to: getTypeName(target.type) },
|
|
30760
|
+
target: context.decoratorTarget,
|
|
30761
|
+
});
|
|
30762
|
+
return false;
|
|
30763
|
+
}
|
|
30764
|
+
return true;
|
|
30765
|
+
});
|
|
30766
|
+
const [
|
|
30767
|
+
/**
|
|
30768
|
+
* Check if the given property is the `@pageIndex` property for a paging operation.
|
|
30769
|
+
* @param program Program
|
|
30770
|
+
* @param target Model Property
|
|
30771
|
+
*/
|
|
30772
|
+
isContinuationTokenProperty, markContinuationTokenProperty,
|
|
30773
|
+
/** {@inheritdoc ContinuationTokenDecorator} */
|
|
30774
|
+
continuationTokenDecorator,] = createMarkerDecorator("continuationToken", (context, target) => {
|
|
30775
|
+
if (!isStringType(context.program, target.type)) {
|
|
30776
|
+
reportDiagnostic(context.program, {
|
|
30777
|
+
code: "decorator-wrong-target",
|
|
30778
|
+
messageId: "withExpected",
|
|
30779
|
+
format: { decorator: "continuationToken", expected: "string", to: getTypeName(target.type) },
|
|
30780
|
+
target: context.decoratorTarget,
|
|
30781
|
+
});
|
|
30782
|
+
return false;
|
|
30783
|
+
}
|
|
30784
|
+
return true;
|
|
30785
|
+
});
|
|
30786
|
+
const [
|
|
30787
|
+
/**
|
|
30788
|
+
* Check if the given property is the `@nextLink` property for a paging operation.
|
|
30789
|
+
* @param program Program
|
|
30790
|
+
* @param target Model Property
|
|
30791
|
+
*/
|
|
30792
|
+
isNextLink, markNextLink,
|
|
30793
|
+
/** {@inheritdoc NextLinkDecorator} */
|
|
30794
|
+
nextLinkDecorator,] = createMarkerDecorator("nextLink");
|
|
30795
|
+
const [
|
|
30796
|
+
/**
|
|
30797
|
+
* Check if the given property is the `@prevLink` property for a paging operation.
|
|
30798
|
+
* @param program Program
|
|
30799
|
+
* @param target Model Property
|
|
30800
|
+
*/ isPrevLink, markPrevLink,
|
|
30801
|
+
/** {@inheritdoc PrevLinkDecorator} */
|
|
30802
|
+
prevLinkDecorator,] = createMarkerDecorator("prevLink");
|
|
30803
|
+
const [
|
|
30804
|
+
/**
|
|
30805
|
+
* Check if the given property is the `@firstLink` property for a paging operation.
|
|
30806
|
+
* @param program Program
|
|
30807
|
+
* @param target Model Property
|
|
30808
|
+
*/ isFirstLink, markFirstLink,
|
|
30809
|
+
/** {@inheritdoc FirstLinkDecorator} */
|
|
30810
|
+
firstLinkDecorator,] = createMarkerDecorator("firstLink");
|
|
30811
|
+
const [
|
|
30812
|
+
/**
|
|
30813
|
+
* Check if the given property is the `@lastLink` property for a paging operation.
|
|
30814
|
+
* @param program Program
|
|
30815
|
+
* @param target Model Property
|
|
30816
|
+
*/ isLastLink, markLastLink,
|
|
30817
|
+
/** {@inheritdoc LastLinkDecorator} */
|
|
30818
|
+
lastLinkDecorator,] = createMarkerDecorator("lastLink");
|
|
30819
|
+
const inputProps = new Set(["offset", "pageIndex", "pageSize", "continuationToken"]);
|
|
30820
|
+
const outputProps = new Set([
|
|
30821
|
+
"pageItems",
|
|
30822
|
+
"nextLink",
|
|
30823
|
+
"prevLink",
|
|
30824
|
+
"firstLink",
|
|
30825
|
+
"lastLink",
|
|
30826
|
+
"continuationToken",
|
|
30827
|
+
]);
|
|
30828
|
+
function findPagingProperties(program, op, base, source) {
|
|
30829
|
+
const diags = createDiagnosticCollector();
|
|
30830
|
+
const acceptableProps = source === "input" ? inputProps : outputProps;
|
|
30831
|
+
const duplicateTracker = new DuplicateTracker();
|
|
30832
|
+
const data = {};
|
|
30833
|
+
navigateProperties(base, (property, path) => {
|
|
30834
|
+
const kind = diags.pipe(getPagingProperty(program, property));
|
|
30835
|
+
if (kind === undefined) {
|
|
30836
|
+
return;
|
|
30837
|
+
}
|
|
30838
|
+
duplicateTracker.track(kind, property);
|
|
30839
|
+
if (acceptableProps.has(kind)) {
|
|
30840
|
+
data[kind] = { property, path };
|
|
30841
|
+
}
|
|
30842
|
+
else {
|
|
30843
|
+
diags.add(createDiagnostic({
|
|
30844
|
+
code: "invalid-paging-prop",
|
|
30845
|
+
messageId: source === "input" ? "input" : "output",
|
|
30846
|
+
format: { kind },
|
|
30847
|
+
target: property,
|
|
30848
|
+
}));
|
|
30849
|
+
}
|
|
30850
|
+
});
|
|
30851
|
+
for (const [key, duplicates] of duplicateTracker.entries()) {
|
|
30852
|
+
for (const prop of duplicates) {
|
|
30853
|
+
diags.add(createDiagnostic({
|
|
30854
|
+
code: "duplicate-paging-prop",
|
|
30855
|
+
format: { kind: key, operationName: op.name },
|
|
30856
|
+
target: prop,
|
|
30857
|
+
}));
|
|
30858
|
+
}
|
|
30859
|
+
}
|
|
30860
|
+
return diags.wrap(data);
|
|
30861
|
+
}
|
|
30862
|
+
function getPagingOperation(program, op) {
|
|
30863
|
+
const diags = createDiagnosticCollector();
|
|
30864
|
+
const result = {
|
|
30865
|
+
input: diags.pipe(findPagingProperties(program, op, op.parameters, "input")),
|
|
30866
|
+
output: diags.pipe(findPagingProperties(program, op, op.returnType, "output")),
|
|
30867
|
+
};
|
|
30868
|
+
if (result.output.pageItems === undefined) {
|
|
30869
|
+
diags.add(createDiagnostic({
|
|
30870
|
+
code: "missing-paging-items",
|
|
30871
|
+
format: { operationName: op.name },
|
|
30872
|
+
target: op,
|
|
30873
|
+
}));
|
|
30874
|
+
return diags.wrap(undefined);
|
|
30875
|
+
}
|
|
30876
|
+
return diags.wrap(result);
|
|
30877
|
+
}
|
|
30878
|
+
function navigateProperties(type, callback, path = []) {
|
|
30879
|
+
switch (type.kind) {
|
|
30880
|
+
case "Model":
|
|
30881
|
+
for (const prop of type.properties.values()) {
|
|
30882
|
+
callback(prop, [...path, prop]);
|
|
30883
|
+
navigateProperties(prop.type, callback, [...path, prop]);
|
|
30884
|
+
}
|
|
30885
|
+
break;
|
|
30886
|
+
case "Union":
|
|
30887
|
+
for (const member of type.variants.values()) {
|
|
30888
|
+
navigateProperties(member, callback, path);
|
|
30889
|
+
}
|
|
30890
|
+
break;
|
|
30891
|
+
case "UnionVariant":
|
|
30892
|
+
navigateProperties(type.type, callback, path);
|
|
30893
|
+
break;
|
|
30894
|
+
}
|
|
30895
|
+
}
|
|
30896
|
+
function getPagingProperty(program, prop) {
|
|
30897
|
+
const diagnostics = [];
|
|
30898
|
+
const props = {
|
|
30899
|
+
offset: isOffsetProperty(program, prop),
|
|
30900
|
+
pageIndex: isPageIndexProperty(program, prop),
|
|
30901
|
+
pageItems: isPageItemsProperty(program, prop),
|
|
30902
|
+
pageSize: isPageSizeProperty(program, prop),
|
|
30903
|
+
continuationToken: isContinuationTokenProperty(program, prop),
|
|
30904
|
+
nextLink: isNextLink(program, prop),
|
|
30905
|
+
prevLink: isPrevLink(program, prop),
|
|
30906
|
+
lastLink: isLastLink(program, prop),
|
|
30907
|
+
firstLink: isFirstLink(program, prop),
|
|
30908
|
+
};
|
|
30909
|
+
const defined = Object.entries(props).filter((x) => !!x[1]);
|
|
30910
|
+
if (defined.length > 1) {
|
|
30911
|
+
diagnostics.push(createDiagnostic({
|
|
30912
|
+
code: "incompatible-paging-props",
|
|
30913
|
+
format: { kinds: defined.map((x) => x[0]).join(", ") },
|
|
30914
|
+
target: prop,
|
|
30915
|
+
}));
|
|
30916
|
+
}
|
|
30917
|
+
if (defined.length === 0) {
|
|
30918
|
+
return [undefined, diagnostics];
|
|
30919
|
+
}
|
|
30920
|
+
return [defined[0][0], diagnostics];
|
|
30921
|
+
}
|
|
30922
|
+
function createMarkerDecorator(key, validate) {
|
|
30923
|
+
const [isLink, markLink] = useStateSet(createStateSymbol(key));
|
|
30924
|
+
const decorator = (...args) => {
|
|
30925
|
+
if (validate && !validate(...args)) {
|
|
30926
|
+
return;
|
|
30927
|
+
}
|
|
30928
|
+
const [context, target] = args;
|
|
30929
|
+
markLink(context.program, target);
|
|
30930
|
+
};
|
|
30931
|
+
return [isLink, markLink, decorator];
|
|
30932
|
+
}
|
|
30933
|
+
function createNumericValidation(decoratorName) {
|
|
30934
|
+
return (context, target) => {
|
|
30935
|
+
if (!isNumericType(context.program, target.type)) {
|
|
30936
|
+
reportDiagnostic(context.program, {
|
|
30937
|
+
code: "decorator-wrong-target",
|
|
30938
|
+
messageId: "withExpected",
|
|
30939
|
+
format: {
|
|
30940
|
+
decorator: decoratorName,
|
|
30941
|
+
expected: "numeric",
|
|
30942
|
+
to: getTypeName(target.type),
|
|
30943
|
+
},
|
|
30944
|
+
target: context.decoratorTarget,
|
|
30945
|
+
});
|
|
30946
|
+
return false;
|
|
30947
|
+
}
|
|
30948
|
+
return true;
|
|
30949
|
+
};
|
|
30950
|
+
}
|
|
30951
|
+
|
|
30952
|
+
// Copyright (c) Microsoft Corporation
|
|
30953
|
+
// Licensed under the MIT license.
|
|
30954
|
+
// TypeSpec Visibility System
|
|
30955
|
+
// --------------------------
|
|
30956
|
+
// This module defines the core visibility system of the TypeSpec language. The
|
|
30957
|
+
// visibility system is used to decide when properties of a _conceptual resource_
|
|
30958
|
+
// are present. The system is based on the concept of _visibility classes_,
|
|
30959
|
+
// represented by TypeSpec enums. Each visibility class has a set of _visibility
|
|
30960
|
+
// modifiers_ that can be applied to a model property, each modifier represented
|
|
30961
|
+
// by a member of the visibility class enum.
|
|
30962
|
+
//
|
|
30963
|
+
// Each visibility class has a _default modifier set_ that is used when no
|
|
30964
|
+
// modifiers are specified for a property, and each property has an _active
|
|
30965
|
+
// modifier set_ that is used when analyzing the visibility of the property.
|
|
30966
|
+
//
|
|
30967
|
+
// Visibility can be _sealed_ for a program, property, or visibility class
|
|
30968
|
+
// within a property. Once visibility is sealed, it cannot be unsealed, and any
|
|
30969
|
+
// attempts to modify a sealed visibility will fail.
|
|
30970
|
+
/**
|
|
30971
|
+
* The global visibility store.
|
|
30972
|
+
*
|
|
30973
|
+
* This store is used to track the visibility modifiers
|
|
30974
|
+
*/
|
|
30975
|
+
const [getVisibilityStore, setVisibilityStore] = useStateMap(createStateSymbol("visibilityStore"));
|
|
30976
|
+
/**
|
|
30977
|
+
* Stores the default modifier set for a given visibility class.
|
|
30978
|
+
*/
|
|
30979
|
+
const [getDefaultModifiers, setDefaultModifiers] = useStateMap(createStateSymbol("defaultVisibilityModifiers"));
|
|
30980
|
+
/**
|
|
30981
|
+
* Gets the default modifier set for a visibility class. If no default modifier set has been set, this function will
|
|
30982
|
+
* initialize the default modifier set to ALL the visibility class's members.
|
|
30983
|
+
*
|
|
30984
|
+
* @param program - the program in which the visibility class occurs
|
|
30985
|
+
* @param visibilityClass - the visibility class to get the default modifier set for
|
|
30986
|
+
* @returns the default modifier set for the visibility class
|
|
30987
|
+
*/
|
|
30988
|
+
function getDefaultModifierSetForClass(program, visibilityClass) {
|
|
30989
|
+
const cached = getDefaultModifiers(program, visibilityClass);
|
|
30990
|
+
if (cached)
|
|
30991
|
+
return new Set(cached);
|
|
30992
|
+
const defaultModifierSet = new Set(visibilityClass.members.values());
|
|
30993
|
+
setDefaultModifiers(program, visibilityClass, defaultModifierSet);
|
|
30994
|
+
// Explicitly clone the set again to prevent accidental modification of the default set.
|
|
30995
|
+
return new Set(defaultModifierSet);
|
|
30996
|
+
}
|
|
30997
|
+
// #endregion
|
|
30998
|
+
// #region Visibility Analysis API
|
|
30999
|
+
/**
|
|
31000
|
+
* Returns the active visibility modifiers for a property in a given visibility class.
|
|
31001
|
+
*
|
|
31002
|
+
* This function is infallible. If the visibility modifiers for the given class have not been set explicitly, it will
|
|
31003
|
+
* return the default visibility modifiers for the class.
|
|
31004
|
+
*
|
|
31005
|
+
* @param program - the program in which the property occurs
|
|
31006
|
+
* @param property - the property to get visibility modifiers for
|
|
31007
|
+
* @param visibilityClass - the visibility class to get visibility modifiers for
|
|
31008
|
+
* @returns the set of active modifiers (enum members) for the property and visibility class
|
|
31009
|
+
*/
|
|
31010
|
+
function getVisibilityForClass(program, property, visibilityClass) {
|
|
31011
|
+
const store = getVisibilityStore(program, property);
|
|
31012
|
+
return store?.get(visibilityClass) ?? getDefaultModifierSetForClass(program, visibilityClass);
|
|
31013
|
+
}
|
|
31014
|
+
// #endregion
|
|
31015
|
+
|
|
31016
|
+
function getLocationContext(program, type) {
|
|
31017
|
+
const sourceLocation = getSourceLocation(type);
|
|
31018
|
+
if (sourceLocation.isSynthetic) {
|
|
31019
|
+
return { type: "synthetic" };
|
|
31020
|
+
}
|
|
31021
|
+
return program.getSourceFileLocationContext(sourceLocation.file);
|
|
31022
|
+
}
|
|
31023
|
+
|
|
31024
|
+
/**
|
|
31025
|
+
* Flow control for mutators.
|
|
31026
|
+
*
|
|
31027
|
+
* When filtering types in a mutator, the filter function may return MutatorFlow flags to control how mutation should
|
|
31028
|
+
* proceed.
|
|
31029
|
+
*
|
|
31030
|
+
* @see {@link MutatorFilterFn}
|
|
31031
|
+
*
|
|
31032
|
+
* @experimental
|
|
31033
|
+
*/
|
|
31034
|
+
var MutatorFlow;
|
|
31035
|
+
(function (MutatorFlow) {
|
|
31036
|
+
/**
|
|
31037
|
+
* Mutate the type and recur, further mutating the type's children. This is the default behavior.
|
|
31038
|
+
*/
|
|
31039
|
+
MutatorFlow[MutatorFlow["MutateAndRecur"] = 0] = "MutateAndRecur";
|
|
31040
|
+
/**
|
|
31041
|
+
* If this flag is set, the type will not be mutated.
|
|
31042
|
+
*/
|
|
31043
|
+
MutatorFlow[MutatorFlow["DoNotMutate"] = 1] = "DoNotMutate";
|
|
31044
|
+
/**
|
|
31045
|
+
* If this flag is set, the mutator will not proceed recursively into the children of the type.
|
|
31046
|
+
*/
|
|
31047
|
+
MutatorFlow[MutatorFlow["DoNotRecur"] = 2] = "DoNotRecur";
|
|
31048
|
+
})(MutatorFlow || (MutatorFlow = {}));
|
|
31049
|
+
// #endregion
|
|
31050
|
+
|
|
31051
|
+
function replaceTemplatedStringFromProperties(formatString, sourceObject) {
|
|
31052
|
+
// Template parameters are not valid source objects, just skip them
|
|
31053
|
+
if (sourceObject.kind === "TemplateParameter") {
|
|
31054
|
+
return formatString;
|
|
31055
|
+
}
|
|
31056
|
+
return formatString.replace(/{(\w+)}/g, (_, propName) => {
|
|
31057
|
+
return sourceObject[propName];
|
|
31058
|
+
});
|
|
31059
|
+
}
|
|
31060
|
+
const [getSummary, setSummary] = useStateMap(createStateSymbol("summary"));
|
|
31061
|
+
/**
|
|
31062
|
+
* @doc attaches a documentation string. Works great with multi-line string literals.
|
|
31063
|
+
*
|
|
31064
|
+
* The first argument to @doc is a string, which may contain template parameters, enclosed in braces,
|
|
31065
|
+
* which are replaced with an attribute for the type (commonly "name") passed as the second (optional) argument.
|
|
31066
|
+
*
|
|
31067
|
+
* @doc can be specified on any language element -- a model, an operation, a namespace, etc.
|
|
31068
|
+
*/
|
|
31069
|
+
const $doc = (context, target, text, sourceObject) => {
|
|
31070
|
+
validateDecoratorUniqueOnNode(context, target, $doc);
|
|
31071
|
+
if (sourceObject) {
|
|
31072
|
+
text = replaceTemplatedStringFromProperties(text, sourceObject);
|
|
31073
|
+
}
|
|
31074
|
+
setDocData(context.program, target, "self", { value: text, source: "decorator" });
|
|
31075
|
+
};
|
|
31076
|
+
/**
|
|
31077
|
+
* Get the documentation string for the given type.
|
|
31078
|
+
* @param program Program
|
|
31079
|
+
* @param target Type
|
|
31080
|
+
* @returns Documentation value
|
|
31081
|
+
*/
|
|
31082
|
+
function getDoc(program, target) {
|
|
31083
|
+
return getDocDataInternal(program, target, "self")?.value;
|
|
31084
|
+
}
|
|
31085
|
+
function isStringType(program, target) {
|
|
31086
|
+
const stringType = program.checker.getStdType("string");
|
|
31087
|
+
return (target.kind === "Scalar" && program.checker.isTypeAssignableTo(target, stringType, target)[0]);
|
|
31088
|
+
}
|
|
31089
|
+
function isNumericType(program, target) {
|
|
31090
|
+
const numericType = program.checker.getStdType("numeric");
|
|
31091
|
+
return (target.kind === "Scalar" && program.checker.isTypeAssignableTo(target, numericType, target)[0]);
|
|
31092
|
+
}
|
|
31093
|
+
// -- @error decorator ----------------------
|
|
31094
|
+
const [getErrorState, setErrorState] = useStateSet(createStateSymbol("error"));
|
|
31095
|
+
/**
|
|
31096
|
+
* Check if the type is an error model or a descendant of an error model.
|
|
31097
|
+
*/
|
|
31098
|
+
function isErrorModel(program, target) {
|
|
31099
|
+
if (target.kind !== "Model") {
|
|
31100
|
+
return false;
|
|
31101
|
+
}
|
|
31102
|
+
let current = target;
|
|
31103
|
+
while (current) {
|
|
31104
|
+
if (getErrorState(program, current)) {
|
|
31105
|
+
return true;
|
|
31106
|
+
}
|
|
31107
|
+
current = current.baseModel;
|
|
31108
|
+
}
|
|
31109
|
+
return false;
|
|
31110
|
+
}
|
|
31111
|
+
// -- @format decorator ---------------------
|
|
31112
|
+
const [getFormat, setFormat] = useStateMap(createStateSymbol("format"));
|
|
31113
|
+
const [getEncode, setEncodeData] = useStateMap(createStateSymbol("encode"));
|
|
31114
|
+
|
|
31115
|
+
defineKit({
|
|
31116
|
+
enum: {
|
|
31117
|
+
create(desc) {
|
|
31118
|
+
const en = this.program.checker.createType({
|
|
31119
|
+
kind: "Enum",
|
|
31120
|
+
name: desc.name,
|
|
31121
|
+
decorators: decoratorApplication(this, desc.decorators),
|
|
31122
|
+
members: createRekeyableMap(),
|
|
31123
|
+
});
|
|
31124
|
+
if (Array.isArray(desc.members)) {
|
|
31125
|
+
for (const member of desc.members) {
|
|
31126
|
+
member.enum = en;
|
|
31127
|
+
en.members.set(member.name, member);
|
|
31128
|
+
}
|
|
31129
|
+
}
|
|
31130
|
+
else {
|
|
31131
|
+
for (const [name, member] of Object.entries(desc.members ?? {})) {
|
|
31132
|
+
en.members.set(name, this.enumMember.create({ name, value: member, enum: en }));
|
|
31133
|
+
}
|
|
31134
|
+
}
|
|
31135
|
+
this.program.checker.finishType(en);
|
|
31136
|
+
return en;
|
|
31137
|
+
},
|
|
31138
|
+
is(type) {
|
|
31139
|
+
return type.kind === "Enum";
|
|
31140
|
+
},
|
|
31141
|
+
createFromUnion(type) {
|
|
31142
|
+
if (!type.name) {
|
|
31143
|
+
throw new Error("Cannot create an enum from an anonymous union.");
|
|
31144
|
+
}
|
|
31145
|
+
const enumMembers = [];
|
|
31146
|
+
for (const variant of type.variants.values()) {
|
|
31147
|
+
if ((variant.name && typeof variant.name === "symbol") ||
|
|
31148
|
+
(!this.literal.isString(variant.type) && !this.literal.isNumeric(variant.type))) {
|
|
31149
|
+
continue;
|
|
31150
|
+
}
|
|
31151
|
+
const variantDoc = getDoc(this.program, variant);
|
|
31152
|
+
enumMembers.push(this.enumMember.create({
|
|
31153
|
+
name: variant.name,
|
|
31154
|
+
value: variant.type.value,
|
|
31155
|
+
decorators: variantDoc ? [[$doc, variantDoc]] : undefined,
|
|
31156
|
+
}));
|
|
31157
|
+
}
|
|
31158
|
+
const unionDoc = getDoc(this.program, type);
|
|
31159
|
+
return this.enum.create({
|
|
31160
|
+
name: type.name,
|
|
31161
|
+
members: enumMembers,
|
|
31162
|
+
decorators: unionDoc ? [[$doc, unionDoc]] : undefined,
|
|
31163
|
+
});
|
|
31164
|
+
},
|
|
31165
|
+
},
|
|
31166
|
+
});
|
|
31167
|
+
|
|
31168
|
+
class InvalidNumericError extends Error {
|
|
31169
|
+
code = "InvalidNumeric";
|
|
31170
|
+
}
|
|
31171
|
+
/** @internal */
|
|
31172
|
+
const InternalDataSym = Symbol.for("NumericInternalData");
|
|
31173
|
+
/**
|
|
31174
|
+
* Represent any possible numeric value
|
|
31175
|
+
*/
|
|
31176
|
+
function Numeric(stringValue) {
|
|
31177
|
+
if (new.target) {
|
|
31178
|
+
throw new Error("Numeric is not a constructor");
|
|
31179
|
+
}
|
|
31180
|
+
const data = parse(stringValue);
|
|
31181
|
+
const isInteger = data.d === 0;
|
|
31182
|
+
const obj = {
|
|
31183
|
+
[InternalDataSym]: data,
|
|
31184
|
+
isInteger,
|
|
31185
|
+
};
|
|
31186
|
+
// We are explicitly not using a class here due to version mismatch between the compiler and the runtime that could happen and break instanceof checks.
|
|
31187
|
+
const numeric = setTypedProptotype(obj, NumericPrototype);
|
|
31188
|
+
return Object.freeze(numeric);
|
|
31189
|
+
}
|
|
31190
|
+
function setTypedProptotype(obj, prototype) {
|
|
31191
|
+
Object.setPrototypeOf(obj, prototype);
|
|
31192
|
+
return obj;
|
|
31193
|
+
}
|
|
31194
|
+
function parse(original) {
|
|
31195
|
+
let stringValue = original;
|
|
31196
|
+
let start = 0;
|
|
31197
|
+
let sign = 1;
|
|
31198
|
+
let n;
|
|
31199
|
+
let exp;
|
|
31200
|
+
let decimal = undefined;
|
|
31201
|
+
if (stringValue[0] === "-") {
|
|
31202
|
+
start = 1;
|
|
31203
|
+
sign = -1;
|
|
31204
|
+
}
|
|
31205
|
+
const second = stringValue[start + 1]?.toLowerCase();
|
|
31206
|
+
if (stringValue[start] === "0" && (second === "b" || second === "x" || second === "o")) {
|
|
31207
|
+
try {
|
|
31208
|
+
n = BigInt(stringValue.slice(start));
|
|
31209
|
+
exp = n.toString().length;
|
|
31210
|
+
decimal = 0;
|
|
31211
|
+
}
|
|
31212
|
+
catch {
|
|
31213
|
+
throw new InvalidNumericError(`Invalid numeric value: ${original}`);
|
|
31214
|
+
}
|
|
31215
|
+
}
|
|
31216
|
+
else {
|
|
31217
|
+
// Skip leading 0.
|
|
31218
|
+
while (stringValue[start] === "0") {
|
|
31219
|
+
start++;
|
|
31220
|
+
}
|
|
31221
|
+
const decimalPointIndex = stringValue.indexOf(".");
|
|
31222
|
+
const adjustedPointIndex = decimalPointIndex - start;
|
|
31223
|
+
// Decimal point?
|
|
31224
|
+
if (decimalPointIndex !== -1) {
|
|
31225
|
+
exp = adjustedPointIndex;
|
|
31226
|
+
stringValue = stringValue.replace(".", "");
|
|
31227
|
+
}
|
|
31228
|
+
let i;
|
|
31229
|
+
if ((i = stringValue.search(/e/i)) > 0) {
|
|
31230
|
+
// Determine exponent.
|
|
31231
|
+
if (exp === undefined) {
|
|
31232
|
+
exp = i - start;
|
|
31233
|
+
}
|
|
31234
|
+
exp += Number(stringValue.slice(i + 1));
|
|
31235
|
+
stringValue = stringValue.slice(start, i);
|
|
31236
|
+
decimal = Math.max(stringValue.length - exp, 0);
|
|
31237
|
+
}
|
|
31238
|
+
else if (exp === undefined) {
|
|
31239
|
+
// Integer.
|
|
31240
|
+
exp = stringValue.length - start;
|
|
31241
|
+
stringValue = stringValue.slice(start);
|
|
31242
|
+
}
|
|
31243
|
+
else {
|
|
31244
|
+
stringValue = stringValue.slice(start);
|
|
31245
|
+
}
|
|
31246
|
+
let end = stringValue.length;
|
|
31247
|
+
while (stringValue[end - 1] === "0" && end > adjustedPointIndex) {
|
|
31248
|
+
end--;
|
|
31249
|
+
}
|
|
31250
|
+
// Only if there is 0 before the decimal point, keeps checking how many 0 there is after it and update the exponent accordingly.
|
|
31251
|
+
if (start === adjustedPointIndex + 1) {
|
|
31252
|
+
let cur = adjustedPointIndex;
|
|
31253
|
+
while (stringValue[cur] === "0" && cur < end) {
|
|
31254
|
+
cur++;
|
|
31255
|
+
exp--;
|
|
31256
|
+
}
|
|
31257
|
+
}
|
|
31258
|
+
try {
|
|
31259
|
+
stringValue = stringValue.slice(0, end);
|
|
31260
|
+
stringValue = stringValue + "0".repeat(Math.max(exp - stringValue.length, 0)); // add remaining zeros for cases like 3e30
|
|
31261
|
+
n = BigInt(stringValue);
|
|
31262
|
+
if (n === 0n) {
|
|
31263
|
+
decimal = 0;
|
|
31264
|
+
}
|
|
31265
|
+
else if (decimal === undefined) {
|
|
31266
|
+
decimal = Math.max(stringValue.length - Math.max(exp, 0), 0);
|
|
31267
|
+
}
|
|
31268
|
+
}
|
|
31269
|
+
catch {
|
|
31270
|
+
throw new InvalidNumericError(`Invalid numeric value: ${original}`);
|
|
31271
|
+
}
|
|
31272
|
+
}
|
|
31273
|
+
return { n, e: exp, s: sign, d: decimal };
|
|
31274
|
+
}
|
|
31275
|
+
function stringify(value) {
|
|
31276
|
+
if (value.n === 0n)
|
|
31277
|
+
return "0";
|
|
31278
|
+
const n = value.n.toString();
|
|
31279
|
+
const sign = value.s === -1 ? "-" : "";
|
|
31280
|
+
const int = value.e <= 0 ? "0" : n.slice(0, value.e);
|
|
31281
|
+
const decimal = value.e < n.length ? "." + n.slice(-value.d).padStart(value.d, "0") : "";
|
|
31282
|
+
return sign + int + decimal;
|
|
30916
31283
|
}
|
|
30917
|
-
|
|
30918
|
-
|
|
30919
|
-
|
|
31284
|
+
const equals = (a, b) => a.n === b.n && a.e === b.e;
|
|
31285
|
+
const compare = (a, b) => {
|
|
31286
|
+
if (a.s < b.s) {
|
|
31287
|
+
return -1;
|
|
30920
31288
|
}
|
|
30921
|
-
|
|
30922
|
-
|
|
30923
|
-
|
|
30924
|
-
const regex = /^(application|audio|font|example|image|message|model|multipart|text|video|x-(?:[0-9A-Za-z!#$%&'*+.^_`|~-]+))\/([0-9A-Za-z!#$%&'*+.^_`|~-]+)$/;
|
|
30925
|
-
function parseMimeType(mimeType) {
|
|
30926
|
-
const match = mimeType.match(regex);
|
|
30927
|
-
if (match == null) {
|
|
30928
|
-
return undefined;
|
|
31289
|
+
else if (a.s > b.s) {
|
|
31290
|
+
return 1;
|
|
30929
31291
|
}
|
|
30930
|
-
const
|
|
30931
|
-
|
|
30932
|
-
|
|
30933
|
-
};
|
|
30934
|
-
return type;
|
|
30935
|
-
}
|
|
30936
|
-
function parseSubType(value) {
|
|
30937
|
-
if (!value.includes("+"))
|
|
30938
|
-
return { subtype: value };
|
|
30939
|
-
const [subtype, suffix] = value.split("+", 2);
|
|
30940
|
-
return { subtype, suffix };
|
|
30941
|
-
}
|
|
30942
|
-
|
|
30943
|
-
const [getEncodedNamesMap, setEncodedNamesMap, getEncodedNamesStateMap] = useStateMap(createStateSymbol("encodedName"));
|
|
30944
|
-
function getEncodedName(program, target, mimeType) {
|
|
30945
|
-
const mimeTypeObj = parseMimeType(mimeType);
|
|
30946
|
-
if (mimeTypeObj === undefined) {
|
|
30947
|
-
return undefined;
|
|
31292
|
+
const neg = a.s;
|
|
31293
|
+
if (a.e < b.e) {
|
|
31294
|
+
return (-1 * neg);
|
|
30948
31295
|
}
|
|
30949
|
-
|
|
30950
|
-
|
|
30951
|
-
: mimeType;
|
|
30952
|
-
return getEncodedNamesMap(program, target)?.get(resolvedMimeType);
|
|
30953
|
-
}
|
|
30954
|
-
/**
|
|
30955
|
-
* Resolve the encoded name for the given type when serialized to the given mime type.
|
|
30956
|
-
* 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.
|
|
30957
|
-
*
|
|
30958
|
-
* @example
|
|
30959
|
-
*
|
|
30960
|
-
* For the given
|
|
30961
|
-
* ```tsp
|
|
30962
|
-
* model Certificate {
|
|
30963
|
-
* @encodedName("application/json", "exp")
|
|
30964
|
-
* @encodedName("application/xml", "expiry")
|
|
30965
|
-
* expireAt: utcDateTime;
|
|
30966
|
-
*
|
|
30967
|
-
* }
|
|
30968
|
-
* ```
|
|
30969
|
-
*
|
|
30970
|
-
* ```ts
|
|
30971
|
-
* resolveEncodedName(program, type, "application/json") // exp
|
|
30972
|
-
* resolveEncodedName(program, type, "application/merge-patch+json") // exp
|
|
30973
|
-
* resolveEncodedName(program, type, "application/xml") // expireAt
|
|
30974
|
-
* resolveEncodedName(program, type, "application/yaml") // expiry
|
|
30975
|
-
* ```
|
|
30976
|
-
*/
|
|
30977
|
-
function resolveEncodedName(program, target, mimeType) {
|
|
30978
|
-
return getEncodedName(program, target, mimeType) ?? target.name;
|
|
30979
|
-
}
|
|
30980
|
-
|
|
30981
|
-
function getLocationContext(program, type) {
|
|
30982
|
-
const sourceLocation = getSourceLocation(type);
|
|
30983
|
-
if (sourceLocation.isSynthetic) {
|
|
30984
|
-
return { type: "synthetic" };
|
|
31296
|
+
else if (a.e > b.e) {
|
|
31297
|
+
return (1 * neg);
|
|
30985
31298
|
}
|
|
30986
|
-
|
|
30987
|
-
|
|
30988
|
-
|
|
30989
|
-
|
|
30990
|
-
|
|
30991
|
-
|
|
30992
|
-
|
|
30993
|
-
|
|
30994
|
-
|
|
30995
|
-
*
|
|
30996
|
-
|
|
30997
|
-
*
|
|
30998
|
-
|
|
30999
|
-
|
|
31000
|
-
|
|
31001
|
-
|
|
31002
|
-
|
|
31003
|
-
|
|
31004
|
-
|
|
31005
|
-
|
|
31006
|
-
|
|
31007
|
-
|
|
31008
|
-
|
|
31009
|
-
|
|
31010
|
-
|
|
31011
|
-
|
|
31012
|
-
|
|
31013
|
-
|
|
31014
|
-
|
|
31299
|
+
let aN = a.n;
|
|
31300
|
+
let bN = b.n;
|
|
31301
|
+
if (a.d < b.d) {
|
|
31302
|
+
aN *= 10n ** BigInt(b.d - a.d);
|
|
31303
|
+
}
|
|
31304
|
+
else {
|
|
31305
|
+
bN *= 10n ** BigInt(a.d - b.d);
|
|
31306
|
+
}
|
|
31307
|
+
if (aN < bN)
|
|
31308
|
+
return (-1 * neg);
|
|
31309
|
+
if (aN > bN)
|
|
31310
|
+
return (1 * neg);
|
|
31311
|
+
return 0;
|
|
31312
|
+
};
|
|
31313
|
+
const NumericPrototype = {
|
|
31314
|
+
toString: function () {
|
|
31315
|
+
return stringify(this[InternalDataSym]);
|
|
31316
|
+
},
|
|
31317
|
+
asNumber: function () {
|
|
31318
|
+
const num = Number(stringify(this[InternalDataSym]));
|
|
31319
|
+
return equals(this[InternalDataSym], Numeric(num.toString())[InternalDataSym]) ? num : null;
|
|
31320
|
+
},
|
|
31321
|
+
asBigInt: function () {
|
|
31322
|
+
if (!this.isInteger) {
|
|
31323
|
+
return null;
|
|
31324
|
+
}
|
|
31325
|
+
const { s, n } = this[InternalDataSym];
|
|
31326
|
+
return BigInt(s) * n;
|
|
31327
|
+
},
|
|
31328
|
+
equals: function (other) {
|
|
31329
|
+
return equals(this[InternalDataSym], other[InternalDataSym]);
|
|
31330
|
+
},
|
|
31331
|
+
lt: function (other) {
|
|
31332
|
+
return compare(this[InternalDataSym], other[InternalDataSym]) === -1;
|
|
31333
|
+
},
|
|
31334
|
+
lte: function (other) {
|
|
31335
|
+
return compare(this[InternalDataSym], other[InternalDataSym]) <= 0;
|
|
31336
|
+
},
|
|
31337
|
+
gt: function (other) {
|
|
31338
|
+
return compare(this[InternalDataSym], other[InternalDataSym]) === 1;
|
|
31339
|
+
},
|
|
31340
|
+
gte: function (other) {
|
|
31341
|
+
return compare(this[InternalDataSym], other[InternalDataSym]) >= 0;
|
|
31342
|
+
},
|
|
31343
|
+
};
|
|
31344
|
+
NumericPrototype.toString = function () {
|
|
31345
|
+
return stringify(this[InternalDataSym]);
|
|
31346
|
+
};
|
|
31015
31347
|
|
|
31016
|
-
|
|
31017
|
-
|
|
31018
|
-
|
|
31019
|
-
|
|
31020
|
-
|
|
31021
|
-
|
|
31022
|
-
|
|
31023
|
-
|
|
31024
|
-
|
|
31025
|
-
|
|
31026
|
-
|
|
31027
|
-
|
|
31028
|
-
|
|
31348
|
+
defineKit({
|
|
31349
|
+
literal: {
|
|
31350
|
+
create(value) {
|
|
31351
|
+
if (typeof value === "string") {
|
|
31352
|
+
return this.literal.createString(value);
|
|
31353
|
+
}
|
|
31354
|
+
else if (typeof value === "number") {
|
|
31355
|
+
return this.literal.createNumeric(value);
|
|
31356
|
+
}
|
|
31357
|
+
else {
|
|
31358
|
+
return this.literal.createBoolean(value);
|
|
31359
|
+
}
|
|
31360
|
+
},
|
|
31361
|
+
createString(value) {
|
|
31362
|
+
return this.program.checker.createType({
|
|
31363
|
+
kind: "String",
|
|
31364
|
+
value,
|
|
31365
|
+
});
|
|
31366
|
+
},
|
|
31367
|
+
createNumeric(value) {
|
|
31368
|
+
const valueAsString = String(value);
|
|
31369
|
+
return this.program.checker.createType({
|
|
31370
|
+
kind: "Number",
|
|
31371
|
+
value,
|
|
31372
|
+
valueAsString,
|
|
31373
|
+
numericValue: Numeric(valueAsString),
|
|
31374
|
+
});
|
|
31375
|
+
},
|
|
31376
|
+
createBoolean(value) {
|
|
31377
|
+
return this.program.checker.createType({
|
|
31378
|
+
kind: "Boolean",
|
|
31379
|
+
value,
|
|
31380
|
+
});
|
|
31381
|
+
},
|
|
31382
|
+
isBoolean(type) {
|
|
31383
|
+
return type.kind === "Boolean";
|
|
31384
|
+
},
|
|
31385
|
+
isString(type) {
|
|
31386
|
+
return type.kind === "String";
|
|
31387
|
+
},
|
|
31388
|
+
isNumeric(type) {
|
|
31389
|
+
return type.kind === "Number";
|
|
31390
|
+
},
|
|
31391
|
+
is(type) {
|
|
31392
|
+
return (this.literal.isBoolean(type) || this.literal.isNumeric(type) || this.literal.isString(type));
|
|
31393
|
+
},
|
|
31394
|
+
},
|
|
31395
|
+
});
|
|
31029
31396
|
|
|
31030
31397
|
defineKit({
|
|
31031
31398
|
modelProperty: {
|
|
@@ -31045,7 +31412,6 @@ defineKit({
|
|
|
31045
31412
|
return this.program.checker.createType({
|
|
31046
31413
|
kind: "ModelProperty",
|
|
31047
31414
|
name: desc.name,
|
|
31048
|
-
node: undefined,
|
|
31049
31415
|
type: desc.type,
|
|
31050
31416
|
optional: desc.optional ?? false,
|
|
31051
31417
|
decorators: [],
|
|
@@ -31065,7 +31431,6 @@ defineKit({
|
|
|
31065
31431
|
name: desc.name ?? "",
|
|
31066
31432
|
decorators: decoratorApplication(this, desc.decorators),
|
|
31067
31433
|
properties: properties,
|
|
31068
|
-
node: undefined,
|
|
31069
31434
|
derivedModels: desc.derivedModels ?? [],
|
|
31070
31435
|
sourceModels: desc.sourceModels ?? [],
|
|
31071
31436
|
indexer: desc.indexer,
|
|
@@ -31143,13 +31508,13 @@ defineKit({
|
|
|
31143
31508
|
}
|
|
31144
31509
|
return undefined;
|
|
31145
31510
|
},
|
|
31146
|
-
getDiscriminatedUnion(model) {
|
|
31511
|
+
getDiscriminatedUnion: createDiagnosable(function (model) {
|
|
31147
31512
|
const discriminator = getDiscriminator(this.program, model);
|
|
31148
31513
|
if (!discriminator) {
|
|
31149
|
-
return undefined;
|
|
31514
|
+
return [undefined, []];
|
|
31150
31515
|
}
|
|
31151
|
-
return
|
|
31152
|
-
},
|
|
31516
|
+
return getDiscriminatedUnionFromInheritance(model, discriminator);
|
|
31517
|
+
}),
|
|
31153
31518
|
},
|
|
31154
31519
|
});
|
|
31155
31520
|
|
|
@@ -31158,6 +31523,9 @@ defineKit({
|
|
|
31158
31523
|
is(type) {
|
|
31159
31524
|
return type.kind === "Operation";
|
|
31160
31525
|
},
|
|
31526
|
+
getPagingMetadata: createDiagnosable(function (operation) {
|
|
31527
|
+
return getPagingOperation(this.program, operation);
|
|
31528
|
+
}),
|
|
31161
31529
|
create(desc) {
|
|
31162
31530
|
const parametersModel = this.model.create({
|
|
31163
31531
|
name: `${desc.name}Parameters`,
|
|
@@ -31172,7 +31540,6 @@ defineKit({
|
|
|
31172
31540
|
decorators: [],
|
|
31173
31541
|
parameters: parametersModel,
|
|
31174
31542
|
returnType: desc.returnType,
|
|
31175
|
-
node: undefined,
|
|
31176
31543
|
});
|
|
31177
31544
|
this.program.checker.finishType(operation);
|
|
31178
31545
|
return operation;
|
|
@@ -31292,6 +31659,23 @@ function extendsStdType(typeName) {
|
|
|
31292
31659
|
};
|
|
31293
31660
|
}
|
|
31294
31661
|
|
|
31662
|
+
defineKit({
|
|
31663
|
+
tuple: {
|
|
31664
|
+
is(type) {
|
|
31665
|
+
return type.kind === "Tuple";
|
|
31666
|
+
},
|
|
31667
|
+
create(values = []) {
|
|
31668
|
+
const tuple = this.program.checker.createType({
|
|
31669
|
+
kind: "Tuple",
|
|
31670
|
+
name: "Tuple",
|
|
31671
|
+
values,
|
|
31672
|
+
});
|
|
31673
|
+
this.program.checker.finishType(tuple);
|
|
31674
|
+
return tuple;
|
|
31675
|
+
},
|
|
31676
|
+
},
|
|
31677
|
+
});
|
|
31678
|
+
|
|
31295
31679
|
/**
|
|
31296
31680
|
* Get a plausible name for the given type.
|
|
31297
31681
|
* @experimental
|
|
@@ -31386,7 +31770,7 @@ defineKit({
|
|
|
31386
31770
|
return clone;
|
|
31387
31771
|
},
|
|
31388
31772
|
isError(type) {
|
|
31389
|
-
return
|
|
31773
|
+
return isErrorModel(this.program, type);
|
|
31390
31774
|
},
|
|
31391
31775
|
getEncodedName(type, encoding) {
|
|
31392
31776
|
return resolveEncodedName(this.program, type, encoding);
|
|
@@ -31402,7 +31786,7 @@ defineKit({
|
|
|
31402
31786
|
},
|
|
31403
31787
|
getDiscriminator(type) {
|
|
31404
31788
|
let discriminator;
|
|
31405
|
-
if (
|
|
31789
|
+
if (this.model.is(type)) {
|
|
31406
31790
|
discriminator = getDiscriminator(this.program, type);
|
|
31407
31791
|
}
|
|
31408
31792
|
else {
|
|
@@ -31455,7 +31839,6 @@ defineKit({
|
|
|
31455
31839
|
name: desc.name ?? Symbol("name"),
|
|
31456
31840
|
decorators: decoratorApplication(this, desc.decorators),
|
|
31457
31841
|
type: desc.type,
|
|
31458
|
-
node: undefined,
|
|
31459
31842
|
union: desc.union,
|
|
31460
31843
|
});
|
|
31461
31844
|
this.program.checker.finishType(variant);
|
|
@@ -31483,7 +31866,6 @@ defineKit({
|
|
|
31483
31866
|
return Array.from(this.variants.values()).map((v) => v.type);
|
|
31484
31867
|
},
|
|
31485
31868
|
expression: desc.name === undefined,
|
|
31486
|
-
node: undefined,
|
|
31487
31869
|
});
|
|
31488
31870
|
if (Array.isArray(desc.variants)) {
|
|
31489
31871
|
for (const variant of desc.variants) {
|
|
@@ -31499,6 +31881,22 @@ defineKit({
|
|
|
31499
31881
|
this.program.checker.finishType(union);
|
|
31500
31882
|
return union;
|
|
31501
31883
|
},
|
|
31884
|
+
createFromEnum(type) {
|
|
31885
|
+
const enumDoc = getDoc(this.program, type);
|
|
31886
|
+
return this.union.create({
|
|
31887
|
+
name: type.name,
|
|
31888
|
+
decorators: enumDoc ? [[$doc, enumDoc]] : undefined,
|
|
31889
|
+
variants: Array.from(type.members.values()).map((member) => {
|
|
31890
|
+
const memberDoc = getDoc(this.program, member);
|
|
31891
|
+
const value = member.value ?? member.name;
|
|
31892
|
+
return this.unionVariant.create({
|
|
31893
|
+
name: member.name,
|
|
31894
|
+
type: this.literal.create(value),
|
|
31895
|
+
decorators: memberDoc ? [[$doc, memberDoc]] : undefined,
|
|
31896
|
+
});
|
|
31897
|
+
}),
|
|
31898
|
+
});
|
|
31899
|
+
},
|
|
31502
31900
|
is(type) {
|
|
31503
31901
|
return type.kind === "Union";
|
|
31504
31902
|
},
|
|
@@ -31536,9 +31934,9 @@ defineKit({
|
|
|
31536
31934
|
isExpression(type) {
|
|
31537
31935
|
return type.name === undefined || type.name === "";
|
|
31538
31936
|
},
|
|
31539
|
-
getDiscriminatedUnion(type) {
|
|
31540
|
-
return
|
|
31541
|
-
},
|
|
31937
|
+
getDiscriminatedUnion: createDiagnosable(function (type) {
|
|
31938
|
+
return getDiscriminatedUnion(this.program, type);
|
|
31939
|
+
}),
|
|
31542
31940
|
},
|
|
31543
31941
|
});
|
|
31544
31942
|
|
|
@@ -31646,9 +32044,28 @@ function createTypekit(realm) {
|
|
|
31646
32044
|
const value = Reflect.get(target, prop, receiver);
|
|
31647
32045
|
// Wrap functions to set `this` correctly
|
|
31648
32046
|
if (typeof value === "function") {
|
|
31649
|
-
|
|
32047
|
+
const proxyWrapper = function (...args) {
|
|
32048
|
+
// Call the original function (`value`) with the correct `this` (the proxy)
|
|
31650
32049
|
return value.apply(proxy, args);
|
|
31651
32050
|
};
|
|
32051
|
+
// functions may also have properties added to them, like in the case of `withDiagnostics`.
|
|
32052
|
+
// Copy enumerable properties from the original function (`value`) to the wrapper
|
|
32053
|
+
for (const propName of Object.keys(value)) {
|
|
32054
|
+
const originalPropValue = value[propName];
|
|
32055
|
+
if (typeof originalPropValue === "function") {
|
|
32056
|
+
// If the property is a function, wrap it to ensure `this` is bound correctly
|
|
32057
|
+
proxyWrapper[propName] = function (...args) {
|
|
32058
|
+
// Call the original property function with `this` bound to the proxy
|
|
32059
|
+
return originalPropValue.apply(proxy, args);
|
|
32060
|
+
};
|
|
32061
|
+
}
|
|
32062
|
+
else {
|
|
32063
|
+
// If the property is not a function, copy it directly
|
|
32064
|
+
// Use Reflect.defineProperty to handle potential getters/setters correctly, though Object.keys usually only returns data properties.
|
|
32065
|
+
Reflect.defineProperty(proxyWrapper, propName, Reflect.getOwnPropertyDescriptor(value, propName));
|
|
32066
|
+
}
|
|
32067
|
+
}
|
|
32068
|
+
return proxyWrapper;
|
|
31652
32069
|
}
|
|
31653
32070
|
// Only wrap objects marked as Typekit namespaces
|
|
31654
32071
|
if (typeof value === "object" && value !== null && isTypekitNamespace(value)) {
|
|
@@ -31665,11 +32082,7 @@ function isTypekitNamespace(obj) {
|
|
|
31665
32082
|
return obj && !!obj[TypekitNamespaceSymbol];
|
|
31666
32083
|
}
|
|
31667
32084
|
// #region Default Typekit
|
|
31668
|
-
const CURRENT_PROGRAM = Symbol.for("TypeSpec.Typekit.CURRENT_PROGRAM");
|
|
31669
32085
|
const DEFAULT_REALM = Symbol.for("TypeSpec.Typekit.DEFAULT_TYPEKIT_REALM");
|
|
31670
|
-
function getCurrentProgram() {
|
|
31671
|
-
return globalThis[CURRENT_PROGRAM];
|
|
31672
|
-
}
|
|
31673
32086
|
function _$(arg) {
|
|
31674
32087
|
let realm;
|
|
31675
32088
|
if (Object.hasOwn(arg, "projectRoot")) {
|
|
@@ -31685,26 +32098,16 @@ function _$(arg) {
|
|
|
31685
32098
|
/**
|
|
31686
32099
|
* Typekit - Utilities for working with TypeSpec types.
|
|
31687
32100
|
*
|
|
31688
|
-
*
|
|
31689
|
-
*
|
|
31690
|
-
* Each typekit is associated with a Realm in which it operates. The default typekit
|
|
31691
|
-
* will use the default typekit realm for the current program.
|
|
32101
|
+
* Each typekit is associated with a Realm in which it operates.
|
|
31692
32102
|
*
|
|
31693
|
-
*
|
|
31694
|
-
*
|
|
31695
|
-
*
|
|
31696
|
-
*
|
|
32103
|
+
* You can get the typekit associated with that realm by calling
|
|
32104
|
+
* `$` with the realm as an argument, or by calling `$` with a program
|
|
32105
|
+
* as an argument (in this case, it will use that program's default
|
|
32106
|
+
* typekit realm or create one if it does not already exist).
|
|
31697
32107
|
*
|
|
31698
32108
|
* @example
|
|
31699
32109
|
* ```ts
|
|
31700
|
-
* import { $ } from "@typespec/compiler/experimental";
|
|
31701
|
-
*
|
|
31702
|
-
* const clone = $.type.clone(inputType);
|
|
31703
|
-
* ```
|
|
31704
|
-
*
|
|
31705
|
-
* @example
|
|
31706
|
-
* ```ts
|
|
31707
|
-
* import { $, Realm } from "@typespec/compiler/experimental";
|
|
32110
|
+
* import { unsafe_$ as $, Realm } from "@typespec/compiler/experimental";
|
|
31708
32111
|
*
|
|
31709
32112
|
* const realm = new Realm(program, "my custom realm");
|
|
31710
32113
|
*
|
|
@@ -31713,30 +32116,16 @@ function _$(arg) {
|
|
|
31713
32116
|
*
|
|
31714
32117
|
* @example
|
|
31715
32118
|
* ```ts
|
|
31716
|
-
* import { $ } from "@typespec/compiler/experimental";
|
|
31717
|
-
*
|
|
31718
|
-
* const projectedProgram = projectProgram(program, ...);
|
|
32119
|
+
* import { unsafe_$ as $ } from "@typespec/compiler/experimental";
|
|
31719
32120
|
*
|
|
31720
|
-
* const clone = $(
|
|
32121
|
+
* const clone = $(program).type.clone(inputType);
|
|
31721
32122
|
* ```
|
|
31722
32123
|
*
|
|
31723
32124
|
* @see {@link Realm}
|
|
31724
32125
|
*
|
|
31725
32126
|
* @experimental
|
|
31726
32127
|
*/
|
|
31727
|
-
const $$1 =
|
|
31728
|
-
get(_target, prop, _receiver) {
|
|
31729
|
-
const currentProgram = getCurrentProgram();
|
|
31730
|
-
compilerAssert(currentProgram !== undefined, "Default typekits may not be used until a program is set in the compiler.");
|
|
31731
|
-
if (prop === "program")
|
|
31732
|
-
return currentProgram;
|
|
31733
|
-
const realm = (currentProgram[DEFAULT_REALM] ??= new Realm(currentProgram, "default typekit realm"));
|
|
31734
|
-
if (prop === "realm")
|
|
31735
|
-
return realm;
|
|
31736
|
-
const tk = _$(realm);
|
|
31737
|
-
return Reflect.get(tk, prop, tk);
|
|
31738
|
-
},
|
|
31739
|
-
});
|
|
32128
|
+
const $$1 = _$;
|
|
31740
32129
|
// #endregion
|
|
31741
32130
|
|
|
31742
32131
|
var _a;
|
|
@@ -32226,7 +32615,7 @@ function filterModelProperties(program, model, filter) {
|
|
|
32226
32615
|
return model;
|
|
32227
32616
|
}
|
|
32228
32617
|
const realm = Realm.realmForType.get(model);
|
|
32229
|
-
const typekit = realm ? $$1(realm) : $$1;
|
|
32618
|
+
const typekit = realm ? $$1(realm) : $$1(program);
|
|
32230
32619
|
const newModel = typekit.model.create({
|
|
32231
32620
|
name: "",
|
|
32232
32621
|
indexer: undefined,
|
|
@@ -33611,7 +34000,7 @@ let manifest;
|
|
|
33611
34000
|
try {
|
|
33612
34001
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
33613
34002
|
// @ts-ignore
|
|
33614
|
-
manifest = (await import('../manifest-
|
|
34003
|
+
manifest = (await import('../manifest-DR_CKuUi.js')).default;
|
|
33615
34004
|
}
|
|
33616
34005
|
catch {
|
|
33617
34006
|
const name = "../dist/manifest.js";
|