Skip to content

Commit b2c4d50

Browse files
authored
feat(dts-generator): allow "esmOnly" in directives and "readonly" props (#491)
"esmOnly" can be used as property of entire overlays as well as of single methods and properties. An ObjectProperty in api.json or an overlay for it can now be "readonly".
1 parent 00c72f3 commit b2c4d50

File tree

7 files changed

+40
-10
lines changed

7 files changed

+40
-10
lines changed

packages/dts-generator/api-report/dts-generator.api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ export interface Directives {
5252
[orgNamespace: string]: true | [true] | [true, "keep_original_ns"];
5353
};
5454
overlays: {
55-
[libraryName: string]: ConcreteSymbol[];
55+
[libraryName: string]: (ConcreteSymbol & {
56+
esmOnly?: boolean;
57+
})[];
5658
};
5759
typeTyposMap: {
5860
[orgType: string]: string;

packages/dts-generator/src/generate-from-objects.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export interface Directives {
8282
* mapped to TypeScript and cannot be changed in a compatible way.
8383
*/
8484
overlays: {
85-
[libraryName: string]: ConcreteSymbol[];
85+
[libraryName: string]: (ConcreteSymbol & { esmOnly?: boolean })[];
8686
};
8787

8888
/**
@@ -160,6 +160,7 @@ export async function generateFromObjects(config: GenerateFromObjectsConfig) {
160160
apiObject,
161161
actualOptions.dependencyApiObjects,
162162
actualOptions.directives,
163+
actualOptions.generateGlobals,
163164
);
164165

165166
// Phase 2 - jsonToAst:

packages/dts-generator/src/phases/dts-code-gen.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ function genField(ast: Variable) {
630630
text += JSDOC(ast) + NL;
631631
text += applyTsIgnore(ast);
632632
text += ast.static ? "static " : "";
633+
text += ast.readonly ? "readonly " : "";
633634
text +=
634635
`${ast.name} : ${ast.type ? genType(ast.type, "property") : "any"}` + NL;
635636
return text;

packages/dts-generator/src/phases/json-fixer.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ const preparedCache = new Map();
3131
* @param apijson
3232
* @param directives
3333
*/
34-
function mergeOverlays(apijson: ApiJSON, directives: Directives) {
34+
function mergeOverlays(
35+
apijson: ApiJSON,
36+
directives: Directives,
37+
options = { generateGlobals: false },
38+
) {
3539
const overlays = directives.overlays && directives.overlays[apijson.library];
3640
if (overlays == null) {
3741
return; // no overlays defined
@@ -81,25 +85,36 @@ function mergeOverlays(apijson: ApiJSON, directives: Directives) {
8185
}
8286

8387
overlays.forEach((overlay) => {
88+
// do not generate esm-only symbols if generateGlobals is set
89+
if (overlay.esmOnly && options.generateGlobals) {
90+
return;
91+
}
8492
log.verbose(` ${overlay.name}`);
8593
const symbol = find(overlay.name);
8694
if (symbol == null) {
8795
// addition
8896
apijson.symbols.push(overlay);
8997
return;
9098
}
91-
// overlay
99+
// overlay needs to be merged into existing symbol
92100
Object.keys(overlay).forEach((prop) => {
93101
if (prop == "name") {
94102
return; // ignore name property, it's the 'primary key' and can't be changed
95103
}
96104
if (mapLikeProperties.has(prop)) {
97-
if (!Array.isArray(symbol[prop])) {
98-
symbol[prop] = overlay[prop];
105+
// = methods, properties
106+
if (!Array.isArray(symbol[prop]) && Array.isArray(overlay[prop])) {
107+
symbol[prop] = overlay[prop].filter(
108+
(item) => !options.generateGlobals || !item.esmOnly,
109+
);
99110
return;
100111
}
101112
const symbolItems: ConcreteSymbol[] = symbol[prop];
102113
overlay[prop].forEach((overlayItem: ConcreteSymbol) => {
114+
if (overlayItem.esmOnly && options.generateGlobals) {
115+
// skip esm-only ones in globals mode
116+
return;
117+
}
103118
const item = symbolItems.find(
104119
(symbolItem) =>
105120
symbolItem.name === overlayItem.name &&
@@ -864,9 +879,9 @@ function markDeprecatedAliasesForEnums(
864879
function _prepareApiJson(
865880
json: ApiJSON,
866881
directives: Directives,
867-
options = { mainLibrary: false },
882+
options = { mainLibrary: false, generateGlobals: false },
868883
) {
869-
mergeOverlays(json, directives);
884+
mergeOverlays(json, directives, { generateGlobals: options.generateGlobals });
870885
substituteSapClassInfoTypedef(json);
871886
convertCoreAndConfigurationIntoANamespace(json, directives);
872887
moveTypeParametersFromConstructorToClass(json);
@@ -904,17 +919,22 @@ export function fixApiJsons(
904919
targetLibJson: ApiJSON,
905920
dependencies: ApiJSON[],
906921
directives: Directives,
922+
generateGlobals?: boolean,
907923
) {
908924
// Part 1: "prepare JSON"
909925
let targetLibFixedJson = _prepareApiJson(targetLibJson, directives, {
910926
mainLibrary: true,
927+
generateGlobals,
911928
});
912929

913930
let depsFixedJsons: ApiJSON[] = dependencies.map((depjson) => {
914931
const key = `${depjson.library}-${depjson.version}`;
915932
let preparedjson = preparedCache.get(key);
916933
if (!preparedjson) {
917-
preparedjson = _prepareApiJson(depjson, directives);
934+
preparedjson = _prepareApiJson(depjson, directives, {
935+
mainLibrary: false,
936+
generateGlobals,
937+
});
918938
preparedCache.set(key, preparedjson);
919939
}
920940
return JSON.parse(JSON.stringify(preparedjson)); // cloning needed to avoid multiple processing within the subsequent steps; // TODO: but this can likely be improved

packages/dts-generator/src/phases/json-to-ast.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,14 +1197,18 @@ const buildNestedTypedefs = _.partialRight(
11971197
* @returns
11981198
*/
11991199
function buildVariable(property: ObjProperty): Variable {
1200-
assertKnownProps(["examples", "name", "type", "value", "optional"], property);
1200+
assertKnownProps(
1201+
["examples", "name", "type", "value", "optional", "esmOnly", "readonly"],
1202+
property,
1203+
);
12011204

12021205
const astNode: Variable = {
12031206
kind: "Variable",
12041207
name: property.name,
12051208
static: property.static === true,
12061209
type: buildType(property.type),
12071210
visibility: property.visibility,
1211+
readonly: property.readonly === true,
12081212
optional: property.optional === true,
12091213
};
12101214

packages/dts-generator/src/types/api-json.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ export interface ObjProperty {
257257
export?: string;
258258
resource?: string;
259259
visibility?: "public" | "protected" | "private" | "restricted";
260+
readonly?: boolean;
260261
static?: boolean;
261262
type: string;
262263
description?: string;

packages/dts-generator/src/types/ast.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export interface Variable extends AstNode, UI5JSDocs {
129129
static?: boolean;
130130
type: Type;
131131
visibility: UI5Visibility;
132+
readonly?: boolean;
132133
optional: boolean;
133134
}
134135

0 commit comments

Comments
 (0)