@ui5/linter
Version:
A static code analysis tool for UI5
184 lines • 7.33 kB
JavaScript
import { readFile } from "node:fs/promises";
;
export class ApiExtractImpl {
data;
constructor(data) {
this.data = data;
}
/**
* Checks whether a given option is part of a UI5 symbol.
* @example doesOptionExist("sap.m.App", "backgroundColor", "property")
* returns true
* @example doesOptionExist("sap.m.App", "pages", "property") // pages is an aggregation
* returns false
*/
doesOptionExist(symbolName, optionName, optionType, checkBorrowed = true) {
let foundSymbolRecord = this.data.metadata[symbolName];
// Check own options and resolve borrowed options with "extends":
while (foundSymbolRecord) {
if (foundSymbolRecord[optionType]?.includes(optionName)) {
return true;
}
if (checkBorrowed && foundSymbolRecord.extends) {
foundSymbolRecord = this.data.metadata[foundSymbolRecord.extends];
}
else {
break;
}
}
return false;
}
/**
* Returns all options of a given option type in a UI5 symbol.
* (not including borrowed ones is optional)
* @example getAllOptionsByType("sap.m.App", "property", false)
* returns ["backgroundColor", "backgroundImage", "backgroundRepeat", *etc.*]
* @example getAllOptionsByType("sap.m.App", "notExistingOptionType")
* returns []
* @example getAllOptionsByType("sap.xyz.notExistingSymbol", "property")
* returns undefined
*/
getAllOptionsByType(symbolName, optionType, includeBorrowed = true) {
const values = [];
let foundSymbolRecord = this.data.metadata[symbolName];
if (!foundSymbolRecord) {
return undefined;
}
// Check own options and resolve borrowed options with "extends":
while (foundSymbolRecord) {
if (foundSymbolRecord[optionType]) {
values.push(...foundSymbolRecord[optionType]);
}
if (includeBorrowed && foundSymbolRecord.extends) {
foundSymbolRecord = this.data.metadata[foundSymbolRecord.extends];
}
else {
break;
}
}
return values;
}
/**
* Returns the type of a given option in a UI5 symbol record.
* (not checking borrowed ones is optional)
* @example getTypeByOption("sap.m.App", "backgroundColor")
* returns "properties"
* @example getTypeByOption("sap.m.App", "notExistingOption")
* returns undefined
* @example getTypeByOption("sap.xyz.notExistingSymbol", "backgroundColor")
* returns undefined
*/
getTypeByOption(symbolName, optionName, checkBorrowed = true) {
let foundSymbolRecord = this.data.metadata[symbolName];
// Check own types and resolve borrowed types with "extends":
while (foundSymbolRecord) {
// Loop through all keys of the symbol record:
for (const [key, value] of Object.entries(foundSymbolRecord)) {
if (key !== "extends" &&
((Array.isArray(value) && value.includes(optionName)) || value === optionName)) {
return key;
}
}
if (checkBorrowed && foundSymbolRecord.extends) {
foundSymbolRecord = this.data.metadata[foundSymbolRecord.extends];
}
else {
break;
}
}
return undefined;
}
;
/**
* Checks whether a given aggregation is part of a UI5 symbol.
* @example isAggregation("sap.m.NavContainer", "pages")
* returns true
* @example isAggregation("sap.m.App", "pages", false) // pages is a borrowed aggregation of "sap.m.NavContainer"
* returns false
*/
isAggregation(symbolName, aggregationName, checkBorrowed = true) {
return this.doesOptionExist(symbolName, aggregationName, "aggregation", checkBorrowed);
}
/**
* Checks whether a given association is part of a UI5 symbol.
* @example isAssociation("sap.m.NavContainer", "initialPage")
* returns true
* @example isAssociation("sap.m.App", "initialPage", false) // initialPage is borrowed from "sap.m.NavContainer"
* returns false
*/
isAssociation(symbolName, associationName, checkBorrowed = true) {
return this.doesOptionExist(symbolName, associationName, "association", checkBorrowed);
}
/**
* Checks whether a given property is part of a UI5 symbol.
* @example isProperty("sap.m.App", "backgroundColor")
* returns true
* @example isProperty("sap.m.App", "pages") // pages is a borrowed default aggregation of "sap.m.NavContainer"
* returns false
*/
isProperty(symbolName, propertyName, checkBorrowed = true) {
return this.doesOptionExist(symbolName, propertyName, "property", checkBorrowed);
}
/**
* Checks whether a given event is part of a UI5 symbol.
* @example isEvent("sap.m.NavContainer", "afterNavigate")
* returns true
* @example isEvent("sap.m.App", "afterNavigate", false) // afterNavigate is borrowed from "sap.m.NavContainer"
* returns false
*/
isEvent(symbolName, eventName, checkBorrowed = true) {
return this.doesOptionExist(symbolName, eventName, "event", checkBorrowed);
}
/**
* Checks whether a given method is part of a UI5 symbol.
* @example isMethod("sap.m.App", "getBackgroundColor")
* returns true
* @example isMethod("sap.m.App", "addPage", false) // addPage is borrowed from "sap.m.NavContainer"
* returns false
*/
isMethod(symbolName, methodName, checkBorrowed = true) {
return this.doesOptionExist(symbolName, methodName, "method", checkBorrowed);
}
/**
* Returns the default aggregation of a given UI5 class.
* (returns a borrowed one too)
* @example getDefaultAggregation("sap.m.App")
* returns "pages"
*/
getDefaultAggregation(symbolName) {
let foundSymbolRecord = this.data.metadata[symbolName];
// Check own defaultAggregation and resolve borrowed one with "extends":
while (foundSymbolRecord) {
if (foundSymbolRecord.defaultAggregation) {
return foundSymbolRecord.defaultAggregation;
}
if (foundSymbolRecord.extends) {
foundSymbolRecord = this.data.metadata[foundSymbolRecord.extends];
}
else {
break;
}
}
return undefined;
}
getDeprecationInfo(symbolName) {
for (const [kind, list] of Object.entries(this.data.deprecations)) {
if (list[symbolName]) {
const symbolKind = kind;
return {
symbolKind,
text: list[symbolName],
};
}
}
}
}
let resolveWithSingleton;
export async function loadApiExtract() {
resolveWithSingleton ??= (async () => {
const data = await readFile(new URL("../../resources/api-extract.json", import.meta.url), { encoding: "utf-8" });
return new ApiExtractImpl(JSON.parse(data));
})();
return resolveWithSingleton;
}
//# sourceMappingURL=ApiExtract.js.map