Skip to content

Commit 3088ecb

Browse files
committed
feat: Create definitions for pseudo modules
1 parent cd36baf commit 3088ecb

File tree

4 files changed

+219
-4
lines changed

4 files changed

+219
-4
lines changed

npm-shrinkwrap.json

Lines changed: 77 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"unit-debug": "ava debug",
4444
"unit-update-snapshots": "ava --update-snapshots",
4545
"unit-watch": "ava --watch",
46-
"update-semantic-model-info": "tsx scripts/metadataProvider/createMetadataInfo.ts"
46+
"update-semantic-model-info": "tsx scripts/metadataProvider/createMetadataInfo.ts",
47+
"update-pseudo-modules-info": "tsx scripts/metadataProvider/createPseudoModulesInfo.ts"
4748
},
4849
"files": [
4950
"CHANGELOG.md",
@@ -83,6 +84,7 @@
8384
"@types/he": "^1.2.3",
8485
"@types/node": "^20.12.2",
8586
"@types/sinon": "^17.0.3",
87+
"@types/unzip-stream": "^0.3.4",
8688
"@types/yargs": "^17.0.32",
8789
"@ui5-language-assistant/semantic-model": "^3.3.1",
8890
"@ui5-language-assistant/semantic-model-types": "^3.3.1",
@@ -97,6 +99,7 @@
9799
"semver": "^7.6.0",
98100
"sinon": "^17.0.1",
99101
"tsx": "^4.7.1",
100-
"typescript-eslint": "^7.4.0"
102+
"typescript-eslint": "^7.4.0",
103+
"unzip-stream": "^0.3.1"
101104
}
102105
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import {pipeline} from "node:stream/promises";
2+
import {Extract} from "unzip-stream";
3+
import MetadataProvider from "./MetadataProvider.js";
4+
import {writeFile} from "node:fs/promises";
5+
6+
import type {UI5Enum} from "@ui5-language-assistant/semantic-model-types";
7+
8+
const RAW_API_JSON_FILES_FOLDER = "tmp/apiJson";
9+
10+
async function downloadAPIJsons(url: string) {
11+
const response = await fetch(url);
12+
if (!response.ok) {
13+
throw new Error(`unexpected response ${response.statusText}`);
14+
}
15+
16+
if (response.body && response.body instanceof ReadableStream) {
17+
await pipeline(response.body, Extract({path: RAW_API_JSON_FILES_FOLDER}));
18+
} else {
19+
throw new Error("Malformed response");
20+
}
21+
}
22+
23+
async function transformFiles() {
24+
const metadataProvider = new MetadataProvider();
25+
await metadataProvider.init(RAW_API_JSON_FILES_FOLDER);
26+
27+
const {enums} = metadataProvider.getModel();
28+
29+
const groupedEnums = Object.keys(enums).reduce((acc: Record<string, UI5Enum[]>, enumKey: string) => {
30+
const curEnum = enums[enumKey];
31+
32+
acc[curEnum.library] = acc[curEnum.library] ?? [];
33+
acc[curEnum.library].push(curEnum);
34+
35+
return acc;
36+
}, Object.create(null));
37+
38+
await addOverrides(groupedEnums);
39+
}
40+
41+
async function addOverrides(enums: Record<string, UI5Enum[]>) {
42+
const indexFilesImports: string[] = [];
43+
const buildJSDoc = (enumEntry: UI5Enum, indent: string = "") => {
44+
const jsDocBuilder: string[] = [`${indent}/**`];
45+
46+
if (enumEntry.description) {
47+
jsDocBuilder.push(`${indent} * ${enumEntry.description.replaceAll("\n", "\n" + indent + " * ")}`);
48+
jsDocBuilder.push(`${indent} *`);
49+
}
50+
51+
if (enumEntry.experimentalInfo) {
52+
let experimental: string = `${indent} * @experimental`;
53+
if (enumEntry.experimentalInfo.since) {
54+
experimental += ` (since ${enumEntry.experimentalInfo.since})`;
55+
}
56+
if (enumEntry.experimentalInfo.text) {
57+
experimental += ` - ${enumEntry.experimentalInfo.text}`;
58+
}
59+
jsDocBuilder.push(experimental);
60+
}
61+
62+
if (enumEntry.deprecatedInfo) {
63+
let deprecated: string = `${indent} * @deprecated`;
64+
if (enumEntry.deprecatedInfo.since) {
65+
deprecated += ` (since ${enumEntry.deprecatedInfo.since})`;
66+
}
67+
if (enumEntry.deprecatedInfo.text) {
68+
deprecated += ` - ${enumEntry.deprecatedInfo.text}`;
69+
}
70+
jsDocBuilder.push(deprecated);
71+
}
72+
73+
if (enumEntry.visibility) {
74+
jsDocBuilder.push(`${indent} * @${enumEntry.visibility}`);
75+
}
76+
77+
if (enumEntry.since) {
78+
jsDocBuilder.push(`${indent} * @since ${enumEntry.since}`);
79+
}
80+
jsDocBuilder.push(`${indent}*/`);
81+
82+
return jsDocBuilder.join("\n");
83+
}
84+
85+
Object.keys(enums).forEach(async (libName) => {
86+
const enumEntries = enums[libName];
87+
88+
let stringBuilder: string[] = [
89+
`declare module "${libName.replaceAll(".", "/")}/library" {`
90+
];
91+
enumEntries.forEach((enumEntry) => {
92+
if (enumEntry.kind !== "UI5Enum") {
93+
return;
94+
}
95+
96+
stringBuilder.push(buildJSDoc(enumEntry, "\t"));
97+
stringBuilder.push(`\texport enum ${enumEntry.name} {`);
98+
enumEntry.fields.forEach((value) => {
99+
stringBuilder.push(buildJSDoc(value, "\t\t"));
100+
stringBuilder.push(`\t\t${value.name} = "${value.name}",`);
101+
});
102+
stringBuilder.push(`\t}`);
103+
104+
return stringBuilder.join("\n");
105+
});
106+
stringBuilder.push(`}`)
107+
108+
indexFilesImports.push(`import "./${libName}";`);
109+
await writeFile(
110+
new URL(`../../resources/overrides/library/${libName}.d.ts`, import.meta.url),
111+
stringBuilder.join("\n")
112+
);
113+
});
114+
115+
await writeFile(
116+
new URL(`../../resources/overrides/library/index.d.ts`, import.meta.url),
117+
indexFilesImports.join("\n")
118+
);
119+
}
120+
121+
async function main(url: string) {
122+
await downloadAPIJsons(url);
123+
124+
await transformFiles();
125+
}
126+
127+
try {
128+
const url = process.argv[2];
129+
if (!url) {
130+
throw new Error("second argument \"url\" is missing");
131+
}
132+
await main(url);
133+
} catch (err) {
134+
process.stderr.write(String(err));
135+
process.exit(1);
136+
}

scripts/metadataProvider/model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export async function createSemanticModel(apiJsonsRoot: string): Promise<UI5Sema
7171
console.error = () => {};
7272
}
7373
model = generate({
74-
version: "1.120.9",
74+
version: "1.120.11",
7575
libraries: indexJson,
7676
typeNameFix: getTypeNameFix(),
7777
strict: false, // Throw instead of log errors

0 commit comments

Comments
 (0)