1
0
mirror of https://github.com/simple-icons/simple-icons.git synced 2024-11-16 00:59:07 +02:00
simple-icons/scripts/release/update-sdk-ts-defs.js
2024-09-29 22:28:34 +08:00

121 lines
3.5 KiB
JavaScript

#!/usr/bin/env node
/**
* @file
* Updates the SDK Typescript definitions located in the file sdk.d.ts
* to match the current definitions of functions of sdk.mjs.
*/
import {execSync} from 'node:child_process';
import fs from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';
import {getDirnameFromImportMeta} from '../../sdk.mjs';
const __dirname = getDirnameFromImportMeta(import.meta.url);
const rootDirectory = path.resolve(__dirname, '..', '..');
const sdkTs = path.resolve(rootDirectory, 'sdk.d.ts');
const sdkMts = path.resolve(rootDirectory, 'sdk.d.mts');
const sdkMjs = path.resolve(rootDirectory, 'sdk.mjs');
const generateSdkMts = async () => {
// Remove temporally type definitions imported with comments
// in sdk.mjs to avoid circular imports
const originalSdkMjsContent = await fs.readFile(sdkMjs, 'utf8');
const temporarySdkMjsContent = originalSdkMjsContent
.split('\n')
.filter((line) => {
return !line.startsWith(' * @typedef {import("./sdk")');
})
.join('\n');
await fs.writeFile(sdkMjs, temporarySdkMjsContent);
try {
execSync(
'npx tsc sdk.mjs' +
' --declaration --emitDeclarationOnly --allowJs --removeComments',
);
} catch (/** @type {unknown} */ error) {
await fs.writeFile(sdkMjs, originalSdkMjsContent);
let errorMessage = error;
if (error instanceof Error) {
// The `execSync` function throws a generic Node.js Error
errorMessage = error.message;
}
process.stdout.write(
`Error generating Typescript definitions: '${errorMessage}'\n`,
);
process.exit(1);
}
await fs.writeFile(sdkMjs, originalSdkMjsContent);
};
/**
* We must remove the duplicated export types that tsc generates from
* JSDoc `typedef` comments.
* See {@link https://github.com/microsoft/TypeScript/issues/46011}.
* @param {string} content Content of the file.
* @returns {string} The content without duplicated export types.
*/
const removeDuplicatedExportTypes = (content) => {
const newContent = [];
const lines = content.split('\n');
/** @type {string[]} */
const exportTypesFound = [];
for (const line of lines) {
if (line.startsWith('export type ')) {
const type = line.split(' ')[2];
if (!exportTypesFound.includes(type)) {
newContent.push(line);
exportTypesFound.push(type);
}
} else {
newContent.push(line);
}
}
return newContent.join('\n');
};
const generateSdkTs = async () => {
const fileExists = await fs
.access(sdkMts)
.then(() => true)
.catch(() => false);
if (fileExists) await fs.unlink(sdkMts);
await generateSdkMts();
const autogeneratedMessage =
'/* The next code is autogenerated from sdk.mjs */\n/* eslint-disable */';
const newSdkTsContent =
// eslint-disable-next-line unicorn/no-await-expression-member
(await fs.readFile(sdkTs, 'utf8')).split(autogeneratedMessage)[0] +
`${autogeneratedMessage}\n\n${await fs.readFile(sdkMts, 'utf8')}`;
await fs.writeFile(sdkTs, removeDuplicatedExportTypes(newSdkTsContent));
await fs.unlink(sdkMts);
try {
execSync('npx prettier -w sdk.d.ts');
} catch (error) {
let errorMessage = error;
if (error instanceof Error) {
// The `execSync` function throws a generic Node.js Error
errorMessage = error.message;
}
process.stdout.write(
'Error executing Prettier to prettify' +
` SDK TS definitions: '${errorMessage}'` +
'\n',
);
process.exit(1);
}
};
await generateSdkTs();